[systemd-commits] 5 commits - TODO src/core src/libsystemd src/shared src/systemd src/test

Lennart Poettering lennart at kemper.freedesktop.org
Thu Apr 30 03:39:20 PDT 2015


 TODO                               |    8 ++-
 src/core/unit-printf.c             |   39 ++++++++++------
 src/libsystemd/libsystemd.sym.m4   |   22 +++++++--
 src/libsystemd/sd-bus/bus-creds.c  |   36 +++++++++++++--
 src/libsystemd/sd-bus/bus-creds.h  |    1 
 src/libsystemd/sd-bus/bus-dump.c   |   18 ++++---
 src/libsystemd/sd-login/sd-login.c |   22 +++++++++
 src/shared/cgroup-util.c           |   86 +++++++++++++++++++++++++------------
 src/shared/cgroup-util.h           |    2 
 src/systemd/sd-bus.h               |   36 ++++++++-------
 src/systemd/sd-login.h             |   25 ++++++----
 src/test/test-cgroup-util.c        |   32 +++++++++++++
 12 files changed, 242 insertions(+), 85 deletions(-)

New commits:
commit e7e90a8eee056fd12c8ad83470143f7798240dbc
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 30 12:35:15 2015 +0200

    update TODO

diff --git a/TODO b/TODO
index c881af3..0a88cb1 100644
--- a/TODO
+++ b/TODO
@@ -49,11 +49,15 @@ Before 220:
 
 * introduce argv0array=
 
+* be stricter when validating slice names
+
 Features:
 
-* when detecting kdbus support in busname.c make sure to check kdbus kernel ioctl version
+* logind: rename session scope so that it includes the UID. THat way
+  the session scope can be arranged freely in slices and we don't have
+  make assumptions about their slice anymore.
 
-* intrdouce sd_pid_get_user_slice() and friends
+* when detecting kdbus support in busname.c make sure to check kdbus kernel ioctl version
 
 * journalctl: -m should access container journals directly by enumerating them via machined, and also watch containers coming and going. Benefit: nspawn --ephemeral would start working nicely with the journal.
 

commit 696fd1ef4f2f8574e349332a16987c6772641edd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 30 12:33:54 2015 +0200

    core: simplify %r and %R logic a bit
    
    Do not calculate the cgroup path manually, just use normal unit fields
    and calls for that.

diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
index bb4aa21..5513fe7 100644
--- a/src/core/unit-printf.c
+++ b/src/core/unit-printf.c
@@ -128,26 +128,35 @@ static int specifier_cgroup(char specifier, void *data, void *userdata, char **r
 
 static int specifier_cgroup_root(char specifier, void *data, void *userdata, char **ret) {
         Unit *u = userdata;
-        const char *slice;
         char *n;
-        int r;
 
         assert(u);
 
-        slice = unit_slice_name(u);
-        if (specifier == 'R' || !slice)
-                n = strdup(u->manager->cgroup_root);
-        else {
-                _cleanup_free_ char *p = NULL;
+        n = strdup(u->manager->cgroup_root);
+        if (!n)
+                return -ENOMEM;
 
-                r = cg_slice_to_path(slice, &p);
-                if (r < 0)
-                        return r;
+        *ret = n;
+        return 0;
+}
 
-                n = strjoin(u->manager->cgroup_root, "/", p, NULL);
-                if (!n)
-                        return -ENOMEM;
-        }
+static int specifier_cgroup_slice(char specifier, void *data, void *userdata, char **ret) {
+        Unit *u = userdata;
+        char *n;
+
+        assert(u);
+
+        if (UNIT_ISSET(u->slice)) {
+                Unit *slice;
+
+                slice = UNIT_DEREF(u->slice);
+
+                if (slice->cgroup_path)
+                        n = strdup(slice->cgroup_path);
+                else
+                        n = unit_default_cgroup_path(slice);
+        } else
+                n = strdup(u->manager->cgroup_root);
 
         *ret = n;
         return 0;
@@ -392,7 +401,7 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
 
                 { 'f', specifier_filename,            NULL },
                 { 'c', specifier_cgroup,              NULL },
-                { 'r', specifier_cgroup_root,         NULL },
+                { 'r', specifier_cgroup_slice,        NULL },
                 { 'R', specifier_cgroup_root,         NULL },
                 { 't', specifier_runtime,             NULL },
                 { 'U', specifier_user_name,           NULL },

commit c96cc5822c165e86be78ed96dac6573986032fab
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 30 12:33:35 2015 +0200

    core: catch some special cases in cg_slice_to_path()

diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index dbf7942..1306cc1 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1642,6 +1642,16 @@ int cg_slice_to_path(const char *unit, char **ret) {
         assert(unit);
         assert(ret);
 
+        if (streq(unit, "-.slice")) {
+                char *x;
+
+                x = strdup("");
+                if (!x)
+                        return -ENOMEM;
+                *ret = x;
+                return 0;
+        }
+
         if (!unit_name_is_valid(unit, TEMPLATE_INVALID))
                 return -EINVAL;
 
@@ -1657,8 +1667,10 @@ int cg_slice_to_path(const char *unit, char **ret) {
                 _cleanup_free_ char *escaped = NULL;
                 char n[dash - p + sizeof(".slice")];
 
-                strcpy(stpncpy(n, p, dash - p), ".slice");
+                if (isempty(dash + 1))
+                        return -EINVAL;
 
+                strcpy(stpncpy(n, p, dash - p), ".slice");
                 if (!unit_name_is_valid(n, TEMPLATE_INVALID))
                         return -EINVAL;
 
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index 79c11e2..efe99cb 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -268,9 +268,14 @@ static void test_slice_to_path(void) {
         test_slice_to_path_one("foobar.slice", "foobar.slice", 0);
         test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0);
         test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL);
-        test_slice_to_path_one("-.slice", NULL, -EINVAL);
+        test_slice_to_path_one("-.slice", "", 0);
+        test_slice_to_path_one("--.slice", NULL, -EINVAL);
+        test_slice_to_path_one("-", NULL, -EINVAL);
         test_slice_to_path_one("-foo-.slice", NULL, -EINVAL);
         test_slice_to_path_one("-foo.slice", NULL, -EINVAL);
+        test_slice_to_path_one("foo-.slice", NULL, -EINVAL);
+        test_slice_to_path_one("foo--bar.slice", "foo.slice/foo-.slice/foo--bar.slice", 0);
+        test_slice_to_path_one("foo.slice/foo--bar.slice", NULL, -EINVAL);
         test_slice_to_path_one("a-b.slice", "a.slice/a-b.slice", 0);
         test_slice_to_path_one("a-b-c-d-e.slice", "a.slice/a-b.slice/a-b-c.slice/a-b-c-d.slice/a-b-c-d-e.slice", 0);
 }

commit 6bd68a1aa2c4a6250308882caf1025100908b15f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 30 12:01:19 2015 +0200

    sym: adding missing symbols to .sym file

diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4
index 8c28d72..72213c2 100644
--- a/src/libsystemd/libsystemd.sym.m4
+++ b/src/libsystemd/libsystemd.sym.m4
@@ -329,11 +329,18 @@ global:
         sd_bus_creds_unref;
         sd_bus_creds_get_mask;
         sd_bus_creds_get_augmented_mask;
-        sd_bus_creds_get_uid;
-        sd_bus_creds_get_gid;
         sd_bus_creds_get_pid;
         sd_bus_creds_get_ppid;
         sd_bus_creds_get_tid;
+        sd_bus_creds_get_uid;
+        sd_bus_creds_get_euid;
+        sd_bus_creds_get_suid;
+        sd_bus_creds_get_fsuid;
+        sd_bus_creds_get_gid;
+        sd_bus_creds_get_egid;
+        sd_bus_creds_get_sgid;
+        sd_bus_creds_get_fsgid;
+        sd_bus_creds_get_supplementary_gids;
         sd_bus_creds_get_comm;
         sd_bus_creds_get_tid_comm;
         sd_bus_creds_get_exe;

commit 329ac4bc5429cd86c4ac76b13e7e2784f3982760
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 30 11:58:06 2015 +0200

    sd-bus,sd-login: add api for querying the slice within the the user systemd instance of a process
    
    units are organized in slice trees, not only for the system instance,
    but also for user systemd instances, expose this properly.

diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4
index 098b6a0..8c28d72 100644
--- a/src/libsystemd/libsystemd.sym.m4
+++ b/src/libsystemd/libsystemd.sym.m4
@@ -163,6 +163,12 @@ global:
         sd_pid_notify_with_fds;
 } LIBSYSTEMD_217;
 
+LIBSYSTEMD_220 {
+global:
+        sd_pid_get_user_slice;
+        sd_peer_get_user_slice;
+} LIBSYSTEMD_219;
+
 m4_ifdef(`ENABLE_KDBUS',
 LIBSYSTEMD_FUTURE {
 global:
@@ -334,8 +340,9 @@ global:
         sd_bus_creds_get_cmdline;
         sd_bus_creds_get_cgroup;
         sd_bus_creds_get_unit;
-        sd_bus_creds_get_user_unit;
         sd_bus_creds_get_slice;
+        sd_bus_creds_get_user_unit;
+        sd_bus_creds_get_user_slice;
         sd_bus_creds_get_session;
         sd_bus_creds_get_owner_uid;
         sd_bus_creds_has_effective_cap;
@@ -459,5 +466,5 @@ global:
         /* sd-path */
         sd_path_home;
         sd_path_search;
-} LIBSYSTEMD_217;
+} LIBSYSTEMD_220;
 )
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index ed9bf52..fed6682 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -53,6 +53,7 @@ void bus_creds_done(sd_bus_creds *c) {
         free(c->unit);
         free(c->user_unit);
         free(c->slice);
+        free(c->user_slice);
         free(c->unescaped_description);
         free(c->supplementary_gids);
         free(c->tty);
@@ -466,6 +467,33 @@ _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
         return 0;
 }
 
+_public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) {
+        int r;
+
+        assert_return(c, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_USER_SLICE))
+                return -ENODATA;
+
+        assert(c->cgroup);
+
+        if (!c->user_slice) {
+                const char *shifted;
+
+                r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
+                if (r < 0)
+                        return r;
+
+                r = cg_path_get_user_slice(shifted, (char**) &c->user_slice);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret = c->user_slice;
+        return 0;
+}
+
 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
         int r;
 
@@ -1013,7 +1041,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                         c->mask |= SD_BUS_CREDS_TID_COMM;
         }
 
-        if (missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) {
+        if (missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) {
 
                 if (!c->cgroup) {
                         r = cg_pid_get_path(NULL, pid, &c->cgroup);
@@ -1030,7 +1058,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                 }
 
                 if (c->cgroup)
-                        c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID);
+                        c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID);
         }
 
         if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
@@ -1224,7 +1252,7 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_CMDLINE;
         }
 
-        if (c->mask & mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_OWNER_UID)) {
+        if (c->mask & mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_SLICE|SD_BUS_CREDS_OWNER_UID)) {
                 assert(c->cgroup);
 
                 n->cgroup = strdup(c->cgroup);
@@ -1235,7 +1263,7 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 if (!n->cgroup_root)
                         return -ENOMEM;
 
-                n->mask |= mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_OWNER_UID);
+                n->mask |= mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_SLICE|SD_BUS_CREDS_OWNER_UID);
         }
 
         if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h
index 42f76b8..209d216 100644
--- a/src/libsystemd/sd-bus/bus-creds.h
+++ b/src/libsystemd/sd-bus/bus-creds.h
@@ -61,6 +61,7 @@ struct sd_bus_creds {
         char *unit;
         char *user_unit;
         char *slice;
+        char *user_slice;
 
         char *tty;
 
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 47a5c6b..9db86ad 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -335,7 +335,7 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
         uint32_t audit_sessionid;
         char **cmdline = NULL, **well_known = NULL;
         const char *prefix, *color, *suffix, *s;
-        int r, q, v, w;
+        int r, q, v, w, z;
 
         assert(c);
 
@@ -447,19 +447,23 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
         if (r != -ENODATA)
                 fprintf(f, "%sUnit=%s%s%s", prefix, color, strna(s), suffix);
         s = NULL;
-        q = sd_bus_creds_get_user_unit(c, &s);
-        if (q != -ENODATA)
-                fprintf(f, "%sUserUnit=%s%s%s", prefix, color, strna(s), suffix);
-        s = NULL;
         v = sd_bus_creds_get_slice(c, &s);
         if (v != -ENODATA)
                 fprintf(f, "%sSlice=%s%s%s", prefix, color, strna(s), suffix);
         s = NULL;
-        w = sd_bus_creds_get_session(c, &s);
+        q = sd_bus_creds_get_user_unit(c, &s);
+        if (q != -ENODATA)
+                fprintf(f, "%sUserUnit=%s%s%s", prefix, color, strna(s), suffix);
+        s = NULL;
+        w = sd_bus_creds_get_user_slice(c, &s);
         if (w != -ENODATA)
+                fprintf(f, "%sUserSlice=%s%s%s", prefix, color, strna(s), suffix);
+        s = NULL;
+        z = sd_bus_creds_get_session(c, &s);
+        if (z != -ENODATA)
                 fprintf(f, "%sSession=%s%s%s", prefix, color, strna(s), suffix);
 
-        if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || r != -ENODATA || q != -ENODATA || v != -ENODATA || w != -ENODATA))
+        if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || r != -ENODATA || q != -ENODATA || v != -ENODATA || w != -ENODATA || z != -ENODATA))
                 fputs("\n", f);
 
         r = sd_bus_creds_get_audit_login_uid(c, &audit_loginuid);
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 7b8f063..ed8aa09 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -74,6 +74,14 @@ _public_ int sd_pid_get_slice(pid_t pid, char **slice) {
         return cg_pid_get_slice(pid, slice);
 }
 
+_public_ int sd_pid_get_user_slice(pid_t pid, char **slice) {
+
+        assert_return(pid >= 0, -EINVAL);
+        assert_return(slice, -EINVAL);
+
+        return cg_pid_get_user_slice(pid, slice);
+}
+
 _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
 
         assert_return(pid >= 0, -EINVAL);
@@ -166,6 +174,20 @@ _public_ int sd_peer_get_slice(int fd, char **slice) {
         return cg_pid_get_slice(ucred.pid, slice);
 }
 
+_public_ int sd_peer_get_user_slice(int fd, char **slice) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(slice, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_user_slice(ucred.pid, slice);
+}
+
 static int file_of_uid(uid_t uid, char **p) {
         assert(p);
 
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 67e6f70..dbf7942 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1317,45 +1317,37 @@ static const char *skip_user_manager(const char *p) {
         return NULL;
 }
 
-int cg_path_get_user_unit(const char *path, char **ret) {
+static const char *skip_user_prefix(const char *path) {
         const char *e, *t;
-        char *unit;
-        int r;
 
         assert(path);
-        assert(ret);
-
-        /* 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 user manager... */
+        /* Skip the user manager, if it's in the path now... */
         t = skip_user_manager(e);
+        if (t)
+                return t;
 
-        /* Alternatively skip the user session... */
-        if (!t)
-                t = skip_session(e);
-        if (!t)
-                return -ENXIO;
+        /* Alternatively skip the user session if it is in the path... */
+        return skip_session(e);
+}
 
-        /* ... and skip more slices if there are any */
-        e = skip_slices(t);
+int cg_path_get_user_unit(const char *path, char **ret) {
+        const char *t;
 
-        r = cg_path_decode_unit(e, &unit);
-        if (r < 0)
-                return r;
+        assert(path);
+        assert(ret);
 
-        /* We skipped over the slices, don't accept any now */
-        if (endswith(unit, ".slice")) {
-                free(unit);
+        t = skip_user_prefix(path);
+        if (!t)
                 return -ENXIO;
-        }
 
-        *ret = unit;
-        return 0;
+        /* And from here on it looks pretty much the same as for a
+         * system unit, hence let's use the same parser from here
+         * on. */
+        return cg_path_get_unit(t, ret);
 }
 
 int cg_pid_get_user_unit(pid_t pid, char **unit) {
@@ -1487,6 +1479,9 @@ int cg_path_get_slice(const char *p, char **slice) {
         assert(p);
         assert(slice);
 
+        /* Finds the right-most slice unit from the beginning, but
+         * stops before we come to the first non-slice unit. */
+
         for (;;) {
                 size_t n;
 
@@ -1527,6 +1522,33 @@ int cg_pid_get_slice(pid_t pid, char **slice) {
         return cg_path_get_slice(cgroup, slice);
 }
 
+int cg_path_get_user_slice(const char *p, char **slice) {
+        const char *t;
+        assert(p);
+        assert(slice);
+
+        t = skip_user_prefix(p);
+        if (!t)
+                return -ENXIO;
+
+        /* And now it looks pretty much the same as for a system
+         * slice, so let's just use the same parser from here on. */
+        return cg_path_get_slice(t, slice);
+}
+
+int cg_pid_get_user_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_user_slice(cgroup, slice);
+}
+
 char *cg_escape(const char *p) {
         bool need_prefix = false;
 
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index 96a3d3b..cbf7201 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -104,6 +104,7 @@ int cg_path_get_unit(const char *path, char **unit);
 int cg_path_get_user_unit(const char *path, char **unit);
 int cg_path_get_machine_name(const char *path, char **machine);
 int cg_path_get_slice(const char *path, char **slice);
+int cg_path_get_user_slice(const char *path, char **slice);
 
 int cg_shift_path(const char *cgroup, const char *cached_root, const char **shifted);
 int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **cgroup);
@@ -114,6 +115,7 @@ int cg_pid_get_unit(pid_t pid, char **unit);
 int cg_pid_get_user_unit(pid_t pid, char **unit);
 int cg_pid_get_machine_name(pid_t pid, char **machine);
 int cg_pid_get_slice(pid_t pid, char **slice);
+int cg_pid_get_user_slice(pid_t pid, char **slice);
 
 int cg_path_decode_unit(const char *cgroup, char **unit);
 
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 19f01a6..9dadae9 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -73,23 +73,24 @@ enum {
         SD_BUS_CREDS_CMDLINE            = 1ULL << 15,
         SD_BUS_CREDS_CGROUP             = 1ULL << 16,
         SD_BUS_CREDS_UNIT               = 1ULL << 17,
-        SD_BUS_CREDS_USER_UNIT          = 1ULL << 18,
-        SD_BUS_CREDS_SLICE              = 1ULL << 19,
-        SD_BUS_CREDS_SESSION            = 1ULL << 20,
-        SD_BUS_CREDS_OWNER_UID          = 1ULL << 21,
-        SD_BUS_CREDS_EFFECTIVE_CAPS     = 1ULL << 22,
-        SD_BUS_CREDS_PERMITTED_CAPS     = 1ULL << 23,
-        SD_BUS_CREDS_INHERITABLE_CAPS   = 1ULL << 24,
-        SD_BUS_CREDS_BOUNDING_CAPS      = 1ULL << 25,
-        SD_BUS_CREDS_SELINUX_CONTEXT    = 1ULL << 26,
-        SD_BUS_CREDS_AUDIT_SESSION_ID   = 1ULL << 27,
-        SD_BUS_CREDS_AUDIT_LOGIN_UID    = 1ULL << 28,
-        SD_BUS_CREDS_TTY                = 1ULL << 29,
-        SD_BUS_CREDS_UNIQUE_NAME        = 1ULL << 30,
-        SD_BUS_CREDS_WELL_KNOWN_NAMES   = 1ULL << 31,
-        SD_BUS_CREDS_DESCRIPTION        = 1ULL << 32,
+        SD_BUS_CREDS_SLICE              = 1ULL << 18,
+        SD_BUS_CREDS_USER_UNIT          = 1ULL << 19,
+        SD_BUS_CREDS_USER_SLICE         = 1ULL << 20,
+        SD_BUS_CREDS_SESSION            = 1ULL << 21,
+        SD_BUS_CREDS_OWNER_UID          = 1ULL << 22,
+        SD_BUS_CREDS_EFFECTIVE_CAPS     = 1ULL << 23,
+        SD_BUS_CREDS_PERMITTED_CAPS     = 1ULL << 24,
+        SD_BUS_CREDS_INHERITABLE_CAPS   = 1ULL << 25,
+        SD_BUS_CREDS_BOUNDING_CAPS      = 1ULL << 26,
+        SD_BUS_CREDS_SELINUX_CONTEXT    = 1ULL << 27,
+        SD_BUS_CREDS_AUDIT_SESSION_ID   = 1ULL << 28,
+        SD_BUS_CREDS_AUDIT_LOGIN_UID    = 1ULL << 29,
+        SD_BUS_CREDS_TTY                = 1ULL << 30,
+        SD_BUS_CREDS_UNIQUE_NAME        = 1ULL << 31,
+        SD_BUS_CREDS_WELL_KNOWN_NAMES   = 1ULL << 32,
+        SD_BUS_CREDS_DESCRIPTION        = 1ULL << 33,
         SD_BUS_CREDS_AUGMENT            = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
-        _SD_BUS_CREDS_ALL               = (1ULL << 33) -1,
+        _SD_BUS_CREDS_ALL               = (1ULL << 34) -1,
 };
 
 enum {
@@ -351,8 +352,9 @@ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe);
 int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline);
 int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **cgroup);
 int sd_bus_creds_get_unit(sd_bus_creds *c, const char **unit);
-int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **unit);
 int sd_bus_creds_get_slice(sd_bus_creds *c, const char **slice);
+int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **unit);
+int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **slice);
 int sd_bus_creds_get_session(sd_bus_creds *c, const char **session);
 int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid);
 int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability);
diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
index 24c8595..9260396 100644
--- a/src/systemd/sd-login.h
+++ b/src/systemd/sd-login.h
@@ -62,22 +62,25 @@ int sd_pid_get_session(pid_t pid, char **session);
  * return an error for system processes. */
 int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
 
-/* Get systemd unit (i.e. service) name from PID, for system
+/* Get systemd non-slice unit (i.e. service) name from PID, for system
  * services. This will return an error for non-service processes. */
 int sd_pid_get_unit(pid_t pid, char **unit);
 
-/* Get systemd unit (i.e. service) name from PID, for user
+/* Get systemd non-slice unit (i.e. service) name from PID, for user
  * services. This will return an error for non-user-service
  * processes. */
 int sd_pid_get_user_unit(pid_t pid, char **unit);
 
+/* Get slice name from PID. */
+int sd_pid_get_slice(pid_t pid, char **slice);
+
+/* Get user slice name from PID. */
+int sd_pid_get_user_slice(pid_t pid, char **slice);
+
 /* Get machine name from PID, for processes assigned to a VM or
  * container. This will return an error for non-machine processes. */
 int sd_pid_get_machine_name(pid_t pid, char **machine);
 
-/* Get slice name from PID. */
-int sd_pid_get_slice(pid_t pid, char **slice);
-
 /* Similar to sd_pid_get_session(), but retrieves data about peer of
  * connected AF_UNIX socket */
 int sd_peer_get_session(int fd, char **session);
@@ -94,14 +97,18 @@ int sd_peer_get_unit(int fd, char **unit);
  * connected AF_UNIX socket */
 int sd_peer_get_user_unit(int fd, char **unit);
 
-/* Similar to sd_pid_get_machine_name(), but retrieves data about peer
- * of connected AF_UNIX socket */
-int sd_peer_get_machine_name(int fd, char **machine);
-
 /* Similar to sd_pid_get_slice(), but retrieves data about peer of
  * connected AF_UNIX socket */
 int sd_peer_get_slice(int fd, char **slice);
 
+/* Similar to sd_pid_get_user_slice(), but retrieves data about peer of
+ * connected AF_UNIX socket */
+int sd_peer_get_user_slice(int fd, char **slice);
+
+/* Similar to sd_pid_get_machine_name(), but retrieves data about peer
+ * of connected AF_UNIX socket */
+int sd_peer_get_machine_name(int fd, char **machine);
+
 /* Get state from UID. Possible states: offline, lingering, online, active, closing */
 int sd_uid_get_state(uid_t uid, char **state);
 
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index 759ca44..79c11e2 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -142,6 +142,30 @@ static void test_path_get_slice(void) {
         check_p_g_slice("foo.slice/foo-bar.slice/waldo.service", 0, "foo-bar.slice");
 }
 
+static void check_p_g_u_slice(const char *path, int code, const char *result) {
+        _cleanup_free_ char *s = NULL;
+
+        assert_se(cg_path_get_user_slice(path, &s) == code);
+        assert_se(streq_ptr(s, result));
+}
+
+static void test_path_get_user_slice(void) {
+        check_p_g_u_slice("/user.slice", -ENXIO, NULL);
+        check_p_g_u_slice("/foobar", -ENXIO, NULL);
+        check_p_g_u_slice("/user.slice/user-waldo.slice", -ENXIO, NULL);
+        check_p_g_u_slice("", -ENXIO, NULL);
+        check_p_g_u_slice("foobar", -ENXIO, NULL);
+        check_p_g_u_slice("foobar.slice", -ENXIO, NULL);
+        check_p_g_u_slice("foo.slice/foo-bar.slice/waldo.service", -ENXIO, NULL);
+
+        check_p_g_u_slice("foo.slice/foo-bar.slice/user at 1000.service", 0, "-.slice");
+        check_p_g_u_slice("foo.slice/foo-bar.slice/user at 1000.service/", 0, "-.slice");
+        check_p_g_u_slice("foo.slice/foo-bar.slice/user at 1000.service///", 0, "-.slice");
+        check_p_g_u_slice("foo.slice/foo-bar.slice/user at 1000.service/waldo.service", 0, "-.slice");
+        check_p_g_u_slice("foo.slice/foo-bar.slice/user at 1000.service/piep.slice/foo.service", 0, "piep.slice");
+        check_p_g_u_slice("/foo.slice//foo-bar.slice/user at 1000.service/piep.slice//piep-pap.slice//foo.service", 0, "piep-pap.slice");
+}
+
 static void test_get_paths(void) {
         _cleanup_free_ char *a = NULL;
 
@@ -273,6 +297,7 @@ int main(void) {
         test_path_get_session();
         test_path_get_owner_uid();
         test_path_get_slice();
+        test_path_get_user_slice();
         TEST_REQ_RUNNING_SYSTEMD(test_get_paths());
         test_proc();
         TEST_REQ_RUNNING_SYSTEMD(test_escape());



More information about the systemd-commits mailing list