diff --git a/src/core/namespace.c b/src/core/namespace.c index fee4c98096..d4702cdd96 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -1063,14 +1063,6 @@ static int apply_mount( return 0; } -/* Change per-mount flags on an existing mount */ -static int bind_remount_one(const char *path, unsigned long orig_flags, unsigned long new_flags, unsigned long flags_mask) { - if (mount(NULL, path, NULL, (orig_flags & ~flags_mask) | MS_REMOUNT | MS_BIND | new_flags, NULL) < 0) - return -errno; - - return 0; -} - static int make_read_only(const MountEntry *m, char **blacklist, FILE *proc_self_mountinfo) { unsigned long new_flags = 0, flags_mask = 0; bool submounts = false; @@ -1102,7 +1094,7 @@ static int make_read_only(const MountEntry *m, char **blacklist, FILE *proc_self if (submounts) r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), new_flags, flags_mask, blacklist, proc_self_mountinfo); else - r = bind_remount_one(mount_entry_path(m), m->flags, new_flags, flags_mask); + r = bind_remount_one_with_mountinfo(mount_entry_path(m), new_flags, flags_mask, proc_self_mountinfo); /* Not that we only turn on the MS_RDONLY flag here, we never turn it off. Something that was marked * read-only already stays this way. This improves compatibility with container managers, where we diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index c74f391b06..32c5332822 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -326,6 +326,38 @@ int bind_remount_recursive( return bind_remount_recursive_with_mountinfo(prefix, new_flags, flags_mask, blacklist, proc_self_mountinfo); } +int bind_remount_one_with_mountinfo( + const char *path, + unsigned long new_flags, + unsigned long flags_mask, + FILE *proc_self_mountinfo) { + + _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; + unsigned long orig_flags = 0; + int r; + + assert(path); + assert(proc_self_mountinfo); + + rewind(proc_self_mountinfo); + + table = mnt_new_table(); + if (!table) + return -ENOMEM; + + r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo"); + if (r < 0) + return r; + + /* Try to reuse the original flag set */ + (void) get_mount_flags(table, path, &orig_flags); + + if (mount(NULL, path, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0) + return -errno; + + return 0; +} + int mount_move_root(const char *path) { assert(path); diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index 9a8d073631..06fddacf16 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -10,6 +10,7 @@ int repeat_unmount(const char *path, int flags); int umount_recursive(const char *target, int flags); int bind_remount_recursive(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **blacklist); int bind_remount_recursive_with_mountinfo(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **blacklist, FILE *proc_self_mountinfo); +int bind_remount_one_with_mountinfo(const char *path, unsigned long new_flags, unsigned long flags_mask, FILE *proc_self_mountinfo); int mount_move_root(const char *path);