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


15

我正在创建新的基本规则

/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
将文件名更改为99-myrule.rules...
jasonwryan 2015年

@jasonwryan:相同:什么也没发生。如何对udev规则进行故障排除?我应该手动触发它(在这种情况下如何?)
Basj 2015年

是否会systemd改变正常的udev行为?
巴吉2015年

1
试试udevadm monitor,看看这个这个
水瓶座电力

1
AFAIK不需要重新引导即可使udev重新读取规则(请参见unix.stackexchange.com/a/39371/44760)。我已经使用进行了udev调试(这确实不是最简单的任务!),udevadm test并使用验证了针对现实的规则udevadm info
zagrimsan

Answers:


11
  • 10-就像jasonwryan提到的那样,请使用高编号(90的好)。因此,您的规则不会被另一个规则所取代。
  • 根据实际需要使用最小键。例如,!=GOTO/ LABEL,而不是直接使用==

    ACTION=="add", KERNEL=="sdb*", RUN+="/usr/bin/mount /dev/sdb1 /media"
    
  • 您的目标是sdb1使用固定命令,使用KERNEL=="sdb1"

  • 我发现创建阴影调试规则很有用,我称它为shadow,因为我总是将阴影保留在同一文件中,因此在需要时可以使用它。

    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缓冲问题。

  • 使用udevadm monitor -uudevadm test ...udevadm trigger ... 验证其规则处理的事件。

  • 通过保存脚本的返回值stdoutstderr消息,脚本内部可以制作调试日志并捕获失败的命令。

更新:

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

    RUN{type}

    Note that running programs that access the network or mount/unmount filesystems is not
    allowed inside of udev rules, due to the default sandbox that is enforced on
    systemd-udevd.service.
    

1
很有用。udevadm test...似乎有一些注释仅向您显示环境变量,ATTRS您可以使用udevadm info $DEVICE它们找到其他设置。
Att Righ

1
udevadm info返回的设备树中,小心区分设备及其父设备之间的设置(如果未覆盖属性,则属性似乎是继承的)。在我的情况下,子系统是错误的。
Att Righ

udevadm test "This program is for debugging only, it does not run any program specified by a RUN key. It may show incorrect results, because some values may be different, or not available at a simulation run."有没有办法只追踪实际发生的事情?
MarcH '18 -10-31

@MarcH,您可以udevadm monitor -u用来检查事件/条件并udevadm trigger ...测试其动作。
user.dz

@MarcH,但是在脚本内部由您决定是否要调试日志并捕获失败的命令(通过保存它们的返回值以及stdout和stderr消息)。
user.dz

1

我认为您要在此处查找的命令是udevadm。您将使用triggertest参数分别触发udev事件的重新扫描和测试特定事件。

在使用EL 7中的新网络设备命名时,我学到了这难的方法。祝您好运!


1
  1. 创建udev规则文件

    sudo nano /etc/udev/rules.d/99-removable-sd.rules
    
  2. 添加告诉udisk自动挂载的规则

    SUBSYSTEM=="block", SUBSYSTEMS=="mmc", DRIVERS=="mmcblk", ATTRS{type}=="SD", ENV{UDISKS_AUTO}="1", ENV{UDISKS_SYSTEM}="0"
    

    ATTRS{type}=="SD" 如果您使用其他类型,则可能不需要。

  3. 重新加载规则

    sudo udevadm control -R
    
  4. 弹出然后放回去。

参考: Archlinux Wiki:有些设备应视为可移动设备,但不能


0

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

所以我做了以下事情:

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.