blob: 45c9b5b1e3b1b004963a4960641d41349a9357f7 [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From 5b75a72ee968c9666b5f2ea313720b6c383cb4c2 Mon Sep 17 00:00:00 2001
2From: Yu Watanabe <watanabe.yu+github@gmail.com>
3Date: Fri, 13 Jul 2018 17:38:47 +0900
4Subject: [PATCH] sd-bus: make BUS_DEFAULT_TIMEOUT configurable
5
6This adds sd_bus_{get,set}_method_call_timeout().
7If the timeout is not set or set to 0, then the timeout value is
8parsed from $SYSTEMD_BUS_TIMEOUT= environment variable. If the
9environment 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
19Upstream-Status: Backport
20
21Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
22
23diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md
24index 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
39diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
40index 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;
52diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
53index 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
86diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
87index 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)
104diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
105index 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+}
159diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
160index 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--
1742.11.0
175