Linux之udev热插拔规则

背景

udev 是 Linux 系统中用于管理设备节点的工具,它可以根据设备的属性动态地创建设备文件,并执行特定的命令,通常用来处理热插拔。
udev 规则用于指定这些行为,它们一般存储在 /etc/udev/rules.d/ 目录下的 .rules 文件中。

udev规则语法简单介绍

udev 规则的语法如下:

ACTION=="action", KERNEL=="kernel", ATTR{attribute}=="value", ... , RUN{command}

以下是 udev 规则中各个部分的详细说明:

  • ACTION:触发规则的事件类型,例如 addremovechange 等。
  • KERNEL:设备的内核名称,通常是 /dev 下设备文件的名称,不包括 /dev/ 前缀。
  • ATTR{attribute}:设备的属性,通常与 sysfs 文件系统中的属性相对应。
  • VALUE:属性的值。
  • RUN{command}:当规则匹配时要执行的命令。

规则文件中的每一行通常是一个单独的规则,或者可以通过 \ 符号将一条规则延续到下一行,注释以 # 开头。
以下是一些规则中的关键字和它们的含义:

  • ==:表示等于。
  • !=:表示不等于。
  • ><>=<=:表示大小比较。
  • RUN{}:在规则匹配时运行的程序,RUN+ 表示在所有规则处理完毕后运行。
  • IMPORT{}:导入一个外部程序的结果到环境中。
  • NAME:设置设备节点的名称。
  • SYMLINK:为设备节点创建符号链接。
  • OWNERGROUPMODE:设置设备节点的所有权、组和权限。
    udev 规则可以非常复杂,并且可以根据需要定制,以实现各种设备管理的需求。

udev规则示例

下面是一些示例规则:

  1. 为特定 USB 存储设备设置标签:
    ACTION=="add", KERNEL=="sd?[", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0951", ATTRS{idProduct}=="1603", SYMLINK+="my_usb_drive"
    这条规则会在识别到特定供应商和产品ID的USB存储设备时创建一个名为 my_usb_drive 的符号链接。
  2. 当 USB 鼠标插入时运行一个脚本:
    ACTION=="add", KERNEL=="mouse[0-9]*", SUBSYSTEM=="input", RUN+="/usr/local/bin/mouse-connected.sh"
  3. 插入特定设备时运行一个脚本并传递相关参数:
    SUBSYSTEM=="usb", ATTRS{idVendor}=="3574", ATTRS{idProduct}=="6241", ACTION=="add", RUN+="/usr/local/bin/my_shell.sh %s{idVendor} %s{idProduct} %k"
    其中,%k %s 是用于动态替换的占位符,%k 代表的是设备内核名称, %s代表设备的属性值,通常用于引用设备的某个属性,和第一节中的字段说明对应。
  4. 为所有串行设备设置权限:
    KERNEL=="ttyUSB[0-9]*", MODE="0666"
    这条规则将所有串行设备(例如,USB转串口设备)的权限设置为所有用户可读写。

udev规则生效及触发

udev 规则通常在设备添加、移除或更改时被触发。
如果你已经创建了新的 udev 规则或者修改了现有的规则,并且希望它们立即生效,而不是等待设备下次插拔,你可以通过udevadm 工具来让规则立即生效:

  1. 重新加载 udev 规则
    使用 udevadm 工具可以重新加载 udev 规则,而无需重启系统。以下命令可以做到这一点:
    sudo udevadm control --reload-rules
    这个命令会告诉 udev 重新读取规则文件。
  2. 重新触发设备的 udev 事件
    如果你希望对已经连接的设备应用新的规则,可以使用以下命令触发设备的 udev 事件:
    sudo udevadm trigger
    这个命令会触发所有设备的 uevent,让 udev 根据新的规则重新处理它们。
  3. 针对特定设备
    如果你只想对特定的设备应用新的规则,可以使用以下命令:
    sudo udevadm trigger --action=add --subsystem-match=subsystem --attr-match=ATTR{attribute}=value
    替换 subsystem 为你的设备子系统(例如 usbsound 等),替换 attributevalue 为你的设备特定的属性和值。
  4. 检查规则是否正确应用
    你可以使用以下命令来检查规则是否已经正确应用:
    sudo udevadm test /sys/class/your_deviceSubsystem/your_device
    替换 your_deviceSubsystemyour_device 为你的设备在 /sys/class/ 下的路径。

请注意,这些命令需要 root 权限才能执行。如果你在修改规则文件后遇到了问题,可以通过 journalctl -u udev 命令或直接查看syslog来查看 udev 的日志,以便于调试。

注:udevadm 是 Linux 系统中用于管理和调试 udev 设备管理器的命令行工具。它提供了多种功能,包括查看设备信息、触发设备事件、监控设备变化等。