linux udev学习整理

linux udev学习整理
自2.6 核心开始,就可以使用udev 协助管理系统中各设备名称。例如,磁盘设备排序、网卡设备排序等。udev能动态地在/dev 目录里产生自定义的、标识性强的设备文件或设备链接。本文即以红旗Asianux 3.0 平台,给新加载的U盘设备自定义一个链接为例进行简要说明。

一、关于udev
2.4 内核使用devfs(设备文件系统)在设备初始化时创建设备文件,设备驱动程序可以指定设备号、所有者、用户空间等信息,devfs 运行在内核环境中,并有不少缺点:可能出现主/辅设备号不够,命名不灵活,不能指定设备名称等问题。而自2.6 内核开始,引入了sysfs 文件系统。sysfs 把连接在系统上的设备和总线组织成一个分级的文件,并提供给用户空间存取使用。udev 运行在用户模式,而非内核中。udev 的初始化脚本在系统启动时创建设备节点,并且当插入新设备——加入驱动模块——在sysfs上注册新的数据后,udev会创新新的设备节点。
udev 是一个工作在用户空间的工具,它能根据系统中硬件设备的状态动态的更新设备文件,包括设备文件的创建,删除,权限等。这些文件通常都定义在/dev 目录下,但也可以在配置文件中指定。udev 必须内核中的sysfs和tmpfs支持,sysfs 为udev 提供设备入口和uevent 通道,tmpfs 为udev 设备文件提供存放空间。
注意,udev 是通过对内核产生的设备文件修改,或增加别名的方式来达到自定义设备文件的目的。但是,udev 是用户模式程序,其不会更改内核行为。也就是说,内核仍然会创建sda,sdb等设备文件,而udev可根据设备的唯一信息来区分不同的设备,并产生新的设备文件(或链接)。而在用户的应用中,只要使用新产生的设备文件即可。
udev 的工作流程图:

二、参考文档
正如前面提到的,udev 依赖于2.6 核心上的sysfs 文件系统。因此,只有在红旗DC 5.0以上版本中才能使用。随着udev 的不断发展,不同版本的udev 规则也有不少差别,编写规则时必须注意。
因为不同版本的udev 规则定义方式不同,在编写时需特别留意。我主要是参考以下资料来了解相关规则的:
官网:http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html
man udev
Writing udev rules
使用 udev 高效、动态地管理 Linux 设备文件
udev 服务的主要配置文件在/etc/udev/udev.conf,但通常不同修改。
规 则文件是存放在/etc/udev/rules.d 目录下面,所有的规则文件都必须以.rules 作为后缀名。系统安装完毕后,该目录中就会有一些默认的规则文件,主要用于产生一些容易标识的设备符号链接。同时,一些应用程序,为了在/dev 下产生方便使用的标识符,也会放入一些规则,例如:40-multipath.rules、99-fuse.rules 等。
udev 是按照规则文件的字母顺序来解析各规则文件的,并根据匹配上的规则创建对应的设备文件或链接。所以,解析的顺序很重要,为了使自定义的规则生效,可以把规则写入较前的规则文件中,例如20-names.rules。

三、规则说明
以下规则说明来自使用 udev 高效、动态地管理 Linux 设备文件一文,与Asianux 3.0 中man udev 中的说明一致,我就不一一翻译了。
1、udev 规则的所有操作符

“==”:比较键、值,若等于,则该条件满足;
“!=”: 比较键、值,若不等于,则该条件满足;
“=”: 对一个键赋值;
“+=”:为一个表示多个条目的键赋值。
“:=”:对一个键赋值,并拒绝之后所有对该键的改动。目的是防止后面的规则文件对该键赋值。

2、udev 规则的匹配键

ACTION: 事件 (uevent) 的行为,例如:add( 添加设备 )、remove( 删除设备 )。
KERNEL: 内核设备名称,例如:sda, cdrom。
DEVPATH:设备的 devpath 路径。
SUBSYSTEM: 设备的子系统名称,例如:sda 的子系统为 block。
BUS: 设备在 devpath 里的总线名称,例如:usb。
DRIVER: 设备在 devpath 里的设备驱动名称,例如:ide-cdrom。
ID: 设备在 devpath 里的识别号。
SYSFS{filename}: 设备的 devpath 路径下,设备的属性文件“filename”里的内容。
例如:SYSFS{model}==“ST936701SS”表示:如果设备的型号为 ST936701SS,则该设备匹配该 匹配键。
在一条规则中,可以设定最多五条 SYSFS 的 匹配键。
ENV{key}: 环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键。
PROGRAM:调用外部命令。
RESULT: 外部命令 PROGRAM 的返回结果。

3、udev 的重要赋值键

