Yesterday I was messing around with UDEV. I own some usb storage devices which are not plugged into my main computer all the time, but only when I need them. In a such situation, the order you plug in the devices has an effect on the way their nodes are created in /dev
. For example, if I plug in my 7-in-1 card reader and then my Iomega ZIP usb drive, the nodes sda, sdb, sdc are created for the card reader and sdd for the ZIP drive. If I plug them in the other way around, sda stands for the ZIP drive and sdb, sdc and sdd for the card reader.
This should not be a problem for most people, but if you use custom scripts to backup data on the ZIP drive or to retrieve photographs and videos from the cards, you should always plug these devices in the same order, so that their nodes always point to the same actual device, sda for the ZIP drive, sdb for the compact flash reader and so on. UDEV can give a solution to this issue. For example, you can create a rule that says: Every time I plug in a device that its model is “ZIP 100” and its vendor is “Iomega” create a symbolic link to its node, named “zipdrive“. So, pointing your scripts to the symlink instead of the device node you are sure that you always access the ZIP drive to store the data and not the card reader, regardless of the order you plugged in the devices. This is cool, isn’t it?
Creating UDEV rules is really easy. You only need to know the device’s or the “partition”‘s information. The kernel stores this info in /sys. Then there is this little utility, udevinfo, that can retrieve this information for you. For example, here is what I did for my usb ZIP 100 drive:
After plugging it in, I inserted a disk. It was the disk’s node that I was after. Then I run:
# dmesg
The last lines showed that sda was the ZIP drive’s node and sda4 was the disk’s (let’s say partition’s) node. Knowing this, I asked udevinfo to give me the sda4 node’s path in /sys:
# udevinfo -q path -n /dev/sda4
So, /sys/block/sda/sda4 is the path that contains all my ZIP diskette’s info. I then used udevinfo again to retrieve all this information and piped the results to a pager :
# udevinfo -a -p /sys/block/sda/sda4 | less
I had all the keys and their values for sda4. That was all I needed to create a UDEV rule for it. I keep my UDEV rulesets in a file in /etc/udev/rules.d/60-udev.rules, so that it is read after the default rules file. Now, which properties uniquely identify my ZIP disk’s node? It’s always created as sda4 or sdd4 etc. So the first key would be the name the kernel gives to it:
KERNEL=="sd[a-z]4"
This means that UDEV should match all the device nodes from sda4 through sdz4.
It is possible to define a new name for the device node that is created in /dev. I didn’t want to change that. I only needed a symlink to it, as I wrote earlier. So :
NAME="%k"
%k represents the name that the kernel gives to the node.
Then I added the keys that uniquely identify sda4:
SYSFS{vendor}=="IOMEGA",
SYSFS{model}=="ZIP*100"
We can also set the node’s permissions. I usually do that for my block devices, so I set:
GROUP="disk", MODE="0660"
And finally, I set a name for the symlink:
SYMLINK="mydev/zipdisk"
The symlink’s path would be /dev/mydev/zipdisk. The whole rule would look like this:
KERNEL=="sd[a-z]4", NAME="%k", SYSFS{vendor}=="IOMEGA", SYSFS{model}=="ZIP*100", GROUP="disk", MODE="0660", SYMLINK="mydev/zipdisk"
Then, I saved the 60-udev.rules file and ejected/reinserted the disk into the drive. The symlink was properly created in /dev/mydev/ and my desired permissions were set on the /dev/sda4 node. That was it and I hadn’t even tried! Pretty easy, huh?
A good rule should contain all the keys that narrow UDEV’s search for the device. Usually its model and vendor should be fine, except for the case that you own two identical devices. In that case, you could include the serial number or other unique info from sysfs.
I hope this post will get you going with UDEV.
You can find more information at the following link:
Writing UDEV rules
UDEV by George Notaras is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Copyright © 2005 - Some Rights Reserved
Newer versions of udev seems to want ATTRS instead of SYSFS. There are two variants, ATTR and ATTRS. ATTR only looks at the node being added (And the vendor and model info isn’t available at this – the partition – level) whilst ATTRS searches up the tree. See the udev(7) man page for more info.
Hi, thanks for the info. This post is rather old and I need to update it (time permitting).