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.

(cherry picked from commit 44a9316bf49967164567a7c716b79af7edf53d03)
This commit is contained in:
Lennart Poettering
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent cb2f3814bb
commit 9752a9ef8f
+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: