diff --git a/NEWS b/NEWS index e772f08c2bb..947b831001d 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,11 @@ CHANGES WITH 257 in spe: and 'block-weak' inhibitor modes were added, if taken they will make the inhibitor lock work as in the previous versions. + * systemd-nspawn will now mount the unified cgroup hierarchy into a + container if no systemd installation is found in a container's root + filesystem. `$SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=0` can be used to override + this behavior. + — , CHANGES WITH 256: diff --git a/src/nspawn/nspawn-util.c b/src/nspawn/nspawn-util.c index 6c3848916d2..2cd73fe87c9 100644 --- a/src/nspawn/nspawn-util.c +++ b/src/nspawn/nspawn-util.c @@ -9,6 +9,7 @@ #include "string-util.h" int systemd_installation_has_version(const char *root, const char *minimal_version) { + bool found = false; int r; /* Try to guess if systemd installation is later than the specified version. This @@ -63,6 +64,8 @@ int systemd_installation_has_version(const char *root, const char *minimal_versi continue; *t2 = '\0'; + found = true; + r = strverscmp_improved(t, minimal_version); log_debug("Found libsystemd shared at \"%s.so\", version %s (%s).", *name, t, @@ -72,5 +75,5 @@ int systemd_installation_has_version(const char *root, const char *minimal_versi } } - return false; + return !found ? -ENOENT : false; } diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index e7d96821ea3..d1186884487 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -530,23 +530,25 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) { return log_error_errno(r, "Failed to determine whether we are in all unified mode."); if (r > 0) { /* 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. */ + * routine only detects 231, so we'll have a false negative here for 230. If there is no + * systemd installation in the container, we use the unified cgroup hierarchy. */ r = systemd_installation_has_version(directory, "230"); - if (r < 0) + if (r < 0 && r != -ENOENT) return log_error_errno(r, "Failed to determine systemd version in container: %m"); - if (r > 0) + if (r == 0) + arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE; + else arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_ALL; - else - arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE; } else if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) { - /* Mixed cgroup hierarchy support was added in 233 */ + /* Mixed cgroup hierarchy support was added in 233. If there is no systemd installation in + * the container, we use the unified cgroup hierarchy. */ r = systemd_installation_has_version(directory, "233"); - if (r < 0) + if (r < 0 && r != -ENOENT) return log_error_errno(r, "Failed to determine systemd version in container: %m"); - if (r > 0) - arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_SYSTEMD; - else + if (r == 0) arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE; + else + arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_SYSTEMD; } else arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE; diff --git a/src/nspawn/test-nspawn-util.c b/src/nspawn/test-nspawn-util.c index 533edde5aaa..45fc8ad927a 100644 --- a/src/nspawn/test-nspawn-util.c +++ b/src/nspawn/test-nspawn-util.c @@ -1,19 +1,28 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "nspawn-util.h" -#include "string-util.h" +#include "rm-rf.h" #include "strv.h" #include "tests.h" +#include "tmpfile-util.h" TEST(systemd_installation_has_version) { int r; FOREACH_STRING(version, "0", "231", PROJECT_VERSION_FULL, "999") { r = systemd_installation_has_version(saved_argv[1], version); - assert_se(r >= 0); + /* The build environment may not have a systemd installation. */ + if (r == -ENOENT) + continue; + ASSERT_OK(r); log_info("%s has systemd >= %s: %s", saved_argv[1] ?: "Current installation", version, yes_no(r)); } + + _cleanup_(rm_rf_physical_and_freep) char *t = NULL; + ASSERT_OK(mkdtemp_malloc(NULL, &t)); + + ASSERT_ERROR(systemd_installation_has_version(t, PROJECT_VERSION_FULL), ENOENT); } /* This program can be called with a path to an installation root.