Linux – How to mount removable media in /media/

automounthotpluglinuxremovable-media

I have a Debian sid system (Wheezy) (and same question for arch as well), without any desktop environment (and no Xorg at all).

I can mount my SD-cards, USB sticks, external HDD manually with mount / umount with the suitable entries in /etc/fstab but this is compelling, and to restrictive: if I want them to be mounted in /media/<LABEL> each device with a different <LABEL> needs its own entry, and each <LABEL> directory needs to be created / removed manually in /media/ as well).

So, what is the best way to mount them automatically in /media/<LABEL> at insertion (and to unmount them from the filesystem as soon as they are unplugged)?

The ideal solution would:

  1. detect when a removable media is plugged-in (added in /dev/ as
    sdax, sdbx, … by udev)
  2. create a directory in /media/ according to its label (label of the removable media)
  3. mount it in the directory /media/<LABEL> in RW mode (if it's filesystem is supported)
  4. detect if the media has been unplugged
  5. if then, unmout it from the filesystem
  6. remove the corresponding directory from /media/

(the devices should be mounted in synchronous mode oviously, to avoid any data loss when hot unplugged because of caching)

I found some info about autofs, HAL, udisks, udisks2, etc., but it's unclear which one is deprecated or preferred, and anyway, I haven't figured out how to configure them easily on my system to do that, up to now …

Minimalism, elegance, KISS, *nix-minded, no crazy unbearable XML policies files, and up-to-date highly appreciated.

edit: trying to make my question more clear

Best Answer

Ok, it's been a long time, but I'll still answer my question with the best option I found as of now.

The best way is to create a udev rule, associated with some scripts (that will create / remove directories and mount / unmount removable devices), and attached to partition udev device event type.

1 - Creating add / remove scripts

Add this script storage-automount.sh in /lib/udev/ and set it to executable (sudo chmod +x /lib/udev/storage-automount.sh):

#!/bin/sh

# set the mountpoint name according to partition or device name
mount_point=$ID_FS_LABEL
if [ -z $mount_point ]; then
    mount_point=${DEVNAME##*/}
fi

# if a plugdev group exist, retrieve its gid set & it as owner of mountpoint
plugdev_gid="$(grep plugdev /etc/group|cut -f3 -d:)"
if [ -z $plugdev_gid ]; then
    gid=''
else
    chown root:plugdev $mount_point
    gid=",gid=$plugdev_gid"
fi

# create the mountpoint directory in /media/ (if not empty)
if [ -n $mount_point ]; then
    mkdir -p /media/$mount_point
    # other options (breaks POSIX): noatime,nodiratime,nosuid,nodev
    mount -t $ID_FS_TYPE \
      -o rw,flush,user,uid=0$gid,umask=002,dmask=002,fmask=002 \
      $DEVNAME /media/$mount_point
fi

Add this script storage-autounmount.sh in /lib/udev/ and set it to executable (sudo chmod +x /lib/udev/storage-autounmount.sh):

#!/bin/sh

# set the mountpoint name according to partition or device name
mount_point=$ID_FS_LABEL
if [ -z $mount_point ]; then
    mount_point=${DEVNAME##*/}
fi

# remove the mountpoint directory from /media/ (if not empty)
if [ -n $mount_point ]; then
    umount -l /media/$mount_point
    rm -R /media/$mount_point
fi

2 - Creating the udev rule to attach those scripts to events

And finally, add a udev rule in /etc/udev/rules.d, for instance 85-storage-automount.rules:

ENV{DEVTYPE}=="partition", RUN+="/lib/udev/storage-automount.sh", ENV{REMOVE_CMD}="/lib/udev/storage-autounmount.sh"

And that's it.

Now, when you plug a storage device in, a directory will be created in /media/ according to the partition name (I don't remember but I think it's working with NTFS partitions as well) and your partition will be mounted into it. It's R/W for users if you have a plugdev group on your system. Also, the devices are mounted in synchronous mode in order to limit the risks of data loss in case of hot unplugging.

When the device is removed, it's unmounted and the directory is removed from /media.

Also, the tool to monitor the udev events is udevadm monitor, with options like --env or --property:

$ udevadm monitor --env

This is tested and working fine on both Debian and Arch, but probably works on all distributions that rely on udev.

Related Question