]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
unmount: Pass in mount options when remounting read-only 1686/head
authorJan Janssen <medhefgo@web.de>
Mon, 26 Oct 2015 14:13:28 +0000 (15:13 +0100)
committerJan Janssen <medhefgo@web.de>
Mon, 26 Oct 2015 14:13:28 +0000 (15:13 +0100)
man 2 mount says that the mountflags and data parameteres should
match the original values except for the desired changes. We only
bother with the mount options since the only flags we can change
are MS_RDONLY, MS_SYNCHRONOUS and MS_MANDLOCK; which shouldn't
matter too much.

Fixes: #351
src/core/umount.c

index 0e61bcaebbd91685cf86245dddb15907bdf58043..8735bed7b17f41b11a6d2fa5a660fcca74c72b38 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "escape.h"
 #include "fd-util.h"
+#include "fstab-util.h"
 #include "list.h"
 #include "mount-setup.h"
 #include "path-util.h"
@@ -42,6 +43,7 @@
 
 typedef struct MountPoint {
         char *path;
+        char *options;
         dev_t devnum;
         LIST_FIELDS(struct MountPoint, mount_point);
 } MountPoint;
@@ -75,7 +77,7 @@ static int mount_points_list_get(MountPoint **head) {
                 return -errno;
 
         for (i = 1;; i++) {
-                _cleanup_free_ char *path = NULL;
+                _cleanup_free_ char *path = NULL, *options = NULL;
                 char *p = NULL;
                 MountPoint *m;
                 int k;
@@ -86,15 +88,15 @@ static int mount_points_list_get(MountPoint **head) {
                            "%*s "       /* (3) major:minor */
                            "%*s "       /* (4) root */
                            "%ms "       /* (5) mount point */
-                           "%*s"        /* (6) mount options */
+                           "%*s"        /* (6) mount flags */
                            "%*[^-]"     /* (7) optional fields */
                            "- "         /* (8) separator */
                            "%*s "       /* (9) file system type */
                            "%*s"        /* (10) mount source */
-                           "%*s"        /* (11) mount options 2 */
+                           "%ms"        /* (11) mount options */
                            "%*[^\n]",   /* some rubbish at the end */
-                           &path);
-                if (k != 1) {
+                           &path, &options);
+                if (k != 2) {
                         if (k == EOF)
                                 break;
 
@@ -129,6 +131,9 @@ static int mount_points_list_get(MountPoint **head) {
                 }
 
                 m->path = p;
+                m->options = options;
+                options = NULL;
+
                 LIST_PREPEND(mount_point, *head, m);
         }
 
@@ -373,6 +378,14 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
                    benefits, but might confuse the host, as we remount
                    the superblock here, not the bind mound. */
                 if (detect_container() <= 0)  {
+                        _cleanup_free_ char *options = NULL;
+                        /* MS_REMOUNT requires that the data parameter
+                         * should be the same from the original mount
+                         * except for the desired changes. Since we want
+                         * to remount read-only, we should filter out
+                         * rw (and ro too, because it confuses the kernel) */
+                        (void) fstab_filter_options(m->options, "rw\0ro\0", NULL, NULL, &options);
+
                         /* We always try to remount directories
                          * read-only first, before we go on and umount
                          * them.
@@ -389,7 +402,8 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
                          * alias read-only we hence should be
                          * relatively safe regarding keeping the fs we
                          * can otherwise not see dirty. */
-                        (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
+                        log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
+                        (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
                 }
 
                 /* Skip / and /usr since we cannot unmount that