linux内核md源代码解读 八 阵列同步二:同步过程
副标题[/!--empirenews.page--] 在上一小节里讲到启动同步线程: 7824 mddev->sync_thread = md_register_thread(md_do_sync, 7825 mddev, 7826 "resync"); md_register_thread函数如下: 6697 struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev *mddev, 6698 const char *name) 6699 { 6700 struct md_thread *thread; 6701 6702 thread = kzalloc(sizeof(struct md_thread), GFP_KERNEL); 6703 if (!thread) 6704 return NULL; 6705 6706 init_waitqueue_head(&thread->wqueue); 6707 6708 thread->run = run; 6709 thread->mddev = mddev; 6710 thread->timeout = MAX_SCHEDULE_TIMEOUT; 6711 thread->tsk = kthread_run(md_thread, thread, 6712 "%s_%s", 6713 mdname(thread->mddev), 6714 name); 6715 if (IS_ERR(thread->tsk)) { 6716 kfree(thread); 6717 return NULL; 6718 } 6719 return thread; 6720 } 我相信所有拿过程序员证书,北大青鸟证书的哥们看这些代码是轻而易举,然而我没上过这些培训学校,也没有拿过程序员证,实在是惭愧啊。这在很大程度上拖了广大技术人员的后腿,于是心里十分忐忑,特别是上海火灾是临时工所为,火车票系统出错是程序员无证上岗所为。想想在学校时老师教育我们:难道你们四年的学习都比不上一张证书,老师四年的培养都比不上一张程序员证吗?当时准备报名考试的我顿时就羞愧难当了。然而社会就是社会从来都没有哪次求职说要程序员证。但最怕的还是有关部门,哪天都有可能被抓去判个无证上岗。 这个函数有两个看点: 6706行,初始化等待队列,在此等待队列上休眠的线程正是md_thread,那又是谁来唤醒的呢?唤醒的函数都叫wakeup,那就find symbol看一下有没有叫md wakeup的函数,果真有md_wakeup_thread()函数。所以下次看到这个函数的时候就知道轮到线程处理啦。 6711行,创建一个线程,先关心一下线程的名字,是md名和作用名的结合。当这里执行完成之后,在用户态ps一下就能看到这个线程了。除了线程名字,我们还关心这个线程做什么?运行的是md_thread()函数,这个函数只是提供了一个线程运行模板,真正做的事情是函数传进来的run函数。回到7824行,我们知道同步真正做事情的是md_do_sync。 于是我们就跟进md_do_sync函数: 7245 #define SYNC_MARKS 10 7246 #define SYNC_MARK_STEP (3*HZ) 7247 void md_do_sync(struct mddev *mddev) 7248 { 7249 struct mddev *mddev2; 7250 unsigned int currspeed = 0, 7251 window; 7252 sector_t max_sectors,j, io_sectors; 7253 unsigned long mark[SYNC_MARKS]; 7254 sector_t mark_cnt[SYNC_MARKS]; 7255 int last_mark,m; 7256 struct list_head *tmp; 7257 sector_t last_check; 7258 int skipped = 0; 7259 struct md_rdev *rdev; 7260 char *desc; 7261 struct blk_plug plug; 7262 7263 /* just incase thread restarts... */ 7264 if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) 7265 return; 7266 if (mddev->ro) /* never try to sync a read-only array */ 7267 return; 7268 7269 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { 7270 if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) 7271 desc = "data-check"; 7272 else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) 7273 desc = "requested-resync"; 7274 else 7275 desc = "resync"; 7276 } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) 7277 desc = "reshape"; 7278 else 7279 desc = "recovery"; 7264行,检查同步是否完成,再次友情提醒,这里的同步是指广义上的同步。 7266行,只读阵列就不要同步了。 7269行之后,设置线程打印信息。 7279-7345行,是用磁盘分区创建的阵列同步互斥用的。商业化的阵列没有必要用磁盘分区做阵列的,所以直接跳过。 (编辑:徐州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |