1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-27 18:55:40 +03:00

core/unit: increase the NameOwnerChanged/GetNameOwner timeout to the unit's start timeout

When dbus is overloaded, these messages are easily timedout,
systemd may kill dbus-type service by mistake. This PR
mitigates this problem by increasing the timeout to the
unit's start timeout.
This commit is contained in:
licunlong 2023-05-24 11:45:31 +08:00
parent f5a9d2ee2a
commit 8df433d7cd

View File

@ -14,6 +14,7 @@
#include "bpf-foreign.h" #include "bpf-foreign.h"
#include "bpf-socket-bind.h" #include "bpf-socket-bind.h"
#include "bus-common-errors.h" #include "bus-common-errors.h"
#include "bus-internal.h"
#include "bus-util.h" #include "bus-util.h"
#include "cgroup-setup.h" #include "cgroup-setup.h"
#include "cgroup-util.h" #include "cgroup-util.h"
@ -3612,7 +3613,9 @@ static int get_name_owner_handler(sd_bus_message *message, void *userdata, sd_bu
} }
int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) { int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
const char *match; const char *match;
usec_t timeout_usec = 0;
int r; int r;
assert(u); assert(u);
@ -3622,6 +3625,12 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
if (u->match_bus_slot || u->get_name_owner_slot) if (u->match_bus_slot || u->get_name_owner_slot)
return -EBUSY; return -EBUSY;
/* NameOwnerChanged and GetNameOwner is used to detect when a service finished starting up. The dbus
* call timeout shouldn't be earlier than that. If we couldn't get the start timeout, use the default
* value defined above. */
if (UNIT_VTABLE(u)->get_timeout_start_usec)
timeout_usec = UNIT_VTABLE(u)->get_timeout_start_usec(u);
match = strjoina("type='signal'," match = strjoina("type='signal',"
"sender='org.freedesktop.DBus'," "sender='org.freedesktop.DBus',"
"path='/org/freedesktop/DBus'," "path='/org/freedesktop/DBus',"
@ -3629,20 +3638,40 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
"member='NameOwnerChanged'," "member='NameOwnerChanged',"
"arg0='", name, "'"); "arg0='", name, "'");
r = sd_bus_add_match_async(bus, &u->match_bus_slot, match, signal_name_owner_changed, NULL, u); r = bus_add_match_full(
bus,
&u->match_bus_slot,
true,
match,
signal_name_owner_changed,
NULL,
u,
timeout_usec);
if (r < 0) if (r < 0)
return r; return r;
r = sd_bus_call_method_async( r = sd_bus_message_new_method_call(
bus, bus,
&u->get_name_owner_slot, &m,
"org.freedesktop.DBus", "org.freedesktop.DBus",
"/org/freedesktop/DBus", "/org/freedesktop/DBus",
"org.freedesktop.DBus", "org.freedesktop.DBus",
"GetNameOwner", "GetNameOwner");
if (r < 0)
return r;
r = sd_bus_message_append(m, "s", name);
if (r < 0)
return r;
r = sd_bus_call_async(
bus,
&u->get_name_owner_slot,
m,
get_name_owner_handler, get_name_owner_handler,
u, u,
"s", name); timeout_usec);
if (r < 0) { if (r < 0) {
u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
return r; return r;