summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/basic/cgroup-util.c41
-rw-r--r--src/basic/cgroup-util.h1
-rw-r--r--src/core/cgroup.c2
3 files changed, 29 insertions, 15 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index fcab1775bd..88d6d7a6fb 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -527,15 +527,21 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
return 0;
}
-static int controller_is_v1_accessible(const char *controller) {
- const char *cc, *dn;
+static int controller_is_v1_accessible(const char *root, const char *controller) {
+ const char *cpath, *dn;
assert(controller);
dn = controller_to_dirname(controller);
- cc = strjoina("/sys/fs/cgroup/", dn);
-
- if (laccess(cc, F_OK) < 0)
+ cpath = strjoina("/sys/fs/cgroup/", dn);
+ if (root)
+ /* Also check that:
+ * - possible subcgroup is created at root,
+ * - we can modify the hierarchy.
+ * "Leak" cpath on stack */
+ cpath = strjoina(cpath, root, "/cgroup.procs");
+
+ if (laccess(cpath, root ? W_OK : F_OK) < 0)
return -errno;
return 0;
@@ -560,7 +566,7 @@ int cg_get_path_and_check(const char *controller, const char *path, const char *
return -EOPNOTSUPP;
} else {
/* Check if the specified controller is actually accessible */
- r = controller_is_v1_accessible(controller);
+ r = controller_is_v1_accessible(NULL, controller);
if (r < 0)
return r;
}
@@ -1847,7 +1853,7 @@ int cg_mask_from_string(const char *value, CGroupMask *ret) {
return 0;
}
-int cg_mask_supported(CGroupMask *ret) {
+int cg_mask_supported_subtree(const char *root, CGroupMask *ret) {
CGroupMask mask;
int r;
@@ -1859,15 +1865,11 @@ int cg_mask_supported(CGroupMask *ret) {
if (r < 0)
return r;
if (r > 0) {
- _cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
+ _cleanup_free_ char *controllers = NULL, *path = NULL;
/* In the unified hierarchy we can read the supported and accessible controllers from
* the top-level cgroup attribute */
- r = cg_get_root_path(&root);
- if (r < 0)
- return r;
-
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, "cgroup.controllers", &path);
if (r < 0)
return r;
@@ -1886,7 +1888,7 @@ int cg_mask_supported(CGroupMask *ret) {
} else {
CGroupController c;
- /* In the legacy hierarchy, we check which hierarchies are mounted. */
+ /* In the legacy hierarchy, we check which hierarchies are accessible. */
mask = 0;
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -1897,7 +1899,7 @@ int cg_mask_supported(CGroupMask *ret) {
continue;
n = cgroup_controller_to_string(c);
- if (controller_is_v1_accessible(n) >= 0)
+ if (controller_is_v1_accessible(root, n) >= 0)
mask |= bit;
}
}
@@ -1906,6 +1908,17 @@ int cg_mask_supported(CGroupMask *ret) {
return 0;
}
+int cg_mask_supported(CGroupMask *ret) {
+ _cleanup_free_ char *root = NULL;
+ int r;
+
+ r = cg_get_root_path(&root);
+ if (r < 0)
+ return r;
+
+ return cg_mask_supported_subtree(root, ret);
+}
+
int cg_kernel_controllers(Set **ret) {
_cleanup_set_free_free_ Set *controllers = NULL;
_cleanup_fclose_ FILE *f = NULL;
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index c5f54aafea..4f1d95620c 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -257,6 +257,7 @@ int cg_slice_to_path(const char *unit, char **ret);
typedef const char* (*cg_migrate_callback_t)(CGroupMask mask, void *userdata);
int cg_mask_supported(CGroupMask *ret);
+int cg_mask_supported_subtree(const char *root, CGroupMask *ret);
int cg_mask_from_string(const char *s, CGroupMask *ret);
int cg_mask_to_string(CGroupMask mask, char **ret);
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index c9cf7fb16c..a0d188e1c4 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -3110,7 +3110,7 @@ int manager_setup_cgroup(Manager *m) {
(void) cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
/* 8. Figure out which controllers are supported */
- r = cg_mask_supported(&m->cgroup_supported);
+ r = cg_mask_supported_subtree(m->cgroup_root, &m->cgroup_supported);
if (r < 0)
return log_error_errno(r, "Failed to determine supported controllers: %m");