利用UDEV机制固定存储设备的名称

什么是udev
  udev为一些实际的设备提供了一个动态的设备目录,这些目录里包含这些实际设备所对应的文件。它创建或移除在/dev目录里的设备节点文件,或者重命名网络接口。
  通常udev运行udevd,如果一个设备增加进系统或者从系统中移除,它就会直接从内核中接受到这个udev的事件。
  如果udev接受到一个设备事件,它就会从它的配置(或是规则)文件(有三个位置/etc/udev/rules.d、/dev/.udev/rules.d、/lib/udev/rules.d)中去匹配从sysfs中得到的设备属性来辨识这个设备。这些rules配置文件会去比较所提供的附加(新增加进来的)的设备的信息或者指定一个设备节点名并操作符号链接名来指示udev运行附加的程序来作为设备事件的处理。

udev的组成
  udev由namedev、libsysfs和udev三部分组成。其中,namedev是设备命名子系统;libsysfs提供访问sysfs文件系统,并从中获取信息的标准接口;udev提供/dev设备节点文件的动态创建和删除策略。udev程序负责namedev和libsysfs库交互的任务,当/sbin/hotplug程序被内核调用时,udev将运行。
  udev有很多以.rules为后缀的规则文件,以行为单位,除去以“#”开头的代表注释的行外,每一行代表一个规则。每个规则分成一个或多个匹配和赋值部分。匹配部分用匹配专用的关键字来表示,相应的赋值部分用专用的关键字来表示。

udev的工作原理
  设备节点的创建,是通过sysfs接口分析dev规则文件取得设备节点号。udevd通过netlink socket通讯机制在内核和用户空间之间传递信息,来得知内核里模块的变化情况,通过hotplug机制得知设备的插入移除情况。
  内核调用kobject_uevent函数发送netlink message给用户空间,这部分工作通常无需驱动去自己处理,在统一设备模型里面,在子系统这一层面,已将这部分代码处理好了,包括在设备对应的特定的Kobject创建和移除的时候都会发送相应add和remove消息,当然前提是您在内核中配置了hotplug的支持。
  Netlink socket作为一种内核和用户空间的通信方式,不仅用在hotplug机制中,同样还应用在其他很多真正和网络相关的内核子系统中。Udevd通过标准的socket机制,创建socket连接来获取内核广播的uevent事件并解析这些uevent事件。

应用
  要使用udev自定义设备名,就需要获取到设备的相关且唯一的信息,用于书写udev规则:
在rhel5,可以使用udevinfo -a -p $(udevinfo -q path -n /dev/sdb)来获取设备信息,在rhel6,使用udevadm info -a -n /dev/sdb来获取设备信息。
  针对iscsi设备,使用udevadm info -a -n /dev/sdb可能获取不到类似序列号之类的信息,可以使用udevadm info -q all -n /dev/sdb试试,但是通常我们会这么去使用,在rhel5, scsi_id -g -s $(udevinfo -q path -n /dev/sdc)获取信息,在rhel6,scsi_id --whitelisted --replace-whitespace /dev/sdc获取信息,用作书写udev规则。

下面看看例子:
例一:
如我们rhel6系统插入了一个u盘,自动识别为/dev/sdb,而我们希望将其固定为/dev/MyUsbDisk。

则我们可以使用udevadm info -a -n /dev/sdb获取到ATTRS{serial}=="AC681DEB"信息,书写如下规则即可。
KERNEL=="sd*", SUBSYSTEMS=="usb",ATTRS{serial}=="AC681DEB",NAME="MyUsbDisk"


例二:
rhel6下,已经挂载一个iscsi target端导出的存储,没写udev规则之前,自动识别为sdc,我们想将这个iscsi存储的节点固定为叫做Idisk,如果做了分区,则sdc1固定为Idisk1。
我们书写一个udev规则
KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM="/sbin/scsi_id --whitelisted --replace-whitespace /dev/$name", RESULT=="1IET_00010001",NAME="Idisk%n"
内核检测信息是sd*,子系统信息为块设备,执行程序scsi_id --whitelisted --replace-whitespace /dev/$name,结果为1IET_00010001,则重命名节点为Idisk%n,   $name为内核检测出信息是sdb则$name=sdb,%n为内核检测信息为sdb,则%n为空,检测信息为sdb1,则%n为1,这么写的作用在于挂载iscsi导出的一个lun后,我们对这个lun进行分区的情况,如果一个lun为一个分区,则无需写上%n。

扩展:
  用如下规则之一也可实现上条规则的效果,只是上条规则在iscsi设备login时能触发,如下两条规则必须由udev触发,如手动start_udev。所以通常应使用上述规则较好。
KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM="/sbin/udevadm info -q all -n /dev/$name", RESULT=="*beaf11*", NAME="Idisk%n"
KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM="/sbin/udevadm info -q all -p %p", RESULT=="*beaf11*", NAME="Idisk%n"

关于udev的调试:
udevadm trigger是udev触发器,执行此指令也是触发rules规则,执行结果同start_udev。
udevadm test /block/sdc可以看到udev规则执行流程,显示出来的信息较多,需要从中提取需要的信息,达到调试的目的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值