如何调试 udev 规则(在 /etc/udev/rules.d/... 中)

如何调试 udev 规则(在 /etc/udev/rules.d/... 中)

我正在创建一个新的基本规则

/etc/udev/rules.d/10-myrule.rules

包含:

KERNEL!="sdb*", GOTO="auto_mount_end"
ACTION=="add", RUN+="/usr/bin/mount /dev/sdb1 /media"
LABEL="auto_mount_end"

我保存、重新启动并插入 SD 卡(由 识别/dev/sdb1,我用 看到它dmesg),但没有任何反应。当我手动执行时mount /dev/sdb1 /media,它有效。

我如何排除/调试这样的udev规则?

注意:我使用的是 ArchLinux,但它在任何发行版上都应该是相同的?

答案1

更新

  • 参考: udev_237 -手动udev (Ubuntu_18.04)

    RUN{type}

       ︙

      请注意,由于 systemd-udevd.service 上强制执行默认沙箱,因此 udev 规则内不允许运行访问网络或挂载/卸载文件系统的程序。


原答案调试提示对其他 udev 规则应用程序有效。

  • 10-正如 jasonwryan 所提到的,使用高编号(90 的好)。因此,您的规则不会被另一规则覆盖。

  • 根据您的实际需要使用最少的键。例如,!=& GOTO/ LABEL,而不是直接使用==

      ACTION=="add", KERNEL=="sdb*", RUN+="/usr/bin/mount /dev/sdb1 /media"
    
  • 你的目标是sdb1固定命令,使用最小化盲匹配KERNEL=="sdb1"

  • 我发现创建影子调试规则很有用,我称之为影子,因为我总是将它留在同一个文件中,所以我在需要时使用它。

      ACTION=="add", KERNEL=="sdb*", RUN+="/bin/sh -c 'echo == >> /home/user/Desktop/udev-env.txt; env >> /home/user/Desktop/udev-env.txt'"
      #ACTION=="add", KERNEL=="sdb*", RUN+="/usr/bin/mount /dev/sdb1 /media"
    

    笔记:

    • udev-env.txt创建后无论如何都会触发规则。==对应的行匹配节点。该文件中记录的 ENV 可能是 2 个或更多节点之间的混合,几乎同时创建,这是一个stdout缓冲问题。
    • 在此调试中显示的某些环境变量可能无法用于条件,因为此时 udev 处理匹配它们尚未填充(根据之前的规则)。看https://www.suse.com/support/kb/doc/?id=000016106(@clonejo 在评论中提到)
  • 使用udevadm monitor -uudevadm test ...udevadm trigger ... 验证哪些规则处理了事件。

  • 在脚本内部,您可以通过保存返回值和stdout消息来创建调试日志并捕获失败的命令stderr

答案2

该命令将允许观察规则的执行:

udevadm control --log-priority=debug
journalctl -f

(并将udevadm control --log-priority=info其恢复到正常水平)

答案3

我认为您在这里寻找的命令是udevadm.您将使用triggertest参数来触发 udev 事件的重新扫描,并分别测试特定事件。

在研究 EL 7 中的新网络设备命名时,我经历了惨痛的教训才了解到这一点。祝你好运!

答案4

我在使用 RASPBERRY PI 3 B+ 时遇到了同样的问题,以上命令可能会对您有所帮助。但这对我没有帮助。我试图调用插入 USB 存储设备的脚本。这些规则不会记录在系统日志中,因此很难了解哪个规则有效或哪个规则失败。

所以我做了以下事情:

(1)我在/etc/udev/rules.d/100-myrule.rules中创建了我的规则文件

(2)然后我运行命令sudo /etc/init.d/udev restart

然后我检查它是否有效。一条信息可能对您有用,也可能没用,但在执行 (2) 处的命令之前,文件系统对于 udev 是只读的。

相关内容