In Ubuntu (and Linux I presume) removable devices, like my USB flash drives, digital audio players and digital cameras, have this tendancy to appear in different device node locations (/dev/sda, /dev/sdc1, etc) depending on which port they plug into, or which device is plugged in first. This is a real pain for trying to customise your /etc/fstab.
Some nice soul on the Ubuntu Forums suggested udev as a solution, so I thought I'd look into it. udev allows persistent device naming, based on a match with a given udev rule. In other words, if a device is attached that matches certain criteria it is given it's own device node, rather than being assigned a dynamic one.
It's actually really easy to setup.
To start with you need to know the dynamic device node that is given to a device when attached for the first time, the best way that I know of to determine this is to use the tail command
tail -f /var/log/messages
When a device is plugged in, the screen will update with the newest messages, usually imparting some knowledge on the location of the new device. So first my USB disc
[4295259.290000] usb 1-3: new full speed USB device using ohci_hcd and address 5 [4295259.558000] Initializing USB Mass Storage driver... [4295259.558000] scsi6 : SCSI emulation for USB Mass Storage devices [4295259.558000] usbcore: registered new driver usb-storage [4295259.558000] USB Mass Storage support registered. [4295264.572000] Vendor: Model: TS128MJFLASHA Rev: 1.00 [4295264.572000] Type: Direct-Access ANSI SCSI revision: 02 [4295264.596000] SCSI device sdc: 253400 512-byte hdwr sectors (130 MB) [4295264.609000] sdc: Write Protect is off [4295264.637000] SCSI device sdc: 253400 512-byte hdwr sectors (130 MB) [4295264.650000] sdc: Write Protect is off [4295264.650000] sdc: sdc1 [4295264.758000] sd 6:0:0:0: Attached scsi removable disk sdc [4295264.758000] sd 6:0:0:0: Attached scsi generic sg2 type 0
I guess that more than you need to know, but there is some very useful information in there. Most I don't really care about now, except that the USB flash disc has been given the dynamic device node /dev/sdc1.
Next my other devices, a SD card reader, which is given /dev/sdd1. My Digital Audio Player is assigned /dev/sde1. My digital camera and mobile phone didn't like playing ball, so I'll leave that for another day, at least the SD card reader was okay.
So next thing is to find out some unique information from each device, information that will be used in defining the udev rules, remembering a match is required to assign the persistant node. The next command is from the 'Writing udev rules' link at the bottom of this entry
udevinfo -a -p $(udevinfo -q path -n /dev/sdc)
Which yields some information on my USB flash disc. I've trimmed the output quite a bit.
looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.0/usb1/1-3':BUS=="usb" SYSFS{product}=="TS128MJFLASHA"
These are the two items of interest to me. The device is connected to the USB bus, and the product is identified by TS128MJFLASHA.
Next thing is to create the udev rule concerning this device. I'll start by creating my own .rules file
sudo nano /etc/udev/rules.d/10-local.rules
Apparently the default udev rules are 50-udev.rules, so by naming my rules 10-local.rules, they are looked at first. I don't have any 50-udev.rules file, but I'll name it 10-local.rules anyway. The rule I will use for the flash disc looks like this.
BUS=="usb", SYSFS{product}=="TS128MJFLASHA", KERNEL=="sd?1", NAME="transcend128mb", SYMLINK="usbdevices/transcend128mb"
The KERNEL="sd?1" will only match locations like /dev/sda1, /dev/sdb1 and more importantly, as the guide says, it won't match nodes like /dev/sda, /dev/sdb, which can be fdisk'ed.
The NAME="128FLASH", SYMLINK="usbdisc/128FLASH" will create the persistant node at /dev/1transcend128mb and a symlink /dev/usbdisc/transcend128mb that points to the persistant node /dev/transcend128mb.
Following the same method for the other USB devices, my complete udev.rules will look like
BUS=="usb", SYSFS{product}=="TS128MJFLASHA", KERNEL=="sd?1", NAME="transcend128mb", SYMLINK="usbdevices/transcend128mb"
BUS=="usb", SYSFS{manufacturer}=="Alcor Micro", KERNEL=="sd?1", NAME="sd_reader", SYMLINK="usbdevices/sd_reader"
BUS=="usb", SYSFS{manufacturer}=="SAMSUNG ", SYSFS{product}=="YP-T8 ", KERNEL=="sd?1", NAME="ypt8_dap", SYMLINK="usbdevices/ypt8_dap"
To start using these new rules, you need to run the command udevstart if you are using Ubuntu Breezy 5.10.
sudo udevstart
Now to quicly check that the new nodes have been created.
ls -l /dev/usbdevices total 0 lrwxrwxrwx 1 root root 12 2006-04-25 17:13 sd_reader -> ../sd_reader lrwxrwxrwx 1 root root 17 2006-04-25 17:13 transcend128mb -> ../transcend128mb lrwxrwxrwx 1 root root 11 2006-04-25 17:13 ypt8_dap -> ../ypt8_dap
Finally I can edit my /etc/fstab to setup the mount points for these devices
/dev/usbdevices/transcend128mb /media/usb128mb vfat iocharset=utf8,umask=000 0 0 /dev/usbdevices/sd_reader /media/sd_card vfat iocharset=utf8,umask=000 0 0 /dev/usbdevices/ypt8_dap /media/ypt8 vfat iocharset=utf8,umask=000 0 0
Not hard, not a lot of work, but that was a lot to write down!
This is a great link for creating udev rules, and where I got most of this from.
http://reactivated.net/writing_udev_rules.html
(Wish I could find a way to make code blocks look better too)




1 Response to “Stay put! USB devices and udev”