NAME:在 /dev下产生的设备文件名。只有第一次对某个设备的 NAME 的赋值行为生效,之后匹配的规则再对该设备的 NAME 赋值行为将被忽略。如果没有任何规则对设备的 NAME 赋值,udev 将使用内核设备名称来产生设备文件。
SYMLINK:为 /dev/下的设备文件产生符号链接。由于 udev 只能为某个设备产生一个设备文件,所以为了不覆盖系统默认的 udev 规则所产生的文件,推荐使用符号链接。
OWNER, GROUP, MODE:为设备设定权限。
ENV{key}:导入一个环境变量。

4、udev 的值和可调用的替换操作符
Linux 用户可以随意地定制 udev 规则文件的值。例如:my_root_disk, my_printer。同时也可以引用下面的替换操作符:

$kernel, %k:设备的内核设备名称,例如:sda、cdrom。
$number, %n:设备的内核号码,例如:sda3 的内核号码是 3$devpath, %p:设备的 devpath路径。
$id, %b:设备在 devpath里的 ID 号。
$sysfs{file}, %s{file}:设备的 sysfs里 file 的内容。其实就是设备的属性值。
$env{key}, %E{key}:一个环境变量的值。
$major, %M:设备的 major 号。
$minor %m:设备的 minor 号。
$result, %c:PROGRAM 返回的结果。
$parent, %P:父设备的设备文件名。
$root, %r:udev_root的值,默认是 /dev/。
$tempnode, %N:临时设备名。
%%:符号 % 本身。
$$:符号 $ 本身。

四、配置文件
一般放在/etc/udev/和/lib/udev/。udev的主配置文件是/etc/udev/udev.conf,里面主要设置
udev_root和udev_log。udev_root指定放置设备结点的位置,默认是/dev。udev_log保存记录优先级,有效的值为err, info和debug或者syslog优先级支持的数字。
udev的规则文件
一般存放在/lib/udev/rules.d/和/etc/udev/rules.d/,前者存放默认的规则,后者存放自定义的规则。还有一个存放临时规则的目录/run/udev/rules.d/。这些规则汇总后按字母排序。但是/etc/udev/rules.d/下面的同名规则优先于/lib/udev/rules.d/默认的规则。

五、编写udev规则文件
匹配键和赋值键操作符解释见下表:

操作符     匹配或赋值                         解释
----------------------------------------
     ==            匹配              相等比较
     !=            匹配              不等比较
     =             赋值              分配一个特定的值给该键,他可以覆盖之前的赋值.
     +=            赋值              追加特定的值给已经存在的键
     :=            赋值              分配一个特定的值给该键,后面的规则不可能覆盖它.

udev规则匹配表:

