summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-26 17:52:37 +0100
committerLennart Poettering <lennart@poettering.net>2015-10-26 17:52:37 +0100
commit5422848d63cdab4beac935d78de229676ba87243 (patch)
tree58d2bc5567406ed5da28631c59c5ba78cb56d518
parentad1a44b23bbc909aa3f5876dadd482a9f6c18d5c (diff)
parent471b48ed2ff6539e7071ff4694c03483c5835639 (diff)
Merge pull request #1686 from medhefgo/remount-ro-fix
unmount: Pass in mount options when remounting read-only
-rw-r--r--src/core/umount.c26
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