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

linux内核奇遇记之md源代码解读之七阵列同步一
linux内核奇遇记之md源代码解读之七阵列同步一
转载请注明出处:http://blog.csdn.net/liumangxiong
阵列同步在md_do_sync,那么入口在哪里呢?就是说阵列同步触发点在哪里呢?听说过md_check_recovery吧,但这还不是同步的入口点。那raid5d函数是入口点吧?如果要认真分析起来还不算是。
真正的同步入口点在do_md_run函数,就是在运行阵列run函数之后,有这么一行:
5171         md_wakeup_thread(mddev->thread);
是这一行把raid5d唤醒的,raid5d函数如下:
4823 static void raid5d(struct md_thread *thread)
4824 {
4825         struct mddev *mddev = thread->mddev;
4826         struct r5conf *conf = mddev->private;
4827         int handled;
4828         struct blk_plug plug;
4829 
4830         pr_debug("+++ raid5d active\n");
4831 
4832         md_check_recovery(mddev);
4832行,顾名思义就是检查同步,说明这里只是同步的检查点,不是真正处理同步的地方。
raid5d剩余部分是处理数据流的地方先不看,跟进md_check_recovery,先看注释:
7672 /*
7673  * This routine is regularly called by all per-raid-array threads to
7674  * deal with generic issues like resync and super-block update.
7675  * Raid personalities that don't have a thread (linear/raid0) do not
7676  * need this as they never do any recovery or update the superblock.
7677  *
7678  * It does not do any resync itself, but rather "forks" off other threads
7679  * to do that as needed.
7680  * When it is determined that resync is needed, we set MD_RECOVERY_RUNNING in
7681  * "->recovery" and create a thread at ->sync_thread.
7682  * When the thread finishes it sets MD_RECOVERY_DONE
7683  * and wakeups up this thread which will reap the thread and finish up.
7684  * This thread also removes any faulty devices (with nr_pending == 0).
7685  *
7686  * The overall approach is:
7687  *  1/ if the superblock needs updating, update it.
7688  *  2/ If a recovery thread is running, don't do anything else.
7689  *  3/ If recovery has finished, clean up, possibly marking spares active.
7690  *  4/ If there are any faulty devices, remove them.
7691  *  5/ If array is degraded, try to add spares devices
7692  *  6/ If array has spares or is not in-sync, start a resync thread.
7693  */

这个函数通常由阵列主线程调用,用于处理同步和超级块更新等事件。没有主线程的阵列不需要调用(如线性/raid0),因为这些阵列不需要重建或更新超级块。
这个函数并不做具体事宜,只是按需启动阵列同步线程。
当阵列需要同步时,设置MD_RECOVERY_RUNNING标志,并创建同步线程。
当同步线程结束时设置MD_RECOVERY_DONE标志,并唤醒主线程回收同步线程并结束同步。