linux内核奇遇记之md源代码解读之二
linux-dash
A beautiful web dashboard for Linux
项目地址:https://gitcode.com/gh_mirrors/li/linux-dash
免费下载资源
·
linux内核奇遇记之md源代码解读之二
转载请注明出处:http://blog.csdn.net/liumangxiong
在编译完成linux内核源代码的时候,drivers/md目录下会生成多个ko文件,那么这些内核模块哪一个先加载,哪一个后加载的呢?例如md-mod.ko, raid5.ko, raid10.ko,这些模块是一起加载的呢,还是有先后顺序呢?如果熟悉linux内核编程的话,知道有一个request_module函数,这个函数用于请求加载一个模块,但这个函数并不能说明一个模块对另一个模块的依赖关系。准确的信息还是来自于Kconfig,这里只抽取Kconfig中相关的部分:
config BLK_DEV_MD
tristate "RAID support"
tristate "RAID support"
config MD_RAID10
tristate "RAID-10 (mirrored striping) mode"
depends on BLK_DEV_MD
tristate "RAID-10 (mirrored striping) mode"
depends on BLK_DEV_MD
config MD_RAID456
tristate "RAID-4/RAID-5/RAID-6 mode"
depends on BLK_DEV_MD
tristate "RAID-4/RAID-5/RAID-6 mode"
depends on BLK_DEV_MD
从这里我们可以看出,raid5.ko, raid10.ko都是依赖于md-mod.ko的,这就决定了我们的阅读方向是从md-mod.ko中开始的。
那么md-mod.ko中又是从哪个文件开始的呢?这就要找module_init函数,这个函数在md.c中定义的,那么就从这里入手。
8416 static int __init md_init(void) 8417 { 8418 int ret = -ENOMEM; 8419 8420 md_wq = alloc_workqueue("md", WQ_MEM_RECLAIM, 0); 8421 if (!md_wq) 8422 goto err_wq; 8423 8424 md_misc_wq = alloc_workqueue("md_misc", 0, 0); 8425 if (!md_misc_wq) 8426 goto err_misc_wq; 8427 8428 if ((ret = register_blkdev(MD_MAJOR, "md")) < 0) 8429 goto err_md; 8430 8431 if ((ret = register_blkdev(0, "mdp")) < 0) 8432 goto err_mdp; 8433 mdp_major = ret; 8434 8435 blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE, 8436 md_probe, NULL, NULL); 8437 blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE, 8438 md_probe, NULL, NULL); 8439 8440 register_reboot_notifier(&md_notifier); 8441 raid_table_header = register_sysctl_table(raid_root_table); 8442 8443 md_geninit(); 8444 return 0; 8445 8446 err_mdp: 8447 unregister_blkdev(MD_MAJOR, "md"); 8448 err_md: 8449 destroy_workqueue(md_misc_wq); 8450 err_misc_wq: 8451 destroy_workqueue(md_wq); 8452 err_wq: 8453 return ret; 8454 }
模块的初始化过程看起来异常地简单,这就像有些人表面看起来十分普通,内心里却无比地强大,所以不要只看外表,还要听其言观其行。内在的美丽比外表的荣华更具吸引力和持久性。
8420和8424行,分别创建了工作队列,md_wq是用于flush命令的,另一个md_misc_wq,misc是miscellaneous的简写,是杂项的意思,用于处理一些零零碎碎的事情。
8428和8431行,创建了两个块设备,刚开始我只注意md的设备,压根没在意mdp,搜索变量mdp_major,在函数autorun_devices中使用了这个变量:
5474 if (part) { 5475 dev = MKDEV(mdp_major, 5476 rdev0->preferred_minor << MdpMinorShift); 5477 unit = MINOR(dev) >> MdpMinorShift; 5478 } else { 5479 dev = MKDEV(MD_MAJOR, rdev0->preferred_minor); 5480 unit = MINOR(dev); 5481 }
5474行,变量part是函数传入参数,表示磁盘第几个分区,那么就知道mdp_major中字母p是表示part的意思,而mdp_major就表示用磁盘分区创建的阵列。
8435和8437行,创建了两个region,这两个函数的作用是在用户态创建了一个/dev/md*设备时,内核态就会对应调用md_probe创建一个mddev结构体,之后在用户态对/dev/md*的操作到内核态就相应地对mddev的操作了。
8440行,注册关机回调函数,主要作用是停止阵列线程,刷数据操作。
8441行,注册sysctl函数,用于控制阵列最小和最大的sync速度。
8443行,注册proc函数,于是有了目录/proc/mdstat,该目录的显示由函数md_seq_show控制。
md初始化代码就这样轻松地完成了,可是回到我们的初衷,仍然对md设备一无所知。那么md设备是如何创建的呢?创建的过程又是怎么的呢?一个阵列拥有哪些资源?下一节我们直入核心,开始阅读阵列创建的过程。
转载请注明出处:http://blog.csdn.net/liumangxiong
GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e
added ecosystem file for PM2 4 年前
5def40a3
Add host customization support for the NodeJS version 4 年前
更多推荐
已为社区贡献5条内容
所有评论(0)