diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index bda5c555ad..c828d10149 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -55,6 +55,7 @@ #include "stdio-util.h" #include "string-table.h" #include "string-util.h" +#include "strv.h" #include "unit-name.h" #include "user-util.h" @@ -2211,6 +2212,60 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) return 0; } +int cg_mask_to_string(CGroupMask mask, char **ret) { + const char *controllers[_CGROUP_CONTROLLER_MAX + 1]; + CGroupController c; + int i = 0; + char *s; + + assert(ret); + + if (mask == 0) { + *ret = NULL; + return 0; + } + + for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { + + if (!(mask & CGROUP_CONTROLLER_TO_MASK(c))) + continue; + + controllers[i++] = cgroup_controller_to_string(c); + controllers[i] = NULL; + } + + s = strv_join((char **)controllers, NULL); + if (!s) + return -ENOMEM; + + *ret = s; + return 0; +} + +int cg_mask_from_string(const char *value, CGroupMask *mask) { + assert(mask); + assert(value); + + for (;;) { + _cleanup_free_ char *n = NULL; + CGroupController v; + int r; + + r = extract_first_word(&value, &n, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; + + v = cgroup_controller_from_string(n); + if (v < 0) + continue; + + *mask |= CGROUP_CONTROLLER_TO_MASK(v); + } + return 0; +} + int cg_mask_supported(CGroupMask *ret) { CGroupMask mask = 0; int r; @@ -2224,7 +2279,6 @@ int cg_mask_supported(CGroupMask *ret) { return r; if (r > 0) { _cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL; - const char *c; /* In the unified hierarchy we can read the supported * and accessible controllers from a the top-level @@ -2242,23 +2296,9 @@ int cg_mask_supported(CGroupMask *ret) { if (r < 0) return r; - c = controllers; - for (;;) { - _cleanup_free_ char *n = NULL; - CGroupController v; - - r = extract_first_word(&c, &n, NULL, 0); - if (r < 0) - return r; - if (r == 0) - break; - - v = cgroup_controller_from_string(n); - if (v < 0) - continue; - - mask |= CGROUP_CONTROLLER_TO_MASK(v); - } + r = cg_mask_from_string(controllers, &mask); + if (r < 0) + return r; /* Currently, we support the cpu, memory, io and pids * controller in the unified hierarchy, mask diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index a522095d95..c16a33723c 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -235,6 +235,8 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p); int cg_mask_supported(CGroupMask *ret); +int cg_mask_from_string(const char *s, CGroupMask *ret); +int cg_mask_to_string(CGroupMask mask, char **ret); int cg_kernel_controllers(Set *controllers); diff --git a/src/core/unit.c b/src/core/unit.c index 01fa0d0d46..e4b51e295f 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -956,9 +956,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tPerpetual: %s\n" "%s\tSlice: %s\n" "%s\tCGroup: %s\n" - "%s\tCGroup realized: %s\n" - "%s\tCGroup mask: 0x%x\n" - "%s\tCGroup members mask: 0x%x\n", + "%s\tCGroup realized: %s\n", prefix, u->id, prefix, unit_description(u), prefix, strna(u->instance), @@ -975,9 +973,18 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, yes_no(u->perpetual), prefix, strna(unit_slice_name(u)), prefix, strna(u->cgroup_path), - prefix, yes_no(u->cgroup_realized), - prefix, u->cgroup_realized_mask, - prefix, u->cgroup_members_mask); + prefix, yes_no(u->cgroup_realized)); + + if (u->cgroup_realized_mask != 0) { + _cleanup_free_ char *s = NULL; + (void) cg_mask_to_string(u->cgroup_realized_mask, &s); + fprintf(f, "%s\tCGroup mask: %s\n", prefix, strnull(s)); + } + if (u->cgroup_members_mask != 0) { + _cleanup_free_ char *s = NULL; + (void) cg_mask_to_string(u->cgroup_members_mask, &s); + fprintf(f, "%s\tCGroup members mask: %s\n", prefix, strnull(s)); + } SET_FOREACH(t, u->names, i) fprintf(f, "%s\tName: %s\n", prefix, t);