Merge pull request #4395 from s-urbaniak/rw-support
nspawn: R/W support for /sysfs, /proc, and /proc/sys/net
This commit is contained in:
+46
-7
@@ -197,6 +197,7 @@ static const char *arg_container_service_name = "systemd-nspawn";
|
||||
static bool arg_notify_ready = false;
|
||||
static bool arg_use_cgns = true;
|
||||
static unsigned long arg_clone_ns_flags = CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS;
|
||||
static MountSettingsMask arg_mount_settings = MOUNT_APPLY_APIVFS_RO;
|
||||
|
||||
static void help(void) {
|
||||
printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
|
||||
@@ -380,6 +381,31 @@ static void parse_share_ns_env(const char *name, unsigned long ns_flag) {
|
||||
arg_clone_ns_flags = (arg_clone_ns_flags & ~ns_flag) | (r > 0 ? 0 : ns_flag);
|
||||
}
|
||||
|
||||
static void parse_mount_settings_env(void) {
|
||||
int r;
|
||||
const char *e;
|
||||
|
||||
e = getenv("SYSTEMD_NSPAWN_API_VFS_WRITABLE");
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
if (streq(e, "network")) {
|
||||
arg_mount_settings |= MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS;
|
||||
return;
|
||||
}
|
||||
|
||||
r = parse_boolean(e);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to parse SYSTEMD_NSPAWN_API_VFS_WRITABLE from environment, ignoring.");
|
||||
return;
|
||||
} else if (r > 0)
|
||||
arg_mount_settings &= ~MOUNT_APPLY_APIVFS_RO;
|
||||
else
|
||||
arg_mount_settings |= MOUNT_APPLY_APIVFS_RO;
|
||||
|
||||
arg_mount_settings &= ~MOUNT_APPLY_APIVFS_NETNS;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
@@ -1072,6 +1098,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS);
|
||||
parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_SYSTEM", CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS);
|
||||
|
||||
if (arg_userns_mode != USER_NAMESPACE_NO)
|
||||
arg_mount_settings |= MOUNT_USE_USERNS;
|
||||
|
||||
if (arg_private_network)
|
||||
arg_mount_settings |= MOUNT_APPLY_APIVFS_NETNS;
|
||||
|
||||
parse_mount_settings_env();
|
||||
|
||||
if (!(arg_clone_ns_flags & CLONE_NEWPID) ||
|
||||
!(arg_clone_ns_flags & CLONE_NEWUTS)) {
|
||||
arg_register = false;
|
||||
@@ -1166,6 +1200,15 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
static int verify_arguments(void) {
|
||||
if (arg_userns_mode != USER_NAMESPACE_NO && (arg_mount_settings & MOUNT_APPLY_APIVFS_NETNS) && !arg_private_network) {
|
||||
log_error("Invalid namespacing settings. Mounting sysfs with --private-users requires --private-network.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arg_userns_mode != USER_NAMESPACE_NO && !(arg_mount_settings & MOUNT_APPLY_APIVFS_RO)) {
|
||||
log_error("Cannot combine --private-users with read-write mounts.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arg_volatile_mode != VOLATILE_NO && arg_read_only) {
|
||||
log_error("Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy.");
|
||||
@@ -2702,9 +2745,7 @@ static int inner_child(
|
||||
return log_error_errno(r, "Couldn't become new root: %m");
|
||||
|
||||
r = mount_all(NULL,
|
||||
arg_userns_mode != USER_NAMESPACE_NO,
|
||||
true,
|
||||
arg_private_network,
|
||||
arg_mount_settings | MOUNT_IN_USERNS,
|
||||
arg_uid_shift,
|
||||
arg_uid_range,
|
||||
arg_selinux_apifs_context);
|
||||
@@ -2712,7 +2753,7 @@ static int inner_child(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = mount_sysfs(NULL);
|
||||
r = mount_sysfs(NULL, arg_mount_settings);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -3079,9 +3120,7 @@ static int outer_child(
|
||||
}
|
||||
|
||||
r = mount_all(directory,
|
||||
arg_userns_mode != USER_NAMESPACE_NO,
|
||||
false,
|
||||
arg_private_network,
|
||||
arg_mount_settings,
|
||||
arg_uid_shift,
|
||||
arg_uid_range,
|
||||
arg_selinux_apifs_context);
|
||||
|
||||
Reference in New Issue
Block a user