181 lines
6.9 KiB
Diff
181 lines
6.9 KiB
Diff
From f4d3078bd16a814364e653c1e1c2e53af301f0e7 Mon Sep 17 00:00:00 2001
|
|
From: Ronan Pigott <ronan@rjp.ie>
|
|
Date: Thu, 28 Nov 2024 12:53:32 -0700
|
|
Subject: [PATCH] dbus: stash the subscriber list when we disconenct from the
|
|
bus
|
|
|
|
If we unexpectly disconnect from the bus, systemd would end up dropping
|
|
the list of subscribers, which breaks the ability of clients like logind
|
|
to monitor the state of units.
|
|
|
|
Stash the list of subscribers into the deserialized state in the event
|
|
of a disconnect so that when we recover we can renew the broken
|
|
subscriptions.
|
|
|
|
(cherry picked from commit 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98)
|
|
|
|
Resolves: RHEL-73780
|
|
---
|
|
src/core/dbus.c | 21 +++++++++++++++------
|
|
src/core/dbus.h | 2 +-
|
|
src/core/manager.c | 8 ++++----
|
|
src/shared/bus-util.c | 22 ++++++++++++++++++++++
|
|
src/shared/bus-util.h | 1 +
|
|
5 files changed, 43 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/src/core/dbus.c b/src/core/dbus.c
|
|
index 3f0f40e702..9abc35888d 100644
|
|
--- a/src/core/dbus.c
|
|
+++ b/src/core/dbus.c
|
|
@@ -860,6 +860,8 @@ int bus_init_api(Manager *m) {
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to set up API bus: %m");
|
|
|
|
+ (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->deserialized_subscribed);
|
|
+ m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
|
m->api_bus = TAKE_PTR(bus);
|
|
|
|
return 0;
|
|
@@ -1004,8 +1006,17 @@ 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_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
|
|
+ strv_free_and_replace(m->deserialized_subscribed, subscribed);
|
|
+
|
|
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 +1075,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 +1163,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 d00c14d3b7..eb1baf6049 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 485fdd1a66..068ea2ab03 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 ff80e580fc..2cdde97b78 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 fbccb24314..83522ad1c1 100644
|
|
--- a/src/shared/bus-util.h
|
|
+++ b/src/shared/bus-util.h
|
|
@@ -63,6 +63,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) {
|