dryang / rpms / systemd

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