Bug 56837

Summary: Enable custom path to be ignored on shutdown umount cycle
Product: systemd Reporter: aleksei.lissitsin
Component: generalAssignee: systemd-bugs
Status: RESOLVED FIXED QA Contact: systemd-bugs
Severity: major    
Priority: medium    
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description aleksei.lissitsin 2012-11-07 09:03:54 UTC
In systemd it should be possible to specify which mountpoints must not be unmounted on shutdown.

I have the following setup:
Archlinux (guest) is installed into a file on an ntfs partition (host).

Initrd mounts the host (say, /dev/sda2) into its (initrd's) filesystem using
an executable whose name starts with @ (so that the process would not be killed by systemd on shutdown).

Then initrd creates a loop device using the file on the host and proceeds to start the guest using it as the root device.

But I still want to access the host from the guest, so initrd bind-mounts
the host to a path in guest's filesystem (I cannot mount it later from guest because /dev/sda2 would be busy as already mounted).

This causes /dev/sda2 to appear in guest's mountinfo, so that systemd will try (and succeed) to unmount it while there are still some processes writing to guest's filesystem. --> BAD THINGS HAPPEN THEN

I currently solve the issue by the following patch 
(my host is mounted to /host in guest filesystem)

--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -127,7 +127,7 @@ bool mount_point_ignore(const char *path) {
                 if (path_equal(path, i))
                         return true;
 
-        return false;
+        return path_startswith(path, "/host");
 }
 
 static int mount_one(const MountPoint *p, bool relabel) {

But I think that using predefined prefixes is not the best solution and systemd should allow one to somehow specify exactly which mountpoints not to unmount on shutdown.
Comment 1 Lennart Poettering 2013-01-15 00:57:51 UTC
Hmm, systemd should only unmount the bind mount it sees, but can't really do anything about the mount. (Note that bind mounts are just aliases to the same fs, and there is zero difference between the various mounts of the same file system). 

Also, a busy fs cannot be unmounted anyway, this will fail with EBUSY and systemd relies on that in the shutdown loop.

So, for these two reasons I don't really grok the issue?
Comment 2 aleksei.lissitsin 2013-01-15 09:39:52 UTC
I cannot say how it is with the up-to-date systemd. I should test on that machine.

But back then (07.11.2012) it DID manage to unmount the host solely by bind-mount path.

I found another workaround for that: I just manually unmount the bind-mount on shutdown with umount (and it correctly just removes the bind-mount). Then the host is not in mountinfo, and systemd does not try to unmount it.

(Although (this is another issue of course) for some strange reason one cannot guarantee that on-shutdown script ends before systemd umount cycle begins, so there is a race, but so far my script is lucky.)

So to wrap it, the problem here seems to be that 
umount2(m->path, MNT_FORCE)
in function mount_points_list_umount of core/umount.c
actually manages to unmount the host (/dev/sda2) by its bind-mount name no matter whether it is busy or not.
Comment 3 aleksei.lissitsin 2013-01-15 12:02:38 UTC
Systemd 196 - the problem still here.

I'll wait for Archlinux to introduce v197 to "Core" to test there but I suspect that the problem will remain because the behaviour in mount_points_list_umount in umount.c seems the same.
Comment 4 aleksei.lissitsin 2013-01-18 10:42:04 UTC
Yep, in systemd v197 it is the same.

Shutdown umount cycle unmounts host device (/dev/sda2) completely whenever it is present in mountinfo (i.e. bind-mounted somewhere in the guest). (Then I immediately get write errors on guest filesystem, because it becomes unavailable.)

So either this behaviour should be corrected (only unmount binds, not the device in shutdown cycle). Or one must be able to specify what paths not to unmount.
Comment 5 Lennart Poettering 2013-01-18 18:47:46 UTC
Note that systemd git no longer uses MNT_FORCE when unmounting file systems in the final loop. I figure that might fix your issue.
Comment 6 aleksei.lissitsin 2013-01-21 13:01:59 UTC
Yes. Without MNT_FORCE it now seems to behave correctly: only bind-mount gets unmounted.

Just for the info: the problem only exists in the setting when only the bind-mount is seen in mountinfo, and the real mountpoint is hidden. umount2 with MNT_FORCE then incorrectly assumes that the bind-mount is the last mountpoint and proceeds to unmount the device (it succeeds because of MNT_FORCE probably).

If both mountpoints are seen, it would correctly only detach the bind-mount and leave the device mounted.
Comment 7 Lennart Poettering 2013-01-23 01:47:21 UTC
OK, closing then.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.