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

Bas*_*asj 26 arch-linux udev mount

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

/etc/udev/rules.d/10-myrule.rules
Run Code Online (Sandbox Code Playgroud)

包含:

KERNEL!="sdb*", GOTO="auto_mount_end"
ACTION=="add", RUN+="/usr/bin/mount /dev/sdb1 /media"
LABEL="auto_mount_end"
Run Code Online (Sandbox Code Playgroud)

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

如何对这样的udev规则进行故障排除/调试?

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

use*_*.dz 19

更新

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

    RUN{type}

      ??

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


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

  • 10-正如 jasonwryan 所提到的,使用高编号(90 年代的好)。所以你的规则不会被另一个规则覆盖。

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

      ACTION=="add", KERNEL=="sdb*", RUN+="/usr/bin/mount /dev/sdb1 /media"
    
    Run Code Online (Sandbox Code Playgroud)
  • 你的目标是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"
    
    Run Code Online (Sandbox Code Playgroud)

    注意: udev-env.txt创建然后规则无论如何都会被触发。线==对应于一个匹配的节点。该文件中记录的 ENV 可能是 2 个或更多节点之间的混合,几乎同时创建,这是一个stdout缓冲问题。

  • 使用udevadm monitor -u,udevadm test ...udevadm trigger ... 来验证哪些规则处理了事件。

  • 在脚本内部由您来制作调试日志并捕获失败的命令,同时保存它们的返回值stdoutstderr消息。


Gea*_*phy 6

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

udevadm control --log-priority=debug
journalctl -f
Run Code Online (Sandbox Code Playgroud)

(并将udevadm control --log-priority=info其设置回正常水平)