diff options
author | Jan Janssen <medhefgo@web.de> | 2015-10-26 15:13:28 +0100 |
---|---|---|
committer | Jan Janssen <medhefgo@web.de> | 2015-10-26 15:13:28 +0100 |
commit | 471b48ed2ff6539e7071ff4694c03483c5835639 (patch) | |
tree | 58d2bc5567406ed5da28631c59c5ba78cb56d518 | |
parent | ad1a44b23bbc909aa3f5876dadd482a9f6c18d5c (diff) |
unmount: Pass in mount options when remounting read-only
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
-rw-r--r-- | src/core/umount.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/core/umount.c b/src/core/umount.c index 0e61bcaebb..8735bed7b1 100644 --- a/src/core/umount.c +++ b/src/core/umount.c @@ -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 |