AFAIK,实现是在用户空间中,它基本上通过命令使用内核的设备映射器机制(模块)来lvm
设置映射表。dm-mod
dmsetup
这就是最终导致的事件顺序,这是否正确/dev/dm-x
?
- 块设备上线
udev
触发一条规则,扫描块设备的分区,并识别分区中前几个扇区中的lvm卷组/逻辑卷元数据(通过dmsetup
?)- 然后该
udev
规则加载该dm-mod
模块,并调用 dmsetup 来创建一个名为 的新设备/dev/dm-x
,并使用上述元数据设置映射表。 - 其他一些
udev
规则创建符号链接,例如/dev/mapper/vg_name-lv_name
以下是问题,
- 哪个特定
udev
规则加载dm-mod
模块? - 哪个特定
udev
规则创建该文件/dev/mapper/control
? - 哪个特定
udev
规则创建/dev/dm-x
文件?
我大致知道它们应该来自xx-dm.rules
(稍后xx-dm-lvm.rules
仅添加/dev/vg_name/lv_name
符号链接),但是该文件中的哪些行正是执行这些操作?
答案1
您的事件顺序大部分是正确的,但以下情况除外:
udev
不会触发dm_mod
内核模块的加载,kmod
是这样的。pvscan
与 LVM 最相关的 udev 规则是导致在新的类似磁盘和分区的块设备上调用的规则。pvscan
通常是包含所有 LVM 工具的单个多调用二进制文件的一部分,并用于libdevmapper
直接与设备映射器通信,而无需调用dmsetup
.- LVM 工具二进制文件还直接负责读取 LVM 元数据并指定符号链接名称,尽管
udev
实际上最终由低级工作人员完成创建链接的工作。
哪个特定
udev
规则加载dm-mod
模块?
udev
这里不涉及。这是由devtmpfs
文件系统和kmod
子系统处理的。当任何东西试图访问不存在的/dev/mapper/control
设备时,devtmpfs
将搁置该请求,并启动kmod
子系统加载适当模块的请求。它最终本质上是运行,它是中定义的modprobe devname:mapper/control
别名,在内核安装或启动时从内核模块文件中的元数据收集。dm_mod
/lib/modules/$(uname -r)/modules.alias
depmod
一旦模块被加载并初始化(并且它已经创建了预期的设备节点),访问尝试就会恢复并执行,就像设备节点一直存在一样。
哪个特定
udev
规则创建该文件/dev/mapper/control
?
该设备节点可能根本没有udev
规则,或者只是一些特定于发行版的规则来调整最终设备的权限。当dm_mod
内核模块初始化时,它使用misc_register()
内核函数来启动设备节点创建过程,内核代码为其指定默认名称和其他默认参数。由于/dev/mapper/control
是用于控制设备映射器子系统的标准静态设备名称,因此通常没有理由过多更改默认值。
哪个特定
udev
规则创建/dev/dm-x
文件?
同样,udev
不会发起设备的创建 - 当调用内核函数时,主动权来自内核内的设备映射器子系统register_blkdev()
。一旦设备映射器指定它想要创建一个设备(具有指定的默认名称和其他默认属性),udev
只能调整该请求的参数并将其他操作链接到设备事件,然后根据内核的 request + udev 规则,使用用户空间mknod()
系统调用来完成设备节点创建请求。
如果没有适用于该请求的 udev 规则,udev
则将仅使用设备映射器内核代码指定的默认名称、所有权、权限和其他属性创建设备。当更高级别的子系统(即此处的 LVM)请求创建新映射时,其中一些参数可能已由更高级别的子系统指定。
您可以为新设备创建任意数量的 udev 规则,但除非某些内核代码调用来注册与这些规则的参数匹配的设备,否则这些规则将闲置,不执行任何操作。
现代内核函数register_blkdev()
将register_chrdev()
让调用者仅指定设备名称,因为长期目标是使大多数/所有设备主/次编号动态分配,并让 udev 处理任何权限的分配。但旧版本misc_register()
允许指定整个设备结构,允许创建具有静态主/次节点号和其他属性的设备。
套用质量效应 2 的话:内核决定什么时候创建一个设备;udev
决定如何为其创建一个设备节点。