Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm running Debian Squeeze on a plug computer (so SSH only, no GUI) and what I'm trying to do is get it so that when a USB stick is plugged in, it gets automatically mounted.

What I've done is install autofs which from what I gather handles the automounting providing it knows where the device is in /dev.

The problem is that the USB stick isn't always on the same device name. Sometime's it's /dev/sdc1, sometimes /dev/sdd1, etc.

I gather that to remedy this, I need to use udev to ensure that the USB stick is always given the same name.

I got the following info out of udevadm:

Udevadm info 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/sdd/sdd1':
    KERNEL=="sdd1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{partition}=="1"
    ATTR{start}=="63"
    ATTR{size}=="129339"
    ATTR{ro}=="0"
    ATTR{alignment_offset}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{stat}=="      31      244      275      190        0        0        0        0        0      190      190"
    ATTR{inflight}=="       0        0"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8/target8:0:0/8:0:0:0/block/sdd':
    KERNELS=="sdd"
    SUBSYSTEMS=="block"
    DRIVERS==""
    ATTRS{range}=="16"
    ATTRS{ext_range}=="256"
    ATTRS{removable}=="1"
    ATTRS{ro}=="0"
    ATTRS{size}=="129439"
    ATTRS{alignment_offset}=="0"
    ATTRS{discard_alignment}=="0"
    ATTRS{capability}=="51"
    ATTRS{stat}=="      56      727      783      520        0        0        0        0        0      520      520"
    ATTRS{inflight}=="       0        0"
    ATTRS{events}=="media_change"
    ATTRS{events_async}==""
    ATTRS{events_poll_msecs}=="-1"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8/target8:0:0/8:0:0:0':
    KERNELS=="8:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{device_blocked}=="0"
    ATTRS{type}=="0"
    ATTRS{scsi_level}=="3"
    ATTRS{vendor}=="        "
    ATTRS{model}=="Flash Disk      "
    ATTRS{rev}=="2.00"
    ATTRS{state}=="running"
    ATTRS{timeout}=="30"
    ATTRS{iocounterbits}=="32"
    ATTRS{iorequest_cnt}=="0x90"
    ATTRS{iodone_cnt}=="0x90"
    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"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8/target8:0:0':
    KERNELS=="target8:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8':
    KERNELS=="host8"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0':
    KERNELS=="1-1.2:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb-storage"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{bInterfaceClass}=="08"
    ATTRS{bInterfaceSubClass}=="06"
    ATTRS{bInterfaceProtocol}=="50"
    ATTRS{modalias}=="usb:v1976p6025d0100dc00dsc00dp00ic08isc06ip50"
    ATTRS{supports_autosuspend}=="1"

  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}=="100mA"
    ATTRS{urbnum}=="383"
    ATTRS{idVendor}=="1976"
    ATTRS{idProduct}=="6025"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="11"
    ATTRS{devpath}=="1.2"
    ATTRS{version}==" 1.10"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{urbnum}=="197"
    ATTRS{idVendor}=="1a40"
    ATTRS{idProduct}=="0101"
    ATTRS{bcdDevice}=="0111"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="4"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{product}=="USB 2.0 Hub"

  looking at parent device '/devices/platform/orion-ehci.0/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="24"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0002"
    ATTRS{bcdDevice}=="0206"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="1"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 2.6.38.8 ehci_hcd"
    ATTRS{product}=="Marvell Orion EHCI"
    ATTRS{serial}=="orion-ehci.0"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/platform/orion-ehci.0':
    KERNELS=="orion-ehci.0"
    SUBSYSTEMS=="platform"
    DRIVERS=="orion-ehci"
    ATTRS{modalias}=="platform:orion-ehci"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

I've been trying to write udev rules to force the USB stick to take the name /dev/usbstick but so far I haven't been successful.

Can someone help out with what rule I need to specify in my rules file to get this USB stick to always get the same name?

-- Or, is there much easier way to automount the USB stick that I'm missing entirely?

UPDATE

OK so I have made some progress. I added the following rule:

SUBSYSTEMS=="scsi", ATTRS{model}=="Flash Disk ", DRIVERS=="sd", NAME="usbstick-%k" RUN+="mkdir /mnt/usbstick-%k; mount /dev/usbstick-%k /mnt/usbstick-%k"

I know this still needs some work in terms of handling add/remove, but it's just a basic test for now.

The effect of this is that I now manage to get three new device nodes in /dev, namely /dev/usbstick-sdc, /dev/usbstick-sdc1 and usbstick-sg2.

