diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index f5fed2a927..0100fc6dbf 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -2244,10 +2244,10 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) } int cg_mask_to_string(CGroupMask mask, char **ret) { - const char *controllers[_CGROUP_CONTROLLER_MAX + 1]; + _cleanup_free_ char *s = NULL; + size_t n = 0, allocated = 0; + bool space = false; CGroupController c; - int i = 0; - char *s; assert(ret); @@ -2257,19 +2257,32 @@ int cg_mask_to_string(CGroupMask mask, char **ret) { } for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { + const char *k; + size_t l; if (!(mask & CGROUP_CONTROLLER_TO_MASK(c))) continue; - controllers[i++] = cgroup_controller_to_string(c); - controllers[i] = NULL; + k = cgroup_controller_to_string(c); + l = strlen(k); + + if (!GREEDY_REALLOC(s, allocated, n + space + l + 1)) + return -ENOMEM; + + if (space) + s[n] = ' '; + memcpy(s + n + space, k, l); + n += space + l; + + space = true; } - s = strv_join((char **)controllers, NULL); - if (!s) - return -ENOMEM; + assert(s); + s[n] = 0; *ret = s; + s = NULL; + return 0; } diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c index 6fd35c81dc..4415bc7b9d 100644 --- a/src/test/test-cgroup-mask.c +++ b/src/test/test-cgroup-mask.c @@ -22,6 +22,7 @@ #include "macro.h" #include "manager.h" #include "rm-rf.h" +#include "string-util.h" #include "test-helper.h" #include "tests.h" #include "unit.h" @@ -117,10 +118,38 @@ static int test_cgroup_mask(void) { return 0; } +static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) { + _cleanup_free_ char *b = NULL; + + assert_se(cg_mask_to_string(mask, &b) >= 0); + assert_se(streq_ptr(b, t)); +} + +static void test_cg_mask_to_string(void) { + test_cg_mask_to_string_one(0, NULL); + test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct io blkio memory devices pids"); + test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu"); + test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct"); + test_cg_mask_to_string_one(CGROUP_MASK_IO, "io"); + test_cg_mask_to_string_one(CGROUP_MASK_BLKIO, "blkio"); + test_cg_mask_to_string_one(CGROUP_MASK_MEMORY, "memory"); + test_cg_mask_to_string_one(CGROUP_MASK_DEVICES, "devices"); + test_cg_mask_to_string_one(CGROUP_MASK_PIDS, "pids"); + test_cg_mask_to_string_one(CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT, "cpu cpuacct"); + test_cg_mask_to_string_one(CGROUP_MASK_CPU|CGROUP_MASK_PIDS, "cpu pids"); + test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT|CGROUP_MASK_PIDS, "cpuacct pids"); + test_cg_mask_to_string_one(CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS, "devices pids"); + test_cg_mask_to_string_one(CGROUP_MASK_IO|CGROUP_MASK_BLKIO, "io blkio"); +} + int main(int argc, char* argv[]) { int rc = 0; + log_parse_environment(); + log_open(); + TEST_REQ_RUNNING_SYSTEMD(rc = test_cgroup_mask()); + test_cg_mask_to_string(); return rc; }