core: postpone dbus queue dispatch while API bus setup is pending (#43200)

Since 1166f4472d the API bus setup
and the subscriber coldplug happen only once the asynchronous GetId
reply is processed by the event loop. After a daemon-reexec,
manager_dispatch_dbus_queue() runs before subscribers were registered
and consumed send_reloading_done, so the one-shot Reloading(false)
signal was never sent.

Clients that wait for this signal to detect that a reexec finished time out.

Track the pending setup and hold the flag until the reply handler has
re-added the subscriptions.

Also affects v261.2 via backport 26f3717e27f6f08347adf851c605d5fe1f52ac57.
This commit is contained in:
Yu Watanabe
2026-07-29 20:38:21 +09:00
committed by GitHub
4 changed files with 90 additions and 0 deletions
+4
View File
@@ -812,6 +812,8 @@ static int bus_setup_api(Manager *m, sd_bus *bus) {
if (r < 0)
log_warning_errno(r, "Failed to register MemoryAllocation1, ignoring: %m");
m->api_bus_ready = true;
log_debug("Successfully connected to API bus.");
return 0;
@@ -1104,6 +1106,8 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
void bus_done_api(Manager *m) {
destroy_bus(m, &m->api_bus);
m->api_bus_ready = false;
}
void bus_done_system(Manager *m) {
+8
View File
@@ -2892,6 +2892,14 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
assert(m);
/* If the API bus is connected but not fully set up yet (see bus_init_api()), postpone
* dispatching the queue, otherwise subscribers restored from a previous reexec would miss
* messages. The pending Varlink reload reply does not depend on the API bus, but it is held
* back too, so that the order between D-Bus messages and Varlink replies is preserved for
* clients that monitor both. */
if (m->api_bus && !m->api_bus_ready)
return 0;
/* When we are reloading, let's not wait with generating signals, since we need to exit the manager as quickly
* as we can. There's no point in throttling generation of signals in that case. */
if (MANAGER_IS_RELOADING(m) || m->send_reloading_done || m->pending_reload_message_dbus || m->pending_reload_message_vl)
+5
View File
@@ -341,6 +341,11 @@ typedef struct Manager {
sd_bus_track *subscribed;
char **subscribed_as_strv;
/* Set once bus_setup_api() succeeded for the current API bus connection, i.e. after any
* subscriptions deserialized from a previous reload/reexec were coldplugged. Unset when the
* connection is torn down. */
bool api_bus_ready;
/* The bus id of API bus acquired through org.freedesktop.DBus.GetId, which before deserializing
* subscriptions we'd use to verify the bus is still the same instance as before. */
sd_id128_t bus_id, deserialized_bus_id;