为什么如果我使用 udevadm 触发器,我的 udev 规则会运行,但在启动时却不运行?

为什么如果我使用 udevadm 触发器,我的 udev 规则会运行,但在启动时却不运行?

我遇到了 udev 规则无法运行的问题。以下是示例:

我有一条规则/etc/udev/rules.d/99-test.rules,其中包含:

ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/sayhi"

而且sayhi只有:

#!/bin/bash
date +"%Y-%m-%d %H:%M:%S,%3N" >> /saidhi

这是一台英特尔机器,我显然有许多供应商 0x8086 PCI 设备:

root@imtrobot:~# lspci -n |grep 8086
00:00.0 0600: 8086:2770 (rev 02)
00:02.0 0300: 8086:2772 (rev 02)
00:1d.0 0c03: 8086:27c8 (rev 01)
[ etc. 12 lines total ]

然而,当我启动时,/saidhi要么根本就不会创建,要么其中只有 1 或 2 个日期行。

如果在启动后,我运行udevadm trigger --action=add --subsystem-match=pci 然后 /saidhi将获得准确数量的日期添加到其中。

为什么这在启动过程中不起作用?

答案1

我实际上有一种方法可以等待适当的时间,而不是任意的 30 秒。我在 Raspberry Pi 上这样做,以便在连接时以及启动时自动安装所有连接的 USB 磁盘。

该规则与您的类似:

$ sudo cat /etc/udev/rules.d/10-usb_automount.rules 
KERNEL=="sd*", RUN+="/home/pi/bin/usb-automount"

现在该脚本实际上是一个递归调用(我知道这很邪恶):

$ cat /home/pi/bin/usb-automount
#!/bin/sh

ROOT_RW=`mount | grep 'dev/root' | grep -E '\(.*rw.*\)'`

if [ -z "$ROOT_RW" ]; then
 sleep 3 
 /home/pi/bin/usb-automount & disown
else
 /home/pi/bin/usb-automount.sh
fi

请注意,“grep 'dev/root'”特定于 Raspbian OS,因此在 Ubuntu 上,您需要设计自己的 grep 来检测 rootfs(或者更好的是设计一些通用 grep)。请注意,脚本将在后台调用自身并退出,并且只有当 rootfs 为“rw”时才会调用正确的安装脚本。脚本“/home/pi/bin/usb-automount.sh”执行实际安装或在您的情况下执行日志记录。

请注意,此脚本仍需要 3 秒才能执行,因此您可以通过更改为进一步优化:

if [ -z "$ROOT_RW" ]; then
 ( sleep 3; /home/pi/bin/usb-automount ) & disown
else
 /home/pi/bin/usb-automount.sh
fi

但是我从未检查过并且不知道这是否会按预期工作(我不是脚本专家)。

答案2

udev正如其他人提到的,由的指令启动的进程RUN=应该是短期运行。我想建议另一种更简单的方法脱钩udev通过使用系统调度程序命令来长时间运行的进程at

ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/usr/bin/at -M -f /sayhi now"

只需确保您的/sayhi脚本/bin/sh兼容 - 这是使用的 shell at

答案3

我讲的和@dmd 讲的一样,PCI uevents 在文件系统重新挂载之前出现rw。(但有时,一些 PCI uevents 会在之后出现,竞争条件,并行工作)

dmesg | grep -i -e mount -e pci

@Sparhawksleep这个想法对我来说似乎不错。我认为这是它不起作用的原因 (参考: man udev):

这只能用于运行时间非常短的前台任务。长时间运行事件进程可能会阻止此设备或相关设备的所有后续事件。

启动守护进程或其他长时间运行的进程对于 udev 来说是不合适的;分叉的进程,无论是否分离,都会在事件处理完成后被无条件终止。

因此,我创建了启动的新脚本和disown具有命令的脚本sleep。实际上,它确实有效!

$ ls -l /sa*
-rw-r--r-- 1 root root 1104 Oct 24 12:37 /saidhi
-rwxr-xr-x 1 root root   29 Oct 24 12:31 /sayhi
-rwxr-xr-x 1 root root   62 Oct 24 12:28 /sayhi2

$ cat /sayhi
#!/bin/bash
/sayhi2 & disown

$ cat /sayhi2 
#!/bin/bash
sleep 30
date +"%Y-%m-%d %H:%M:%S,%3N" >> /saidhi

$ cat /etc/udev/rules.d/99-test.rules 
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/sayhi"

相关内容