diff --git a/src/core/dbus.c b/src/core/dbus.c index 3f0f40e702b..df0979756b4 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -860,6 +860,10 @@ int bus_init_api(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to set up API bus: %m"); + r = bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->deserialized_subscribed); + if (r < 0) + return r; + m->deserialized_subscribed = strv_free(m->deserialized_subscribed); m->api_bus = TAKE_PTR(bus); return 0; @@ -1004,8 +1008,19 @@ static void destroy_bus(Manager *m, sd_bus **bus) { } /* Get rid of tracked clients on this bus */ - if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus) + if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus) { + _cleanup_strv_free_ char **subscribed = NULL; + int r; + + r = bus_track_to_strv(m->subscribed, &subscribed); + if (r < 0) + log_error_errno(r, "Failed to serialize api subscribers: %m"); + r = strv_extend_strv_consume(&m->deserialized_subscribed, TAKE_PTR(subscribed), /* filter_duplicates = */ false); + if (r < 0) + log_error_errno(r, "Failed to record api subscribers: %m"); + m->subscribed = sd_bus_track_unref(m->subscribed); + } HASHMAP_FOREACH(j, m->jobs) if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus) @@ -1064,7 +1079,6 @@ void bus_done(Manager *m) { assert(!m->subscribed); - m->deserialized_subscribed = strv_free(m->deserialized_subscribed); m->polkit_registry = hashmap_free(m->polkit_registry); } @@ -1153,20 +1167,19 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) { } } -int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) { +int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l) { int r; - assert(m); assert(t); if (strv_isempty(l)) return 0; - if (!m->api_bus) + if (!bus) return 0; if (!*t) { - r = sd_bus_track_new(m->api_bus, t, NULL, NULL); + r = sd_bus_track_new(bus, t, NULL, NULL); if (r < 0) return r; } diff --git a/src/core/dbus.h b/src/core/dbus.h index d00c14d3b72..eb1baf60493 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -19,7 +19,7 @@ void bus_done(Manager *m); int bus_fdset_add_all(Manager *m, FDSet *fds); void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix); -int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l); +int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l); int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata); diff --git a/src/core/manager.c b/src/core/manager.c index f21a4f7ceb8..8fb52666c0f 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1803,6 +1803,9 @@ Manager* manager_free(Manager *m) { free(m->switch_root); free(m->switch_root_init); + sd_bus_track_unref(m->subscribed); + strv_free(m->deserialized_subscribed); + unit_defaults_done(&m->defaults); FOREACH_ARRAY(map, m->units_needing_mounts_for, _UNIT_MOUNT_DEPENDENCY_TYPE_MAX) { @@ -2139,7 +2142,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo manager_setup_bus(m); /* Now that we are connected to all possible buses, let's deserialize who is tracking us. */ - r = bus_track_coldplug(m, &m->subscribed, false, m->deserialized_subscribed); + r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->deserialized_subscribed); if (r < 0) log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m"); m->deserialized_subscribed = strv_free(m->deserialized_subscribed); @@ -3813,9 +3816,6 @@ int manager_reload(Manager *m) { /* Clean up runtime objects no longer referenced */ manager_vacuum(m); - /* Clean up deserialized tracked clients */ - m->deserialized_subscribed = strv_free(m->deserialized_subscribed); - /* Consider the reload process complete now. */ assert(m->n_reloading > 0); m->n_reloading--; diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 8313dfdd14e..f6d88564b6c 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -698,6 +698,28 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) { return r; } +int bus_track_to_strv(sd_bus_track *t, char ***ret) { + _cleanup_strv_free_ char **subscribed = NULL; + int r = 0; + + assert(ret); + + for (const char *n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) { + r = sd_bus_track_count_name(t, n); + if (r < 0) + return r; + + for (int j = 0; j < r; j++) { + r = strv_extend(&subscribed, n); + if (r < 0) + return r; + } + } + + *ret = TAKE_PTR(subscribed); + return r; +} + int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description) { _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL; const char *e; diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index e1908ecbaaf..95b9adb7b1b 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -66,6 +66,7 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external); int bus_track_add_name_many(sd_bus_track *t, char **l); +int bus_track_to_strv(sd_bus_track *t, char ***ret); int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description); static inline int bus_open_system_watch_bind(sd_bus **ret) {