core: do not disconnect from bus when failed to install signal match (#35779)
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 https://github.com/systemd/systemd/issues/30573, but should improve the situation when the issue is triggered.
This commit is contained in:
+28
-3
@@ -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)
|
||||
@@ -3623,7 +3649,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;
|
||||
|
||||
@@ -3616,7 +3616,6 @@ int bus_add_match_full(
|
||||
add_match_callback,
|
||||
s,
|
||||
timeout_usec);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user