return cg_mask_supported_subtree(root, ret);
}
-/* The hybrid mode was initially implemented in v232 and simply mounted cgroup2 on
- * /sys/fs/cgroup/systemd. This unfortunately broke other tools (such as docker) which expected the v1
- * "name=systemd" hierarchy on /sys/fs/cgroup/systemd. From v233 and on, the hybrid mode mounts v2 on
- * /sys/fs/cgroup/unified and maintains "name=systemd" hierarchy on /sys/fs/cgroup/systemd for compatibility
- * with other tools.
- *
- * To keep live upgrade working, we detect and support v232 layout. When v232 layout is detected, to keep
- * cgroup v2 process management but disable the compat dual layout, we return true on
- * cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) and false on cg_hybrid_unified().
- */
-static thread_local bool unified_systemd_v232;
-
-int cg_unified_cached(bool flush) {
- static thread_local CGroupUnified unified_cache = CGROUP_UNIFIED_UNKNOWN;
-
- struct statfs fs;
-
- /* Checks if we support the unified hierarchy. Returns an
- * error when the cgroup hierarchies aren't mounted yet or we
- * have any other trouble determining if the unified hierarchy
- * is supported. */
-
- if (flush)
- unified_cache = CGROUP_UNIFIED_UNKNOWN;
- else if (unified_cache >= CGROUP_UNIFIED_NONE)
- return unified_cache;
-
- if (statfs("/sys/fs/cgroup/", &fs) < 0)
- return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/\") failed: %m");
-
- if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
- log_debug("Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy");
- unified_cache = CGROUP_UNIFIED_ALL;
- } else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) {
- if (statfs("/sys/fs/cgroup/unified/", &fs) == 0 &&
- F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
- log_debug("Found cgroup2 on /sys/fs/cgroup/unified, unified hierarchy for systemd controller");
- unified_cache = CGROUP_UNIFIED_SYSTEMD;
- unified_systemd_v232 = false;
- } else {
- if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0) {
- if (errno == ENOENT) {
- /* Some other software may have set up /sys/fs/cgroup in a configuration we do not recognize. */
- log_debug_errno(errno, "Unsupported cgroupsv1 setup detected: name=systemd hierarchy not found.");
- return -ENOMEDIUM;
- }
- return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/systemd\" failed: %m");
- }
-
- if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
- log_debug("Found cgroup2 on /sys/fs/cgroup/systemd, unified hierarchy for systemd controller (v232 variant)");
- unified_cache = CGROUP_UNIFIED_SYSTEMD;
- unified_systemd_v232 = true;
- } else if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC)) {
- log_debug("Found cgroup on /sys/fs/cgroup/systemd, legacy hierarchy");
- unified_cache = CGROUP_UNIFIED_NONE;
- } else {
- log_debug("Unexpected filesystem type %llx mounted on /sys/fs/cgroup/systemd, assuming legacy hierarchy",
- (unsigned long long) fs.f_type);
- unified_cache = CGROUP_UNIFIED_NONE;
- }
- }
- } else if (F_TYPE_EQUAL(fs.f_type, SYSFS_MAGIC)) {
- return log_debug_errno(SYNTHETIC_ERRNO(ENOMEDIUM),
- "No filesystem is currently mounted on /sys/fs/cgroup.");
- } else
- return log_debug_errno(SYNTHETIC_ERRNO(ENOMEDIUM),
- "Unknown filesystem type %llx mounted on /sys/fs/cgroup.",
- (unsigned long long)fs.f_type);
-
- return unified_cache;
-}
-
-int cg_unified_controller(const char *controller) {
- int r;
-
- r = cg_unified_cached(false);
- if (r < 0)
- return r;
-
- if (r == CGROUP_UNIFIED_NONE)
- return false;
-
- if (r >= CGROUP_UNIFIED_ALL)
- return true;
-
- return streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER);
-}
-
-int cg_all_unified(void) {
- int r;
-
- r = cg_unified_cached(false);
- if (r < 0)
- return r;
-
- return r >= CGROUP_UNIFIED_ALL;
-}
-
-int cg_hybrid_unified(void) {
- int r;
-
- r = cg_unified_cached(false);
- if (r < 0)
- return r;
-
- return r == CGROUP_UNIFIED_SYSTEMD && !unified_systemd_v232;
-}
-
int cg_is_delegated(const char *path) {
int r;
CGROUP_BFQ_WEIGHT_DEFAULT + (io_weight - CGROUP_WEIGHT_DEFAULT) * (CGROUP_BFQ_WEIGHT_MAX - CGROUP_BFQ_WEIGHT_DEFAULT) / (CGROUP_WEIGHT_MAX - CGROUP_WEIGHT_DEFAULT);
}
-typedef enum CGroupUnified {
- CGROUP_UNIFIED_UNKNOWN = -1,
- CGROUP_UNIFIED_NONE = 0, /* Both systemd and controllers on legacy */
- CGROUP_UNIFIED_SYSTEMD = 1, /* Only systemd on unified */
- CGROUP_UNIFIED_ALL = 2, /* Both systemd and controllers on unified */
-} CGroupUnified;
-
/*
* General rules:
*
bool cg_kill_supported(void);
-int cg_all_unified(void);
-int cg_hybrid_unified(void);
-int cg_unified_controller(const char *controller);
-int cg_unified_cached(bool flush);
-static inline int cg_unified(void) {
- return cg_unified_cached(true);
-}
-
const char* cgroup_controller_to_string(CGroupController c) _const_;
CGroupController cgroup_controller_from_string(const char *s) _pure_;
yes_no(m & CGROUP_CONTROLLER_TO_MASK(c)));
}
-TEST(cg_tests) {
- int all, hybrid, systemd, r;
-
- r = cg_unified();
- if (IN_SET(r, -ENOENT, -ENOMEDIUM))
- return (void) log_tests_skipped("cgroup not mounted");
- assert_se(r >= 0);
-
- all = cg_all_unified();
- assert_se(IN_SET(all, 0, 1));
-
- hybrid = cg_hybrid_unified();
- assert_se(IN_SET(hybrid, 0, 1));
-
- systemd = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
- assert_se(IN_SET(systemd, 0, 1));
-
- if (all) {
- assert_se(systemd);
- assert_se(!hybrid);
-
- } else if (hybrid) {
- assert_se(systemd);
- assert_se(!all);
-
- } else
- assert_se(!systemd);
-}
-
TEST(cg_get_keyed_attribute) {
_cleanup_free_ char *val = NULL;
char *vals3[3] = {}, *vals3a[3] = {};