[systemd-commits] 7 commits - Makefile.am man/systemd.journal-fields.xml src/core src/journal src/shared src/systemctl src/test

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Fri Jan 18 09:02:08 PST 2013


 Makefile.am                    |   10 +-
 man/systemd.journal-fields.xml |    4 
 src/core/execute.c             |   12 +-
 src/core/job.c                 |   16 +--
 src/core/mount.c               |    4 
 src/core/service.c             |    4 
 src/core/unit.c                |    8 -
 src/core/unit.h                |    5 -
 src/journal/journald-server.c  |   11 +-
 src/shared/cgroup-util.c       |   96 ++++++++++++-------
 src/shared/cgroup-util.h       |    3 
 src/shared/logs-show.c         |  205 +++++++++++++++++++++++++++++------------
 src/shared/logs-show.h         |   12 ++
 src/systemctl/systemctl.c      |   24 +++-
 src/test/test-cgroup-util.c    |   27 +++++
 15 files changed, 315 insertions(+), 126 deletions(-)

New commits:
commit 96cde13ace6406582688028f3df5668a172ba628
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Jan 18 01:13:27 2013 -0500

    core/cgroup-util: simplify functions and add tests

diff --git a/Makefile.am b/Makefile.am
index ab9fb99..25d9995 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1194,7 +1194,8 @@ noinst_tests += \
 	test-replace-var \
 	test-sched-prio \
 	test-calendarspec \
-	test-strip-tab-ansi
+	test-strip-tab-ansi \
+	test-cgroup-util
 
 EXTRA_DIST += \
 	test/sched_idle_bad.service \
@@ -1311,6 +1312,13 @@ test_cgroup_LDADD = \
 	libsystemd-label.la \
 	libsystemd-shared.la
 
+test_cgroup_util_SOURCES = \
+	src/test/test-cgroup-util.c
+
+test_cgroup_util_LDADD = \
+	libsystemd-label.la \
+	libsystemd-shared.la
+
 test_env_replace_SOURCES = \
 	src/test/test-env-replace.c
 
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index af52278..f0d0d48 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1211,69 +1211,57 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
         return 0;
 }
 
-static int instance_unit_from_cgroup(char **cgroup){
+static int instance_unit_from_cgroup(char *cgroup){
         char *at;
 
         assert(cgroup);
 
-        at = memchr(*cgroup, '@', strlen(*cgroup));
-        if (at && at[1] == '.') {
-                char *i, *s;
-
+        at = strstr(cgroup, "@.");
+        if (at) {
                 /* This is a templated service */
-                i = memchr(at, '/', strlen(at));
-                if(!i)
-                        return -EIO;
 
-                s = strndup(at + 1, i - at);
-                if (!s)
-                        return -ENOMEM;
+                char *i;
+                char _cleanup_free_ *i2 = NULL, *s = NULL;
 
-                i = strdup(i + 1);
-                if (!i) {
-                        free(s);
-                        return -ENOMEM;
-                }
+                i = strchr(at, '/');
+                if (!i || !i[1]) /* disallow empty instances */
+                        return -EINVAL;
 
-                strcpy(at + 1, i);
-                strcpy(at + strlen(i) + 1, s);
-                at[strlen(at) - 1] = '\0';
+                s = strndup(at + 1, i - at - 1);
+                i2 = strdup(i + 1);
+                if (!s || !i2)
+                        return -ENOMEM;
 
-                free(i);
-                free(s);
+                strcpy(at + 1, i2);
+                strcat(at + 1, s);
         }
 
         return 0;
 }
 
-static int cgroup_to_unit(char *cgroup, char **unit){
+/* non-static only for testing purposes */
+int cgroup_to_unit(char *cgroup, char **unit){
         int r;
-        char *b, *p;
-        size_t k;
+        char *p;
 
         assert(cgroup);
         assert(unit);
 
-        r = instance_unit_from_cgroup(&cgroup);
+        r = instance_unit_from_cgroup(cgroup);
         if (r < 0)
                 return r;
 
-        p = strrchr(cgroup, '/') + 1;
-        k = strlen(p);
+        p = strrchr(cgroup, '/');
+        assert(p);
 
-        b = strndup(p, k);
+        r = unit_name_is_valid(p + 1, true);
+        if (!r)
+                return -EINVAL;
 
-        if (!b)
+        *unit = strdup(p + 1);
+        if (!*unit)
                 return -ENOMEM;
 
-        r = unit_name_is_valid(b, true);
-        if (!r) {
-                free(b);
-                return -ENOENT;
-        }
-
-        *unit = b;
-
         return 0;
 }
 
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index 2429ba2..920cf63 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -73,4 +73,6 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup);
 int cg_pid_get_unit(pid_t pid, char **unit);
 int cg_pid_get_user_unit(pid_t pid, char **unit);
 
+int cgroup_to_unit(char *cgroup, char **unit);
+
 char **cg_shorten_controllers(char **controllers);
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
new file mode 100644
index 0000000..b30bf23
--- /dev/null
+++ b/src/test/test-cgroup-util.c
@@ -0,0 +1,27 @@
+#include <assert.h>
+
+#include "util.h"
+#include "cgroup-util.h"
+
+#define check_c_t_u(path, code, result) \
+{ \
+   char a[] = path; \
+   char *unit = NULL; \
+   assert_se(cgroup_to_unit(a, &unit) == code); \
+   assert(code < 0 || streq(unit, result));                 \
+}
+
+
+static void test_cgroup_to_unit(void) {
+        check_c_t_u("/system/getty at .service/tty2", 0, "getty at tty2.service");
+        check_c_t_u("/system/getty at .service/", -EINVAL, "getty at tty2.service");
+        check_c_t_u("/system/getty at .service", -EINVAL, "getty at tty2.service");
+        check_c_t_u("/system/getty.service", 0, "getty.service");
+        check_c_t_u("/system/getty", -EINVAL, "getty.service");
+}
+
+int main(void) {
+        test_cgroup_to_unit();
+
+        return 0;
+}

commit 3f98659cce700fea91959312297950f15011b07b
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Jan 18 01:13:26 2013 -0500

    core/group-util: merge two functions

diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 3d12233..af52278 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1277,9 +1277,9 @@ static int cgroup_to_unit(char *cgroup, char **unit){
         return 0;
 }
 
-int cg_pid_get_unit(pid_t pid, char **unit) {
+static int cg_pid_get(const char *prefix, pid_t pid, char **unit) {
         int r;
-        char *cgroup;
+        char _cleanup_free_ *cgroup = NULL;
 
         assert(pid >= 0);
         assert(unit);
@@ -1288,45 +1288,17 @@ int cg_pid_get_unit(pid_t pid, char **unit) {
         if (r < 0)
                 return r;
 
-        if (!startswith(cgroup, "/system/")) {
-                free(cgroup);
+        if (!startswith(cgroup, prefix))
                 return -ENOENT;
-        }
 
         r = cgroup_to_unit(cgroup, unit);
-        if (r < 0){
-                free(cgroup);
-                return r;
-        }
-
-        free(cgroup);
+        return r;
+}
 
-        return 0;
+int cg_pid_get_unit(pid_t pid, char **unit) {
+        return cg_pid_get("/system/", pid, unit);
 }
 
 int cg_pid_get_user_unit(pid_t pid, char **unit) {
-        int r;
-        char *cgroup;
-
-        assert(pid >= 0);
-        assert(unit);
-
-        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        if (!startswith(cgroup, "/user/")) {
-                free(cgroup);
-                return -ENOENT;
-        }
-
-        r = cgroup_to_unit(cgroup, unit);
-        if (r < 0) {
-                free(cgroup);
-                return r;
-        }
-
-        free(cgroup);
-
-        return 0;
+        return cg_pid_get("/user/", pid, unit);
 }

commit 64abe9aa3f7dc7d755a4d3d1783fe3f0285edaea
Author: Mirco Tischler <mt-ml at gmx.de>
Date:   Thu Jan 17 18:55:09 2013 +0100

    man: document the _SYSTEMD_USER_UNIT journal field

diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index 13af4fd..2e9bc5b 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -212,13 +212,15 @@
                                 <term><varname>_SYSTEMD_CGROUP=</varname></term>
                                 <term><varname>_SYSTEMD_SESSION=</varname></term>
                                 <term><varname>_SYSTEMD_UNIT=</varname></term>
+                                <term><varname>_SYSTEMD_USER_UNIT=</varname></term>
                                 <term><varname>_SYSTEMD_OWNER_UID=</varname></term>
 
                                 <listitem>
                                         <para>The control group path in
                                         the systemd hierarchy, the
                                         systemd session ID (if any),
-                                        the systemd unit name (if any)
+                                        the systemd unit name (if any),
+                                        the systemd user session unit name (if any)
                                         and the owner UID of the
                                         systemd session (if any) of
                                         the process the journal entry

commit cc86e6b86e6431940a68fae56b84b865cf5b1e6d
Author: Mirco Tischler <mt-ml at gmx.de>
Date:   Thu Jan 17 18:55:08 2013 +0100

    systemctl: print the user session journal for user session units.

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index f3d661d..fb4ae24 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2734,13 +2734,23 @@ static void print_status_info(UnitStatusInfo *i) {
 
         if (i->id && arg_transport != TRANSPORT_SSH) {
                 printf("\n");
-                show_journal_by_unit(stdout,
-                                     i->id,
-                                     arg_output,
-                                     0,
-                                     i->inactive_exit_timestamp_monotonic,
-                                     arg_lines,
-                                     flags);
+                if(arg_scope == UNIT_FILE_SYSTEM)
+                        show_journal_by_unit(stdout,
+                                             i->id,
+                                             arg_output,
+                                             0,
+                                             i->inactive_exit_timestamp_monotonic,
+                                             arg_lines,
+                                             flags);
+                else
+                        show_journal_by_user_unit(stdout,
+                                                  i->id,
+                                                  arg_output,
+                                                  0,
+                                                  i->inactive_exit_timestamp_monotonic,
+                                                  arg_lines,
+                                                  getuid(),
+                                                  flags);
         }
 
         if (i->need_daemon_reload)

commit 1a6c43e94649b3f271502a88655f63ea85168fec
Author: Mirco Tischler <mt-ml at gmx.de>
Date:   Thu Jan 17 18:55:07 2013 +0100

    logs-show: add show_journal_by_user_unit
    
    Print the journal for a user session unit. For now this filters by
    _SYSTEMD_USER_UNIT and USER_UNIT and additionally _UID.

diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index c221af3..034fde6 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -774,72 +774,22 @@ int output_journal(
         return ret;
 }
 
-int show_journal_by_unit(
-                FILE *f,
-                const char *unit,
-                OutputMode mode,
-                unsigned n_columns,
-                usec_t not_before,
-                unsigned how_many,
-                OutputFlags flags) {
+static int show_journal(FILE *f,
+                        sd_journal *j,
+                        OutputMode mode,
+                        unsigned n_columns,
+                        usec_t not_before,
+                        unsigned how_many,
+                        OutputFlags flags) {
 
-        _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL;
-        sd_journal *j = NULL;
         int r;
         unsigned line = 0;
         bool need_seek = false;
         int warn_cutoff = flags & OUTPUT_WARN_CUTOFF;
 
+        assert(j);
         assert(mode >= 0);
         assert(mode < _OUTPUT_MODE_MAX);
-        assert(unit);
-
-        if (!endswith(unit, ".service") &&
-            !endswith(unit, ".socket") &&
-            !endswith(unit, ".mount") &&
-            !endswith(unit, ".swap"))
-                return 0;
-
-        if (how_many <= 0)
-                return 0;
-
-        if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 ||
-            asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 ||
-            asprintf(&m3, "UNIT=%s", unit) < 0) {
-                r = -ENOMEM;
-                goto finish;
-        }
-
-        r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY);
-        if (r < 0)
-                goto finish;
-
-        /* Look for messages from the service itself */
-        r = sd_journal_add_match(j, m1, 0);
-        if (r < 0)
-                goto finish;
-
-        /* Look for coredumps of the service */
-        r = sd_journal_add_disjunction(j);
-        if (r < 0)
-                goto finish;
-        r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0);
-        if (r < 0)
-                goto finish;
-        r = sd_journal_add_match(j, m2, 0);
-        if (r < 0)
-                goto finish;
-
-        /* Look for messages from PID 1 about this service */
-        r = sd_journal_add_disjunction(j);
-        if (r < 0)
-                goto finish;
-        r = sd_journal_add_match(j, "_PID=1", 0);
-        if (r < 0)
-                goto finish;
-        r = sd_journal_add_match(j, m3, 0);
-        if (r < 0)
-                goto finish;
 
         /* Seek to end */
         r = sd_journal_seek_tail(j);
@@ -916,6 +866,145 @@ int show_journal_by_unit(
         }
 
 finish:
+        return r;
+}
+
+int show_journal_by_unit(
+                FILE *f,
+                const char *unit,
+                OutputMode mode,
+                unsigned n_columns,
+                usec_t not_before,
+                unsigned how_many,
+                OutputFlags flags) {
+
+        _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL;
+        sd_journal *j = NULL;
+        int r;
+
+        assert(mode >= 0);
+        assert(mode < _OUTPUT_MODE_MAX);
+        assert(unit);
+
+        if (!endswith(unit, ".service") &&
+            !endswith(unit, ".socket") &&
+            !endswith(unit, ".mount") &&
+            !endswith(unit, ".swap"))
+                return 0;
+
+        if (how_many <= 0)
+                return 0;
+
+        if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 ||
+            asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 ||
+            asprintf(&m3, "UNIT=%s", unit) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY);
+        if (r < 0)
+                goto finish;
+
+        /* Look for messages from the service itself */
+        r = sd_journal_add_match(j, m1, 0);
+        if (r < 0)
+                goto finish;
+
+        /* Look for coredumps of the service */
+        r = sd_journal_add_disjunction(j);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m2, 0);
+        if (r < 0)
+                goto finish;
+
+        /* Look for messages from PID 1 about this service */
+        r = sd_journal_add_disjunction(j);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, "_PID=1", 0);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m3, 0);
+        if (r < 0)
+                goto finish;
+
+        r = show_journal(f, j, mode, n_columns, not_before, how_many, flags);
+        if (r < 0)
+                goto finish;
+
+finish:
+        if (j)
+                sd_journal_close(j);
+
+        return r;
+}
+
+int show_journal_by_user_unit(
+                FILE *f,
+                const char *unit,
+                OutputMode mode,
+                unsigned n_columns,
+                usec_t not_before,
+                unsigned how_many,
+                uid_t uid,
+                OutputFlags flags) {
+
+        _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL;
+        sd_journal *j = NULL;
+        int r;
+
+        assert(mode >= 0);
+        assert(mode < _OUTPUT_MODE_MAX);
+        assert(unit);
+
+        if (!endswith(unit, ".service") &&
+            !endswith(unit, ".socket"))
+
+                return 0;
+
+        if (how_many <= 0)
+                return 0;
+
+        if (asprintf(&m1, "_SYSTEMD_USER_UNIT=%s", unit) < 0 ||
+            asprintf(&m2, "USER_UNIT=%s", unit) < 0 ||
+            asprintf(&m3, "_UID=%d", uid) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
+        if (r < 0)
+                goto finish;
+
+        /* Look for messages from the user service itself */
+        r = sd_journal_add_match(j, m1, 0);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m3, 0);
+        if (r < 0)
+                goto finish;
+
+        /* Look for messages from systemd about this service */
+        r = sd_journal_add_disjunction(j);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m2, 0);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m3, 0);
+        if (r < 0)
+                goto finish;
+
+        r = show_journal(f, j, mode, n_columns, not_before, how_many, flags);
+        if (r < 0)
+                goto finish;
+
+finish:
         if (j)
                 sd_journal_close(j);
 
diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h
index 6c32aa7..a835112 100644
--- a/src/shared/logs-show.h
+++ b/src/shared/logs-show.h
@@ -22,6 +22,8 @@
 ***/
 
 #include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
 
 #include <systemd/sd-journal.h>
 
@@ -44,6 +46,16 @@ int show_journal_by_unit(
                 unsigned how_many,
                 OutputFlags flags);
 
+int show_journal_by_user_unit(
+                FILE *f,
+                const char *unit,
+                OutputMode mode,
+                unsigned n_columns,
+                usec_t not_before,
+                unsigned how_many,
+                uid_t uid,
+                OutputFlags flags);
+
 void json_escape(
                 FILE *f,
                 const char* p,

commit bbc9006e6b5665073149331d75c104a33224dc19
Author: Mirco Tischler <mt-ml at gmx.de>
Date:   Thu Jan 17 18:55:06 2013 +0100

    core: log USER_UNIT instead of UNIT if in user session

diff --git a/src/core/execute.c b/src/core/execute.c
index 9718e43..65a10af 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1024,8 +1024,8 @@ int exec_spawn(ExecCommand *command,
 
         r = exec_context_load_environment(context, &files_env);
         if (r < 0) {
-                log_struct(LOG_ERR,
-                           "UNIT=%s", unit_id,
+                log_struct_unit(LOG_ERR,
+                           unit_id,
                            "MESSAGE=Failed to load environment files: %s", strerror(-r),
                            "ERRNO=%d", -r,
                            NULL);
@@ -1039,8 +1039,8 @@ int exec_spawn(ExecCommand *command,
         if (!line)
                 return log_oom();
 
-        log_struct(LOG_DEBUG,
-                   "UNIT=%s", unit_id,
+        log_struct_unit(LOG_DEBUG,
+                   unit_id,
                    "MESSAGE=About to execute %s", line,
                    NULL);
         free(line);
@@ -1512,8 +1512,8 @@ int exec_spawn(ExecCommand *command,
                 _exit(r);
         }
 
-        log_struct(LOG_DEBUG,
-                   "UNIT=%s", unit_id,
+        log_struct_unit(LOG_DEBUG,
+                   unit_id,
                    "MESSAGE=Forked %s as %lu",
                           command->path, (unsigned long) pid,
                    NULL);
diff --git a/src/core/job.c b/src/core/job.c
index 31ab118..e381ea2 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -713,25 +713,25 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
                 sd_id128_t mid;
 
                 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
-                log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                           u->id,
                            MESSAGE_ID(mid),
-                           "UNIT=%s", u->id,
                            "RESULT=%s", job_result_to_string(result),
                            "MESSAGE=%s", buf,
                            NULL);
 
         } else if (t == JOB_STOP)
-                log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                           u->id,
                            MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
-                           "UNIT=%s", u->id,
                            "RESULT=%s", job_result_to_string(result),
                            "MESSAGE=%s", buf,
                            NULL);
 
         else if (t == JOB_RELOAD)
-                log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                           u->id,
                            MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
-                           "UNIT=%s", u->id,
                            "RESULT=%s", job_result_to_string(result),
                            "MESSAGE=%s", buf,
                            NULL);
@@ -818,8 +818,8 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
          * this context. And JOB_FAILURE is already handled by the
          * unit itself. */
         if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
-                log_struct(LOG_NOTICE,
-                           "UNIT=%s", u->id,
+                log_struct_unit(LOG_NOTICE,
+                           u->id,
                            "JOB_TYPE=%s", job_type_to_string(t),
                            "JOB_RESULT=%s", job_result_to_string(result),
                            "Job %s/%s failed with result '%s'.",
diff --git a/src/core/mount.c b/src/core/mount.c
index 25bc7e1..18ce73b 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -955,11 +955,11 @@ fail:
 void warn_if_dir_nonempty(const char *unit, const char* where) {
         if (dir_is_empty(where) > 0)
                 return;
-        log_struct(LOG_NOTICE,
+        log_struct_unit(LOG_NOTICE,
+                   unit,
                    "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
                    unit, where,
                    "WHERE=%s", where,
-                   "_SYSTEMD_UNIT=%s", unit,
                    MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
                    NULL);
 }
diff --git a/src/core/service.c b/src/core/service.c
index 9e46dba..bc41617 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2939,13 +2939,13 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 f = SERVICE_SUCCESS;
                 }
 
-                log_struct(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+                log_struct_unit(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+                           u->id,
                            "MESSAGE=%s: main process exited, code=%s, status=%i/%s",
                                   u->id, sigchld_code_to_string(code), status,
                                   strna(code == CLD_EXITED
                                         ? exit_status_to_string(status, EXIT_STATUS_FULL)
                                         : signal_to_string(status)),
-                           "UNIT=%s", u->id,
                            "EXIT_CODE=%s", sigchld_code_to_string(code),
                            "EXIT_STATUS=%i", status,
                            NULL);
diff --git a/src/core/unit.c b/src/core/unit.c
index d26f6e4..83359e1 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1022,9 +1022,9 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
               t == JOB_STOP  ? SD_MESSAGE_UNIT_STOPPING :
                                SD_MESSAGE_UNIT_RELOADING;
 
-        log_struct(LOG_INFO,
+        log_struct_unit(LOG_INFO,
+                   u->id,
                    MESSAGE_ID(mid),
-                   "UNIT=%s", u->id,
                    "MESSAGE=%s", buf,
                    NULL);
 }
@@ -1438,9 +1438,9 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
                         check_unneeded_dependencies(u);
 
                 if (ns != os && ns == UNIT_FAILED) {
-                        log_struct(LOG_NOTICE,
+                        log_struct_unit(LOG_NOTICE,
+                                   u->id,
                                    "MESSAGE=Unit %s entered failed state", u->id,
-                                   "UNIT=%s", u->id,
                                    NULL);
                         unit_trigger_on_failure(u);
                 }
diff --git a/src/core/unit.h b/src/core/unit.h
index d1ecae7..23cd9ef 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -23,6 +23,7 @@
 
 #include <stdbool.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 typedef struct Unit Unit;
 typedef struct UnitVTable UnitVTable;
@@ -556,9 +557,11 @@ UnitActiveState unit_active_state_from_string(const char *s);
 const char *unit_dependency_to_string(UnitDependency i);
 UnitDependency unit_dependency_from_string(const char *s);
 
-#define log_full_unit(level, unit, ...) log_meta_object(level,   __FILE__, __LINE__, __func__, "UNIT=", unit, __VA_ARGS__)
+#define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__)
 #define log_debug_unit(unit, ...)       log_full_unit(LOG_DEBUG, unit, __VA_ARGS__)
 #define log_info_unit(unit, ...)        log_full_unit(LOG_INFO, unit, __VA_ARGS__)
 #define log_notice_unit(unit, ...)      log_full_unit(LOG_NOTICE, unit, __VA_ARGS__)
 #define log_warning_unit(unit, ...)     log_full_unit(LOG_WARNING, unit, __VA_ARGS__)
 #define log_error_unit(unit, ...)       log_full_unit(LOG_ERR, unit, __VA_ARGS__)
+
+#define log_struct_unit(level, unit, ...) log_struct(level, getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit, __VA_ARGS__)

commit ef1673d16907726d83bdff2e57b5261997a85020
Author: Mirco Tischler <mt-ml at gmx.de>
Date:   Thu Jan 17 18:55:05 2013 +0100

    journal: log _SYSTEMD_USER_UNIT for user session units

diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index ec9be65..12a46e6 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -601,8 +601,15 @@ static void dispatch_message_real(
                 if (cg_pid_get_unit(ucred->pid, &t) >= 0) {
                         unit = strappend("_SYSTEMD_UNIT=", t);
                         free(t);
-                } else if (unit_id)
-                        unit = strappend("_SYSTEMD_UNIT=", unit_id);
+                } else if (cg_pid_get_user_unit(ucred->pid, &t) >= 0) {
+                        unit = strappend("_SYSTEMD_USER_UNIT=", t);
+                        free(t);
+                } else if (unit_id) {
+                        if (session)
+                                unit = strappend("_SYSTEMD_USER_UNIT=", unit_id);
+                        else
+                                unit = strappend("_SYSTEMD_UNIT=", unit_id);
+                }
 
                 if (unit)
                         IOVEC_SET_STRING(iovec[n++], unit);
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 9dfab2e..3d12233 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;
@@ -1210,11 +1211,76 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
         return 0;
 }
 
-int cg_pid_get_unit(pid_t pid, char **unit) {
+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;
+}
+
+static int cgroup_to_unit(char *cgroup, char **unit){
         int r;
-        char *cgroup, *p, *at, *b;
+        char *b, *p;
         size_t k;
 
+        assert(cgroup);
+        assert(unit);
+
+        r = instance_unit_from_cgroup(&cgroup);
+        if (r < 0)
+                return r;
+
+        p = strrchr(cgroup, '/') + 1;
+        k = strlen(p);
+
+        b = strndup(p, k);
+
+        if (!b)
+                return -ENOMEM;
+
+        r = unit_name_is_valid(b, true);
+        if (!r) {
+                free(b);
+                return -ENOENT;
+        }
+
+        *unit = b;
+
+        return 0;
+}
+
+int cg_pid_get_unit(pid_t pid, char **unit) {
+        int r;
+        char *cgroup;
+
         assert(pid >= 0);
         assert(unit);
 
@@ -1227,38 +1293,40 @@ int cg_pid_get_unit(pid_t pid, char **unit) {
                 return -ENOENT;
         }
 
-        p = cgroup + 8;
-        k = strcspn(p, "/");
+        r = cgroup_to_unit(cgroup, unit);
+        if (r < 0){
+                free(cgroup);
+                return r;
+        }
 
-        at = memchr(p, '@', k);
-        if (at && at[1] == '.') {
-                size_t j;
+        free(cgroup);
 
-                /* This is a templated service */
-                if (p[k] != '/') {
-                        free(cgroup);
-                        return -EIO;
-                }
+        return 0;
+}
 
-                j = strcspn(p+k+1, "/");
+int cg_pid_get_user_unit(pid_t pid, char **unit) {
+        int r;
+        char *cgroup;
 
-                b = malloc(k + j + 1);
+        assert(pid >= 0);
+        assert(unit);
 
-                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);
+        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
+        if (r < 0)
+                return r;
 
-        free(cgroup);
+        if (!startswith(cgroup, "/user/")) {
+                free(cgroup);
+                return -ENOENT;
+        }
 
-        if (!b)
-                return -ENOMEM;
+        r = cgroup_to_unit(cgroup, unit);
+        if (r < 0) {
+                free(cgroup);
+                return r;
+        }
 
-        *unit = b;
-        return 0;
+        free(cgroup);
 
+        return 0;
 }
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index f663fba..2429ba2 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -71,5 +71,6 @@ int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_
 int cg_get_user_path(char **path);
 int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup);
 int cg_pid_get_unit(pid_t pid, char **unit);
+int cg_pid_get_user_unit(pid_t pid, char **unit);
 
 char **cg_shorten_controllers(char **controllers);



More information about the systemd-commits mailing list