16

How can I implement udev rules for any USB mass-storage device plugged in, not just for specific one? What should be changed in idVendor, and idProduct?

 ACTION=="add", SUBSYSTEM=="usb", SYSFS{idVendor}=="0204", SYSFS{idProduct}=="6025",
     RUN+="/home/workspace/bash_script.sh"
0

1 Answer 1

11

A storage device is in the block subsystem, so you'll want SUBSYSTEM=="block" in your rule, like this:

ACTION=="add", KERNEL=="sd?", SUBSYSTEM=="block", ENV{ID_BUS}=="usb", \
    RUN+="/path/to/script"

If you're using systemd, you could run a systemd unit each time a USB storage device is added. Create the unit file, e.g. /etc/systemd/system/my-usb-rule.service:

[Service]
Type=oneshot
ExecStart=/path/to/script

and the rule, e.g. /etc/udev/rules.d/85-my-usb-rule.rules:

ACTION=="add", KERNEL=="sd?", SUBSYSTEM=="block", ENV{ID_BUS}=="usb", \
    ENV{SYSTEMD_WANTS}="my-usb-rule.service"

Now udev will trigger my-usb-rule.service (which in turn will execute your script) on any usb storage device add event.


Don't forget to reload the configuration after you edit the rules/units:

udevadm control --reload
systemctl daemon-reload
5
  • When I add a USB mass storage, I would like to act on the partition(s) it contains. On udev level I can see events from 4 subsystems: usb, scsi, bdi, and block (in this order). The first 3 ones are unusable, because the partition is not yet known. The block event has ID_BUS=scsi, not usb as in your code example. I don't see any suitable attribute in the block event, that would tell me whether it is USB mass storage or not. (Investigation done using udevadm monitor and udevadm info). Unless I could trust that ID_BUS=scsi could not reasonably be anything else but USB mass storage.
    – Uwe Geuder
    Commented Jan 16, 2017 at 15:53
  • @UweGeuder - nothing stopping you to use the device name as an argument to your program and based on that act on the partitions... Commented Jan 16, 2017 at 17:33
  • 1
    Well, in the USB events the device name is something like /dev/bus/usb/002/040. Not sure what to do with that in my program. In the Block events the device name is something like /dev/sdb or /dev/sdb1. That's what I want, but now I'm back to the problem that ID_BUS=scsi. I got a bit further: There is a rules file 80-udisk2, which adds a property ID_DRIVE_THUMB. Not sure how robust it is, there seem to very few vendors listed. My rule file was called 70-*, so as expected my /dev/sdb did not match. Weirdly enough /dev/sdb1 matched, although my rule runs first.
    – Uwe Geuder
    Commented Jan 16, 2017 at 19:44
  • 1
    Ah I just note the original question was any USB mass storage drive. That should work with the rule SUBSYSTEM=="block", SUBSYSTEMS=="usb" (note the difference with the S). I doubt it can always work with ENV{ID_BUS}=="usb" in the original answer, because I see the value scsi here. But I am working on a slightly different problem than originally asked, I want any USB stick (pendrive), but no external drives.
    – Uwe Geuder
    Commented Jan 16, 2017 at 20:14
  • 2
    Actually the nasty truth is that ENV{ID_BUS} value is not the same on all systems. Yesterday I was working on an older system with udev 210 (I believe. Cannot check now because the machine is not on the internet), There the value was scsi. Now, I am on newer machine with udev 228 and the value is usb. For the same USB stick, I am carrying it with me. (not sure whether the udev version is the relevant factor here, could also be the kernel or any other package installing udev rules, e,g, udisks2) Still SUBSYSTEM=="block", SUBSYSTEMS=="usb" (note S) might be portable and safe.
    – Uwe Geuder
    Commented Jan 17, 2017 at 10:21

You must log in to answer this question.

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