journald: refresh cached client context if stream's unit doesn't match

On kernels lacking CLONE_INTO_CGROUP sd-executor is forked into the
service manager's cgroup, logs a few messages from there, and only then
attaches itself to the unit's cgroup and connects stdout/stderr to
journald. Since we cache client metadata per PID and only refresh it
after 1s, log output on such a stream was attributed to init.scope
rather than to the unit, and hence "journalctl -u" (and thus
"systemd-run -v", "systemctl -v start", "systemctl -v wait") would not
show it.

Hence, if a stream tells us the unit it belongs to, and that doesn't
match what we have cached, refresh the cached data.
This commit is contained in:
Lennart Poettering committed 2026-09-26 01:26:55 +02:00
1 parent 0e51517319
commit 44a9316bf4
1 file changed
+8
+8
View File
@@ -600,6 +600,14 @@ void client_context_maybe_refresh(
if (label && !streq_ptr(label, c->label))
goto refresh;
/* If the unit the caller told us about (i.e. the one a stdout stream was opened for) doesn't match
* the cached data, then the process likely was moved to a different cgroup since we cached it. This
* happens in particular for sd-executor on kernels lacking CLONE_INTO_CGROUP: it logs a few messages
* while still in the service manager's cgroup, and then attaches itself to the unit's cgroup before
* connecting stdout/stderr to us. */
if (unit_id && !streq_ptr(unit_id, c->unit) && !streq_ptr(unit_id, c->user_unit))
goto refresh;
return;
refresh: