[systemd-devel] [PATCH] cgroup: look up user session units from cgroups as well.

Mirco Tischler mt-ml at gmx.de
Mon Nov 5 15:52:34 PST 2012


This allows the journal code to set the _SYSTEMD_UNIT tag for messages generated
by systemd --user session units.
---
 src/shared/cgroup-util.c | 76 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 27 deletions(-)

diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index b0d378d..11f4f55 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -36,6 +36,7 @@
 #include "util.h"
 #include "path-util.h"
 #include "strv.h"
+#include "unit-name.h"
 
 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
         char *fs;
@@ -1202,9 +1203,44 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
         return 0;
 }
 
+static int instance_unit_from_cgroup(char **cgroup){
+        char *at;
+
+        assert(cgroup);
+
+        at = memchr(*cgroup, '@', strlen(*cgroup));
+        if (at && at[1] == '.') {
+                char *i, *s;
+
+                /* This is a templated service */
+                i = memchr(at, '/', strlen(at));
+                if(!i)
+                        return -EIO;
+
+                s = strndup(at + 1, i - at);
+                if (!s)
+                        return -ENOMEM;
+
+                i = strdup(i + 1);
+                if (!i) {
+                        free(s);
+                        return -ENOMEM;
+                }
+
+                strcpy(at + 1, i);
+                strcpy(at + strlen(i) + 1, s);
+                at[strlen(at) - 1] = '\0';
+
+                free(i);
+                free(s);
+        }
+
+        return 0;
+}
+
 int cg_pid_get_unit(pid_t pid, char **unit) {
         int r;
-        char *cgroup, *p, *at, *b;
+        char *cgroup, *p, *b;
         size_t k;
 
         assert(pid >= 0);
@@ -1214,36 +1250,16 @@ int cg_pid_get_unit(pid_t pid, char **unit) {
         if (r < 0)
                 return r;
 
-        if (!startswith(cgroup, "/system/")) {
+        r = instance_unit_from_cgroup(&cgroup);
+        if(r < 0){
                 free(cgroup);
-                return -ENOENT;
+                return r;
         }
 
-        p = cgroup + 8;
-        k = strcspn(p, "/");
-
-        at = memchr(p, '@', k);
-        if (at && at[1] == '.') {
-                size_t j;
-
-                /* This is a templated service */
-                if (p[k] != '/') {
-                        free(cgroup);
-                        return -EIO;
-                }
-
-                j = strcspn(p+k+1, "/");
+        p = strrchr(cgroup, '/') + 1;
+        k = strlen(p);
 
-                b = malloc(k + j + 1);
-
-                if (b) {
-                        memcpy(b, p, at - p + 1);
-                        memcpy(b + (at - p) + 1, p + k + 1, j);
-                        memcpy(b + (at - p) + 1 + j, at + 1, k - (at - p) - 1);
-                        b[k+j] = 0;
-                }
-        } else
-                  b = strndup(p, k);
+        b = strndup(p, k);
 
         free(cgroup);
 
@@ -1251,6 +1267,12 @@ int cg_pid_get_unit(pid_t pid, char **unit) {
                 return -ENOMEM;
 
         *unit = b;
+        r = unit_name_is_valid(*unit, true);
+        if (!r){
+                free(b);
+                return -ENOENT;
+        }
+
         return 0;
 
 }
-- 
1.8.0



More information about the systemd-devel mailing list