Ubuntu – Mounting alternate devices (with different mount options) at the same mount point

automountingfstablinuxmountUbuntu

I have a server (running Ubuntu 14.04) that has a hot-swap drive bay. I typically use the hot-swap bay to mount one of a bunch of loose hard disks that I shuttle large scientific datasets around on. Some of these disks require different mount options (different filesystems, SSDs v HDDs etc.), which I would normally specify separately for each UUID within /etc/fstab.

In order to simplify some of my scripts for batch processing and backing up this data, I'd like to configure the server to always use the same mount point for whichever one of these hot-swapped disks is currently plugged in.

I've tried putting something like this in my fstab:

UUID=<disk A>  /common_mount_point  ext4   defaults,discard,noatime  0 0
UUID=<disk B>  /common_mount_point  btrfs  defaults,compress=lzo     0 0    

This works fine when I want to mount disk A, but I get an error whenever I try to mount disk B:

mount: special device UUID=<disk B> does not exist

The converse happens if I swap the order of those two lines, so it seems that mount just looks for the first line in fstab that refers to that particular mount point and throws an error if the associated file system descriptor can't be found.

I suppose that I could probably write a bash script to sequentially try mounting several different UUIDs to the same mount point until one of the mount operations succeeds, but I was hoping there would be a more elegant solution.

Update 1

Interestingly if I call sudo mount -a instead of mount /common_mount_point, whilst I still get the error message that the UUID for disk A can't be found, it succeeds at mounting disk B. It therefore seems that mount -a will try multiple fstab entries with the same mountpoint, but I'd rather not have to sudo in order to make this work.

This behavior seems to be related to this reported bug in mountall, which was apparently fixed in v2.50. The newest verison in the Trusty repos is still 2.49, so I'll see if I can find a PPA that has the updated version.

Update 2

It turns out that the bug in mountall was irrelevant, since mountall is only invoked when I call mount -a rather than mount /common_mount_point. In fact I was already running mountall v2.53, according to the output of dpkg -s mountall (even though mountall --version told me it was v2.49). This presumably accounts for the fact that sudo mount -a does indeed try multiple fstab lines that refer to the same mount point.

Best Answer

Leverage udev to use the same device name

Instead of listing UUIDs in /etc/fstab, you could list a device name, and set up udev to use the same device name for all of these devices. Put a line like this in a file in /etc/udev/rules.d:

KERNEL=="sd*", ATTRS{serial}=="123456798", NAME="one_of_my_disks%n"

or

KERNEL=="sd*", ATTRS{serial}=="123456798", SYMLINK+="one_of_my_disks%n"

Run udevadm info -a -n sdb to see what attributes of the disk (like ATTRS{serial}=="123456798" in the example above) you can match against. Note that you can only use multiple attributes but they all have to be from the same section.

Then, in /etc/fstab, use /dev/one_of_my_disks as the block device.

If your disks have different layouts, this is more complicated. You can use auto for the filesystem type; this should work most of the type. If you need different partition numbers or mount options, however, you'll need different fstab entries. You can work around that by editing fstab on the fly through a script invoked by the udev entry, which will be executed when the disk is detected by the system. For example, use the following udev rule:

KERNEL=="sd*", ATTRS{serial}=="123456798", ENV{FSTAB4}="compress=lzo", NAME="one_of_my_disks%n", RUN+="/usr/local/sbin/fstab_update_my_disk"

and the following fstab_update_my_disk script (untested):

#!/bin/sh
/usr/bin/sed -i -e '/^\/dev\/one_of_my_disks1/ s/\([^ \t][^ \t]*[ \t][ \t]*[^ \t][^ \t]*[ \t][ \t]*[^ \t][^ \t]*[ \t][ \t]*\)[^ \t][^ \t]*/\1'"$FSTAB4"'/'

Leverage udev to not care about the mount point

Another approach would be to keep separate fstab entries, with distinct device names and distinct mount points. But use a udev RUN hook to update a symbolic link that points to the mount point.

KERNEL=="sd*", ATTRS{serial}=="123456798", RUN+="/bin/ln -snf /media/disk1 /media/one_of_my_disks"
Related Question