2

I can move the parent directory of a mount point as follows:

$ mkdir -p f/mnt
$ bindfs --no-allow-other f/mnt f/mnt
$ mv f g
$

But I cannot rename the mount point itself:

$ mv g/mnt g/m
mv: cannot move 'g/mnt' to 'g/m': Device or resource busy

Is there a security, compatibility, or implementation reason for this distinction?

My kernel version is 4.17.19-200.fc28.x86_64.

3 Answers 3

2

Schily's answer about why this is not working is accurate.

However, you actually can move mount points themselves on Linux. Borrowing from the example in the question, the correct way to do this is:

mount --move g/mnt g/m

The target directory (in this case g/m) has to be a valid location for a mount point (the directory has to exist, etc) and you must be running with root privileges (or CAP_MOUNT), but otherwise there are essentially no restrictions.

This operation will update all kernel managed data structures referencing that mount point, including mount table entries (within the current mount namespace), open file descriptors, root and current working directories for running programs, and a few other things, so it is (reasonably) safe to do this on a mount point in active use.

The caveat is that anything which is running and uses paths instead of file descriptors may not properly handle it (for example, moving the root of your website this way will probably break the website, because most web servers don't keep open references to all the files for the site).

You may also find the pivot_root command interesting, it's a special case of moving a mount point (it swaps two mount points and updates the root and current working directory of everything on the system), and is used during startup on most modern Linux systems to switch from the initramfs to the real root filesystem.

3
  • +1. This is not at all the answer I was looking for. I should apologize, as it is a good answer to the question I actually wrote :-).
    – sourcejedi
    Commented Sep 11, 2018 at 20:11
  • fails with bsd mount mount: illegal option -- - Commented Oct 19, 2022 at 8:44
  • 1
    @GeoffLangenderfer Yes, because BSD uses different options. AFAIK, BSD does not support moving mount points without unmounting them. The question itself is tagged Linux though, so my answer just focused on Linux. Commented Oct 19, 2022 at 12:00
1

You cannot rename the root directory of a filesystem and this is what you like to do.

If you NFS-mount the filesystem with the underlying mount point, you may be able to rename it as this allows you to see the uncovered mount point.

Background: if something is mounted to an entry in the filesystem, this hides the orignal file, but you would need to rename the original file. What you see is the root directory of the mounted filesytem and that cannot be renamed.

8
  • Right, thanks. You can't rename() a directory to move it from one filesystem to another (EXDEV error).
    – sourcejedi
    Commented Sep 11, 2018 at 17:52
  • 1
    I am indeed able to rename the underlying file, if I use Linux mount namespaces :-). Or a bind mount would allow it also.
    – sourcejedi
    Commented Sep 11, 2018 at 17:57
  • I'm curious if I could explain why the error I get is EBUSY not EXDEV. But I didn't ask about that in the question :-).
    – sourcejedi
    Commented Sep 11, 2018 at 18:05
  • @sourcejedi Because that's the standard return code for indicating that a filesystem object can't be manipulated in the requested way due to it being in use by something that is mutually exclusive with the requested operation. You will get the same return code trying to unmount a filesystem that has open files for example. Commented Sep 11, 2018 at 19:34
  • @AustinHemmelgarn What is using it in my example?
    – sourcejedi
    Commented Sep 11, 2018 at 19:51
0

Yes: compatibility reasons which affect security.

This restriction was deliberately not removed, for a reason reported faithfully by LWN.net. Removing the restriction would create a security hole in some versions of fusermount. fusermount had been improved earlier by adding UMOUNT_NOFOLLOW, and this made it safe. However the old versions of fusermount were still widespread enough to be a concern.

See Mount point removal and renaming, LWN.net 2016.

As far as I can tell from the linked thread, patches 1-3 would have allowed moving a mount point. And then patch 4 was added to forbid it :-).

This is not complete proof. However it suggests the restriction in patch 4 was not due to internal implementation reasons. I also believe kernel developers would have mentioned, if they had any idea that user expectations would have been broken by allowing mount points to be moved.

@schily, however, points out there is something strange about allowing mount points to be moved (or unlinked). It appears that it was possible to allow rename() of a mount point. But only because it was interpreted as renaming the file underlying the mounted filesystem(s).

It would be a strange exception to the current rule, that rename(oldpath, newpath) requires that the oldpath and newpath are on the same filesystem. Otherwise it fails with EXDEV. (In fact they must be on the same mount of the filesystem).

I thought of one extra little strangeness under Linux. If you set the Linux "immutable bit" on the underlying file, I think the rename() should be denied. But if you inspect the immutable bit on the mount point, you will not see the immutable bit of the underlying file! I expect it works fine, it would just be rather annoying if you ever had to troubleshoot it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .