8.13.1. uedev简介

udev完全工作在用户空间,当一个设备被插入或者移除时,内核会通过netlink套接字发送设备详细信息到用户空间,udev获取到设备信息,根据信息内容在/dev下创建并命名设备节点。

  • 冷插拔的设备怎么办

由于冷插拔的设备在开机时就已经存在,在udev启动前已经被插入,针对这种情况,sysfs的设备都存在 uevent 文件,向该文件写入 add ,内核会重新发送netlink,之后udev就可以 受到设备的详细信息了,从而创建/dev下对应的设备节点。

8.13.1.1. udev规则

  • 配置文件

udev的配置文件位于/etc/udev/和/lib/udev

udev的主配置文件是/etc/udev/udev.conf,它包含一套变量,允许用户修改udev默认值,可以设置的变量如下:

udev_root 设备目录,默认是/dev

udev_log 日志等级(表示严重程度),跟syslog一致,例如err,info,debug

  • 规则文件

udev的规则文件一般位于/lib/udev/rules.d/,也可以位于/etc/udev/rules.d/

规则文件是按照字母顺序处理的,对于相同名字的规则文件,/etc/udev/rules.d比/lib/udev/rules.d优先

规则文件必须以.rules作为扩展名,否则不被当作规则文件。

规则文件的每一行哦第时key=vaule的格式,key有两种类型,1) 匹配型key 2) 赋值型key

当所有匹配型key都匹配时,该规则即被采用,赋值型key就会获得相应的值。

一条规则有多个key=value组成,以英文逗号个凯,每个key有一个操作,取决于操作符,有效的操作符如下:

  1. == 比较是否相等

  2. != 比较是否不想等

  3. = 给一个key赋值,表示一个列表的key会被重置,并且把这个唯一的值传给它

  4. += 将一个值增加到key中

  5. := 将一个值传给一个key,并且不允许再修改这个key

  • 匹配型key

下面的key可以匹配设备属性,部分key也可以用于匹配sysfs中父设备属性,不仅仅是产生事件的那个设备。如果在一个规则中,有多个key 匹配了一个父设备,则这些key必须匹配同一个父设备。

key

description

ACTION

匹配事件的动作名

DEVPATH

匹配事件的设备devpath

KERNEL

匹配事件的设备名

NAME

匹配网络接口或者设备节点名字,NAME只有在前面的规则中赋值之后才可以使用

SYMLINK

匹配设备节点的符号连接名字,只有在赋值之后才可以使用

SUBSYSTEM

匹配设备子系统

DRIVER

匹配设备的驱动名,只对绑定到一个驱动的设备有用

ATTR{filename}

匹配事件设备的sysfs属性

KERNELS

向上搜索devpath,知道找到一个匹配的设备名

SUBSYSTEMS

DRIVERS

ATTRS{filename}

ENV{key}

环境变量取值

TAG

设备的TAG

TEST{ }

测试一个文件是否存在

PROGRAM

执行一个程序,如果程序成功返回,key为true,可以从RESULT把这个key读取

RESULT

匹配最近一次PROGRAM调用的返回字符串,应该在PROGRAM之后使用

支持一些shell的通配符

    • 代表0到无穷多个任意字符

  1. ? 代表【一定有一个】任意字符

  2. [] 代表一定有一个在括号内的字符

  • 赋值型KEY

key

description

NAME

根据这个规则创建的设备文件的文件名

SYMLINK

OWNER

设备文件的属组

GROUP

设备文件所在的组

MODE

设备文件的权限,采用8进制

ATTR{key}

TAG

RUN

为设备而执行的程序列表

LABEL

GOTO 可以跳到的地方

GOTO

跳到下一个带有匹配名字的LABEL处

IMPORT

导入一个文件或者一个程序执行后而生成的规则集到当前文件

WAIT_FOR

等待一个特定的设备文件的创建,主要是用作时序和依赖问题

OPTIONS

特定选项:last_rule对这类设备终端规则执行。ignore_divice忽略当前规则

