]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald: correctly attribute log messages also with cgroupsv1
authorMichal Sekletar <msekleta@redhat.com>
Fri, 14 Dec 2018 14:17:27 +0000 (15:17 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Dec 2018 14:16:11 +0000 (15:16 +0100)
With cgroupsv1 a zombie process is migrated to root cgroup in all
hierarchies. This was changed for unified hierarchy and /proc/PID/cgroup
reports cgroup to which process belonged before it exited.

Be more suspicious about cgroup path reported by the kernel and use
unit_id provided by the log client if the kernel reports that process is
running in the root cgroup.

Users tend to care the most about 'log->unit_id' mapping so systemctl
status can correctly report last log lines. Also we wouldn't be able to
infer anything useful from "/" path anyway.

See: https://github.com/torvalds/linux/commit/2e91fa7f6d451e3ea9fec999065d2fd199691f9d

src/journal/journald-context.c

index 1f1603b3767f9b2cb8897ba7c34743cc8ae1611e..8253a45128c6a29e61424153700f75d1ce99b0a5 100644 (file)
@@ -14,6 +14,7 @@
 #include "journal-util.h"
 #include "journald-context.h"
 #include "parse-util.h"
+#include "path-util.h"
 #include "process-util.h"
 #include "string-util.h"
 #include "syslog-util.h"
@@ -252,9 +253,11 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
 
         /* Try to acquire the current cgroup path */
         r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t);
-        if (r < 0) {
+        if (r < 0 || empty_or_root(t)) {
 
-                /* If that didn't work, we use the unit ID passed in as fallback, if we have nothing cached yet */
+                /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted()
+                 * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup
+                 * on cgroupsv1 and we want to be able to map log messages from them too. */
                 if (unit_id && !c->unit) {
                         c->unit = strdup(unit_id);
                         if (c->unit)