]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/unit: increase the NameOwnerChanged/GetNameOwner timeout to the unit's start... 27927/head
authorlicunlong <licunlong1@huawei.com>
Wed, 24 May 2023 03:45:31 +0000 (11:45 +0800)
committerlicunlong <licunlong1@huawei.com>
Fri, 16 Jun 2023 01:19:36 +0000 (09:19 +0800)
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.

src/core/unit.c

index 7b6d50e0eaf554628091f25d3db91cfe4bce882c..df97526e02e17d571c47b8543098831be05c91b7 100644 (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;