dd65c9
From f70113f32c25b8d1c7d87eb812556c91b4b9b5c6 Mon Sep 17 00:00:00 2001
181b3f
From: NeilBrown <neil@brown.name>
181b3f
Date: Thu, 31 Aug 2017 02:48:25 +1000
181b3f
Subject: [PATCH] shutdown: don't remount,ro network filesystems. (#6588)
181b3f
181b3f
systemd-shutdown is run after the network is stopped,
181b3f
so remounting a network filesystem read-only can hang.
181b3f
A simple umount is the most useful thing that can
181b3f
be done for a network filesystem once the network is down.
181b3f
181b3f
(cherry picked from commit 9cbc4547702aac28466c497f720038b9e2dc510c)
181b3f
181b3f
Resolves: #1312002
181b3f
---
181b3f
 src/core/umount.c | 17 ++++++++++++-----
181b3f
 1 file changed, 12 insertions(+), 5 deletions(-)
181b3f
181b3f
diff --git a/src/core/umount.c b/src/core/umount.c
c62b8e
index bfd8aa5f88..6e8ccc794f 100644
181b3f
--- a/src/core/umount.c
181b3f
+++ b/src/core/umount.c
181b3f
@@ -41,6 +41,7 @@
181b3f
 typedef struct MountPoint {
181b3f
         char *path;
181b3f
         char *options;
181b3f
+        char *type;
181b3f
         dev_t devnum;
181b3f
         LIST_FIELDS(struct MountPoint, mount_point);
181b3f
 } MountPoint;
181b3f
@@ -73,7 +74,7 @@ static int mount_points_list_get(MountPoint **head) {
181b3f
                 return -errno;
181b3f
 
181b3f
         for (i = 1;; i++) {
181b3f
-                _cleanup_free_ char *path = NULL, *options = NULL;
181b3f
+                _cleanup_free_ char *path = NULL, *options = NULL, *type = NULL;
181b3f
                 char *p = NULL;
181b3f
                 MountPoint *m;
181b3f
                 int k;
181b3f
@@ -87,11 +88,11 @@ static int mount_points_list_get(MountPoint **head) {
181b3f
                            "%*s"        /* (6) mount flags */
181b3f
                            "%*[^-]"     /* (7) optional fields */
181b3f
                            "- "         /* (8) separator */
181b3f
-                           "%*s "       /* (9) file system type */
181b3f
+                           "%ms "       /* (9) file system type */
181b3f
                            "%*s"        /* (10) mount source */
181b3f
                            "%ms"        /* (11) mount options */
181b3f
                            "%*[^\n]",   /* some rubbish at the end */
181b3f
-                           &path, &options);
181b3f
+                           &path, &type, &options);
181b3f
                 if (k != 2) {
181b3f
                         if (k == EOF)
181b3f
                                 break;
181b3f
@@ -129,6 +130,8 @@ static int mount_points_list_get(MountPoint **head) {
181b3f
                 m->path = p;
181b3f
                 m->options = options;
181b3f
                 options = NULL;
181b3f
+                m->type = type;
181b3f
+                type = NULL;
181b3f
 
181b3f
                 LIST_PREPEND(mount_point, *head, m);
181b3f
         }
181b3f
@@ -371,8 +374,12 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
181b3f
                 /* If we are in a container, don't attempt to
181b3f
                    read-only mount anything as that brings no real
181b3f
                    benefits, but might confuse the host, as we remount
181b3f
-                   the superblock here, not the bind mound. */
181b3f
-                if (detect_container(NULL) <= 0)  {
181b3f
+                   the superblock here, not the bind mount.
181b3f
+                   If the filesystem is a network fs, also skip the
181b3f
+                   remount.  It brings no value (we cannot leave
181b3f
+                   a "dirty fs") and could hang if the network is down.  */
181b3f
+                if (detect_container(NULL) <= 0 &&
181b3f
+                    !fstype_is_network(m->type)) {
181b3f
                         _cleanup_free_ char *options = NULL;
181b3f
                         /* MS_REMOUNT requires that the data parameter
181b3f
                          * should be the same from the original mount