181 lines
6.8 KiB
Diff
181 lines
6.8 KiB
Diff
From 1cbaa08036631f3e633700134cd57d994a4b234c 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)
|
|
|
|
Related: RHEL-111629
|
|
---
|
|
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 1431e079c2..12a6f2fa27 100644
|
|
--- a/src/core/dbus.c
|
|
+++ b/src/core/dbus.c
|
|
@@ -834,6 +834,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;
|
|
@@ -986,8 +988,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)
|
|
@@ -1046,7 +1057,6 @@ void bus_done(Manager *m) {
|
|
|
|
assert(!m->subscribed);
|
|
|
|
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
|
bus_verify_polkit_async_registry_free(m->polkit_registry);
|
|
}
|
|
|
|
@@ -1137,20 +1147,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 50e7bb400e..3f0d902c89 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 daeaa641d7..6c67780c99 100644
|
|
--- a/src/core/manager.c
|
|
+++ b/src/core/manager.c
|
|
@@ -1560,6 +1560,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);
|
|
+
|
|
free(m->default_smack_process_label);
|
|
|
|
rlimit_free_all(m->rlimit);
|
|
@@ -1862,7 +1865,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);
|
|
@@ -3412,9 +3415,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 d09ec5148d..9293f10fdc 100644
|
|
--- a/src/shared/bus-util.c
|
|
+++ b/src/shared/bus-util.c
|
|
@@ -495,6 +495,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 955cdcb57c..e1fdf2ef48 100644
|
|
--- a/src/shared/bus-util.h
|
|
+++ b/src/shared/bus-util.h
|
|
@@ -52,6 +52,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) {
|