Linux – Automounting USB drives on a headless systemd linux box

automountfstablinuxsystemdudev

Approaches to auto-mounting devices in Linux keep changing, and googling returns quite a few solutions with various degrees of applicability for modern systemd-based boxes.

The following approaches seem to exist:

  1. modifying /etc/fstab to add per-drive mounts by UUID/label/device.
  2. udev rules (apparently 'raw rules' might conflict with existing systemd policies)
  3. udisks2 running as a systemd service or via udiskie
  4. udevil
  5. usbmount
  6. automounting provided by the desktop environments, i.e. on XFCE via thunar + thunar-volman packages, or the nautilus automount in Gnome with the gnome-volume-manager package (apparently they rely on udisks).
  7. autofs kernel automounter
  8. systemd automounting, example of usage: automount-usb

The choices can be overwhelming and it is not clear which is the current recommended approach. Moreover, it seems that different auto-mounting subsystems can conflict which each other leading to situations when a partition is mounted by one tool and then in a matter of seconds is automatically unmounted by another tool.

For systems with a desktop environment, it is straightforward since most of them handle USB-mounting automatically, so no extra action is necessary apart from enabling the automounting option in settings.

What would be the current approach for a headless system which mostly operates in text-mode?

Update

After fiddling with all the options I found usbmount to (almost) just work after I edited /lib/systemd/system/systemd-udevd.service and changed MountFlags=slave to MountFlags=shared as described in this issue (❗️❗️UPDATE: For more recent systemd versions PrivateMounts=no should be used instead!). No need to manually add any UUIDs or labels to any config files. The downside is that it creates the mount points under /media/usbN which is not perfect, so I have switched to automount-usb which was surprisingly easy to set up (just ran the configure.sh script) and which creates mount folders like /media/<device>_<disk_label> e.g. like /media/sda2_mylabel.

Relevant links:

Auto-Samba mounting: There is also a fork of automount-usb which automatically adds the attached USB drives as samba read-write mount points.

Best Answer

it is not clear which is the current 'officially' supported approach.

Officially supported by whom? If e.g. GNOME includes automount functionality based on udisks, you can be sure it's officially supported by GNOME themselves.

I am more interested in the second (i.e. whatever USB storage device), since for the first I can just add the entries to /etc/fstab.

There's no "standard way" for doing that. At best, the majority of existing systems have settled on adding automation on top of udisks2. On its own, udisks doesn't automount anything at all – but it's the "backend" used by many graphical desktop environments (at least both GNOME and Xfce use it; I'm only 80% sure about KDE and Enlightenment).

(So your option 3 would be "udisks2 + automount by udiskie", and option 4 would be "udisks2 + automount by desktop environment".)


Regarding udev rules: whether it's about mounting filesystems or starting services, the short answer is "don't do it" (for various reasons); but the long answer is: "don't do it directly, but you can ask init to do it". So it wouldn't be horrible to run systemd-mount from an udev rule, which then just passes the mount request to init just like a .mount unit would...

However, expect this to trigger a systemd bug/wart/misfeature: as udev reports the device to be ready only after processing the rules, you could end up with init automatically unmounting the disk because it thinks the device isn't there yet.

Instead, udevil would work better, since it doesn't run anything via rules but only reacts to "device ready" events emitted by udev.


fstab entries are oriented towards static devices. However, they can be sort-of abused for miscellaneous USB sticks by using /dev/disk/by-path/..., which corresponds to the physical path of a device (e.g. PCI slot 3, USB port 1, partition 1...) This way you can write a fstab entry which matches any disk plugged in to the same USB port.


The autofs kernel automounter is, similarly to udisks, just the backend upon which various automounts can be implemented by userspace. Once an autofs mount is set up, all attempts to access it are reported to the corresponding daemon. The most common implementations are the traditional (maps-based) autofs, and recently systemd with the .automount units.

So the "dynamic" USB device logic would still have to be implemented in userspace, and either way it's more work than just using udisks.

  • With plain systemd, your only option is to build on top of the above fstab "by-path" hack. Once you write a fstab entry for the desired USB port, you can mark it with x-systemd.automount,x-systemd.idle-timeout=300 to use the autofs automounter. (Or, of course, create standalone .mount + .automount units for the same result.)

    If you want to dynamically generate automounts for all USB disks on all ports, systemd cannot do that without third-party scripts.

  • I don't know whether autofsd can do what you want, but I remember that it supports some kinds of dynamic maps (for user home directories). Perhaps using the program map-type (and a script which enumerates all connected disks) would work.

Related Question