USB storage hotplug code. * From: Konstantin Riabitsev* To: rhl-devel-list redhat com * Subject: USB storage hotplug code. * Date: 12 Aug 2003 10:43:22 -0400 Hey, all: I thought I'd share this little bit of code that I've written to handle usb-pen/thumbdrive devices that seem to be pretty popular these days (certainly beats floppies). It is pretty simplistic and will work in 99% of cases, by my estimates. Benefits: 1. Automatically create /dev/diskonkey pointing to the correct device. 2. Automatically create /mnt/diskonkey if missing. 3. Automatically add fstab entries if missing. 4. Automatically set ownership to the console user (if anyone is logged in -- if not, then the ownership will be set by the /mnt/diskonkey* rule in /etc/security/console.perms). Drawbacks: 1. Currently only supports one thumbdrive device at a time, though support for more should be easy to add (I only have one to play with. :)). 2. No way to tell nautilus to re-read /etc/fstab to add diskonkey to the list of mountable devices in rightclick->disks (they claim it's fixed in the newer version of nautilus, but that doesn't help. Currently sending killall -$(anysignal) nautilus will kill it, though theoretically a -HUP should tell it to reread the config). A workaround -- tell your users to plug in the device before they log in. 3. If partition info changes on the device, then things go screwey, as devlabel gets confused (e.g. someone deletes /dev/sda1 and decides to use the entire /dev/sda device instead). This rarely, if ever, happens. 4. This hasn't been overly extensively tested. Installation instructions are in the file itself. I would love to hear any feedback on this. Regards, -- Konstantin ("Icon") Riabitsev Duke Physics Sysadmin, RHCE #!/bin/bash # # This code is free software covered by GNU GPL license version 2 or above. # Please refer to http://www.gnu.org/ for the full license text. # # Some code lifted from usb-mount by Michael Hamilton's usb-mount (LGPL) # see http://users.actrix.co.nz/michael/usbmount.html # # INSTALL # ------- # Put this in /etc/hotplug/usb/diskonkey # Then look in /etc/hotplug/usb.distmap, and copy all usb-storage entries # into /etc/hotplug/usb.usermap, substituting "usb-storage" for "diskonkey". # Otherwise this code is only run during the kernel module invocation/removal # (at least in my tests), which defeats the purpose. # # TODO # ---- # Handle more than one diskonkey device at one time (e.g. /dev/diskonkey1 # and /mnt/diskonkey1), etc. The biggest problem here is the handling in # devlabel, which I haven't yet tried. # # AUTHOR and SUPPORT # ------------------ # Konstantin Riabitsev, . # Send any problem reports to my email address at the moment. # SYMLINKDEV=/dev/diskonkey MOUNTPOINT=/mnt/diskonkey DEVLABEL=/sbin/devlabel DEVLABELCONFIG=/etc/sysconfig/devlabel IAM=$0 ## # Functions lifted near-verbatim from usb-mount code. # function allAttachedScsiUsb { find /proc/scsi/ -path '/proc/scsi/usb-storage*' -type f | xargs grep -l 'Attached: Yes' } function scsiDevFromScsiUsb { echo $1 | awk -F"[-/]" '{ n=$(NF-1); print "/dev/sd" substr("abcdefghijklmnopqrstuvwxyz", n+1, 1) }' } if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ]; then ## # lifted from usbcam code. # if [ -f /var/run/console.lock ]; then CONSOLEOWNER=`cat /var/run/console.lock` elif [ -f /var/lock/console.lock ]; then CONSOLEOWNER=`cat /var/lock/console.lock` else CONSOLEOWNER= fi for procEntry in $(allAttachedScsiUsb); do scsiDev=$(scsiDevFromScsiUsb $procEntry) # Some bug with usb-storage? # partitions are not in /proc/partitions until they are accessed # somehow. /sbin/fdisk -l $scsiDev >/dev/null ## # Most devices have partitioning info, so the data would be on # /dev/sd?1. However, some stupider ones don't have any partitioning # and use the entire device for data storage. This tries to # guess semi-intelligently if we have a /dev/sd?1 and if not, then # it uses the entire device and hopes for the better. # if grep -q `basename $scsiDev`1 /proc/partitions; then part="$scsiDev""1" else part=$scsiDev fi ## # Change ownership of the partition to the console user so they can # mount it. # if [ ! -z "$CONSOLEOWNER" ]; then chown $CONSOLEOWNER:disk $part fi ## # This checks if we already have this UUID defined with devlabel. # If not, it then adds the device to the list. # prodid=`$DEVLABEL printid -d $part` if ! grep -q $prodid $DEVLABELCONFIG; then # cross our fingers and hope it works $DEVLABEL add -d $part -s $SYMLINKDEV 2>/dev/null fi ## # Check if the mount point exists and create if it doesn't. # if [ ! -e $MOUNTPOINT ]; then mkdir -p $MOUNTPOINT fi ## # Take care of /etc/fstab so mounting is easy. # if ! grep -q "^$SYMLINKDEV" /etc/fstab; then # Add an fstab entry echo -e \ "$SYMLINKDEV\t\t$MOUNTPOINT\t\tauto\tnoauto,owner,kudzu 0 0" \ >> /etc/fstab fi done if [ ! -z "$REMOVER" ]; then ## # Make sure this script is triggered on device removal. # mkdir -p `dirname $REMOVER` ln -s $IAM $REMOVER fi elif [ "${ACTION}" = "remove" ]; then ## # If the device is mounted, unmount it cleanly. # if grep -q "$MOUNTPOINT" /etc/mtab; then # unmount cleanly umount -l $MOUNTPOINT fi ## # Remove it from /etc/fstab if it's there. # if grep -q "^$SYMLINKDEV" /etc/fstab; then grep -v "^$SYMLINKDEV" /etc/fstab > /etc/.fstab.new mv -f /etc/.fstab.new /etc/fstab fi fi