日期:2014-05-16  浏览次数:20641 次

linux内核奇遇记之md源代码解读之八阵列同步二
linux内核奇遇记之md源代码解读之八阵列同步二
转载请注明出处:http://blog.csdn.net/liumangxiong
在上一小节里讲到启动同步线程:
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