However, what I've found is that the code in the RUN section only executes once and just makes a directory mnt/usbstick-sdc. I've also found that the directory is always empty, so something is clearly still going wrong! (although I'm making progress).

share|improve this question
    
Was that second /dev/sdc1 supposed to be sdd1? And you can use blkid to uniquely identify the drive (well, actually the partition; it'll change if you reformat). –  Kevin Nov 16 '11 at 15:03
    
Correct, just fixed that. All I want to happen is that when a USB stick is plugged in it gets mounted to some directory. I'm pretty sure I should be using a udev rule to create device nodes for each partition, but I'm not sure what level of the udevadm output to be making rules for! –  jon Nov 16 '11 at 15:09
    
Your rule looks too complicated. Try to make a simple one, with just one ACTION==, one KERNEL== and one ATTRS{something}== (it is completely doable - this is what I use). Also, consider running a single script instaed of the chain of commands in RUN+=. –  rozcietrzewiacz Nov 16 '11 at 16:38
    
Thanks for the advice, but the question remains: which level of the device tree should I be targeting with my rule? This all seems terribly confusing and there really isn't much info online to explain this. I really appreciate the time you've taken to explain it to me so far, I feel like I'm almost there but just missing the level to be targeting. –  jon Nov 16 '11 at 16:42
    
I've now tried this very basic rule: KERNEL=="sd??", NAME="%k", RUN+="mkdir /mnt/usbstick-%k; mount /dev/usbstick-%k /mnt/usbstick-%k" -- but no, of course this doesn't work either. I'm now getting increasingly frustrated after spending nearly the whole day simply trying to work out how to get a USB stick that's plugged in to mount itself. Should things really be this difficult? The output from udevadm test /sys/block/sdd is -- of course -- practically unreadable, so I have no means of knowing where I'm going wrong. Can anyone point me in the right direction on this? –  jon Nov 16 '11 at 17:22

3 Answers 3

Figured there should be a much easier way to address such a common problem, and there is. Here's what I tried on my wheezy/sid server:

sudo apt-get install usbmount

Plug in usb stick, done! My stick is now accessible through /media/usb.

Btw, usbmount doesn't have a man page, please read /usr/share/doc/usbmount/README.gz instead. It seems usbmount mounts your stick with the sync option by default. It might be a whole lot better for your stick to mount it async and run sync or umount before unplugging it. That is configurable.

share|improve this answer
    
see also pumount –  Alex Aug 18 '13 at 18:59

Notice that you can't just have a single device node to represent any possible pendrive attached. What if you plug two of them? Or when the pendrive has more than one partition?

Generally, what you use to create a custom-named device node, is SYMLINK+=. grep for it in the rules to see how it's used: grep SYMLINK /etc/udev/rules.d/*. As in all udev-triggered commands, you can use some meaningful variables that are described in man udev. You might realize you don't really need to give a custom name to the device, since you can feed it's name to a script (via the %k variable).

As for the auto-mount solution, have a look at UAM, which I've described a little bit in the answer to this question.

share|improve this answer
    
I understand these constraints. As it happens, I only ever need to support a single USB stick connected at any one time to this particular system. However, I would need to support multiple partitions on the USB stick (it would be nice if these could be mounted into subfolders from the mount point). Given these requirements, do you have any advice for a potential solution? Due to the nature of the project, I need to avoid using additional third-party software if at all possible. –  jon Nov 16 '11 at 14:59
    
Then have a look at the edit I just made (the middle part). Would this be enough? –  rozcietrzewiacz Nov 16 '11 at 15:07
    
Also note that UAM is not really a program - it is a bunch of nice udev rules with accompanying scripts. You can have a look at the rules and easily adapt them to your needs. –  rozcietrzewiacz Nov 16 '11 at 15:12
    
Thanks for the advice. One other thing: do you think that you could look at my output from udevadm and tell me which device is the device I should actually be targeting with my rule? The various examples I've seen online all seem to involve much shorter trees and each example seems to target a different level of device, with no explanation of which one should be targeted and why. –  jon Nov 16 '11 at 15:49
    
Just added an update above, any ideas? Thanks! –  jon Nov 16 '11 at 16:18

Sorry to answer my own question, and many thanks are due to rozcietrzewiacz for contributing, but I eventually managed to make some major progress using the following rule after hours of reading online:

SUBSYSTEMS=="scsi", KERNEL=="sd[a-h]1", SYMLINK+="removable", RUN+="/bin/mount /dev/removable /path/to/mount"

This will mount the first partition of any SCSI device. I guess the next question will be how to mount multiple partitions, but that's another issue for another day.

share|improve this answer
1  
It is not a good rule. This will match also the partitions of hard drives. there is a removable attribute you should test for, and rather block instead of scsi. –  rozcietrzewiacz Nov 18 '11 at 10:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.