systemctl: subscribe to signals in is-system-running --wait

"systemctl is-system-running --wait" installs a match rule for the
StartupFinished signal, but never calls the manager's Subscribe()
method. PID 1 broadcasts manager signals unconditionally only on direct
(private) bus connections; on the API bus it emits them only while at
least one client is subscribed (see bus_foreach_bus()).

When run as non-root, systemctl talks to PID 1 via the system bus and
only receives StartupFinished if some unrelated client happens to be
subscribed at that moment. Otherwise it keeps waiting after boot has
completed, even though the system state is already "running" or
"degraded".

Call Subscribe() after installing the match and before querying the
current state, so the signal cannot be missed in between. This is a
no-op on direct connections, and the subscription is dropped
automatically when the connection closes.

Fixes: #44150
(cherry picked from commit 9ac5e0b4ee9e87d9ce671a70354dbab2b06c254b)
This commit is contained in:
Alexandru N. Onea
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent 37db22d38b
commit aa1ca34586
+25 -1
View File
@@ -55,8 +55,32 @@ int verb_is_system_running(int argc, char *argv[], uintptr_t _data, void *userda
"StartupFinished",
match_startup_finished, NULL, &state);
if (r < 0) {
log_warning_errno(r, "Failed to request match for StartupFinished: %m");
log_warning_errno(
r,
"Failed to acquire match for StartupFinished, "
"will not wait for startup completion: %m");
arg_wait = false;
} else {
/* On the API bus PID 1 only emits manager signals while at least one client is
* subscribed, so subscribe explicitly. This is a NOP on direct connections, which
* receive signals unconditionally. Do this before querying the state below so that
* we cannot miss StartupFinished in between. */
r = bus_call_method(
bus,
bus_systemd_mgr,
"Subscribe",
&error,
/* ret_reply= */ NULL,
/* types= */ NULL);
if (r < 0) {
log_warning_errno(
r,
"Failed to enable service manager subscription, "
"will not wait for startup completion: %s",
bus_error_message(&error, r));
sd_bus_error_free(&error);
arg_wait = false;
}
}
}