chiark / gitweb /
shared: add formats-util.h
[elogind.git] / src / shared / cgroup-util.c
index 0d3cc53517de07b7ef779ea5c219f7a052cd566d..c746d606d9ff648c29cbcd530d579b5e87acd547 100644 (file)
 #include <ftw.h>
 
 #include "cgroup-util.h"
-#include "log.h"
 #include "set.h"
 #include "macro.h"
 #include "util.h"
+#include "formats-util.h"
 #include "path-util.h"
-#include "strv.h"
-#include "unit-name.h"
 #include "fileio.h"
 #include "special.h"
 #include "mkdir.h"
@@ -441,7 +439,7 @@ static const char *normalize_controller(const char *controller) {
         assert(controller);
 
         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
-                return "systemd";
+                return "elogind";
         else if (startswith(controller, "name="))
                 return controller + 5;
         else
@@ -489,8 +487,10 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
                 int r;
 
                 r = path_is_mount_point("/sys/fs/cgroup", false);
-                if (r <= 0)
-                        return r < 0 ? r : -ENOENT;
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return -ENOENT;
 
                 /* Cache this to save a few stat()s */
                 good = true;
@@ -510,7 +510,7 @@ static int check_hierarchy(const char *p) {
                 return 0;
 
         /* Check if this controller actually really exists */
-        cc = strappenda("/sys/fs/cgroup/", p);
+        cc = strjoina("/sys/fs/cgroup/", p);
         if (laccess(cc, F_OK) < 0)
                 return -errno;
 
@@ -1060,21 +1060,9 @@ int cg_mangle_path(const char *path, char **result) {
 }
 
 int cg_get_root_path(char **path) {
-        char *p, *e;
-        int r;
-
         assert(path);
 
-        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
-        if (r < 0)
-                return r;
-
-        e = endswith(p, "/" SPECIAL_SYSTEM_SLICE);
-        if (e)
-                *e = 0;
-
-        *path = p;
-        return 0;
+        return cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, path);
 }
 
 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
@@ -1137,185 +1125,16 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
         return 0;
 }
 
