udev wrangling
Tuesday, June 25. 2013
Most Linux distros have udev. It has been around a while and is pretty much the way of handling physical devices in your box.
In The Old Ageā¢ making a device to be something was very simple. /dev was in regular filesystem and could have permissions/symlinks/whatever set by admins. During modern era creating a symlink or setting permissions is bit more complex. The steps are:
- Identify the device
- Figure out the identifying attributes from udev
- Choose an operation / operations to be executed when the device is found
- This can be during boot or plug'n'play / USB
- Bring it all together in a configuration file readable by udev
An example:
External USB-drive/-stick can have pretty much any drive letter assigned into it by SCSI-subsystem during plugin. It can be /dev/sde today and /dev/sdf tomorrow. Trying to figure out the drive letter each time it is plugged in is both tedious and unnecessary. With (simple?) udev-wrangling you can have a /dev/myownusb to access it every time the drive is plugged in. Steps:
- Identify
- lsusb is your friend, from the output it is possible to determine that:
Bus 001 Device 007: ID 1941:8021 My C00l USB-drive - Today USB-bus 001 device 007 is the drive. What if you plug it into a different USB-port next time? We need to find identifying attribute/attributes to make configuring possible.
- If we assume that the drive is /dev/sdf this time, all the udev-attributes can be displayed with a:
udevadm info --query=all --name=/dev/sdf --attribute-walk - It will reveal a drive serial number in a format similar to:
ATTRS{serial}=="0000002CE09310500C1B" - The operation we'd like to be done when such a USB-device with a matching serial number is plugged into the computer is a symlink.
- The final step to get this configured would be to create a file into /etc/udev/rules.d/ with a suitable name.
- I chose my configuration to be /etc/udev/rules.d/99-mylocalrules.
- The file will contain a single line with identifying information and the operation. Example:
SUBSYSTEMS=="usb", ATTRS{serial}=="0000002CE09310500C1B", KERNEL=="sd?1", SYMLINK+="myownusb" - That literally reads: Whenever a new device is introduced into USB-subsystem with suitable serial number and having a partition, the 1st partition will be symlinked into udev with name "myownusb"
To get the rule into effect you need to run:
udevadm trigger
It is not necessary to unplug an already working drive. Just confirm that it worked:
ls -l /dev/myownusb
... or similar. Then just mount:
mount /dev/myownusb /mnt/myownusb
Another example:
I have a weather station connected into my Linux via USB-cable. There is no point of accessing it as a root, but out-of-the-box that's the only way to go. I need to chgrp the device after every boot for regular users to gain access into it.
With above process my identifying factor is the USB ID of the device and operation is to chgrp the device with a suitable group to allow access for those users belonging into the group. The rule is:
SUBSYSTEMS=="usb", ATTR{idVendor}=="1941", ATTR{idProduct}=="8021", GROUP="110"
Yet again the udev-rule reads: Whenever a new device is introduced into USB-subsystem with vendor ID of 0x1941 and product ID of 0x8021 the newly created udev-device will have a group with id 110. I prepared a group with groupadd and confirmed that it exists:
# getent group 110
WH-1080usb:*:110:itsme
After a udevadm trigger the result can be confirmed:
# ls -l /dev/bus/usb/001/007
crw-rw-r--. 1 root WH-1080usb 189, 6 Jun 19 10:07 /dev/bus/usb/001/007
The long(ish) path into the device comes from the lsusb output, it reads:
Bus 001 Device 007: ID 1941:8021 Dream Link WH1080 Weather Station
... and can be also translated as /dev/bus/usb/001/007. Simple, huh?