Udev and usb
From PlugWiki
This guide is for setting up multiple USB block devices and keep them ordered, especially useful if you have your rootfs in a flash drive and you don't want the system to assign drive letters in a different way. For this guide we are going to need udev installed (it should be, but just to make sure) and a text editor.
This is NOT about automounting, for that you need a tools like ivman or halevt, but you can use this guide together with them to customize their behaviour.
Contents |
Find information about your device
Before we can do anything fun, we have to identify the information for your device. In this howto I am assuming you want to make a fixed link to /dev/sda1, so you have to substitute it the device you want to use. Let's begin by opening a root terminal and issuing the following command:
udevinfo -a -p /sys/block/sda/sda1/
We are telling udev to show us information for the device sda and the partition sda1, if we wanted /dev/sdd7 it would be: /sys/block/sdd/sdd7 It should print something like this:
Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.
looking at device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1':
KERNEL=="sda1"
SUBSYSTEM=="block"
DRIVER==""
ATTR{partition}=="1"
ATTR{start}=="63"
ATTR{size}=="15679377"
ATTR{stat}==" 5866 347 163644 22550 2957 15644 149296 2986660 0 231380 3009210"
looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host0/target0:0:0/0:0:0:0/block/sda':
KERNELS=="sda"
SUBSYSTEMS=="block"
DRIVERS==""
ATTRS{range}=="16"
ATTRS{ext_range}=="256"
ATTRS{removable}=="1"
ATTRS{ro}=="0"
ATTRS{size}=="15687680"
ATTRS{capability}=="53"
ATTRS{stat}==" 5878 358 163828 22610 2957 15644 149296 2986660 0 231410 3009270"
And a lot more output (too long and boring to paste).
Now, open a text editor in your desktop/laptop not on your plug. We are going to use it as a pasteboard.
We have to find a combination of filters that identify our device without mistake, but we can only choose from the first section (the one that has the "looking at device" message) and a single one of the parents (any other section), in my case I choose to use the USB device section, which goes like this for my device:
looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2':
KERNELS=="1-1.2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="80"
ATTRS{bMaxPower}=="300mA"
ATTRS{urbnum}=="52630"
ATTRS{idVendor}=="0930"
ATTRS{idProduct}=="6545"
ATTRS{bcdDevice}=="0110"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="480"
ATTRS{busnum}=="1"
ATTRS{devnum}=="4"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="Kingston"
ATTRS{product}=="DT 101 II"
ATTRS{serial}=="001372982982B91115FC064E"
The reason is the last line: serial number, something that identifies my device, and I think its very unlikely to be repeated on any other device. Once you decide the sections we have to extract the information, for instance, I am going to use vendor, serial and partition:
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{idVendor}=="0930"
ATTRS{serial}=="001372982982B91115FC064F"
ATTR{partition}=="1"
Notice how I also pasted a SUBSYSTEMS and DRIVERS line, this is because we have to tell udev which parent device to use (maybe serial and vendor are enough, but I'll add them just in case). DO this for each device you want to "fix". Make sure you don't mix them.
As you can see you can use any line from udevinfo, just choose carefully, because if you don't uniquely identify the device, the rule will be applied to every matching device!
Rules
udev uses rules to affect how devices, rules are kept in /etc/udev/rules.d (may be different on your distro, but it should be clearly marked), and contained in *.rules files. Each file usually have a number in the name (90-late-rules.rules), this is because udev loads rules ordered by name, so by prepending a number we can affect the load order.
Each rule must be in one line inside the file, and must follow the following format:
MATCH=="par",REPLACE="value",APPEND+="something"
Basically its a list of MATCHES, each one a keyword followed by a "=" and finally the value to match. Keywords are obtained from the udevinfo command (KERNEL, SUBSYSTEMS, ATTR{Vendor} are keywords), values can be anything, you can also use wildcards (*,?,{}). After that you may add REPLACES, which are values that we want to overwrite, for instance NAME="omgponies" will rename the kernel device to /dev/omgponies. Finally you can add APPENDS, which simply add actions to the rule, for instance RUN+="something" will run the program named "something" and any other program already defined (perhaps in another rule).
In a rule you can edit pretty much anything you want (AFAIK, maybe there are some limits), just be careful. For our objective, we are going to update the SYMLINK property, this tells the system to create a symlink at /dev pointing to the device. To do that we use SYMLINK+="somelink"
Writing the rules
Now that we know how to write rules, lets put everything together. First create a new file inside /etc/udev/rules.d, don't edit existing files, as upgrading udev may remove your modifications. For my sda1 device here is my rule:
ATTR{partition}=="1",SUBSYSTEMS=="usb",DRIVERS=="usb",ATTRS{serial}=="001372982982B91115FC064F",SYMLINK+="rootusb",GROUP="disk",MODE="0660"
As you can see, I used partition, drivers and serial to identify my device. Then I appended a symlink at /dev/rootusb, but there are 2 parameters we haven't met yet, these are the GROUP and MODE keywords. With GROUP we tell udev to create the device with the specified GROUP, since its a disk, we use the disk group, however it may be audio, plugdev, uucp, etc. MODE tells udev the permissions to use, it works just like chmod, however you may have not used the first byte, it is used for gid and suid, two options that are a bit advanced. Since we don't need them we leave them at 0. The other 3 are owner, group and others permissions, unless you have a very good reason leave the MODE as 0660.
Trying it out
One easy way to test your rule is by unplugging and plugging your device, you can then check /dev for the symlinks. If they don't exist, or you can't unplug your device (for instance if its the rootfs) you can use udevadm to try the rules.
udevadm has several uses, but we will be focusing on 2: test and trigger. Test tells udevadm to print what it would do with a certain device, while trigger applies the rules to the device like if you just plugged it. Let's try with sda1:
udevadm test /sys/block/sda/sda1/
There will be a ton of output, look for a line like this:
udev_node_update_symlinks: update symlink 'rootusb' of '/block/sda/sda1'
This means udev is updating (or creating) the /dev/rootusb to point to /dev/sda1, which means we are done!
Advanced rules
Of course, these are simple rules, you can create more complex and amazing rules, but it's outside the scope of this howto, If you want more information go to:
