]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shutdown: don't remount,ro network filesystems. (#6588)
authorNeilBrown <neil@brown.name>
Wed, 30 Aug 2017 16:48:25 +0000 (02:48 +1000)
committerLennart Poettering <lennart@poettering.net>
Wed, 30 Aug 2017 16:48:25 +0000 (18:48 +0200)
systemd-shutdown is run after the network is stopped,
so remounting a network filesystem read-only can hang.
A simple umount is the most useful thing that can
be done for a network filesystem once the network is down.

src/core/umount.c

index 591dac71f0364b97aecf62d6437f829859f5fb59..b83f63114125ca36046f27aaa30fd1efbeaed3aa 100644 (file)
 #include "string-util.h"
 #include "udev-util.h"
 #include "umount.h"
+#include "mount-util.h"
 #include "util.h"
 #include "virt.h"
 
 typedef struct MountPoint {
         char *path;
         char *options;
+        char *type;
         dev_t devnum;
         LIST_FIELDS(struct MountPoint, mount_point);
 } MountPoint;
@@ -76,7 +78,7 @@ static int mount_points_list_get(MountPoint **head) {
                 return -errno;
 
         for (i = 1;; i++) {
-                _cleanup_free_ char *path = NULL, *options = NULL;
+                _cleanup_free_ char *path = NULL, *options = NULL, *type = NULL;
                 char *p = NULL;
                 MountPoint *m;
                 int k;
@@ -90,11 +92,11 @@ static int mount_points_list_get(MountPoint **head) {
                            "%*s"        /* (6) mount flags */
                            "%*[^-]"     /* (7) optional fields */
                            "- "         /* (8) separator */
-                           "%*s "       /* (9) file system type */
+                           "%ms "       /* (9) file system type */
                            "%*s"        /* (10) mount source */
                            "%ms"        /* (11) mount options */
                            "%*[^\n]",   /* some rubbish at the end */
-                           &path, &options);
+                           &path, &type, &options);
                 if (k != 2) {
                         if (k == EOF)
                                 break;
@@ -132,6 +134,8 @@ static int mount_points_list_get(MountPoint **head) {
                 m->path = p;
                 m->options = options;
                 options = NULL;
+                m->type = type;
+                type = NULL;
 
                 LIST_PREPEND(mount_point, *head, m);
         }
@@ -388,8 +392,12 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
                 /* If we are in a container, don't attempt to
                    read-only mount anything as that brings no real
                    benefits, but might confuse the host, as we remount
-                   the superblock here, not the bind mount. */
-                if (detect_container() <= 0)  {
+                   the superblock here, not the bind mount.
+                   If the filesystem is a network fs, also skip the
+                   remount.  It brings no value (we cannot leave
+                   a "dirty fs") and could hang if the network is down.  */
+                if (detect_container() <= 0 &&
+                    !fstype_is_network(m->type)) {
                         _cleanup_free_ char *options = NULL;
                         /* MS_REMOUNT requires that the data parameter
                          * should be the same from the original mount