923a60
From 06456e9d3235921c13e0e2f86a68e41a930aae0c Mon Sep 17 00:00:00 2001
923a60
From: Jan Janssen <medhefgo@web.de>
923a60
Date: Mon, 26 Oct 2015 15:13:28 +0100
923a60
Subject: [PATCH] unmount: Pass in mount options when remounting read-only
923a60
923a60
man 2 mount says that the mountflags and data parameteres should
923a60
match the original values except for the desired changes. We only
923a60
bother with the mount options since the only flags we can change
923a60
are MS_RDONLY, MS_SYNCHRONOUS and MS_MANDLOCK; which shouldn't
923a60
matter too much.
923a60
923a60
Fixes: #351
923a60
923a60
(cherry picked from commit 471b48ed2ff6539e7071ff4694c03483c5835639)
923a60
923a60
Related: #1312002
923a60
---
923a60
 src/core/umount.c | 26 ++++++++++++++++++++------
923a60
 1 file changed, 20 insertions(+), 6 deletions(-)
923a60
923a60
diff --git a/src/core/umount.c b/src/core/umount.c
923a60
index dd7df194de..bfd8aa5f88 100644
923a60
--- a/src/core/umount.c
923a60
+++ b/src/core/umount.c
923a60
@@ -28,6 +28,7 @@
923a60
 #include <linux/loop.h>
923a60
 #include <linux/dm-ioctl.h>
923a60
 
923a60
+#include "fstab-util.h"
923a60
 #include "list.h"
923a60
 #include "mount-setup.h"
923a60
 #include "umount.h"
923a60
@@ -39,6 +40,7 @@
923a60
 
923a60
 typedef struct MountPoint {
923a60
         char *path;
923a60
+        char *options;
923a60
         dev_t devnum;
923a60
         LIST_FIELDS(struct MountPoint, mount_point);
923a60
 } MountPoint;
923a60
@@ -71,7 +73,7 @@ static int mount_points_list_get(MountPoint **head) {
923a60
                 return -errno;
923a60
 
923a60
         for (i = 1;; i++) {
923a60
-                _cleanup_free_ char *path = NULL;
923a60
+                _cleanup_free_ char *path = NULL, *options = NULL;
923a60
                 char *p = NULL;
923a60
                 MountPoint *m;
923a60
                 int k;
923a60
@@ -82,15 +84,15 @@ static int mount_points_list_get(MountPoint **head) {
923a60
                            "%*s "       /* (3) major:minor */
923a60
                            "%*s "       /* (4) root */
923a60
                            "%ms "       /* (5) mount point */
923a60
-                           "%*s"        /* (6) mount options */
923a60
+                           "%*s"        /* (6) mount flags */
923a60
                            "%*[^-]"     /* (7) optional fields */
923a60
                            "- "         /* (8) separator */
923a60
                            "%*s "       /* (9) file system type */
923a60
                            "%*s"        /* (10) mount source */
923a60
-                           "%*s"        /* (11) mount options 2 */
923a60
+                           "%ms"        /* (11) mount options */
923a60
                            "%*[^\n]",   /* some rubbish at the end */
923a60
-                           &path);
923a60
-                if (k != 1) {
923a60
+                           &path, &options);
923a60
+                if (k != 2) {
923a60
                         if (k == EOF)
923a60
                                 break;
923a60
 
923a60
@@ -125,6 +127,9 @@ static int mount_points_list_get(MountPoint **head) {
923a60
                 }
923a60
 
923a60
                 m->path = p;
923a60
+                m->options = options;
923a60
+                options = NULL;
923a60
+
923a60
                 LIST_PREPEND(mount_point, *head, m);
923a60
         }
923a60
 
923a60
@@ -368,6 +373,14 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
923a60
                    benefits, but might confuse the host, as we remount
923a60
                    the superblock here, not the bind mound. */
923a60
                 if (detect_container(NULL) <= 0)  {
923a60
+                        _cleanup_free_ char *options = NULL;
923a60
+                        /* MS_REMOUNT requires that the data parameter
923a60
+                         * should be the same from the original mount
923a60
+                         * except for the desired changes. Since we want
923a60
+                         * to remount read-only, we should filter out
923a60
+                         * rw (and ro too, because it confuses the kernel) */
923a60
+                        (void) fstab_filter_options(m->options, "rw\0ro\0", NULL, NULL, &options);
923a60
+
923a60
                         /* We always try to remount directories
923a60
                          * read-only first, before we go on and umount
923a60
                          * them.
923a60
@@ -384,7 +397,8 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
923a60
                          * alias read-only we hence should be
923a60
                          * relatively safe regarding keeping the fs we
923a60
                          * can otherwise not see dirty. */
923a60
-                        mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
923a60
+                        log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
923a60
+                        (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
923a60
                 }
923a60
 
923a60
                 /* Skip / and /usr since we cannot unmount that