Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame^] | 1 | From 5b75a72ee968c9666b5f2ea313720b6c383cb4c2 Mon Sep 17 00:00:00 2001 |
| 2 | From: Yu Watanabe <watanabe.yu+github@gmail.com> |
| 3 | Date: Fri, 13 Jul 2018 17:38:47 +0900 |
| 4 | Subject: [PATCH] sd-bus: make BUS_DEFAULT_TIMEOUT configurable |
| 5 | |
| 6 | This adds sd_bus_{get,set}_method_call_timeout(). |
| 7 | If the timeout is not set or set to 0, then the timeout value is |
| 8 | parsed from $SYSTEMD_BUS_TIMEOUT= environment variable. If the |
| 9 | environment variable is not set, then built-in timeout is used. |
| 10 | --- |
| 11 | doc/ENVIRONMENT.md | 5 +++++ |
| 12 | src/libsystemd/libsystemd.sym | 5 +++++ |
| 13 | src/libsystemd/sd-bus/bus-internal.h | 9 ++++---- |
| 14 | src/libsystemd/sd-bus/bus-message.c | 7 +++++-- |
| 15 | src/libsystemd/sd-bus/sd-bus.c | 40 ++++++++++++++++++++++++++++++++++-- |
| 16 | src/systemd/sd-bus.h | 3 +++ |
| 17 | 6 files changed, 61 insertions(+), 8 deletions(-) |
| 18 | |
| 19 | Upstream-Status: Backport |
| 20 | |
| 21 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> |
| 22 | |
| 23 | diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md |
| 24 | index 85d26fe28c..641a03d5d7 100644 |
| 25 | --- a/doc/ENVIRONMENT.md |
| 26 | +++ b/doc/ENVIRONMENT.md |
| 27 | @@ -37,6 +37,11 @@ All tools: |
| 28 | useful for debugging, in order to test generators and other code against |
| 29 | specific kernel command lines. |
| 30 | |
| 31 | +* `$SYSTEMD_BUS_TIMEOUT=SECS` — specifies the maximum time to wait for method call |
| 32 | + completion. If no time unit is specified, assumes seconds. The usual other units |
| 33 | + are understood, too (us, ms, s, min, h, d, w, month, y). If it is not set or set |
| 34 | + to 0, then the built-in default is used. |
| 35 | + |
| 36 | systemctl: |
| 37 | |
| 38 | * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus |
| 39 | diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym |
| 40 | index 1eec17db50..006dbc9c3f 100644 |
| 41 | --- a/src/libsystemd/libsystemd.sym |
| 42 | +++ b/src/libsystemd/libsystemd.sym |
| 43 | @@ -570,3 +570,8 @@ global: |
| 44 | sd_event_source_set_destroy_callback; |
| 45 | sd_event_source_get_destroy_callback; |
| 46 | } LIBSYSTEMD_238; |
| 47 | + |
| 48 | +LIBSYSTEMD_240 { |
| 49 | + sd_bus_set_method_call_timeout; |
| 50 | + sd_bus_get_method_call_timeout; |
| 51 | +} LIBSYSTEMD_239; |
| 52 | diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h |
| 53 | index 2087ef8eeb..4864b1e911 100644 |
| 54 | --- a/src/libsystemd/sd-bus/bus-internal.h |
| 55 | +++ b/src/libsystemd/sd-bus/bus-internal.h |
| 56 | @@ -319,6 +319,9 @@ struct sd_bus { |
| 57 | |
| 58 | int *inotify_watches; |
| 59 | size_t n_inotify_watches; |
| 60 | + |
| 61 | + /* zero means use value specified by $SYSTEMD_BUS_TIMEOUT= environment variable or built-in default */ |
| 62 | + usec_t method_call_timeout; |
| 63 | }; |
| 64 | |
| 65 | /* For method calls we time-out at 25s, like in the D-Bus reference implementation */ |
| 66 | @@ -336,8 +339,7 @@ struct sd_bus { |
| 67 | |
| 68 | #define BUS_CONTAINER_DEPTH 128 |
| 69 | |
| 70 | -/* Defined by the specification as maximum size of an array in |
| 71 | - * bytes */ |
| 72 | +/* Defined by the specification as maximum size of an array in bytes */ |
| 73 | #define BUS_ARRAY_MAX_SIZE 67108864 |
| 74 | |
| 75 | #define BUS_FDS_MAX 1024 |
| 76 | @@ -388,8 +390,7 @@ void bus_close_io_fds(sd_bus *b); |
| 77 | _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/')) |
| 78 | |
| 79 | /* If we are invoking callbacks of a bus object, ensure unreffing the |
| 80 | - * bus from the callback doesn't destroy the object we are working |
| 81 | - * on */ |
| 82 | + * bus from the callback doesn't destroy the object we are working on */ |
| 83 | #define BUS_DONT_DESTROY(bus) \ |
| 84 | _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus) |
| 85 | |
| 86 | diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c |
| 87 | index 8d92bc2002..dffe70a665 100644 |
| 88 | --- a/src/libsystemd/sd-bus/bus-message.c |
| 89 | +++ b/src/libsystemd/sd-bus/bus-message.c |
| 90 | @@ -5809,8 +5809,11 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) { |
| 91 | return r; |
| 92 | |
| 93 | timeout = (*m)->timeout; |
| 94 | - if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) |
| 95 | - timeout = BUS_DEFAULT_TIMEOUT; |
| 96 | + if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) { |
| 97 | + r = sd_bus_get_method_call_timeout(bus, &timeout); |
| 98 | + if (r < 0) |
| 99 | + return r; |
| 100 | + } |
| 101 | |
| 102 | r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout); |
| 103 | if (r < 0) |
| 104 | diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c |
| 105 | index 089b51a6d9..945490ebf7 100644 |
| 106 | --- a/src/libsystemd/sd-bus/sd-bus.c |
| 107 | +++ b/src/libsystemd/sd-bus/sd-bus.c |
| 108 | @@ -1611,8 +1611,11 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { |
| 109 | return 0; |
| 110 | } |
| 111 | |
| 112 | - if (timeout == 0) |
| 113 | - timeout = BUS_DEFAULT_TIMEOUT; |
| 114 | + if (timeout == 0) { |
| 115 | + r = sd_bus_get_method_call_timeout(b, &timeout); |
| 116 | + if (r < 0) |
| 117 | + return r; |
| 118 | + } |
| 119 | |
| 120 | if (!m->sender && b->patch_sender) { |
| 121 | r = sd_bus_message_set_sender(m, b->patch_sender); |
| 122 | @@ -4075,3 +4078,36 @@ _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) { |
| 123 | *ret = bus->wqueue_size; |
| 124 | return 0; |
| 125 | } |
| 126 | + |
| 127 | +_public_ int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec) { |
| 128 | + assert_return(bus, -EINVAL); |
| 129 | + assert_return(bus = bus_resolve(bus), -ENOPKG); |
| 130 | + |
| 131 | + bus->method_call_timeout = usec; |
| 132 | + return 0; |
| 133 | +} |
| 134 | + |
| 135 | +_public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) { |
| 136 | + const char *e; |
| 137 | + usec_t usec; |
| 138 | + |
| 139 | + assert_return(bus, -EINVAL); |
| 140 | + assert_return(bus = bus_resolve(bus), -ENOPKG); |
| 141 | + assert_return(ret, -EINVAL); |
| 142 | + |
| 143 | + if (bus->method_call_timeout != 0) { |
| 144 | + *ret = bus->method_call_timeout; |
| 145 | + return 0; |
| 146 | + } |
| 147 | + |
| 148 | + e = secure_getenv("SYSTEMD_BUS_TIMEOUT"); |
| 149 | + if (e && parse_sec(e, &usec) >= 0 && usec != 0) { |
| 150 | + /* Save the parsed value to avoid multiple parsing. To change the timeout value, |
| 151 | + * use sd_bus_set_method_call_timeout() instead of setenv(). */ |
| 152 | + *ret = bus->method_call_timeout = usec; |
| 153 | + return 0; |
| 154 | + } |
| 155 | + |
| 156 | + *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT; |
| 157 | + return 0; |
| 158 | +} |
| 159 | diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h |
| 160 | index 54c4b1ca83..c9fd254834 100644 |
| 161 | --- a/src/systemd/sd-bus.h |
| 162 | +++ b/src/systemd/sd-bus.h |
| 163 | @@ -206,6 +206,9 @@ sd_event *sd_bus_get_event(sd_bus *bus); |
| 164 | int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret); |
| 165 | int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret); |
| 166 | |
| 167 | +int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec); |
| 168 | +int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret); |
| 169 | + |
| 170 | int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata); |
| 171 | int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata); |
| 172 | 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); |
| 173 | -- |
| 174 | 2.11.0 |
| 175 | |