加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux内核md源代码解读 八 阵列同步二:同步过程

发布时间:2016-01-18 12:31:33 所属栏目:Linux 来源:网络整理
导读:在上一小节里讲到启动同步线程: 7824 mddev-sync_thread = md_register_thread(md_do_sync, 7825 mddev, 7826 resync); md_register_thread函数如下: 6697 st
副标题[/!--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行,是用磁盘分区创建的阵列同步互斥用的。商业化的阵列没有必要用磁盘分区做阵列的,所以直接跳过。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读