chiark / gitweb /
core/cgroup-util: simplify functions and add tests
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 18 Jan 2013 06:13:27 +0000 (01:13 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 18 Jan 2013 16:14:00 +0000 (11:14 -0500)
Makefile.am
src/shared/cgroup-util.c
src/shared/cgroup-util.h
src/test/test-cgroup-util.c [new file with mode: 0644]

index ab9fb99..25d9995 100644 (file)
@@ -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
 
index af52278..f0d0d48 100644 (file)
@@ -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;
 }
 
index 2429ba2..920cf63 100644 (file)
@@ -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 (file)
index 0000000..b30bf23
--- /dev/null
@@ -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;
+}