richardphibel / rpms / systemd

Forked from rpms/systemd 2 years ago
Clone
923a60
From 5bace483dedc9098da8191f39c823649948a7a3c Mon Sep 17 00:00:00 2001
923a60
From: NeilBrown <neil@brown.name>
923a60
Date: Wed, 8 Nov 2017 19:29:32 +1100
923a60
Subject: [PATCH] umount: always use MNT_FORCE in umount_all() (#7213)
923a60
923a60
The linux umount2() systemcall accepts a MNT_FORCE flags
923a60
which some filesystems honor, particularly FUSE and various
923a60
network filesystems such as NFS.
923a60
These filesystems can sometimes wait for an indefinite period
923a60
for a response from an external service, and the wait if
923a60
sometimes "uninterruptible" meaning that the process cannot be
923a60
killed.
923a60
Using MNT_FORCE causes any such request that are outstanding to
923a60
be aborted.  This normally allows the waiting process to
923a60
be killed.  It will then realease and reference it has to the
923a60
filesytem, this allowing the filesystem to be unmounted.
923a60
923a60
If there remain active references to the filesystem, MNT_FORCE
923a60
is *not* forcefull enough to unmount the filesystem anyway.
923a60
923a60
By the time that umount_all() is run by systemd-shutdown, all
923a60
filesystems *should* be unmounted, and sync() will have been
923a60
called.  Anything that remains cannot be unmounted in a
923a60
completely clean manner and just nees to be dealt with as firmly
923a60
as possible.  So use MNT_FORCE and try to explain why in the
923a60
comment.
923a60
923a60
Also enhance an earlier comment to explain why umount2() is
923a60
safe even though mount(MNT_REMOUNT) isn't.
923a60
923a60
(cherry picked from commit c44cac7c6c43407d28bd8daebff39f6145a2a33e)
923a60
923a60
Resolves: #1571098
923a60
---
923a60
 src/core/umount.c | 16 +++++++++++-----
923a60
 1 file changed, 11 insertions(+), 5 deletions(-)
923a60
923a60
diff --git a/src/core/umount.c b/src/core/umount.c
923a60
index 3eec0d4592..91d67c06ca 100644
923a60
--- a/src/core/umount.c
923a60
+++ b/src/core/umount.c
923a60
@@ -377,7 +377,9 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
923a60
                    the superblock here, not the bind mount.
923a60
                    If the filesystem is a network fs, also skip the
923a60
                    remount.  It brings no value (we cannot leave
923a60
-                   a "dirty fs") and could hang if the network is down.  */
923a60
+                   a "dirty fs") and could hang if the network is down.
923a60
+                   Note that umount2() is more careful and will not
923a60
+                   hang because of the network being down. */
923a60
                 if (detect_container(NULL) <= 0 &&
923a60
                     !fstype_is_network(m->type)) {
923a60
                         _cleanup_free_ char *options = NULL;
923a60
@@ -418,11 +420,15 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
923a60
                 )
923a60
                         continue;
923a60
 
923a60
-                /* Trying to umount. We don't force here since we rely
923a60
-                 * on busy NFS and FUSE file systems to return EBUSY
923a60
-                 * until we closed everything on top of them. */
923a60
+                /* Trying to umount. Using MNT_FORCE causes some
923a60
+                 * filesystems (e.g. FUSE and NFS and other network
923a60
+                 * filesystems) to abort any pending requests and
923a60
+                 * return -EIO rather than blocking indefinitely.
923a60
+                 * If the filesysten is "busy", this may allow processes
923a60
+                 * to die, thus making the filesystem less busy so
923a60
+                 * the unmount might succeed (rather then return EBUSY).*/
923a60
                 log_info("Unmounting %s.", m->path);
923a60
-                if (umount2(m->path, 0) == 0) {
923a60
+                if (umount2(m->path, MNT_FORCE) == 0) {
923a60
                         if (changed)
923a60
                                 *changed = true;
923a60