sd-bus: make BUS_DEFAULT_TIMEOUT configurable

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.
This commit is contained in:
Yu Watanabe 2018-07-13 17:38:47 +09:00 committed by Lennart Poettering
parent db9eee7e45
commit 385b2eb262
6 changed files with 58 additions and 8 deletions

View 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

View 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;

View 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)

View 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)

View 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;
}

View 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);