Udev (用户设备目录/dev)是 Linux 系统用于动态设备管理的子系统。自系统内核 2.6 以后,Udev 取代了之前的 devfs 和 hotplug 来进行设备文件维护和热插拔。

Udev 会在设备启动时来侦测是否添加或移除了某些设备,并动态在系统中创建或删除设备节点(即设备驱动程序的接口,该接口显示在文件系统中,好像它是一个普通文件,存储在/dev目录下)。之后,它会将有关设备的信息或其状态的更改回传到用户空间。

它的主要功能包括:1)向系统应用程序提供设备事件;2)管理设备节点的权限;3)可以在/dev目录中创建用于访问设备的有用符号链接,甚至重命名网络接口。

Udev的优点之一是,它可以使用持久的设备名称来保证在重新启动时设备的一致命名,而不管它们的发现顺序如何。此功能很有用,因为内核只是根据发现顺序分配不可预测的设备名称。

在本文中,我们将演示如何在 Linux 系统上使用 Udev 进行设备检测和管理。需要指出的是,大多数(如果不是所有)主流现代 Linux 发行版都附带 Udev 作为默认安装的一部分。

Linux Udev 基础知识

udev 守护进程 systemd-udevd(或者是 systemd-udevd.service),每当系统有添加或删除设备或设备更改其状态事件时,都会与内核通信并直接从内核接收该设备事件。

Udev 是基于规则来进行工作的,这些规则不仅灵活而且功能强大。每个设备事件都会匹配 /lib/udev/rules.d 和 /run/udev/rules.d 目录定义的规则。

我们可以尝试在 /etc/udev/rules.d/ 创建规则文件(.rules 扩展名的文件)来处理一个设备,注意,这个目录的规则文件需要具有最高权限。

为了创建设备节点文件,udev 需要使用某些属性来标识设备,如标签、序列号、使用的主要和次要编号、总线设备编号等。此信息由 sysfs 文件系统导出。

无论何时将设备连接到系统,内核都会检测并初始化它,并在 /sys/directory 下创建一个具有设备名称的目录,该目录存储设备属性。

udev 的主要配置文件是 /etc/udev/udev.conf,为了控制 udev 守护进程的运行时行为,可以使用 udevadm 实用程序来管理它。

要显示接收到的内核事件(UEVENT)和 udev 事件(udev 在规则处理后发送),可以使用  monitor 参数执行 udevadm。然后将设备连接到系统,就会从终端显示设备事件是如何处理的。

以下屏幕截图显示了将 U 盘连接到系统后设备内核事件的摘录:

图.1 udevadm monitor监测 U 盘事件

为了查看设备信息,可以使用”lsblk”命令来显示相关内容:

# lsblk

图.2 lsblk 显示块文件信息

从输出可以看出,U 盘设备被命名为 sdb1 和 sdb2(绝对路径是/dev/sdb1 和 /dev/sdb2),可以通过 udevadm info 命令来查看设备的相关信息:

# udevadm info /dev/sdb1

图.3 udevadm info 查看设备属性信息

Linux Udev 规则如何工作

本节,我们将简要讨论如何编写 udev 规则。规则由一个或多个键值对的逗号分隔列表组成。规则允许从默认名称重命名设备节点,修改设备节点的权限和所有权。规则会在创建或删除设备节点时触发程序或脚本的执行。

我们将编写一个简单的规则,用于在添加USB设备和从运行系统中删除USB设备时触发脚本。

我们首先创建两个脚本,用于在规则中执行:

# vim /bin/device_added.sh
# vim /bin/device_removed.sh

内容分别如下:

device_added.sh:
#!/bin/bash
echo "USB device added at $(date)" >>/tmp/scripts.log

device_removed.sh:
#!/bin/bash
echo "USB device removed at $(date)" >>/tmp/scripts.log

之后,给两个脚本添加可执行权限:

# chmod +x /bin/device_added.sh
# chmod +x /bin/device_removed.sh

之后,创建规则文件”/etc/udev/rules.d/80-test.rules”来触发以上两个脚本。规则文件内容如下:

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_removed.sh"

规则文件中:

  • == 表示相等
  • += 表示添加
  • SUBSYSTEM 表示匹配的设备
  • ACTION 表示匹配的设备事件
  • ENV{DEVTYPE} 表示匹配的设备属性值,示例使用的是设备类型值
  • RUN 表示匹配事件后执行的脚本或命令

保存所有文件后,重新启动 udevd 进行以使自定义的规则生效,命令如下:

# udevadm control --reload

最后,就可以插拔 U 盘来看自定义规则是否被正确执行了。如果脚本被正确执行,在 U 盘的插拔事件后,都会在 /tmp/scripts.log 文件中产生相应的内容,查看该文件内容即可验证自定义规则是否生效了:

# ls -l /tmp/scripts.log
# cat /tmp/scripts.log

图.4 自定义 udev 规则

有关如何编写 udev 规则和管理 udev 的更多信息,可以通过以下命令分别查阅 udev 和 udevadm 手册信息:

# man udev
# man duevadm

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注