键                含义
----------------------------------------
ACTION               事件 (uevent) 的行为,例如:add( 添加设备 )、remove( 删除设备 ).
KERNEL               在内核里看到的设备名字,比如sd*表示任意SCSI磁盘设备
DEVPATH              内核设备录进,比如/devices/*
SUBSYSTEM            子系统名字,例如:sda 的子系统为 block.
BUS                  总线的名字,比如IDE,USB
DRIVER               设备驱动的名字,比如ide-cdrom
ID                   独立于内核名字的设备名字
SYSFS{ value}        sysfs属性值,他可以表示任意
ENV{ key}            环境变量,可以表示任意
PROGRAM              可执行的外部程序,如果程序返回0值,该键则认为为真(true)
RESULT               上一个PROGRAM调用返回的标准输出.
NAME                 根据这个规则创建的设备文件的文件名.
(注意:仅仅第一行的NAME描述是有效的,后面的均忽略.如果你想使用使用两个以上的名字来访问一个设备的话,可以考虑SYMLINK键.)
SYMLINK              为 /dev/下的设备文件产生符号链接.由于 udev 只能为某个设备产生一个设备文件,
(所以为了不覆盖系统默认的 udev 规则所产生的文件,推荐使用符号链接.)
OWNER                设备文件的属组
GROUP                设备文件所在的组.
MODE                 设备文件的权限,采用8进制
RUN                  为设备而执行的程序列表
LABEL                在配置文件里为内部控制而采用的名字标签(下下面的GOTO服务)
GOTO                 跳到匹配的规则(通过LABEL来标识),有点类似程序语言中的GOTO
IMPORT{ type}        导入一个文件或者一个程序执行后而生成的规则集到当前文件
WAIT_FOR_SYSFS       等待一个特定的设备文件的创建.主要是用作时序和依赖问题.
PTIONS               特定的选项:
last_rule            对这类设备终端规则执行;
ignore_device        忽略当前规则;
ignore_remove        忽略接下来的并移走请求.
all_partitions       为所有的磁盘分区创建设备文件.

udev一些特殊的值和替换值:
在键值对中的键和操作符都介绍完了,最后是值 (value).Linux 用户可以随意地定制 udev 规则文件的值.

例如:my_root_disk, my_printer.同时也可以引用下面的替换操作符:
----------------------------------------

$kernel,       %k:       设备的内核设备名称,例如:sda、cdrom.
$number,       %n:       设备的内核号码,例如:sda3 的内核号码是 3.
$devpath,      %p:       设备的 devpath路径.
$id,           %b:       设备在 devpath里的 ID 号.
$sysfs{file},  %s{file}: 设备的 sysfs里 file 的内容.其实就是设备的属性值.
$env{key},     %E{key}:   一个环境变量的值.
$major,        %M:        设备的 major 号.
$minor%m:        设备的 minor 号.
$result,       %c:        PROGRAM 返回的结果
$parent,       %P:        父设备的设备文件名.
$root,         %r:        udev_root的值,默认是 /dev/.
$tempnode,     %N:        临时设备名.
%%:           符号 % 本身.
$$:           符号 $ 本身.

六、规则示例


# 如果有设备被内核命名为hdb,那么创建设备节点my_disk替代hdb(即用/dev/my_disk取代/dev/hdb)  
KERNEL=="hdb", NAME="my_disk"  
# 如果匹配到这样一个设备:内核命名为hdb且驱动为ide-disk;那么维持原设备节点名不变  
# 但是为它创建一个叫sparedisk的符号连接(/dev/sparedisk->/dev/hdb)  
KERNEL=="hdb", DRIVER=="ide-disk", SYMLINK+="sparedisk"  
# 为hdc创建两个符号连接cdrom和cdrom0  
KERNEL=="hdc", SYMLINK+="cdrom cdrom0"  
# 如果从sysfs匹配到一个块设备且大小为234441648则为它的设备节点创建符号连接my_disk  
SUBSYSTEM=="block", ATTR{size}=="234441648", SYMLINK+="my_disk"  
# 为/dev/mice创建符号连接/dev/input/mice  
KERNEL=="mice", NAME="input/%k"  
# 为loop0创建设备节点/dev/loop/0,并为它创建符号连接/dev/loop0  
KERNEL=="loop0", NAME="loop/%n", SYMLINK+="%k"  
# 为fd0~fd9创建设备节点/dev/floppy/(0~9),并为它们创建符号连接/dev/fd(0~9)  
KERNEL=="fd[0-9]*", NAME="floppy/%n", SYMLINK+="%k"  
# 为hiddev字符串开头的设备创建设备节点/dev/usb/diddev*  
KERNEL=="hiddev*", NAME="usb/%k"  
# 设置设备节点的group、owner、mode  
KERNEL=="fb[0-9]*", NAME="fb/%n", SYMLINK+="%k", GROUP="video", OWNER="john", MODE="0666"  
# 使用外部程序device_namer(hda为程序参数)的输出作为符号连接名  
KERNEL=="hda", PROGRAM="/bin/device_namer %k", SYMLINK+="%c"  
# 外部程序输出必须以单个空格隔开每个单词; %c{n}表示第n个单词; %c{n+}表示从第n个到最后的所有单词;  
KERNEL=="hda", PROGRAM="/bin/device_namer %k", NAME="%c{1}", SYMLINK+="%c{2+}"  
# 运行外部程序  
KERNEL=="sdb", RUN+="/usr/bin/my_program"  
# 设置udev环境变量  
KERNEL=="fd0", SYMLINK+="floppy", ENV{some_var}="value"  
# 附加选项  
KERNEL=="sda", GROUP="disk", OPTIONS+="last_rule"

SUBSYSTEM=="block", KERNEL=="sdb4", ACTION=="add", NAME="Myusb", SYMLINK+="Myusb_link", RUN+="/bin/bash /home/usbadd.sh"
SUBSYSTEM=="block", KERNEL=="sdb4", ACTION=="remove",    RUN+="/bin/bash /home/usbremove.sh"
udev规则文件的编写方法可参考udev官方文档,这里对上述内容作简单说明:
当插入设备(ACTION=="add")在kernel中设备名为sdb4(KERNEL=="sdb4"),且为块设备(SUBSYSTEM=="block"),满足以上三个条件时,对设备文件命名为Myusb(NAME="Myusb"),并创建软链接Myusb_link(SYMLINK+="Myusb_link"),同时执行/home/usbadd.sh脚本(RUN+="/bin/bash /home/usbadd.sh")。

参考链接:
https://www.cnblogs.com/lpfuture/p/6027091.html
https://blog.csdn.net/xiaoliu5396/article/details/46531893
https://blog.csdn.net/ericzhong83/article/details/4739987

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值