]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: make BUS_DEFAULT_TIMEOUT configurable
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 13 Jul 2018 08:38:47 +0000 (17:38 +0900)
committerLennart Poettering <lennart@poettering.net>
Mon, 16 Jul 2018 13:11:50 +0000 (15:11 +0200)
This adds sd_bus_{get,set}_method_call_timeout().
If the timeout is not set or set to 0, then the timeout value is
parsed from $SYSTEMD_BUS_TIMEOUT= environment variable. If the
environment variable is not set, then built-in timeout is used.

doc/ENVIRONMENT.md
src/libsystemd/libsystemd.sym
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/sd-bus.c
src/systemd/sd-bus.h

index 85d26fe28c9ee9170599f7513b2064ccb083a0e8..641a03d5d722240c13872d0cae1b83d7b88dfa06 100644 (file)
@@ -37,6 +37,11 @@ All tools:
   useful for debugging, in order to test generators and other code against
   specific kernel command lines.
 
+* `$SYSTEMD_BUS_TIMEOUT=SECS` — specifies the maximum time to wait for method call
+  completion. If no time unit is specified, assumes seconds. The usual other units
+  are understood, too (us, ms, s, min, h, d, w, month, y). If it is not set or set
+  to 0, then the built-in default is used.
+
 systemctl:
 
 * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus
index 969a86a0e95cc9780c98fa113c6979861a1a4982..2f1a5bae3b4c7ec852ce31b1d6b5de96cdc46227 100644 (file)
@@ -573,4 +573,6 @@ global:
 
 LIBSYSTEMD_240 {
         sd_bus_message_readv;
+        sd_bus_set_method_call_timeout;
+        sd_bus_get_method_call_timeout;
 } LIBSYSTEMD_239;
index 251fc9b42d1f12e0046f5e1043299f02e5b9732d..55f2bc36fb2686a999e692e2f0f7e0841c3b4ffc 100644 (file)
@@ -316,6 +316,9 @@ struct sd_bus {
 
         int *inotify_watches;
         size_t n_inotify_watches;
+
+        /* zero means use value specified by $SYSTEMD_BUS_TIMEOUT= environment variable or built-in default */
+        usec_t method_call_timeout;
 };
 
 /* For method calls we time-out at 25s, like in the D-Bus reference implementation */
@@ -333,8 +336,7 @@ struct sd_bus {
 
 #define BUS_CONTAINER_DEPTH 128
 
-/* Defined by the specification as maximum size of an array in
- * bytes */
+/* Defined by the specification as maximum size of an array in bytes */
 #define BUS_ARRAY_MAX_SIZE 67108864
 
 #define BUS_FDS_MAX 1024
@@ -385,8 +387,7 @@ void bus_close_io_fds(sd_bus *b);
              _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/'))
 
 /* If we are invoking callbacks of a bus object, ensure unreffing the
- * bus from the callback doesn't destroy the object we are working
- * on */
+ * bus from the callback doesn't destroy the object we are working on */
 #define BUS_DONT_DESTROY(bus) \
         _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus)
 
index c402f188603019200f911d93390e35070b7b2772..55490de1c8b267191e6d12a34eabf8bce71367b5 100644 (file)
@@ -5809,8 +5809,11 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
                 return r;
 
         timeout = (*m)->timeout;
-        if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
-                timeout = BUS_DEFAULT_TIMEOUT;
+        if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) {
+                r = sd_bus_get_method_call_timeout(bus, &timeout);
+                if (r < 0)
+                        return r;
+        }
 
         r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
         if (r < 0)
index ce49580edbbc3601ac578069916d7a1df65221ee..deb664540a526def3e7bd083b4d8059e754ab683 100644 (file)
@@ -1609,8 +1609,11 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
                 return 0;
         }
 
-        if (timeout == 0)
-                timeout = BUS_DEFAULT_TIMEOUT;
+        if (timeout == 0) {
+                r = sd_bus_get_method_call_timeout(b, &timeout);
+                if (r < 0)
+                        return r;
+        }
 
         if (!m->sender && b->patch_sender) {
                 r = sd_bus_message_set_sender(m, b->patch_sender);
@@ -4073,3 +4076,36 @@ _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) {
         *ret = bus->wqueue_size;
         return 0;
 }
+
+_public_ int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec) {
+        assert_return(bus, -EINVAL);
+        assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+        bus->method_call_timeout = usec;
+        return 0;
+}
+
+_public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) {
+        const char *e;
+        usec_t usec;
+
+        assert_return(bus, -EINVAL);
+        assert_return(bus = bus_resolve(bus), -ENOPKG);
+        assert_return(ret, -EINVAL);
+
+        if (bus->method_call_timeout != 0) {
+                *ret = bus->method_call_timeout;
+                return 0;
+        }
+
+        e = secure_getenv("SYSTEMD_BUS_TIMEOUT");
+        if (e && parse_sec(e, &usec) >= 0 && usec != 0) {
+                /* Save the parsed value to avoid multiple parsing. To change the timeout value,
+                 * use sd_bus_set_method_call_timeout() instead of setenv(). */
+                *ret = bus->method_call_timeout = usec;
+                return 0;
+        }
+
+        *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT;
+        return 0;
+}
index ce12b7ffc7a467c47f41274018ed2a860d1e5913..5bc696591661dd1c695572aae0e3d7855d8559fc 100644 (file)
@@ -205,6 +205,9 @@ sd_event *sd_bus_get_event(sd_bus *bus);
 int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret);
 int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret);
 
+int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec);
+int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret);
+
 int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata);
 int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata);
 int sd_bus_add_match_async(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata);