chiark / gitweb /
utf8: ascii_filter() is unused, let's remove it
[elogind.git] / src / shared / cgroup-util.c
index 2e630d4708d6f14814762794d2fe21345322016e..8a4eddab7a27e63fa76636d41b78c979b005c79c 100644 (file)
@@ -39,6 +39,7 @@
 #include "unit-name.h"
 #include "fileio.h"
 #include "special.h"
+#include "mkdir.h"
 
 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
         _cleanup_free_ char *fs = NULL;
@@ -456,23 +457,14 @@ int cg_migrate_recursive_fallback(
 
                 /* This didn't work? Then let's try all prefixes of the destination */
 
-                strcpy(prefix, pto);
-                for (;;) {
-                        char *slash;
-
-                        slash = strrchr(prefix, '/');
-                        if (!slash)
-                                break;
-
-                        *slash = 0;
-
+                PATH_FOREACH_PREFIX(prefix, pto) {
                         r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem);
                         if (r >= 0)
                                 break;
                 }
         }
 
-        return r;
+        return 0;
 }
 
 static const char *normalize_controller(const char *controller) {
@@ -627,6 +619,46 @@ int cg_delete(const char *controller, const char *path) {
         return r == -ENOENT ? 0 : r;
 }
 
+int cg_create(const char *controller, const char *path) {
+        _cleanup_free_ char *fs = NULL;
+        int r;
+
+        r = cg_get_path_and_check(controller, path, NULL, &fs);
+        if (r < 0)
+                return r;
+
+        r = mkdir_parents(fs, 0755);
+        if (r < 0)
+                return r;
+
+        if (mkdir(fs, 0755) < 0) {
+
+                if (errno == EEXIST)
+                        return 0;
+
+                return -errno;
+        }
+
+        return 1;
+}
+
+int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
+        int r, q;
+
+        assert(pid >= 0);
+
+        r = cg_create(controller, path);
+        if (r < 0)
+                return r;
+
+        q = cg_attach(controller, path, pid);
+        if (q < 0)
+                return q;
+
+        /* This does not remove the cgroup on failure */
+        return r;
+}
+
 int cg_attach(const char *controller, const char *path, pid_t pid) {
         _cleanup_free_ char *fs = NULL;
         char c[DECIMAL_STR_MAX(pid_t) + 2];
@@ -661,23 +693,14 @@ int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
                 /* This didn't work? Then let's try all prefixes of
                  * the destination */
 
-                strcpy(prefix, path);
-                for (;;) {
-                        char *slash;
-
-                        slash = strrchr(prefix, '/');
-                        if (!slash)
-                                break;
-
-                        *slash = 0;
-
+                PATH_FOREACH_PREFIX(prefix, path) {
                         r = cg_attach(controller, prefix, pid);
                         if (r >= 0)
                                 break;
                 }
         }
 
-        return r;
+        return 0;
 }
 
 int cg_set_group_access(
@@ -1021,19 +1044,28 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
                 return -EINVAL;
         }
 
-        u = strdup(e+1);
-        if (!u) {
-                free(t);
-                return -ENOMEM;
-        }
-        if (!path_is_safe(u) ||
-            !path_is_absolute(u)) {
-                free(t);
-                free(u);
-                return -EINVAL;
-        }
+        if (streq(e+1, "")) {
+                u = strdup("/");
+                if (!u) {
+                        free(t);
+                        return -ENOMEM;
+                }
+        } else {
+                u = strdup(e+1);
+                if (!u) {
+                        free(t);
+                        return -ENOMEM;
+                }
 
-        path_kill_slashes(u);
+                if (!path_is_safe(u) ||
+                    !path_is_absolute(u)) {
+                        free(t);
+                        free(u);
+                        return -EINVAL;
+                }
+
+                path_kill_slashes(u);
+        }
 
         if (controller)
                 *controller = t;