From 7baf4d234a70f136014f9e92f00c078a55c7adba Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 29 Dec 2024 15:10:53 +0900 Subject: [PATCH 1/2] core,sd-bus: drop empty lines between function call and error check --- src/core/unit.c | 1 - src/libsystemd/sd-bus/sd-bus.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 0d88f4f641..97f2eed6e3 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3623,7 +3623,6 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) { get_name_owner_handler, u, timeout_usec); - if (r < 0) { u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); return r; diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 2683959db5..699761fc31 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -3616,7 +3616,6 @@ int bus_add_match_full( add_match_callback, s, timeout_usec); - if (r < 0) return r; From db6b214f95aa42f9a9fa3d94a3c6492cc57b58fb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 29 Dec 2024 15:50:43 +0900 Subject: [PATCH 2/2] core: do not disconnect from bus when failed to install signal match 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. --- src/core/unit.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 97f2eed6e3..99e36fe455 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3511,6 +3511,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); @@ -3593,10 +3619,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)