udev是运行于Linux中用户态的工具程序,依赖于内核的sysfs文件系统来实现对设备的热插拔处理和设备的识别和挂载。
配置文件
配置文件默认是/etc/udev/udev.conf,这个文件一般缺省有这样几项:
- udev_root="/dev" ; udev产生的设备文件的根目录是/dev
- udev_db="/dev/.udevdb" ; 通过udev产生的设备文件形成的数据库
- udev_rules="/etc/udev/rules.d" ;用于指导udev工作的规则所在目录。
- udev_log="err" ;当出现错误时,用syslog记录错误信息。
工作流程
-
当内核检测到在系统中出现了新设备后,内核会在sysfs文件系统中为该新设备生成一项新的记录,一般sysfs文件系统会被mount到 /sys目录中。新记录是以一个或多个文件或目录的方式来表示。每个文件都包含有特定的信息。
-
udev在系统中是以守护进程的方式udevd在运行,它通过监听内核的一些广播消息(netlink机制)检测到新设备的出现,通过查找设备对应的sysfs中的记录得到设备的一些信息。
-
udev会根据/etc/udev/udev.conf文件中的udev_rules指定的目录,逐个检查该目录下的文件,这个目录下的文件都是针对某类或某个设备应该施行什么措施的规则文件。udev读取文件是按照文件名的ASCII字母顺序来读取的,如果udev一旦找到了与新加入的设备匹配的规则,udev就会根据规则定义的措施对新设备进行配置,同时不再读后续的规则文件。
规则文件
udev的规则文件以行为单位,以"#"开头的行代表注释行。其余的每一行代表一个规则。每个规则分成一个或多个“匹配”和“赋值”部分。“匹配”部分用“匹配“专用的关键字来表示,相应的“赋值”部分用“赋值”专用的关键字来表示。“匹配”关键字包括:ACTION,KERNEL,BUS, SYSFS等等,“赋值”关键字包括:NAME,SYMLINK,OWNER等等。具体详细的描述可以阅读udev的man文档。比如:
SUBSYSTEM=="net", ACTION=="add", SYSFS{address}=="00:0d:87:f6:59:f3", IMPORT="/sbin/rename_netiface %k eth0"
这个规则中的“匹配”部分有三项,分别是SUBSYSTEM,ACTION和SYSFS,而"赋值"部分有一项,是IMPORT。这个规则就是说,当系统中出现的新硬件属于net子系统范畴,系统对该硬件采取的动作是加入这个硬件,且这个硬件在SYSFS文件系统中的“address”信息等于“00: 0d..."时,对这个硬件在udev层次施行的动作是调用外部程序/sbin/rename_netiface,传递的参数有两个,一个是“%k”,代表内核对该新设备定义的名称。另一个是”eth0“。
从上面这个例子中可以看出,udev的规则的写法比较灵活的,尤其在“匹配”部分中,可以通过诸如”*“, ”?“,[a-c],[1-9]等shell通配符来灵活匹配多个匹配项。
从上面也可以知道,实际上udev是通过对内核产生的设备名增加别名的方式来达到上述目的的。因为udev是用户模式程序,不会更改内核的行为。
通过udevinfo这个实用程序可以找到那些可以作为规则文件里的匹配项的项目。使用流程大致如下:
- 把设备插入系统后,系统为设备产生了设备名(如/dev/sda)
- 用udevinfo -q path -n /dev/sda命令获取设备对应在sysfs下的路径,如/block/sda
- 再用udevinfo -a -p /sys/block/sda这个命令打印信息,这些信息实际来自于操作系统维护的sysfs链表,不同的块对应不同的路径
你就可以用这些信息来作为udev规则文件中的匹配项,但需要注意的是,同一个规则只能使用同一块中显示的信息,不能跨块书写规则。