diff options
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | src/shared/cgroup-util.c | 62 | ||||
-rw-r--r-- | src/shared/cgroup-util.h | 2 | ||||
-rw-r--r-- | src/test/test-cgroup-util.c | 27 |
4 files changed, 63 insertions, 38 deletions
diff --git a/Makefile.am b/Makefile.am index ab9fb99f96..25d99950ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1194,7 +1194,8 @@ noinst_tests += \ test-replace-var \ test-sched-prio \ test-calendarspec \ - test-strip-tab-ansi + test-strip-tab-ansi \ + test-cgroup-util EXTRA_DIST += \ test/sched_idle_bad.service \ @@ -1311,6 +1312,13 @@ test_cgroup_LDADD = \ libsystemd-label.la \ libsystemd-shared.la +test_cgroup_util_SOURCES = \ + src/test/test-cgroup-util.c + +test_cgroup_util_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + test_env_replace_SOURCES = \ src/test/test-env-replace.c diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index af5227848d..f0d0d4855b 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1211,69 +1211,57 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) { return 0; } -static int instance_unit_from_cgroup(char **cgroup){ +static int instance_unit_from_cgroup(char *cgroup){ char *at; assert(cgroup); - at = memchr(*cgroup, '@', strlen(*cgroup)); - if (at && at[1] == '.') { - char *i, *s; - + at = strstr(cgroup, "@."); + if (at) { /* This is a templated service */ - i = memchr(at, '/', strlen(at)); - if(!i) - return -EIO; - s = strndup(at + 1, i - at); - if (!s) - return -ENOMEM; + char *i; + char _cleanup_free_ *i2 = NULL, *s = NULL; - i = strdup(i + 1); - if (!i) { - free(s); - return -ENOMEM; - } + i = strchr(at, '/'); + if (!i || !i[1]) /* disallow empty instances */ + return -EINVAL; - strcpy(at + 1, i); - strcpy(at + strlen(i) + 1, s); - at[strlen(at) - 1] = '\0'; + s = strndup(at + 1, i - at - 1); + i2 = strdup(i + 1); + if (!s || !i2) + return -ENOMEM; - free(i); - free(s); + strcpy(at + 1, i2); + strcat(at + 1, s); } return 0; } -static int cgroup_to_unit(char *cgroup, char **unit){ +/* non-static only for testing purposes */ +int cgroup_to_unit(char *cgroup, char **unit){ int r; - char *b, *p; - size_t k; + char *p; assert(cgroup); assert(unit); - r = instance_unit_from_cgroup(&cgroup); + r = instance_unit_from_cgroup(cgroup); if (r < 0) return r; - p = strrchr(cgroup, '/') + 1; - k = strlen(p); + p = strrchr(cgroup, '/'); + assert(p); - b = strndup(p, k); + r = unit_name_is_valid(p + 1, true); + if (!r) + return -EINVAL; - if (!b) + *unit = strdup(p + 1); + if (!*unit) return -ENOMEM; - r = unit_name_is_valid(b, true); - if (!r) { - free(b); - return -ENOENT; - } - - *unit = b; - return 0; } diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 2429ba2430..920cf631e5 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -73,4 +73,6 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup); int cg_pid_get_unit(pid_t pid, char **unit); int cg_pid_get_user_unit(pid_t pid, char **unit); +int cgroup_to_unit(char *cgroup, char **unit); + char **cg_shorten_controllers(char **controllers); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c new file mode 100644 index 0000000000..b30bf23a80 --- /dev/null +++ b/src/test/test-cgroup-util.c @@ -0,0 +1,27 @@ +#include <assert.h> + +#include "util.h" +#include "cgroup-util.h" + +#define check_c_t_u(path, code, result) \ +{ \ + char a[] = path; \ + char *unit = NULL; \ + assert_se(cgroup_to_unit(a, &unit) == code); \ + assert(code < 0 || streq(unit, result)); \ +} + + +static void test_cgroup_to_unit(void) { + check_c_t_u("/system/getty@.service/tty2", 0, "getty@tty2.service"); + check_c_t_u("/system/getty@.service/", -EINVAL, "getty@tty2.service"); + check_c_t_u("/system/getty@.service", -EINVAL, "getty@tty2.service"); + check_c_t_u("/system/getty.service", 0, "getty.service"); + check_c_t_u("/system/getty", -EINVAL, "getty.service"); +} + +int main(void) { + test_cgroup_to_unit(); + + return 0; +} |