Monday, November 5, 2012

Automount USB devices with no desktop environment

I'm running a slim Debian install with Xmonad as my window manager, and need a lightweight automounter for USB devices.  I don't need to worry about icons popping up since I have no desktop environment.  usbmount meets those specs.  As of this writing it is an orphaned package, but is a relatively simple udev script, so I don't anticipate too many surprises.  Setup for generic USB devices is simple, just
ROOTPROMPT$> apt-get install usbmount
   At this point your system should automount ext[3,4] filesystems according to the particular device ownership.  VFAT filesystems don't have such properties so we have to tell usbmount how to handle them.  The instructions in the usbmount.conf file are thorough, so in brief we have to write the desired mount options for the filesystem type into the config file.  I want to mount vfat usb devices to the 'floppy' group with read and write privileges.  To do this open /etc/usbmount/usbmount.conf file as root and set the FS_MOUNTOPTIONS as follows:
FS_MOUNTOPTIONS="-fstype=vfat,gid=floppy,dmask=0007,fmask=0117"
Now the system should automount ext3, ext4 and vfat filesystems upon disk insertion.
   Other devices can be tricky.  I have an HP touchpad that does not have a partition table.  When plugged into the computer, the touchpad asks whether I want it to behave as as USB mass storage device.  After I select yes, is shows up as /dev/sd[b-h] depending on how many other devices I have plugged in.  The example below shows the device as /dev/sdb.
$> dmesg
/////skip a bunch//////
[ 3005.685270] sdb:
[ 3030.915649] usb 1-5: USB disconnect, address 8
[ 3035.340043] usb 1-5: new high speed USB device using ehci_hcd and address 9
[ 3035.474728] usb 1-5: New USB device found, idVendor=0830, idProduct=8074
[ 3035.474735] usb 1-5: New USB device strings: Mfr=2, Product=3, SerialNumber=4
[ 3035.474739] usb 1-5: Product: webOS-device
[ 3035.474743] usb 1-5: Manufacturer: HP
[ 3035.474746] usb 1-5: SerialNumber: 0123456789ABCDEF
[ 3035.474950] usb 1-5: configuration #1 chosen from 1 choice
[ 3035.482227] scsi7 : SCSI emulation for USB Mass Storage devices
[ 3035.486189] usb-storage: device found at 9
[ 3035.486194] usb-storage: waiting for device to settle before scanning
[ 3040.484486] usb-storage: device scan complete
[ 3040.489848] scsi 7:0:0:0: Direct-Access HP webOS-device 0327 PQ: 0 ANSI: 2
[ 3040.493881] sd 7:0:0:0: Attached scsi generic sg2 type 0
[ 3040.509961] sd 7:0:0:0: [sdb] Attached SCSI removable disk
[ 3152.892176] sd 7:0:0:0: [sdb] 57720832 512-byte logical blocks: (29.5 GB/27.5 GiB)
[ 3152.995534] sd 7:0:0:0: [sdb] Assuming drive cache: write through
fdisk shows no partition, just the entire block device.
ROOTPROMPT$> fdisk -l
/*skip other disc info*/
Disk /dev/sdb: 29.6 GB, 29553065984 bytes
64 heads, 32 sectors/track, 28184 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
I can mount it as root and see it is a vfat device.
ROOTPROMPT$> mount /dev/sdb /media/touchpad
ROOTPROMPT$> exit
$> df -T
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/sdb vfat 28853344 1854128 26999216 7% /media/touchpad
I tried adding a UUID based mount rule for the touchpad into the fstab,  but that didn't work until after I ran blkid on the device, which requires root access.
   I read up on writing udev rules at various websites.  The three I found useful are:
http://www.reactivated.net/writing_udev_rules.html - Good explanations, but udevinfo has been replaced by udevadm, so you have to adjust the examples.
http://workaround.org/mount-usb-memory-sticks - Good, but dated and uses udevinfo
http://wiki.debian.org/udev - debian specific udev page with udevadm examples.
   As root, create the rules file in the /etc/udev/rules.d directory.  I created /etc/udev/rules.d/10-touchpad-rules file.  Lower numbers at the beginning of the file increase precedence.  The following command gives a bunch of information, I've trimmed most of it out since I only needed a few pieces to write my rule.
ROOTPROMPT$> udevadm info -q all -n /dev/sdb
/* skip irrelevant details*/
E: UDEV_LOG=3
E: DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6:1.0/host2/target2:0:0/2:0:0:0/block/sdb
E: MAJOR=8
E: MINOR=16
E: DEVNAME=/dev/sdb
E: DEVTYPE=disk
E: SUBSYSTEM=block
E: ID_VENDOR=HP
E: ID_VENDOR_ENC=HP\x20\x20\x20\x20\x20\x20
E: ID_VENDOR_ID=0830
E: ID_MODEL=webOS-device
E: ID_MODEL_ENC=webOS-device\x20\x20\x20\x20
   My rule is one line long and is the only entry in the /etc/udev/rules.d/10-touchpad-rules file:
KERNEL=="sd?", SUBSYSTEM=="block", ATTRS{model}=="webOS-device", SYMLINK+="touchpad"
The KERNEL identifies a block device (with no partition number), the SUBSYSTEM checks for a value of 'block', and the ATTRS{model} checks the ID_MODEL value given from the udevadm command.  If they match the device is symlinked to /dev/touchpad.  As is, my system cannot discriminate between HP touchpads, and if two were plugged in I think they would both symlink to /dev/touchpad.  I don't envision plugging multiple touchpads into my computer though.  The Udev rule creates the device identifier.  Add the following line to /etc/fstab to enable mounting by the user.  Don't forget the newline if at the end of the file.  Archwiki has a good write up on the fstab file to understand the options below.
/dev/touchpad /media/touchpad auto rw,user,noauto  0 0
Plug in the touchpad, and select the 'usbmount' option on that device, then mount it on the computer with
$> mount /media/touchpad
Before unplugging the disk run the following:
$> umount /media/touchpad
$> eject /dev/touchpad