NAME、SYMLINK、PROGRAM、OWNER、GROUP、MODE、RUN这些filed支持一个简单的,类似于printf函数的格式字符串替换,可以的字符串替换如下;

  1. $kernel,%k :该设备在内核中的名字(%k替换$kernel)

  2. $number,%n :该设备的内核号码,例如sda1的内核号码是1

  3. $devpath,%p :该设备的devpath

  4. $id,%b :向上搜索devpath,寻找SUBSYSTEMS,KERNELS,DRIVERS和ATTRS时,被匹配的设备名字

  5. $driver :…被匹配的驱动名字

  6. $attr{file}, %s{file} :一个被发现的设备的sysfs属性的值,如果该设备没有该属性,且前面的KERNELS ,SUBSYSTEMS,DRIVERS或ATTRS测试选择的是一个父设备,那么就用父设备的属性,如果属性是一个符号链,符号链的最后一个元素作为返回值。

  7. $env{key},%E{key} :一个设备的属性值

  8. $major,%M :主设备号

  9. $minor,%m :次设备号

  10. $result,%c :由PROGRAM调用的外部程序返回的字符串,如果这个字符串包含空格,可以用%c{N}选中第N个字段。如果这个数字N后面有一个+字符,则表示选中这个字段开始的后面所有字符

  11. $parent,%p :父设备的节点名字

  12. $name :设备节点的名字,用一个空格作为分割符,该值只有在前面的规则赋值之后才存在

  13. $links :当前符号链的列表,用空格隔开

  14. $root,%r :udev_root的值

  15. $sys,%S :sysfs挂载点

  16. $tempmpde,%N :在真正的设备节点创建之前,创建的一个临时设备节点的名字,这个临时节点供外部程序使用。

  • 查询设备信息

例如:设备sda的SYSFS{size}可以通过cat /sys/block/sda/size得到。SYSFS{model}信息可以通过cat /sys/block/sda/device/model得到

或者可以通过udevadm命令获取设备信息

root@ArkV3:/dev# udevadm info --query=all --name=/dev/mmcblk0
P: /devices/platform/interconnect@100000/4f80000.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0
N: mmcblk0
S: disk/by-id/mmc-S0J57X_0x11bc20a7
S: disk/by-path/platform-4f80000.sdhci
E: DEVLINKS=/dev/disk/by-id/mmc-S0J57X_0x11bc20a7 /dev/disk/by-path/platform-4f80000.sdhci
E: DEVNAME=/dev/mmcblk0
E: DEVPATH=/devices/platform/interconnect@100000/4f80000.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0
E: DEVTYPE=disk
E: ID_NAME=S0J57X
E: ID_PART_TABLE_TYPE=dos
E: ID_PART_TABLE_UUID=19c5099c
E: ID_PATH=platform-4f80000.sdhci
E: ID_PATH_TAG=platform-4f80000_sdhci
E: ID_SERIAL=0x11bc20a7
E: MAJOR=179
E: MINOR=0
E: SUBSYSTEM=block
E: TAGS=:systemd:
E: USEC_INITIALIZED=2619079
  • 调试

以下内容为通过udevadm monitor监测SD卡的拔出以及插入事件

root@ArkV3:~# udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[95305.858326] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p2 (block)
KERNEL[95305.863476] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p1 (block)
UDEV  [95305.863909] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p2 (block)
KERNEL[95305.865764] remove   /devices/virtual/bdi/179:96 (bdi)
KERNEL[95305.865813] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1 (block)
UDEV  [95305.866439] remove   /devices/virtual/bdi/179:96 (bdi)
UDEV  [95305.869234] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p1 (block)
UDEV  [95305.869314] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1 (block)
KERNEL[95305.884325] unbind   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)
KERNEL[95305.884538] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)
UDEV  [95305.887321] unbind   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)
UDEV  [95305.887671] remove   /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)

KERNEL[95312.630739] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)
UDEV  [95312.634149] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)
KERNEL[95312.644368] add      /devices/virtual/bdi/179:96 (bdi)
UDEV  [95312.646727] add      /devices/virtual/bdi/179:96 (bdi)
KERNEL[95312.652352] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1 (block)
KERNEL[95312.652402] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p1 (block)
KERNEL[95312.652431] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p2 (block)
KERNEL[95312.652881] bind     /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)
UDEV  [95312.713507] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1 (block)
UDEV  [95312.827378] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p1 (block)
UDEV  [95312.827647] add      /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa/block/mmcblk1/mmcblk1p2 (block)
UDEV  [95312.830561] bind     /devices/platform/interconnect@100000/4fb0000.sdhci/mmc_host/mmc1/mmc1:aaaa (mmc)