分类: LINUX
2009-08-14 09:18:50
守护进程在很多时候被唤醒,主要是:
1. 设备启动(do_md_run)
2. 用户人工操作时(action_store,md_ioctl)
3. 增加磁盘(add_new_disk)
4. 设备错误(md_error)
5. 同步出错时(md_done_sync)
6. 更新设备超级块时(md_write_start)
7. 写操作结束(md_write_end)
8. 位图从磁盘读出,初始化完成时(bitmap_init_from_disk)
9. RAID1读操作全部结束时(reschedule_retry)
10. RAID1设备unplug操作
守护进程的主要工作是处理设备的两个队列(pending_bio_list,retry_list)完成如下工作:
1. 调用md_check_recovery,进行是否需要同步操作的检查,这个函数在判断需要同步时,激活同步守护进程。
2. 如果有等待的访问请求(pending_bio_list队列不为空),则将这些请求逐一提交。注意在提交写访问前,需要将bitmap内存进行刷新,保证在数据写入前完成bitmap的写入。直到pending_bio_list所有请求全部提交,继续进行3。
3. 如果retry链表也为空,则结束守护进程。在读写访问失败,以及同步操作的读阶段结束(不管成功还是失败)时,由reschedule_retry函数将相关的raid-bio加入到Retry链表。
4. 取出retry队列中的最后一个raid-bio,如果是同步操作放入队列的,则调用sync_request_write处理(由于已经完成读阶段的操作,如果读成功的话,这次调用就是完成下半部分的写工作)。
5. 如果raid-bio是因为设置了路障属性,而子设备又不支持路障而失败的(这个情况只发生在写操作),则清除raid-bio的路障属性,重新提交这个raid-bio。
6. 如果是读失败,则冻结磁阵,尝试修复失败。然后磁阵中另外找一个磁盘,提交该bio。
7. 4,5,6处理后,都转向2重新处理,整个循环只有3可以退出,也就是两个队列全部为空的情况下,守护进程结束。