chiark / gitweb /
switch-root: do not use close old_root_fd after rm_rf_children()
[elogind.git] / src / shared / cgroup-util.c
index 8ceb382820d8e9adea51df7199b79567442b43c4..8d3bdce0f576fa2184cf317e4758259b1e22a9e2 100644 (file)
@@ -34,6 +34,8 @@
 #include "set.h"
 #include "macro.h"
 #include "util.h"
+#include "path-util.h"
+#include "strv.h"
 
 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
         char *fs;
@@ -513,7 +515,7 @@ static const char *normalize_controller(const char *controller) {
 }
 
 static int join_path(const char *controller, const char *path, const char *suffix, char **fs) {
-        char *t;
+        char *t = NULL;
 
         if (!(controller || path))
                 return -EINVAL;
@@ -564,9 +566,23 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
         return join_path(p, path, suffix, fs);
 }
 
+static int check(const char *p) {
+        char *cc;
+
+        assert(p);
+
+        /* Check if this controller actually really exists */
+        cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
+        strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
+        if (access(cc, F_OK) < 0)
+                return -errno;
+
+        return 0;
+}
+
 int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
         const char *p;
-        char *cc;
+        int r;
 
         assert(controller);
         assert(fs);
@@ -574,13 +590,13 @@ int cg_get_path_and_check(const char *controller, const char *path, const char *
         if (isempty(controller))
                 return -EINVAL;
 
+        /* Normalize the controller syntax */
         p = normalize_controller(controller);
 
         /* Check if this controller actually really exists */
-        cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
-        strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
-        if (access(cc, F_OK) < 0)
-                return -errno;
+        r = check(p);
+        if (r < 0)
+                return r;
 
         return join_path(p, path, suffix, fs);
 }
@@ -658,7 +674,7 @@ int cg_delete(const char *controller, const char *path) {
         assert(controller);
         assert(path);
 
-        if ((r = parent_of_path(path, &parent)) < 0)
+        if ((r = path_get_parent(path, &parent)) < 0)
                 return r;
 
         r = cg_migrate_recursive(controller, path, parent, false, true);
@@ -1100,3 +1116,36 @@ int cg_get_user_path(char **path) {
         *path = p;
         return 0;
 }
+
+char **cg_shorten_controllers(char **controllers) {
+        char **f, **t;
+
+        controllers = strv_uniq(controllers);
+
+        if (!controllers)
+                return controllers;
+
+        for (f = controllers, t = controllers; *f; f++) {
+                int r;
+                const char *p;
+
+                if (streq(*f, "systemd") || streq(*f, SYSTEMD_CGROUP_CONTROLLER)) {
+                        free(*f);
+                        continue;
+                }
+
+                p = normalize_controller(*f);
+
+                r = check(p);
+                if (r < 0) {
+                        log_debug("Controller %s is not available, removing from controllers list.", *f);
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return controllers;
+}