]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: do not disconnect from bus when failed to install signal match
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 29 Dec 2024 06:50:43 +0000 (15:50 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 9 Oct 2025 11:22:30 +0000 (13:22 +0200)
If bus_add_match_full() is called without install callback and we failed
to install the signal match e.g. by timeout, then add_match_callback()
will disconnect from the bus.
Let's use a custom install handler and handle failures gracefully.

This does not *solve* the root cause of issue #30573, but should improve
the situation when the issue is triggered.

(cherry picked from commit db6b214f95aa42f9a9fa3d94a3c6492cc57b58fb)

src/core/unit.c

index 5cf052d4d0a507e960d8cf6e9386973659a0a9eb..a762e131d24db96dd52a4f9d9002f0748fb7e7a0 100644 (file)
@@ -3521,6 +3521,32 @@ int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
         return r;
 }
 
+static int signal_name_owner_changed_install_handler(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Unit *u = ASSERT_PTR(userdata);
+        const sd_bus_error *e;
+        int r;
+
+        e = sd_bus_message_get_error(message);
+        if (!e) {
+                log_unit_trace(u, "Successfully installed NameOwnerChanged signal match.");
+                return 0;
+        }
+
+        r = sd_bus_error_get_errno(e);
+        log_unit_error_errno(u, r,
+                             "Unexpected error response on installing NameOwnerChanged signal match: %s",
+                             bus_error_message(e, r));
+
+        /* If we failed to install NameOwnerChanged signal, also unref the bus slot of GetNameOwner(). */
+        u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
+        u->get_name_owner_slot = sd_bus_slot_unref(u->get_name_owner_slot);
+
+        if (UNIT_VTABLE(u)->bus_name_owner_change)
+                UNIT_VTABLE(u)->bus_name_owner_change(u, NULL);
+
+        return 0;
+}
+
 static int signal_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         const char *new_owner;
         Unit *u = ASSERT_PTR(userdata);
@@ -3603,10 +3629,10 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
         r = bus_add_match_full(
                         bus,
                         &u->match_bus_slot,
-                        true,
+                        /* asynchronous = */ true,
                         match,
                         signal_name_owner_changed,
-                        NULL,
+                        signal_name_owner_changed_install_handler,
                         u,
                         timeout_usec);
         if (r < 0)