1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-03 13:47:04 +03:00

Merge pull request #25735 from yuwata/switch-root-follow-ups

mount-util: several follow-ups for recent mount_switch_root() changes
This commit is contained in:
Yu Watanabe 2022-12-15 21:39:40 +09:00 committed by GitHub
commit f4128c8d51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 43 additions and 74 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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,

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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",

View File

@ -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;
}

View File

@ -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)

View File

@ -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) {