Friday, January 16, 2009

usb drives with udev

Hey, finally I managed to actually get something out of udev, which I think is great but I don't really understand yet.
I have an 2.5'' hard drive in an external usb box. I carry this from my workplace home and back again and some stuff in it needs to point to the same absolute path, so it has to be mounted on the same mountpoint. Well, the disk has 2 partitions and I'm actually interested only in the partition /dev/sdc5. It has to be mounted in /media/usb-5, but kde's automounter mounts it in /media/disk. Of course I can ignore kde's automount feature and mount it manually after putting the corresponding entry in /etc/fstab, but I like this kde pop-up, click accept and it's done.
After reading this one, I figure out how to do it:
1. I get the relevant information with udevinfo:
fixdebian:/etc/udev/rules.d# udevinfo -a -p /sys/block/sdc/sdc5

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 '/block/sdc/sdc5':
KERNEL=="sdc5"
SUBSYSTEM=="block"
DRIVER==""
ATTR{dev}=="8:37"
ATTR{start}=="26619831"
ATTR{size}=="51520329"
ATTR{stat}==" 537 537 0 0"

looking at parent device '/block/sdc':
KERNELS=="sdc"
SUBSYSTEMS=="block"
DRIVERS==""
ATTRS{dev}=="8:32"
ATTRS{range}=="16"
ATTRS{removable}=="0"
ATTRS{size}=="78140160"
ATTRS{stat}==" 59 776 1263 747 0 0 0 0 0 636 747"
ATTRS{capability}=="12"

looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-3/1-3:1.0/host4/target4:0:0/4:0:0:0':
KERNELS=="4:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{device_blocked}=="0"
ATTRS{type}=="0"
ATTRS{scsi_level}=="0"
ATTRS{vendor}=="TOSHIBA "
ATTRS{model}=="MK4025GAS "
ATTRS{rev}=="0000"
ATTRS{state}=="running"
ATTRS{timeout}=="30"
ATTRS{iocounterbits}=="32"
ATTRS{iorequest_cnt}=="0x42"
ATTRS{iodone_cnt}=="0x42"
ATTRS{ioerr_cnt}=="0x0"
ATTRS{modalias}=="scsi:t-0x00"
ATTRS{evt_media_change}=="0"
ATTRS{queue_depth}=="1"
ATTRS{queue_type}=="none"
ATTRS{max_sectors}=="240"


(.... and a lot more output that I don't need now).
I pick both lines: ATTRS{vendor}=="TOSHIBA " and
ATTRS{model}=="MK4025GAS "

2. I create a file in /etc/udev/rules.d/ called 010_myusb-disk-part5.rules. The man page says that files included there are read in lexical order, so I guess it could be useful to be one of the first rules that apply to avoid any 'interference' from another file already included by the default udev installation. (Actually, at least in debian, the files included in /etc/udev/rules.d are soft links to files in the parent directory: you don't need to remove the whole file if you don't like it, just remove the link). The file is:
fixdebian:/etc/udev/rules.d# cat 010_myusb-disk-part5.rules
ACTION=="add", KERNEL=="sdc5", ENV{vendor}=="TOSHIBA ", ENV{model}=="MK4025GAS ", RUN+="/home/user/bin/mount-usb-5.sh"


3. The file /home/user/bin/mount-usb-5.sh is a simple executable script with the single line: mount /media/usb-5.
4. Run the udev test:

fixdebian:/etc/udev/rules.d# udevtest /sys/block/sdc/sdc5
parse_file: reading '/etc/udev/rules.d/010_myusb-disk-part5.rules' as rules file
parse_file: reading '/etc/udev/rules.d/020_permissions.rules' as rules file
parse_file: reading '/etc/udev/rules.d/025_libgphoto2.rules' as rules file

(...)
This program is for debugging only, it does not create any node,
or run any program specified by a RUN key. It may show incorrect results,
if rules match against subsystem specfic kernel event variables.

main: looking at device '/block/sdc/sdc5' from subsystem 'block'
udev_rules_get_name: no node name set, will use kernel name 'sdc5'
udev_db_get_device: found a symlink as db file
udev_device_event: device '/block/sdc/sdc5' already in database, validate currently present symlinks
udev_node_add: creating device node '/dev/sdc5', major = '8', minor = '37', mode = '0660', uid = '0', gid = '25'
main: run: 'socket:/org/freedesktop/hal/udev_event'

So this seems to work: at least the syntax of my new file isn't wrong. 5. Restart udev: in my debian box, I run /etc/init.d/udev restart 6. Now I plug in the usb drive, kde's mount pop-up window appears, I accect and, the drive is mounted in /media/usb-5, just as I wanted.

No comments: