]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: serialize API bus id and validate before deserializing bus tracks
authorMike Yuan <me@yhndnzj.com>
Mon, 13 Jan 2025 16:06:35 +0000 (17:06 +0100)
committerMike Yuan <me@yhndnzj.com>
Mon, 13 Jan 2025 20:52:19 +0000 (21:52 +0100)
TODO
src/core/dbus.c
src/core/dbus.h
src/core/manager-serialize.c
src/core/manager.h
src/shared/bus-util.c
src/shared/bus-util.h

diff --git a/TODO b/TODO
index c796b3e1011f4e1415494dabe2249c63f0842bcb..fdd119434e002a5655d4dfd38576b9ecaff4a35f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -131,11 +131,6 @@ Features:
 * in pid1: include ExecStart= cmdlines (and other Exec*= cmdlines) in polkit
   request, so that policies can match against command lines.
 
-* in pid1: before processing subscribed_as_strv when we come back from a
-  bus disconnect, let's check the bus 128bit id reported by the bus driver: if
-  it doesn't equal the one from before we should skip reinstalling the bus
-  tracker objects.
-
 * account number of units currently in activating/active/deactivating state in
   each slice, and expose this as a property of the slice, given this is a key
   metric of the resource management entity that a slice is. (maybe add a 2nd
index 58cd1ee175b05cd95e2282a26394887994a903ea..a2a2611a03ea73216a8f8afcf6647d4beb301cc6 100644 (file)
@@ -5,6 +5,7 @@
 #include <unistd.h>
 
 #include "sd-bus.h"
+#include "sd-id128.h"
 
 #include "alloc-util.h"
 #include "bus-common-errors.h"
@@ -774,6 +775,24 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
         return 0;
 }
 
+static int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, char * const *l) {
+        int r;
+
+        assert(bus);
+        assert(t);
+
+        if (strv_isempty(l))
+                return 0;
+
+        if (!*t) {
+                r = sd_bus_track_new(bus, t, NULL, NULL);
+                if (r < 0)
+                        return r;
+        }
+
+        return bus_track_add_name_many(*t, l);
+}
+
 static int bus_setup_api(Manager *m, sd_bus *bus) {
         char *name;
         Unit *u;
@@ -860,10 +879,15 @@ 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->subscribed_as_strv);
+        r = bus_get_instance_id(bus, &m->bus_id);
+        if (r < 0)
+                log_warning_errno(r, "Failed to query API bus instance ID, not deserializing subscriptions: %m");
+        else if (sd_id128_is_null(m->deserialized_bus_id) || sd_id128_equal(m->bus_id, m->deserialized_bus_id))
+                (void) bus_track_coldplug(bus, &m->subscribed, m->subscribed_as_strv);
         m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
-        m->api_bus = TAKE_PTR(bus);
+        m->deserialized_bus_id = SD_ID128_NULL;
 
+        m->api_bus = TAKE_PTR(bus);
         return 0;
 }
 
@@ -1015,6 +1039,9 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
                         log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
                 strv_free_and_replace(m->subscribed_as_strv, subscribed);
 
+                m->deserialized_bus_id = m->bus_id;
+                m->bus_id = SD_ID128_NULL;
+
                 m->subscribed = sd_bus_track_unref(m->subscribed);
         }
 
@@ -1163,30 +1190,6 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
         }
 }
 
-int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l) {
-        int r;
-
-        assert(t);
-
-        if (strv_isempty(l))
-                return 0;
-
-        if (!bus)
-                return 0;
-
-        if (!*t) {
-                r = sd_bus_track_new(bus, t, NULL, NULL);
-                if (r < 0)
-                        return r;
-        }
-
-        r = sd_bus_track_set_recursive(*t, recursive);
-        if (r < 0)
-                return r;
-
-        return bus_track_add_name_many(*t, l);
-}
-
 uint64_t manager_bus_n_queued_write(Manager *m) {
         uint64_t c = 0;
         sd_bus *b;
index eb1baf604935695cedb47037fc7632762f2efedc..0f81102fc133d4e7082b46aab51554fef80c6272 100644 (file)
@@ -19,7 +19,6 @@ 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(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);
 
index 4aecb6de2f62e00486cca5b3359f58d784660071..fbc1475bcf5c27d5f6a886d92d4520b22a715373 100644 (file)
@@ -158,6 +158,7 @@ int manager_serialize(
         (void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit);
         (void) serialize_ratelimit(f, "reload-reexec-ratelimit", &m->reload_reexec_ratelimit);
 
+        (void) serialize_id128(f, "bus-id", m->bus_id);
         bus_track_serialize(m->subscribed, f, "subscribed");
 
         r = dynamic_user_serialize(m, f, fds);
@@ -487,7 +488,12 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         manager_deserialize_gid_refs_one(m, val);
                 else if ((val = startswith(l, "exec-runtime=")))
                         (void) exec_shared_runtime_deserialize_one(m, val, fds);
-                else if ((val = startswith(l, "subscribed="))) {
+                else if ((val = startswith(l, "bus-id="))) {
+
+                        r = sd_id128_from_string(val, &m->deserialized_bus_id);
+                        if (r < 0)
+                                return r;
+                } else if ((val = startswith(l, "subscribed="))) {
 
                         r = strv_extend(&m->subscribed_as_strv, val);
                         if (r < 0)
index 7016eab2d3be2c1aee7c7411439f159ed4d8c1f8..c5bd242968a40d3aa9acc27d57e1a69ddf6f2336 100644 (file)
@@ -335,13 +335,16 @@ struct Manager {
         int private_listen_fd;
         sd_event_source *private_listen_event_source;
 
-        /* Contains all the clients that are subscribed to signals via
-        the API bus. Note that private bus connections are always
-        considered subscribes, since they last for very short only,
-        and it is much simpler that way. */
+        /* Contains all the clients that are subscribed to signals via the API bus. Note that private bus
+         * connections are always considered subscribes, since they last for very short only, and it is
+         * much simpler that way. */
         sd_bus_track *subscribed;
         char **subscribed_as_strv;
 
+        /* 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;
+
         /* This is used during reloading: before the reload we queue
          * the reply message here, and afterwards we send it */
         sd_bus_message *pending_reload_message;
index 0a887aec7929653433f6437a25b5aa6e0b389a43..05926771d26418dc21a214406a5957db74e3d445 100644 (file)
@@ -686,7 +686,7 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send
         return 1;
 }
 
-int bus_track_add_name_many(sd_bus_track *t, char **l) {
+int bus_track_add_name_many(sd_bus_track *t, char * const *l) {
         int r = 0;
 
         assert(t);
index 5fb4bcca9faaad8e06f9325c918b3dccf24da357..63c3ba5ee3b4985c580fce536ab61bc65cc415cf 100644 (file)
@@ -65,7 +65,7 @@ static inline int bus_log_connect_error(int r, BusTransport transport, RuntimeSc
 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
 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_add_name_many(sd_bus_track *t, char * const *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);