-int cg_path_decode_unit(const char *cgroup, char **unit){
-        char *e, *c, *s;
-
-        assert(cgroup);
-        assert(unit);
-
-        e = strchrnul(cgroup, '/');
-        c = strndupa(cgroup, e - cgroup);
-        c = cg_unescape(c);
-
-        if (!unit_name_is_valid(c, TEMPLATE_INVALID))
-                return -EINVAL;
-
-        s = strdup(c);
-        if (!s)
-                return -ENOMEM;
-
-        *unit = s;
-        return 0;
-}
-
-static const char *skip_slices(const char *p) {
-        /* Skips over all slice assignments */
-
-        for (;;) {
-                size_t n;
-
-                p += strspn(p, "/");
-
-                n = strcspn(p, "/");
-                if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0)
-                        return p;
-
-                p += n;
-        }
-}
-
-int cg_path_get_unit(const char *path, char **unit) {
-        const char *e;
-
-        assert(path);
-        assert(unit);
-
-        e = skip_slices(path);
-
-        return cg_path_decode_unit(e, unit);
-}
-
-int cg_pid_get_unit(pid_t pid, char **unit) {
-        _cleanup_free_ char *cgroup = NULL;
-        int r;
-
-        assert(unit);
-
-        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        return cg_path_get_unit(cgroup, unit);
-}
-
-/**
- * Skip session-*.scope, but require it to be there.
- */
-static const char *skip_session(const char *p) {
-        size_t n;
-
-        assert(p);
-
-        p += strspn(p, "/");
-
-        n = strcspn(p, "/");
-        if (n < strlen("session-x.scope") || memcmp(p, "session-", 8) != 0 || memcmp(p + n - 6, ".scope", 6) != 0)
-                return NULL;
-
-        p += n;
-        p += strspn(p, "/");
-
-        return p;
-}
-
-/**
- * Skip user@*.service, but require it to be there.
- */
-static const char *skip_user_manager(const char *p) {
-        size_t n;
-
-        assert(p);
-
-        p += strspn(p, "/");
-
-        n = strcspn(p, "/");
-        if (n < strlen("user@x.service") || memcmp(p, "user@", 5) != 0 || memcmp(p + n - 8, ".service", 8) != 0)
-                return NULL;
-
-        p += n;
-        p += strspn(p, "/");
-
-        return p;
-}
-
-int cg_path_get_user_unit(const char *path, char **unit) {
-        const char *e, *t;
-
-        assert(path);
-        assert(unit);
-
-        /* We always have to parse the path from the beginning as unit
-         * cgroups might have arbitrary child cgroups and we shouldn't get
-         * confused by those */
-
-        /* Skip slices, if there are any */
-        e = skip_slices(path);
-
-        /* Skip the session scope... */
-        t = skip_session(e);
-        if (t)
-                /* ... and skip more slices if there's one */
-                e = skip_slices(t);
-        else {
-                /* ... or require a user manager unit to be there */
-                e = skip_user_manager(e);
-                if (!e)
-                        return -ENOENT;
-        }
-
-        return cg_path_decode_unit(e, unit);
-}
-
-int cg_pid_get_user_unit(pid_t pid, char **unit) {
-        _cleanup_free_ char *cgroup = NULL;
-        int r;
-
-        assert(unit);
-
-        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        return cg_path_get_user_unit(cgroup, unit);
-}
-
-int cg_path_get_machine_name(const char *path, char **machine) {
-        _cleanup_free_ char *u = NULL, *sl = NULL;
-        int r;
-
-        r = cg_path_get_unit(path, &u);
-        if (r < 0)
-                return r;
-
-        sl = strjoin("/run/systemd/machines/unit:", u, NULL);
-        if (!sl)
-                return -ENOMEM;
-
-        return readlink_malloc(sl, machine);
-}
-
-int cg_pid_get_machine_name(pid_t pid, char **machine) {
-        _cleanup_free_ char *cgroup = NULL;
-        int r;
-
-        assert(machine);
-
-        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        return cg_path_get_machine_name(cgroup, machine);
-}
-
 int cg_path_get_session(const char *path, char **session) {
-        const char *e, *n, *x, *y;
-        char *s;
+        const char *e, *n, *s;
 
-        assert(path);
+        /* Elogind uses a flat hierarchy, just "/SESSION".  The only
+           wrinkle is that SESSION might be escaped.  */
 
-        /* Skip slices, if there are any */
-        e = skip_slices(path);
+        assert(path);
+        assert(path[0] == '/');
 
+        e = path + 1;
         n = strchrnul(e, '/');
         if (e == n)
                 return -ENOENT;
@@ -1323,17 +1142,13 @@ int cg_path_get_session(const char *path, char **session) {
         s = strndupa(e, n - e);
         s = cg_unescape(s);
 
-        x = startswith(s, "session-");
-        if (!x)
-                return -ENOENT;
-        y = endswith(x, ".scope");
-        if (!y || x == y)
+        if (!s[0])
                 return -ENOENT;
 
         if (session) {
                 char *r;
 
-                r = strndup(x, y - x);
+                r = strdup(s);
                 if (!r)
                         return -ENOMEM;
 
@@ -1354,97 +1169,6 @@ int cg_pid_get_session(pid_t pid, char **session) {
         return cg_path_get_session(cgroup, session);
 }
 
-int cg_path_get_owner_uid(const char *path, uid_t *uid) {
-        _cleanup_free_ char *slice = NULL;
-        const char *start, *end;
-        char *s;
-        uid_t u;
-        int r;
-
-        assert(path);
-
-        r = cg_path_get_slice(path, &slice);
-        if (r < 0)
-                return r;
-
-        start = startswith(slice, "user-");
-        if (!start)
-                return -ENOENT;
-        end = endswith(slice, ".slice");
-        if (!end)
-                return -ENOENT;
-
-        s = strndupa(start, end - start);
-        if (!s)
-                return -ENOENT;
-
-        if (parse_uid(s, &u) < 0)
-                return -EIO;
-
-        if (uid)
-                *uid = u;
-
-        return 0;
-}
-
-int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
-        _cleanup_free_ char *cgroup = NULL;
-        int r;
-
-        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        return cg_path_get_owner_uid(cgroup, uid);
-}
-
-int cg_path_get_slice(const char *p, char **slice) {
-        const char *e = NULL;
-        size_t m = 0;
-
-        assert(p);
-        assert(slice);
-
-        for (;;) {
-                size_t n;
-
-                p += strspn(p, "/");
-
-                n = strcspn(p, "/");
-                if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) {
-                        char *s;
-
-                        if (!e)
-                                return -ENOENT;
-
-                        s = strndup(e, m);
-                        if (!s)
-                                return -ENOMEM;
-
-                        *slice = s;
-                        return 0;
-                }
-
-                e = p;
-                m = n;
-
-                p += n;
-        }
-}
-
-int cg_pid_get_slice(pid_t pid, char **slice) {
-        _cleanup_free_ char *cgroup = NULL;
-        int r;
-
-        assert(slice);
-
-        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        return cg_path_get_slice(cgroup, slice);
-}
-
 char *cg_escape(const char *p) {
         bool need_prefix = false;
 
@@ -1531,56 +1255,6 @@ bool cg_controller_is_valid(const char *p, bool allow_named) {
         return true;
 }
 
-int cg_slice_to_path(const char *unit, char **ret) {
-        _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL;
-        const char *dash;
-
-        assert(unit);
-        assert(ret);
-
-        if (!unit_name_is_valid(unit, TEMPLATE_INVALID))
-                return -EINVAL;
-
-        if (!endswith(unit, ".slice"))
-                return -EINVAL;
-
-        p = unit_name_to_prefix(unit);
-        if (!p)
-                return -ENOMEM;
-
-        dash = strchr(p, '-');
-        while (dash) {
-                _cleanup_free_ char *escaped = NULL;
-                char n[dash - p + sizeof(".slice")];
-
-                strcpy(stpncpy(n, p, dash - p), ".slice");
-
-                if (!unit_name_is_valid(n, TEMPLATE_INVALID))
-                        return -EINVAL;
-
-                escaped = cg_escape(n);
-                if (!escaped)
-                        return -ENOMEM;
-
-                if (!strextend(&s, escaped, "/", NULL))
-                        return -ENOMEM;
-
-                dash = strchr(dash+1, '-');
-        }
-
-        e = cg_escape(unit);
-        if (!e)
-                return -ENOMEM;
-
-        if (!strextend(&s, e, NULL))
-                return -ENOMEM;
-
-        *ret = s;
-        s = NULL;
-
-        return 0;
-}
-
 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
         _cleanup_free_ char *p = NULL;
         int r;