1

I have a udev rule file located in /etc/udev/rules.d/usbmount.rules with the following content:

ACTION=="add", KERNEL=="sd*[!0-9]", RUN+="/tmp/debug.sh"

After creating the rule, I did:

chmod +x /tmp/debug.sh
udevadm control --reload-rules

The purpose of this rule is to run a script whenever a usb block device (thumb drive, hard disk, etc) is inserted. I am tearing my hair out as to why it is not triggering. A udevadmmonitor gives me the following when a USB hard drive dock is attached to the system on a USB 3.0 port.

KERNEL[367.932459] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
KERNEL[367.934622] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
KERNEL[367.935236] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0 (scsi)
KERNEL[367.935301] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/scsi_host/host0 (scsi_host)
KERNEL[367.935414] bind     /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
KERNEL[367.935527] bind     /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
UDEV  [367.937750] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
UDEV  [367.939195] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
UDEV  [367.939940] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0 (scsi)
UDEV  [367.945817] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/scsi_host/host0 (scsi_host)
UDEV  [367.947464] bind     /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0 (usb)
UDEV  [367.950394] bind     /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2 (usb)
KERNEL[368.957786] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0 (scsi)
KERNEL[368.957902] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
KERNEL[368.957993] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device)
KERNEL[368.958128] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic)
KERNEL[368.958250] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg)
KERNEL[368.960906] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk)
UDEV  [368.961035] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0 (scsi)
UDEV  [368.965594] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV  [368.971313] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device)
UDEV  [368.973129] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg)
UDEV  [368.975431] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic)
UDEV  [368.976153] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk)
KERNEL[369.010196] add      /devices/virtual/bdi/8:0 (bdi)
UDEV  [369.011230] add      /devices/virtual/bdi/8:0 (bdi)
KERNEL[369.270352] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda (block)
KERNEL[369.270455] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block)
KERNEL[369.276694] bind     /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV  [369.874116] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda (block)
UDEV  [370.252695] add      /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block)
UDEV  [370.275646] bind     /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0 (scsi)

Machine info:

OS: Raspbian GNU/Linux 10 (buster)
Kernel: 5.4.72-v7l+

The sole content of debug.sh is echo "TESTING" >> /tmp/debuglog.txt. Debuglog.txt is not being created.

It would appear this rule is not being triggered. Why? What can I do to fix this?

2 Answers 2

1

The sole content of debug.sh is echo "TESTING" >> /tmp/debuglog.txt. Debuglog.txt is not being created.

That's the issue. The kernel will not execute such shell script, because it doesn't start with the mandatory #!/bin/bash telling the kernel to delegate the execution to the bash interpreter.

This very rarely happens because most tools will use a shell to execute a command if it didn't execute immediately. Here's an example when strace-ing perl to execute this command (while searching without success a tool that would make execution of the script fail immediately):

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");'
execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0
execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = -1 ENOEXEC (Exec format error)
execve("/bin/sh", ["/bin/sh", "/tmp/debug.sh"], [/* 15 vars */]) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14452, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

It attempted first to execute the script without interpreter in its first line and got:

ENOEXEC (Exec format error)

and then tried again by inserting a shell before so it works. Here /bin/sh, is not even bash in this environment, so if the script includes bash constructs, it would subtly misbehave later.

Had /tmp/debug.sh be this (and with the u+rx perms):

#!/bin/bash
echo "TESTING" >> /tmp/debuglog.txt

then:

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");'
execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0
execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14474, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

Then /tmp/debug.sh would have be executed directly by the kernel (which would have actually defered the execution to /bin/bash).

udev doesn't attempt to do this, so it requires a valid binary for the kernel as first file in the command. Either supplying it directly, either by supplying a script which is an adequate executable from the point of view of the kernel by starting with the #!/path/to/interpreter line.

1
  • "will use a shell to execute a command if it didn't execute immediately" they will only do that if execve(2) failed with an ENOEXEC error (NOT with any other errors). That's the behaviour of the execvp(2) library function (which perl is using). On some systems (not on linux) execvp will also retry (with the same path) on ETXTBSY.
    – user313992
    Oct 27, 2020 at 9:21
0

udev on some systems (all?) requires absolute paths for all scripts to execute. If you are executing a shell script, you must specify the shell. For this to work I had to change it to:

ACTION=="add", KERNEL=="sd*[!0-9]", RUN+="/bin/bash /tmp/debug.sh"

0

You must log in to answer this question.

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