udev expansion cardudev expansion card

Using udev can ease your life by using external units, such as memory sticks or removable storage devices which many of us use these days. On a personal note, I have a few memory sticks that I use quite often, as well as Western Digital USB HDD I use for backup purposes.

Having to manually mount these every time I plug them in, is rather a tedious task so I thought about a method to get this done automatically. And here comes our friend udev in for play. The purpose of udev is to manage your /dev entries so that it becomes more manageable. To quote kernel.org on udev;

udev allows Linux users to have a dynamic /dev directory and it provides the ability to have persistent device names.

First things first, we need to find some information about the unit in question. In this case, I want to get information about my USB HDD, which I know has the dev entry of /dev/sdc.

luna:/dev# udevinfo -q path -n /dev/sdc
/block/sdc

Reading this, we now know that the information is found under /sys/block/sdc. Let’s move on.

luna:/dev# udevinfo -q all -p /sys/block/sdc
P: /block/sdc
N: sdc
S: mybook
S: disk/by-id/usb-WD_2500JB_External_57442D5743414E4B38343139353830
S: disk/by-path/pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0
E: ID_VENDOR=WD
E: ID_MODEL=2500JB_External
E: ID_REVISION=0108
E: ID_SERIAL=WD_2500JB_External_57442D5743414E4B38343139353830
E: ID_TYPE=disk
E: ID_BUS=usb
E: ID_PATH=pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0

As we can read from this, we see that there’s an attribute that uniquely identifies this hard drive. The attribute is called «ID_SERIAL». This attribute is what we will use in our udev rule. Let us now proceed to make the actual udev rule.

vim /etc/udev/rules.d/local.rules

I take caution in making a new rules file called «local.rules» to make things more manageable for both myself, more importantly, so that apt doesn’t touch my rule sets when udev might be upgraded in the future.

BUS=="usb", KERNEL=="sd*", ENV{ID_SERIAL}="WD_2500JB_External_57442D5743414E4B38343139353830", NAME="%k", SYMLINK="mybook%n"

An explanation of the above rule

BUS==”usb”
# The unit in question is plugged into the USB bus.
KERNEL==”sd*”
# The system mounts the unit to /dev/sdc as mentioned above.
ENV{ID_SERIAL}
# This is the serial number we got from using «udevinfo» earlier on.
NAME=”%k”
# I have to admit that I’m a bit uncertain what this bit does, but I know that it has to be there.
SYMLINK=”mybook%n”
# This is the name of the symlink we want created when the unit is plugged in.

And that’s all there is to it. Hope this guide was understandable and helpful. And good luck!

Update
As it turns out, udev has certain problems with the above rule set when you attach more than one USB unit that uses the USB storage sub-system. The reason is that udev doesn’t see «ENV{ID_SERIAL} for some obscure reason. Why this is the case eludes me, but I’ve found a workaround.

udevinfo -a -p `udevinfo -q path -n /dev/sdc` | grep serial

Which will yield the following:

ATTRS{serial}=="57442D5743414E4B38343139353830"

On some systems, ATTRS are reported as SYSFS, but pay no attention to that. In udev rule sets, SYSFS must be used at all times, as ATTRS isn’t a recognizable parameter in udev. The new and updated rule set would then be as follows:

BUS=="usb", KERNEL=="sd*", SYSFS{serial}=="57442D5743414E4B38343139353830", NAME="%k", SYMLINK="mybook%n"

By Jostein Elvaker Haande

"A free society is a society where it is safe to be unpopular" - Adlai Stevenson

2 thoughts on “[HOWTO] Writing udev rules”

Leave a Reply

Your email address will not be published. Required fields are marked *