加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux内核md源代码解读 三 阵列建设的进程

发布时间:2016-10-31 07:37:35 所属栏目:Linux 来源:站长网
导读:副标题#e# 这一节我们阅读阵列的创建过程。 按照常理出牌,我们到ioctl中找阵列创建命令,md对应的ioctl函数是md_ioctl,当找对应的cmd命令字时,却完全没有类似CREATE_ARRAY的命令,那么就说明md设备并不是通过ioctl函数来创建的。其实如果我们仔细阅读一
副标题[/!--empirenews.page--]

这一节我们阅读阵列的创建过程。

按照常理出牌,我们到ioctl中找阵列创建命令,md对应的ioctl函数是md_ioctl,当找对应的cmd命令字时,却完全没有类似CREATE_ARRAY的命令,那么就说明md设备并不是通过ioctl函数来创建的。其实如果我们仔细阅读一下md_ioctl函数的原型就会发现其实创建md设备根本就不在这个地方,函数原型如下:

6303 static int md_ioctl(struct block_device *bdev, fmode_t mode,  
6304                         unsigned int cmd, unsigned long arg)

6303行,第一个参数是struct block_device*,就是说对一个块设备下发的命令,可是我们在创建md设备之前就没有对应的md块设备。

到此,线索就断了,创建设备的入口到底是在哪里呢?

此路不通,我们换一条路走。创建md设备总是要创建struct mddev结构吧,那就找哪里申请了struct mddev内存结构不就可以了吗?这个方法是可行的,可是struct mddev结构体是用kmalloc申请的,这是怎么知道的呢?因为在函数md_init中根本就没有申请struct mddev内存池的代码,只好用kmalloc申请了。我们在md.c文件中搜索kmalloc再根据结果一条条找就能找出struct mddev创建的位置。但这里我们使用一个更简便的方法,那就是申请到了struct mddev结构总要进行初始化的吧,初始化函数是mddev_init,搜索这个函数,md.c文件中只有函数mddev_find()一处调用到,很显然已经找到了struct mddev结构的创建入口了,那就接着往上层调用去找创建md设备的入口函数吧。

我们可以找到这样的调用关系,箭头表示调用关系:

mddev_find()  <--- md_alloc()  <--- md_probe()

md_probe()函数就是在模块初始化函数md_init()中调用的blk_register_region()函数中的传入参数,熟悉blk层的同学都知道,只要在用户态创建了一个md设备,就会相应调用到内核probe()函数,而这里传入的probe()函数正是md_probe()。所以创建struct mddev结构体是由用户态触发的,而不是由内核态直接进行的。如果到了今天这个时代,还把这种琐碎的事情放在内核态去做,你都不好意思说你是做linux开发的。做linux开发就是要引导时尚,崇尚简单才是美。linux内核只提供机制,不提供具体实现策略。跟机制不相关的控制命令就需要从内核搬到用户态,一方面简化了内核,突出重点,方便了内核维护,另一方面在用户态维护策略让应用程序更加灵活并且方便了调试。

这样我们就从内核态杀到了用户态,用户态程序就是大名鼎鼎的mdadm,网上随便一搜就是一大堆人云亦云的文章,但最好的文章不是在网上,而是用命令man mdadm。用命令mdadm create来创建一个阵列,这里不去阅读mdadm的代码,因为这是用户态程序不是我们阅读的重点,其次这些代码也很简单基本上学过初中英语的同学都能看得懂。我们需要知道的是mdadm create命令最终会调用mknod()函数来创建一个/dev/md*设备,这样内核也就相应有了struct mddev结构体,这时这个结构体还是一个空结构体,空的意思就是说这个阵列没有设置属性,没有对应的物理磁盘,没有运行阵列。

到这个时候既然已经有了md设备,那就轮到md_ioctl上场的时候了,这个函数对应的ioctl命令字在文件includelinuxraidmd_u.h:

36 /* ioctls */
37   
38 /* status */
39 #define RAID_VERSION            _IOR (MD_MAJOR, 0x10, mdu_version_t)  
40 #define GET_ARRAY_INFO          _IOR (MD_MAJOR, 0x11, mdu_array_info_t)  
41 #define GET_DISK_INFO           _IOR (MD_MAJOR, 0x12, mdu_disk_info_t)  
42 #define PRINT_RAID_DEBUG        _IO (MD_MAJOR, 0x13)  
43 #define RAID_AUTORUN            _IO (MD_MAJOR, 0x14)  
44 #define GET_BITMAP_FILE         _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t)  
45   
46 /* configuration */
47 #define CLEAR_ARRAY             _IO (MD_MAJOR, 0x20)  
48 #define ADD_NEW_DISK            _IOW (MD_MAJOR, 0x21, mdu_disk_info_t)  
49 #define HOT_REMOVE_DISK         _IO (MD_MAJOR, 0x22)  
50 #define SET_ARRAY_INFO          _IOW (MD_MAJOR, 0x23, mdu_array_info_t)  
51 #define SET_DISK_INFO           _IO (MD_MAJOR, 0x24)  
52 #define WRITE_RAID_INFO         _IO (MD_MAJOR, 0x25)  
53 #define UNPROTECT_ARRAY         _IO (MD_MAJOR, 0x26)  
54 #define PROTECT_ARRAY           _IO (MD_MAJOR, 0x27)  
55 #define HOT_ADD_DISK            _IO (MD_MAJOR, 0x28)  
56 #define SET_DISK_FAULTY         _IO (MD_MAJOR, 0x29)  
57 #define HOT_GENERATE_ERROR      _IO (MD_MAJOR, 0x2a)  
58 #define SET_BITMAP_FILE         _IOW (MD_MAJOR, 0x2b, int)  
59   
60 /* usage */
61 #define RUN_ARRAY               _IOW (MD_MAJOR, 0x30, mdu_param_t)  
62 /*  0x31 was START_ARRAY  */
63 #define STOP_ARRAY              _IO (MD_MAJOR, 0x32)  
64 #define STOP_ARRAY_RO           _IO (MD_MAJOR, 0x33)  
65 #define RESTART_ARRAY_RW        _IO (MD_MAJOR, 0x34)

(编辑:PHP编程网 - 黄冈站长网)

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

热点阅读