29

I'm creating a new basic rule

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

containing:

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

I saved, rebooted, and inserted a SD card (recognized by /dev/sdb1, I see it with dmesg), but nothing happens. When I do manually mount /dev/sdb1 /media, it works.

How can I troubleshoot / debug such an udev rule?

Note: I'm using ArchLinux, but it should be the same on any distro?

8
  • 2
    Change the filename to 99-myrule.rules...
    – jasonwryan
    May 4, 2015 at 0:30
  • @jasonwryan : the same : nothing happens. How to troubleshoot an udev rule? Should I trigger it manually (how in this case?)
    – Basj
    May 4, 2015 at 0:37
  • Does systemd change something to the normal udev behaviour?
    – Basj
    May 4, 2015 at 0:38
  • 2
    try udevadm monitor, see this and this May 8, 2015 at 20:42
  • 1
    AFAIK one doesn't neet to reboot in order to get udev to re-read the rules (see unix.stackexchange.com/a/39371/44760). I've done my udev debugging (which indeed isn't the easiest task!) with udevadm test and validated rules against reality with udevadm info.
    – zagrimsan
    Jun 2, 2015 at 12:45

6 Answers 6

21

Update

  • Reference: 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.


Original Answer Debugging hint are valid for other udev rule applications.

  • 10- as mentioned by jasonwryan, use high numbering (90's good). So your rule is not going to be overridden by another one.

  • Use the minimum keys just as you really need. Example, != & GOTO/LABEL, instead use directly ==

      ACTION=="add", KERNEL=="sdb*", RUN+="/usr/bin/mount /dev/sdb1 /media"
    
  • Your target was sdb1 with fixed command, minimize the blind match using KERNEL=="sdb1"

  • I find it useful to create a shadow debugging rule, I called shadow because I always leave it there in same file, so I use it when I need it.

      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"
    

    Notes:

    • udev-env.txt is created then the rule is triggered anyway. Line == corresponding to one matching node. The ENV recorded in that file could be mixture between 2 node or more, created almost in same time, it's a stdout buffering problem.
    • Some environment variables that showed up in this debug, may not be used for condition because at by that time udev processing matches they are not yet populated (from previous rules). See https://www.suse.com/support/kb/doc/?id=000016106 (Mentioned by @clonejo in comments)
  • Use udevadm monitor -u, udevadm test ... and udevadm trigger ... to verify which rules processed the events.

  • Inside the scripts is up to you to make debug log and catch failed commands, by saving their return value also stdout & stderr messages.

8
  • 1
    Very useful. A couple of comments udevadm test... appears to only show you environment variables, to gets ATTRS you can use udevadm info $DEVICE to find these other settings.
    – Att Righ
    Feb 2, 2017 at 18:57
  • 1
    In udevadm info returns a tree of devices be careful to distinguish settings between a device and its parent devices (properties seem to be inherited if not overridden). In my case the subsystem was wrong.
    – Att Righ
    Feb 2, 2017 at 19:03
  • 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." Is there no way to just trace what is actually happening?
    – MarcH
    Oct 31, 2018 at 0:06
  • @MarcH , you could use udevadm monitor -u to check for events/conditions & udevadm trigger ... to test their actions.
    – user.dz
    Oct 31, 2018 at 8:42
  • 1
    Dumping the environment using the dummy rule can have misleading results. Some env vars are only populated by other udev rules, but RUN+= is only executed after all rules have been matched: suse.com/support/kb/doc/?id=000016106
    – clonejo
    Sep 2, 2022 at 18:42
13

This command will allow one to observe the execution of rules:

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

(and udevadm control --log-priority=info to set it back to sane levels)

2

I think the command you're looking for here is udevadm. You'll use the trigger and test parameters to trigger a rescan of the udev events, and to test a specific event, respectively.

I learned this the hard way when putzing around with the new network device naming in EL 7. Good luck!

1
  1. Create a udev rules file

    sudo nano /etc/udev/rules.d/99-removable-sd.rules
    
  2. Add rule that tells udisks to automount it

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

    ATTRS{type}=="SD" may be not required if you are using different types.

  3. Reload rules

    sudo udevadm control -R
    
  4. Eject it then put back.

Reference: Archlinux Wiki: Some devices, that should be treated as removable, are not

1

I was having the same problem with RASPBERRY PI 3 B+, it could be possible that above commands may help you. But it DID NOT help me. I was trying to invoke a script on inserting a USB storage device. The rules do not get logged in syslog, so it becomes very difficult to understand which rule worked or which rule failed.

So I did the following:

(1) I made my rule file in /etc/udev/rules.d/100-myrule.rules

(2) then I ran the command sudo /etc/init.d/udev restart

then I checked it worked. A piece of information, may be useful to you or may not be, but the filesystems are readonly for udev until the command at (2) is executed.

0

For me, the solution was to enable full event monitoring early in the boot process. On Debian 12 "bookworm":

# vi /usr/share/initramfs-tools/init

find the line where devtmpfs is mounted on /dev, and after that add a line to start udevadm monitor in background:

mount -t devtmpfs -o nosuid,mode=0755 udev /dev
udevadm monitor -k -u -p > /dev/debug-udevadm-monitor.txt &

Then call update-initramfs -u to get the change into /boot/initrd.img-xxxx, and shutdown -r now. After the restart, look in /dev/debug-udevadm-monitor.txt for lines containing FAILED or ERRNO, or any other patterns related to the issue being debugged. In my case the problem event looked like this:

UDEV  [2.582336] add      /devices/pci0000:00/0000:00:19.0/net/eth4 (net)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:19.0/net/eth4
SUBSYSTEM=net
INTERFACE=eth4
IFINDEX=4
SEQNUM=1518
USEC_INITIALIZED=1290728
ID_NET_NAMING_SCHEME=v252
ID_NET_NAME_MAC=enx00224d123456
ID_NET_NAME_ONBOARD=eno1
ID_NET_LABEL_ONBOARD=Intel(R) 82579V Gigabit Network Device
ID_NET_NAME_PATH=enp0s25
ID_BUS=pci
ID_VENDOR_ID=0x8086
ID_MODEL_ID=0x1503
ID_PATH=pci-0000:00:19.0
ID_PATH_TAG=pci-0000_00_19_0
ID_NET_DRIVER=e1000e
ID_NET_LINK_FILE=/usr/lib/systemd/network/99-default.link
ID_NET_NAME=eno1
ID_RENAMING=1
INTERFACE_OLD=eth2
UDEV_WORKER_FAILED=1
UDEV_WORKER_ERRNO=17
UDEV_WORKER_ERRNO_NAME=EEXIST

(that is, one cannot rename eth2 to eth4 because the latter already exists).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .