udev简单应用

udev1.0

Posted by 婷 on September 4, 2022 本文总阅读量

总结

这篇先大概对udev的应用有个大概的,简单的了解,具体的一些分析或者其他更深入的一些其他用法,以后有空可以再分析

简介

udevLinuxlinux2.6内核之后)默认的设备管理工具。udev 以守护进程的形式运行,通过侦听内核发出来的uevent来管理 /dev目录下的设备文件。通过udev编写对应规则,实现设备节点变化时做出规定的动作。例如下面要介绍的热插拔实验。

image-20220824224838813

另外,在嵌入式系统中,也可以用udev的轻量级版本mdevmdev集成与busybox中。Android也没有采用udev,采用的是vold,不过机制跟udev是一样的。

应用

场景

假设现在插入U盘,从图中打印其分区为sdb,这时候我想自动挂在 /mnt/usb

image-20220824225604429

这时候可以利用udev相关的规则,来创建一个U盘插入规则。

U盘插入规则

/etc/udev/rules.d目录下添加一个文件,叫做11-add-usb.rules ,用于检测U盘插入规则(add)

vi /etc/udev/rules.d/11-add-usb.rules 

image-20220824225829226

11-add-usb.rules中添加如下内容:

ACTION!="add",GOTO="END"
KERNEL=="sdb[0-9]",RUN+="/etc/mount-usb.sh %k"
LABEL="END"

image-20220824225817030

其中RUN+="/etc/mount-usb.sh %k"需要我们在/etc下相关的U盘挂载规则,也就是我们一开始想实现的:自动挂载到某个固定的路径下。在 /etc 下添加脚本

vi /etc/mount-usb.sh

image-20220824230202257

脚本内容如下

#!/bin/sh

if [ ! -d "/mnt/usb" ]; then
  mkdir -p /mnt/usb
fi

mount  -t vfat /dev/$1 /mnt/usb
sync

image-20220824230142292

给脚本加权限,chmod +x /etc/mount-usb.sh

image-20220824230233604

卸载规则

同理自动卸载

vi /etc/udev/rules.d/11-remove-usb.rules

image-20220824230642907

11-remove-usb.rules中添加如下内容:

ACTION!="remove",GOTO="END"
KERNEL=="sdb[0-9]",RUN+="/etc/umount-usb.sh %k"
LABEL="END"

image-20220824230505191

然后在/etc目录下创建umount-usb.sh脚本,给脚本加权限

vi /etc/umount-usb.sh
chmod +x /etc/umount-usb.sh

image-20220824230936200

umount-usb.sh中添加如下内容:

#!/bin/sh
sync
umount /mnt/usb

image-20220824231034227

验证时刻

插入U盘,此时进入/mnt/usb路径,可以看到U盘内的文件,说明刚刚编写的udevadd规则已经生效了

image-20220824231204561

输入df查看

image-20220824231234600

输入vfat查看

image-20220824231257360

这时候拔出U盘,如下图所示,udevremove规则也是生效的

image-20220824231342952

image-20220824231409689

规则

常用规则

基本语法

  • 规则文件中以 ”#” 开头的行以及空行将被忽略
  • 规则文件必须以 .rules 作为后缀名,否则将被忽略
  • 规则文件分别位于: 系统规则目录(/usr/lib/udev/rules.d)、 运行时规则目录(/run/udev/rules.d)、 本机规则目录(/etc/udev/rules.d)/etc/ 的优先级最高、 /run/ 的优先级居中、 /usr/lib/ 的优先级最低,也就是说我们可以在本机规则目录(/etc/udev/rules.d)下添加新的规则,它优先级最高,如果存有低优先级的同类规则,也会被高优先级的新规则替换掉,规则文件开头的数字越小它的执行顺序越靠前
  • “键”有两种类型:匹配与赋值。 如果某条规则的所有匹配键的值都匹配成功,那么就表示此条规则匹配成功, 也就是此条规则中的所有赋值键都会被赋予指定的值。

匹配类

  • “==”等于
  • “!=”不等于
  • “ACTION”匹配事件的动作,例如"add"表示插入一个设备
  • “KERNEL”匹配设备的内核名称,如sda
  • “SUBSYSTEM” 所属的子系统。例如"sound""net"

赋值类

  • “=”,为键赋予指定的值
  • “LABEL”设置一个可用作 GOTO 跳转目标的标签
  • “GOTO” 跳转到下一个匹配的 LABEL 标签所在的规则
  • “RUN”{类型}对于每一个设备事件来说,在处理完规则之后,都可以再接着执行一个程序列表(默认为空)。 不同的”类型”含义如下
    • "program"一个外部程序, 如果是相对路径, 那么视为相对于 /usr/lib/udev 目录。 否则必须使用绝对路径。如果未明确指定”类型”, 那么这是默认值。
    • "builtin"program 类似,但是仅用于表示内置的程序。程序名与其参数之间用空格分隔。 如果参数中含有空格,那么必须使用单引号(')界定。仅可使用运行时间非常短的前台程序, 切勿设置任何后台守护进程或者长时间运行的程序

举例说明

下面分析add

ACTION!="add",GOTO="END"
KERNEL=="sdb[0-9]",RUN+="/etc/mount-usb.sh %k"
LABEL="END"

如上的内容是:如果不是add添加事件,那么就跳到END标签处结束,如果是add事件那么执行如下规则:如果添加的设备是sdb0至sdb9中任意一个,那么就执行RUN后面的内容,此处是一个脚本,一个挂载U盘的脚本,它还带有个参数%k,表示kernel的值。

同理分析remove

ACTION!="remove",GOTO="END"
KERNEL=="sdb[0-9]",RUN+="/etc/umount-usb.sh %k"
LABEL="END"

如果不是remove添加事件,那么就跳到END标签处结束,如果是remove事件那么执行以下规则:如果移出的设备是sda0sda9中任意一个,那么就执行RUN后面的内容,此处是一个脚本,一个卸载U盘的脚本,它还带有个参数%k,表示kernel的值。

参考链接

  • 参考链接一

  • 《Linux设备驱动开发详解》
  • 《udev 中文手册 [金步国]》
  • 《Writing udev rules.html》