diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index 09fbdcfebec..1136454b7df 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -568,7 +568,7 @@ int mount_nofollow( return mount_fd(source, fd, filesystemtype, mountflags, data); } -const char *mount_propagation_flags_to_string(unsigned long flags) { +const char *mount_propagation_flag_to_string(unsigned long flags) { switch (flags & (MS_SHARED|MS_SLAVE|MS_PRIVATE)) { case 0: @@ -584,7 +584,7 @@ const char *mount_propagation_flags_to_string(unsigned long flags) { return NULL; } -int mount_propagation_flags_from_string(const char *name, unsigned long *ret) { +int mount_propagation_flag_from_string(const char *name, unsigned long *ret) { if (isempty(name)) *ret = 0; @@ -598,3 +598,7 @@ int mount_propagation_flags_from_string(const char *name, unsigned long *ret) { return -EINVAL; return 0; } + +bool mount_propagation_flag_is_valid(unsigned long flag) { + return IN_SET(flag, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE); +} diff --git a/src/basic/mountpoint-util.h b/src/basic/mountpoint-util.h index da5d852ff3e..19709195e84 100644 --- a/src/basic/mountpoint-util.h +++ b/src/basic/mountpoint-util.h @@ -55,5 +55,6 @@ int dev_is_devtmpfs(void); int mount_fd(const char *source, int target_fd, const char *filesystemtype, unsigned long mountflags, const void *data); int mount_nofollow(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data); -const char *mount_propagation_flags_to_string(unsigned long flags); -int mount_propagation_flags_from_string(const char *name, unsigned long *ret); +const char *mount_propagation_flag_to_string(unsigned long flags); +int mount_propagation_flag_from_string(const char *name, unsigned long *ret); +bool mount_propagation_flag_is_valid(unsigned long flag); diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index c5a51bf5cd8..41eeb1ee941 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1599,11 +1599,11 @@ static int parse_personality(const char *s, unsigned long *p) { return 0; } -static const char* mount_propagation_flags_to_string_with_check(unsigned long n) { - if (!IN_SET(n, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE)) +static const char* mount_propagation_flag_to_string_with_check(unsigned long n) { + if (!mount_propagation_flag_is_valid(n)) return NULL; - return mount_propagation_flags_to_string(n); + return mount_propagation_flag_to_string(n); } static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT); @@ -1624,7 +1624,7 @@ static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_pers static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check); static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc); static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string); -static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flags_to_string_with_check); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flag_to_string_with_check); int bus_exec_context_set_transient_property( Unit *u, diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 734a5941cc1..ac8c64fe3b9 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -149,7 +149,7 @@ DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight"); DEFINE_CONFIG_PARSE_PTR(config_parse_cg_cpu_weight, cg_cpu_weight_parse, uint64_t, "Invalid CPU weight"); static DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares_internal, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares"); -DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag"); +DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flag_from_string, unsigned long, "Failed to parse mount flag"); DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_numa_policy, mpol, int, -1, "Invalid NUMA policy type"); DEFINE_CONFIG_PARSE_ENUM(config_parse_status_unit_format, status_unit_format, StatusUnitFormat, "Failed to parse status unit format"); DEFINE_CONFIG_PARSE_ENUM_FULL(config_parse_socket_timestamping, socket_timestamping_from_string_harder, SocketTimestamping, "Failed to parse timestamping precision"); diff --git a/src/core/namespace.c b/src/core/namespace.c index af30f40503d..3bac6bb6a3b 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2488,7 +2488,7 @@ int setup_namespace( goto finish; /* MS_MOVE does not work on MS_SHARED so the remount MS_SHARED will be done later */ - r = mount_switch_root(root, MOUNT_ATTR_PROPAGATION_INHERIT); + r = mount_switch_root(root, /* mount_propagation_flag = */ 0); if (r == -EINVAL && root_directory) { /* If we are using root_directory and we don't have privileges (ie: user manager in a user * namespace) and the root_directory is already a mount point in the parent namespace, @@ -2498,7 +2498,7 @@ int setup_namespace( r = mount_nofollow_verbose(LOG_DEBUG, root, root, NULL, MS_BIND|MS_REC, NULL); if (r < 0) goto finish; - r = mount_switch_root(root, MOUNT_ATTR_PROPAGATION_INHERIT); + r = mount_switch_root(root, /* mount_propagation_flag = */ 0); } if (r < 0) { log_debug_errno(r, "Failed to mount root with MS_MOVE: %m"); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 324cd0e69aa..a1bf5bb1d19 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3973,7 +3973,7 @@ static int outer_child( * directory mount to root later on. * https://github.com/systemd/systemd/issues/3847#issuecomment-562735251 */ - r = mount_switch_root(directory, MOUNT_ATTR_PROPAGATION_SHARED); + r = mount_switch_root(directory, MS_SHARED); if (r < 0) return log_error_errno(r, "Failed to move root directory: %m"); diff --git a/src/shared/bus-print-properties.c b/src/shared/bus-print-properties.c index b0267427fa1..9369866fa1a 100644 --- a/src/shared/bus-print-properties.c +++ b/src/shared/bus-print-properties.c @@ -136,7 +136,7 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b } else if (streq(name, "MountFlags")) { const char *result; - result = mount_propagation_flags_to_string(u); + result = mount_propagation_flag_to_string(u); if (!result) return -EINVAL; diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 6b6383b60b7..7d136df2d92 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -131,7 +131,7 @@ DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse); DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse); DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse); DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_weight_parse); -DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flag_from_string); DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64); DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode); DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou); @@ -1035,7 +1035,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con return bus_append_safe_atou(m, field, eq); if (streq(field, "MountFlags")) - return bus_append_mount_propagation_flags_from_string(m, field, eq); + return bus_append_mount_propagation_flag_from_string(m, field, eq); if (STR_IN_SET(field, "Environment", "UnsetEnvironment", diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index dec12ea3000..8fce74297bd 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -430,31 +430,7 @@ int bind_remount_one_with_mountinfo( return 0; } -static const char *const mount_attr_propagation_type_table[_MOUNT_ATTR_PROPAGATION_TYPE_MAX] = { - [MOUNT_ATTR_PROPAGATION_INHERIT] = "inherited", - [MOUNT_ATTR_PROPAGATION_PRIVATE] = "private", - [MOUNT_ATTR_PROPAGATION_DEPENDENT] = "dependent", - [MOUNT_ATTR_PROPAGATION_SHARED] = "shared", -}; - -DEFINE_STRING_TABLE_LOOKUP(mount_attr_propagation_type, MountAttrPropagationType); - -unsigned int mount_attr_propagation_type_to_flag(MountAttrPropagationType t) { - switch (t) { - case MOUNT_ATTR_PROPAGATION_INHERIT: - return 0; - case MOUNT_ATTR_PROPAGATION_PRIVATE: - return MS_PRIVATE; - case MOUNT_ATTR_PROPAGATION_DEPENDENT: - return MS_SLAVE; - case MOUNT_ATTR_PROPAGATION_SHARED: - return MS_SHARED; - default: - assert_not_reached(); - } -} - -static inline int mount_switch_root_pivot(const char *path, int fd_newroot) { +static int mount_switch_root_pivot(const char *path, int fd_newroot) { _cleanup_close_ int fd_oldroot = -EBADF; fd_oldroot = open("/", O_PATH|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); @@ -484,7 +460,7 @@ static inline int mount_switch_root_pivot(const char *path, int fd_newroot) { return 0; } -static inline int mount_switch_root_move(const char *path) { +static int mount_switch_root_move(const char *path) { if (mount(path, "/", NULL, MS_MOVE, NULL) < 0) return log_debug_errno(errno, "Failed to move new rootfs '%s': %m", path); @@ -497,12 +473,12 @@ static inline int mount_switch_root_move(const char *path) { return 0; } -int mount_switch_root(const char *path, MountAttrPropagationType type) { - int r; +int mount_switch_root(const char *path, unsigned long mount_propagation_flag) { _cleanup_close_ int fd_newroot = -EBADF; - unsigned int flags; + int r; assert(path); + assert(mount_propagation_flag_is_valid(mount_propagation_flag)); fd_newroot = open(path, O_PATH|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); if (fd_newroot < 0) @@ -522,11 +498,13 @@ int mount_switch_root(const char *path, MountAttrPropagationType type) { if (r < 0) return log_debug_errno(r, "Failed to switch to new rootfs '%s': %m", path); - /* Finally, let's establish the requested propagation type. */ - flags = mount_attr_propagation_type_to_flag(type); - if ((flags != 0) && mount(NULL, ".", NULL, flags|MS_REC, 0) < 0) + /* Finally, let's establish the requested propagation flags. */ + if (mount_propagation_flag == 0) + return 0; + + if (mount(NULL, ".", NULL, mount_propagation_flag | MS_REC, 0) < 0) return log_debug_errno(errno, "Failed to turn new rootfs '%s' into %s mount: %m", - mount_attr_propagation_type_to_string(type), path); + mount_propagation_flag_to_string(mount_propagation_flag), path); return 0; } diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index f6de42e1a02..7554bf828e1 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -11,20 +11,6 @@ #include "errno-util.h" #include "macro.h" -typedef enum MountAttrPropagationType { - MOUNT_ATTR_PROPAGATION_INHERIT, /* no special MS_* propagation flags */ - MOUNT_ATTR_PROPAGATION_PRIVATE, /* MS_PRIVATE */ - MOUNT_ATTR_PROPAGATION_DEPENDENT, /* MS_SLAVE */ - MOUNT_ATTR_PROPAGATION_SHARED, /* MS_SHARE */ - - _MOUNT_ATTR_PROPAGATION_TYPE_MAX, - _MOUNT_ATTR_PROPAGATION_TYPE_INVALID = -EINVAL, -} MountAttrPropagationType; - -const char* mount_attr_propagation_type_to_string(MountAttrPropagationType t) _const_; -MountAttrPropagationType mount_attr_propagation_type_from_string(const char *s) _pure_; -unsigned int mount_attr_propagation_type_to_flag(MountAttrPropagationType t); - int repeat_unmount(const char *path, int flags); int umount_recursive(const char *target, int flags); @@ -35,7 +21,7 @@ static inline int bind_remount_recursive(const char *prefix, unsigned long new_f int bind_remount_one_with_mountinfo(const char *path, unsigned long new_flags, unsigned long flags_mask, FILE *proc_self_mountinfo); -int mount_switch_root(const char *path, MountAttrPropagationType type); +int mount_switch_root(const char *path, unsigned long mount_propagation_flag); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(FILE*, endmntent, NULL); #define _cleanup_endmntent_ _cleanup_(endmntentp) diff --git a/src/test/test-mountpoint-util.c b/src/test/test-mountpoint-util.c index ccf18ecd9c5..c4a87d253e9 100644 --- a/src/test/test-mountpoint-util.c +++ b/src/test/test-mountpoint-util.c @@ -17,19 +17,19 @@ #include "tests.h" #include "tmpfile-util.h" -static void test_mount_propagation_flags_one(const char *name, int ret, unsigned long expected) { +static void test_mount_propagation_flag_one(const char *name, int ret, unsigned long expected) { unsigned long flags; log_info("/* %s(%s) */", __func__, strnull(name)); - assert_se(mount_propagation_flags_from_string(name, &flags) == ret); + assert_se(mount_propagation_flag_from_string(name, &flags) == ret); if (ret >= 0) { const char *c; assert_se(flags == expected); - c = mount_propagation_flags_to_string(flags); + c = mount_propagation_flag_to_string(flags); if (isempty(name)) assert_se(isempty(c)); else @@ -37,14 +37,14 @@ static void test_mount_propagation_flags_one(const char *name, int ret, unsigned } } -TEST(mount_propagation_flags) { - test_mount_propagation_flags_one("shared", 0, MS_SHARED); - test_mount_propagation_flags_one("slave", 0, MS_SLAVE); - test_mount_propagation_flags_one("private", 0, MS_PRIVATE); - test_mount_propagation_flags_one(NULL, 0, 0); - test_mount_propagation_flags_one("", 0, 0); - test_mount_propagation_flags_one("xxxx", -EINVAL, 0); - test_mount_propagation_flags_one(" ", -EINVAL, 0); +TEST(mount_propagation_flag) { + test_mount_propagation_flag_one("shared", 0, MS_SHARED); + test_mount_propagation_flag_one("slave", 0, MS_SLAVE); + test_mount_propagation_flag_one("private", 0, MS_PRIVATE); + test_mount_propagation_flag_one(NULL, 0, 0); + test_mount_propagation_flag_one("", 0, 0); + test_mount_propagation_flag_one("xxxx", -EINVAL, 0); + test_mount_propagation_flag_one(" ", -EINVAL, 0); } TEST(mnt_id) {