]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cgroup-util: introduce cg_is_available() and check it in tests
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 29 Aug 2025 22:32:49 +0000 (07:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 17 Nov 2025 12:29:51 +0000 (21:29 +0900)
Now most of our code does not support cgroup v1. Let's skip test cases
if we are running on cgroup v1.

src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/libsystemd/sd-bus/test-bus-creds.c
src/libsystemd/sd-login/test-login.c
src/shared/tests.c
src/test/test-bpf-devices.c
src/test/test-bpf-firewall.c
src/test/test-bpf-foreign-programs.c
src/test/test-cgroup-setup.c
src/test/test-cgroup-util.c
src/test/test-condition.c

index 97f0bc741fd95d95936eff07b34ab72f44404b7b..1251538f0f7df584facd71ca741d2e3f4805de52 100644 (file)
@@ -50,6 +50,19 @@ typedef union {
 /* The .f_handle field is not aligned to 64bit on some archs, hence read it via an unaligned accessor */
 #define CG_FILE_HANDLE_CGROUPID(fh) unaligned_read_ne64(fh.file_handle.f_handle)
 
+int cg_is_available(void) {
+        struct statfs fs;
+
+        if (statfs("/sys/fs/cgroup/", &fs) < 0) {
+                if (errno == ENOENT) /* sysfs not mounted? */
+                        return false;
+
+                return log_debug_errno(errno, "Failed to statfs /sys/fs/cgroup/: %m");
+        }
+
+        return is_fs_type(&fs, CGROUP2_SUPER_MAGIC);
+}
+
 int cg_path_open(const char *controller, const char *path) {
         _cleanup_free_ char *fs = NULL;
         int r;
index 8ed8d7704cdd7d33e067f6ff6bff1831aab8fb6d..fae3709f79aff431c66c0260611a820a20db6f78 100644 (file)
@@ -135,6 +135,8 @@ typedef enum CGroupUnified {
  * generate paths with multiple adjacent / removed.
  */
 
+int cg_is_available(void);
+
 int cg_path_open(const char *controller, const char *path);
 int cg_cgroupid_open(int cgroupfs_fd, uint64_t id);
 
index 7eb7a38c39dc83623a354aa389549d3dd53503b6..3fa1e66b0a09eedc6d7391a38216b83d5ae16fd8 100644 (file)
@@ -13,8 +13,8 @@ int main(int argc, char *argv[]) {
 
         test_setup_logging(LOG_DEBUG);
 
-        if (IN_SET(cg_unified(), -ENOMEDIUM, -ENOENT))
-                return log_tests_skipped("/sys/fs/cgroup/ not available");
+        if (cg_is_available() <= 0)
+                return log_tests_skipped("cgroupfs v2 is not mounted");
 
         r = sd_bus_creds_new_from_pid(&creds, 0, _SD_BUS_CREDS_ALL);
         log_full_errno(r < 0 ? LOG_ERR : LOG_DEBUG, r, "sd_bus_creds_new_from_pid: %m");
index 98846d1011e0f73c18e08f319d8c279177cacf61..7c2b68a5c78d07aa01f5fe435b81f94be037186b 100644 (file)
@@ -327,8 +327,8 @@ TEST(monitor) {
 }
 
 static int intro(void) {
-        if (IN_SET(cg_unified(), -ENOENT, -ENOMEDIUM))
-                return log_tests_skipped("cgroupfs is not mounted");
+        if (cg_is_available() <= 0)
+                return log_tests_skipped("cgroupfs v2 is not mounted");
 
         log_info("/* Information printed is from the live system */");
         return EXIT_SUCCESS;
index 4eb07b11ff76a7d58c47281d5fd67ee1c293067a..eed6ea62493ef77a5d3d9b258a7a8528bdae0ff4 100644 (file)
@@ -287,6 +287,12 @@ static int enter_cgroup(char **ret_cgroup, bool enter_subroot) {
         CGroupMask supported;
         int r;
 
+        r = cg_is_available();
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return log_warning_errno(SYNTHETIC_ERRNO(ENOMEDIUM), "cgroupfs v2 is not mounted.");
+
         r = allocate_scope();
         if (r < 0)
                 log_warning_errno(r, "Couldn't allocate a scope unit for this test, proceeding without.");
index 74e58fd41dd973f931739ef7196b2ce1c5944854..fb8155c45db8eb2d812976feb2ad3cbb7ab04916 100644 (file)
@@ -266,10 +266,6 @@ int main(int argc, char *argv[]) {
         rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE);
         (void) setrlimit(RLIMIT_MEMLOCK, &rl);
 
-        r = cg_all_unified();
-        if (r <= 0)
-                return log_tests_skipped("We don't seem to be running with unified cgroup hierarchy");
-
         if (!can_memlock())
                 return log_tests_skipped("Can't use mlock()");
 
index 7f065899075881fab496e5b8dce490e453549743..c3d8e7d5d54b82c1a0c1187fc69cc18cc86437f3 100644 (file)
@@ -49,10 +49,9 @@ int main(int argc, char *argv[]) {
         if (!can_memlock())
                 return log_tests_skipped("Can't use mlock()");
 
-        _cleanup_free_ char *cgroup_path = NULL;
-        r = enter_cgroup_subroot(&cgroup_path);
+        r = enter_cgroup_subroot(NULL);
         if (r == -ENOMEDIUM)
-                return log_tests_skipped("cgroupfs not available");
+                return log_tests_skipped("cgroupfs v2 is not mounted");
 
         r = find_executable("ping", NULL);
         if (r < 0)
index 6ebd807326aebe388a83ebe83c8fc41c83c8c509..bf56451d2501c47fbaaedd1fb4aa6eea693157f7 100644 (file)
@@ -294,10 +294,6 @@ int main(int argc, char *argv[]) {
         if (!can_memlock())
                 return log_tests_skipped("Can't use mlock()");
 
-        r = cg_all_unified();
-        if (r <= 0)
-                return log_tests_skipped("Unified hierarchy is required");
-
         r = enter_cgroup_subroot(NULL);
         if (r == -ENOMEDIUM)
                 return log_tests_skipped("cgroupfs not available");
index ce20c956d2f1a7900344a83eaf5f14d790daad68..9f0cee9224eb640741da96f1c23a683c7642ce0e 100644 (file)
 TEST(cg_create) {
         int r;
 
-        r = cg_unified_cached(false);
-        if (IN_SET(r, -ENOMEDIUM, -ENOENT))
-                return (void) log_tests_skipped("cgroupfs is not mounted");
-        ASSERT_OK(r);
-
         _cleanup_free_ char *here = NULL;
         ASSERT_OK(cg_pid_get_path_shifted(0, NULL, &here));
 
@@ -61,14 +56,7 @@ TEST(cg_create) {
 
         ASSERT_OK_ZERO(cg_get_path(SYSTEMD_CGROUP_CONTROLLER, test_d, NULL, &path));
         log_debug("test_d: %s", path);
-        const char *full_d;
-        if (cg_all_unified())
-                full_d = strjoina("/sys/fs/cgroup", test_d);
-        else if (cg_hybrid_unified())
-                full_d = strjoina("/sys/fs/cgroup/unified", test_d);
-        else
-                full_d = strjoina("/sys/fs/cgroup/systemd", test_d);
-        ASSERT_TRUE(path_equal(path, full_d));
+        ASSERT_TRUE(path_equal(path, strjoina("/sys/fs/cgroup", test_d)));
         free(path);
 
         ASSERT_OK_POSITIVE(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, test_a));
@@ -86,4 +74,11 @@ TEST(cg_create) {
         ASSERT_OK(cg_trim(test_b, true));
 }
 
-DEFINE_TEST_MAIN(LOG_DEBUG);
+static int intro(void) {
+        if (cg_is_available() <= 0)
+                return log_tests_skipped("cgroupfs v2 is not mounted");
+
+        return 0;
+}
+
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro);
index 997bcf2215569e007942f6ebc9f3abcc72e41183..764e0fb55339efac4fe3fba3736b070e06ccf71d 100644 (file)
@@ -462,19 +462,18 @@ TEST(cg_get_keyed_attribute) {
         char *vals3[3] = {}, *vals3a[3] = {};
         int r;
 
+        if (cg_is_available() <= 0)
+                return (void) log_tests_skipped("cgroupfs v2 is not mounted");
+
         r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val);
-        if (r == -ENOMEDIUM || ERRNO_IS_PRIVILEGE(r)) {
-                log_info_errno(r, "Skipping most of %s, /sys/fs/cgroup not accessible: %m", __func__);
-                return;
-        }
+        if (ERRNO_IS_PRIVILEGE(r))
+                return (void) log_tests_skipped_errno(r, "/sys/fs/cgroup not accessible");
 
         assert_se(r == -ENOENT);
         ASSERT_NULL(val);
 
-        if (access("/sys/fs/cgroup/init.scope/cpu.stat", R_OK) < 0) {
-                log_info_errno(errno, "Skipping most of %s, /init.scope/cpu.stat not accessible: %m", __func__);
-                return;
-        }
+        if (access("/sys/fs/cgroup/init.scope/cpu.stat", R_OK) < 0)
+                return (void) log_tests_skipped_errno(errno, "/init.scope/cpu.stat not accessible");
 
         assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == -ENXIO);
         ASSERT_NULL(val);
@@ -508,14 +507,9 @@ TEST(cgroupid) {
         _cleanup_free_ char *p = NULL, *p2 = NULL;
         _cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
         uint64_t id, id2;
-        int r;
 
-        r = cg_all_unified();
-        if (IN_SET(r, -ENOMEDIUM, -ENOENT))
-                return (void) log_tests_skipped("cgroupfs is not mounted");
-        if (r == 0)
-                return (void) log_tests_skipped("skipping cgroupid test, not running in unified mode");
-        ASSERT_OK_POSITIVE(r);
+        if (cg_is_available() <= 0)
+                return (void) log_tests_skipped("cgroupfs v2 is not mounted");
 
         fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, "/");
         ASSERT_OK(fd);
index 1bae2e3dd83bf0c217fec97d1df40d79e841f5a0..efebf6b49af8ca787f9c5cff759cb32aa9bfff63 100644 (file)
@@ -131,12 +131,9 @@ TEST(condition_test_control_group_controller) {
         Condition *condition;
         CGroupMask system_mask;
         _cleanup_free_ char *controller_name = NULL;
-        int r;
 
-        r = cg_unified();
-        if (IN_SET(r, -ENOMEDIUM, -ENOENT))
-                return (void) log_tests_skipped("cgroupfs is not mounted");
-        ASSERT_OK(r);
+        if (cg_is_available() <= 0)
+                return (void) log_tests_skipped("cgroupfs v2 is not mounted");
 
         /* Invalid controllers are ignored */
         ASSERT_NOT_NULL((condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false)));
@@ -1341,7 +1338,6 @@ TEST(condition_test_os_release) {
 TEST(condition_test_psi) {
         Condition *condition;
         CGroupMask mask;
-        int r;
 
         if (!is_pressure_supported())
                 return (void) log_notice("Pressure Stall Information (PSI) is not supported, skipping %s", __func__);
@@ -1426,11 +1422,8 @@ TEST(condition_test_psi) {
         ASSERT_OK(condition_test(condition, environ));
         condition_free(condition);
 
-        r = cg_all_unified();
-        if (r < 0)
-                return (void) log_notice("Failed to determine whether the unified cgroups hierarchy is used, skipping %s", __func__);
-        if (r == 0)
-                return (void) log_notice("Requires the unified cgroups hierarchy, skipping %s", __func__);
+        if (cg_is_available() <= 0)
+                return (void) log_tests_skipped("cgroupfs v2 is not mounted");
 
         if (cg_mask_supported(&mask) < 0)
                 return (void) log_notice("Failed to get supported cgroup controllers, skipping %s", __func__);