How To: Custom systemd udev Rule for Card Readers

I think at this point we’ve all accidentally done this, especially when trying to write SD cards for embedded development:

#> dd if=<something> of=/dev/sdX ...
_really_ hard sigh... we didn't want to blow sdX away with the input file

The service that controls the names (and symlinks) for nodes in /dev is udev. Therefore we can add a rule to make our card reader establish a symlink to the device and amend our instructions to use that link instead.

The instructions in this post assume you’re using an OS that uses systemd for init, udev, etc. These are CentOS 7, Ubuntu 12+, etc. Check with the OS to see what is being used.

The Rule

First, you need to establish what your device is. I’m using a Transcend USB 3.0 card reader for this, so I plugged it in and ran dmesg:

[180378.201115] usb 3-3: new SuperSpeed USB device number 18 using xhci_hcd
[180378.224128] usb 3-3: New USB device found, idVendor=8564, idProduct=4000
[180378.224132] usb 3-3: New USB device strings: Mfr=3, Product=4, SerialNumber=5
[180378.224135] usb 3-3: Product: Transcend
[180378.224137] usb 3-3: Manufacturer: TS-RDF5 
[180378.224140] usb 3-3: SerialNumber: 000000000037
[180378.225156] usb-storage 3-3:1.0: USB Mass Storage device detected
[180378.225482] scsi host0: usb-storage 3-3:1.0
[180379.258202] scsi 0:0:0:0: Direct-Access     TS-RDF5  SD  Transcend    TS3A PQ: 0 ANSI: 6
[180379.258937] sd 0:0:0:0: Attached scsi generic sg1 type 0
[180379.261028] sd 0:0:0:0: [sdb] Attached SCSI removable disk

Important fields from above are idVendor and idProduct. With those, we can construct our rule over in /etc/udev/rules.d. I chose to name my file 59-sdcard-reader.rules. As root:

touch /etc/udev/rules.d/59-sdcard-reader.rules
chmod 0644 /etc/udev/rules.d/59-sdcard-reader.rules

Then add the rule:

SUBSYSTEMS=="usb"\
   , ATTRS{idVendor}=="8564"\
     , ATTRS{idProduct}=="4000"\
     , KERNEL=="sd?"\
     , SYMLINK+="card-sd"

Creating a udev rule can use the attributes from the device itself and one parent device. You can see the list of the device vs. parent devices using udevadm info -a -p /block/sdX, where X is your currently inserted card reader. The attributes used above will match any /dev/sdX (the KERNEL attribute) and establish the symlink to it as card-sd. You could also name that symlink in usb/card-sd, and it would appear in /dev/usb, for example.

Updating udev

Depending on your OS, you may need to restart udev. One way is using udevadm:

udevadm control --reload-rules && udevadm trigger

Now when you unplug and then plug back in the card reader, the rule creates /dev/card-sd as a symlink pointing to /dev/sdX (where X is whatever it happens to enumerate as at the time).

Conclusion

This process works for other devices as well, and there are many options for rules. For example, you can listen for events and execute scripts when those events occur.

Recent Posts

Ready for an exciting change?

Work with US!