summaryrefslogtreecommitdiff
path: root/src/nspawn
diff options
context:
space:
mode:
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-cgroup.c17
-rw-r--r--src/nspawn/nspawn-mount.c83
-rw-r--r--src/nspawn/nspawn.c33
3 files changed, 69 insertions, 64 deletions
diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c
index 5274767b96..4678a7e349 100644
--- a/src/nspawn/nspawn-cgroup.c
+++ b/src/nspawn/nspawn-cgroup.c
@@ -78,13 +78,9 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t arg_uid_shift)
char tree[] = "/tmp/unifiedXXXXXX", pid_string[DECIMAL_STR_MAX(pid) + 1];
bool undo_mount = false;
const char *fn;
- int unified, r;
-
- unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
- if (unified < 0)
- return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
+ int r;
- if ((unified > 0) == (unified_requested >= CGROUP_UNIFIED_SYSTEMD))
+ if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) == (unified_requested >= CGROUP_UNIFIED_SYSTEMD))
return 0;
/* When the host uses the legacy cgroup setup, but the
@@ -100,7 +96,7 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t arg_uid_shift)
if (!mkdtemp(tree))
return log_error_errno(errno, "Failed to generate temporary mount point for unified hierarchy: %m");
- if (unified)
+ if (cg_unified(SYSTEMD_CGROUP_CONTROLLER))
r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup",
MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
else
@@ -142,7 +138,7 @@ finish:
int create_subcgroup(pid_t pid, CGroupUnified unified_requested) {
_cleanup_free_ char *cgroup = NULL;
const char *child;
- int unified, r;
+ int r;
CGroupMask supported;
/* In the unified hierarchy inner nodes may only contain
@@ -154,10 +150,7 @@ int create_subcgroup(pid_t pid, CGroupUnified unified_requested) {
if (unified_requested == CGROUP_UNIFIED_NONE)
return 0;
- unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
- if (unified < 0)
- return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
- if (unified == 0)
+ if (!cg_unified(SYSTEMD_CGROUP_CONTROLLER))
return 0;
r = cg_mask_supported(&supported);
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 4b2838b752..ed4f1f9db8 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -890,7 +890,7 @@ static int get_controllers(Set *subsystems) {
*e = 0;
- if (STR_IN_SET(l, "", "name=systemd"))
+ if (STR_IN_SET(l, "", "name=systemd", "name=unified"))
continue;
p = strdup(l);
@@ -909,7 +909,6 @@ static int mount_legacy_cgroup_hierarchy(
const char *dest,
const char *controller,
const char *hierarchy,
- CGroupUnified unified_requested,
bool read_only) {
const char *to, *fstype, *opts;
@@ -927,14 +926,12 @@ static int mount_legacy_cgroup_hierarchy(
/* The superblock mount options of the mount point need to be
* identical to the hosts', and hence writable... */
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
- if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
- fstype = "cgroup2";
- opts = NULL;
- } else {
- fstype = "cgroup";
- opts = "none,name=systemd,xattr";
- }
+ if (streq(controller, SYSTEMD_CGROUP_CONTROLLER_HYBRID)) {
+ fstype = "cgroup2";
+ opts = NULL;
+ } else if (streq(controller, SYSTEMD_CGROUP_CONTROLLER_LEGACY)) {
+ fstype = "cgroup";
+ opts = "none,name=systemd,xattr";
} else {
fstype = "cgroup";
opts = controller;
@@ -994,7 +991,7 @@ static int mount_legacy_cgns_supported(
return r;
}
- if (cg_all_unified() > 0)
+ if (cg_all_unified())
goto skip_controllers;
controllers = set_new(&string_hash_ops);
@@ -1012,7 +1009,7 @@ static int mount_legacy_cgns_supported(
if (!controller)
break;
- r = mount_legacy_cgroup_hierarchy("", controller, controller, unified_requested, !userns);
+ r = mount_legacy_cgroup_hierarchy("", controller, controller, !userns);
if (r < 0)
return r;
@@ -1046,7 +1043,13 @@ static int mount_legacy_cgns_supported(
}
skip_controllers:
- r = mount_legacy_cgroup_hierarchy("", SYSTEMD_CGROUP_CONTROLLER, "systemd", unified_requested, false);
+ if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+ r = mount_legacy_cgroup_hierarchy("", SYSTEMD_CGROUP_CONTROLLER_HYBRID, "unified", false);
+ if (r < 0)
+ return r;
+ }
+
+ r = mount_legacy_cgroup_hierarchy("", SYSTEMD_CGROUP_CONTROLLER_LEGACY, "systemd", false);
if (r < 0)
return r;
@@ -1091,7 +1094,7 @@ static int mount_legacy_cgns_unsupported(
return r;
}
- if (cg_all_unified() > 0)
+ if (cg_all_unified())
goto skip_controllers;
controllers = set_new(&string_hash_ops);
@@ -1117,7 +1120,7 @@ static int mount_legacy_cgns_unsupported(
if (r == -EINVAL) {
/* Not a symbolic link, but directly a single cgroup hierarchy */
- r = mount_legacy_cgroup_hierarchy(dest, controller, controller, unified_requested, true);
+ r = mount_legacy_cgroup_hierarchy(dest, controller, controller, true);
if (r < 0)
return r;
@@ -1137,7 +1140,7 @@ static int mount_legacy_cgns_unsupported(
continue;
}
- r = mount_legacy_cgroup_hierarchy(dest, combined, combined, unified_requested, true);
+ r = mount_legacy_cgroup_hierarchy(dest, combined, combined, true);
if (r < 0)
return r;
@@ -1150,7 +1153,13 @@ static int mount_legacy_cgns_unsupported(
}
skip_controllers:
- r = mount_legacy_cgroup_hierarchy(dest, SYSTEMD_CGROUP_CONTROLLER, "systemd", unified_requested, false);
+ if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+ r = mount_legacy_cgroup_hierarchy(dest, SYSTEMD_CGROUP_CONTROLLER_HYBRID, "unified", false);
+ if (r < 0)
+ return r;
+ }
+
+ r = mount_legacy_cgroup_hierarchy(dest, SYSTEMD_CGROUP_CONTROLLER_LEGACY, "systemd", false);
if (r < 0)
return r;
@@ -1202,12 +1211,25 @@ int mount_cgroups(
return mount_legacy_cgns_unsupported(dest, unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
}
+static int mount_systemd_cgroup_writable_one(const char *systemd_own, const char *systemd_root)
+{
+ int r;
+
+ /* Make our own cgroup a (writable) bind mount */
+ r = mount_verbose(LOG_ERR, systemd_own, systemd_own, NULL, MS_BIND, NULL);
+ if (r < 0)
+ return r;
+
+ /* And then remount the systemd cgroup root read-only */
+ return mount_verbose(LOG_ERR, NULL, systemd_root, NULL,
+ MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+}
+
int mount_systemd_cgroup_writable(
const char *dest,
CGroupUnified unified_requested) {
_cleanup_free_ char *own_cgroup_path = NULL;
- const char *systemd_root, *systemd_own;
int r;
assert(dest);
@@ -1220,22 +1242,19 @@ int mount_systemd_cgroup_writable(
if (path_equal(own_cgroup_path, "/"))
return 0;
- if (unified_requested >= CGROUP_UNIFIED_ALL) {
- systemd_own = strjoina(dest, "/sys/fs/cgroup", own_cgroup_path);
- systemd_root = prefix_roota(dest, "/sys/fs/cgroup");
- } else {
- systemd_own = strjoina(dest, "/sys/fs/cgroup/systemd", own_cgroup_path);
- systemd_root = prefix_roota(dest, "/sys/fs/cgroup/systemd");
- }
+ if (unified_requested >= CGROUP_UNIFIED_ALL)
+ return mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup", own_cgroup_path),
+ prefix_roota(dest, "/sys/fs/cgroup"));
- /* Make our own cgroup a (writable) bind mount */
- r = mount_verbose(LOG_ERR, systemd_own, systemd_own, NULL, MS_BIND, NULL);
- if (r < 0)
- return r;
+ if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+ r = mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup/unified", own_cgroup_path),
+ prefix_roota(dest, "/sys/fs/cgroup/unified"));
+ if (r < 0)
+ return r;
+ }
- /* And then remount the systemd cgroup root read-only */
- return mount_verbose(LOG_ERR, NULL, systemd_root, NULL,
- MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+ return mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup/systemd", own_cgroup_path),
+ prefix_roota(dest, "/sys/fs/cgroup/systemd"));
}
int setup_volatile_state(
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 751f26272b..42355115ff 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -316,7 +316,7 @@ static int custom_mount_check_all(void) {
static int detect_unified_cgroup_hierarchy(const char *directory) {
const char *e;
- int r, all_unified, systemd_unified;
+ int r;
/* Allow the user to control whether the unified hierarchy is used */
e = getenv("UNIFIED_CGROUP_HIERARCHY");
@@ -332,15 +332,8 @@ static int detect_unified_cgroup_hierarchy(const char *directory) {
return 0;
}
- all_unified = cg_all_unified();
- systemd_unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-
- if (all_unified < 0 || systemd_unified < 0)
- return log_error_errno(all_unified < 0 ? all_unified : systemd_unified,
- "Failed to determine whether the unified cgroups hierarchy is used: %m");
-
/* Otherwise inherit the default from the host system */
- if (all_unified > 0) {
+ if (cg_all_unified()) {
/* Unified cgroup hierarchy support was added in 230. Unfortunately the detection
* routine only detects 231, so we'll have a false negative here for 230. */
r = systemd_installation_has_version(directory, 230);
@@ -350,9 +343,9 @@ static int detect_unified_cgroup_hierarchy(const char *directory) {
arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_ALL;
else
arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
- } else if (systemd_unified > 0) {
- /* Mixed cgroup hierarchy support was added in 232 */
- r = systemd_installation_has_version(directory, 232);
+ } else if (cg_unified(SYSTEMD_CGROUP_CONTROLLER)) {
+ /* Mixed cgroup hierarchy support was added in 233 */
+ r = systemd_installation_has_version(directory, 233);
if (r < 0)
return log_error_errno(r, "Failed to determine systemd version in container: %m");
if (r > 0)
@@ -2168,8 +2161,6 @@ static int inner_child(
assert(directory);
assert(kmsg_socket >= 0);
- cg_unified_flush();
-
if (arg_userns_mode != USER_NAMESPACE_NO) {
/* Tell the parent, that it now can write the UID map. */
(void) barrier_place(barrier); /* #1 */
@@ -2440,8 +2431,6 @@ static int outer_child(
assert(notify_socket >= 0);
assert(kmsg_socket >= 0);
- cg_unified_flush();
-
if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0)
return log_error_errno(errno, "PR_SET_PDEATHSIG failed: %m");
@@ -2486,10 +2475,6 @@ static int outer_child(
if (r < 0)
return r;
- r = detect_unified_cgroup_hierarchy(directory);
- if (r < 0)
- return r;
-
if (arg_userns_mode != USER_NAMESPACE_NO) {
/* Let the parent know which UID shift we read from the image */
l = send(uid_shift_socket, &arg_uid_shift, sizeof(arg_uid_shift), MSG_NOSIGNAL);
@@ -3542,6 +3527,10 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
+ r = cg_unified_flush();
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m");
+
/* Make sure rename_process() in the stub init process can work */
saved_argv = argv;
saved_argc = argc;
@@ -3810,6 +3799,10 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
+ r = detect_unified_cgroup_hierarchy(arg_directory);
+ if (r < 0)
+ goto finish;
+
interactive =
isatty(STDIN_FILENO) > 0 &&
isatty(STDOUT_FILENO) > 0;