1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +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-socket-bind.h"
#include "bus-common-errors.h"
#include "bus-internal.h"
#include "bus-util.h"
#include "cgroup-setup.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) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
const char *match;
usec_t timeout_usec = 0;
int r;
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)
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',"
"sender='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',"
"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)
return r;
r = sd_bus_call_method_async(
r = sd_bus_message_new_method_call(
bus,
&u->get_name_owner_slot,
&m,
"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,
u,
"s", name);
timeout_usec);
if (r < 0) {
u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
return r;