1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "bus-error.h"
4 #include "bus-locator.h"
5 #include "systemctl-daemon-reload.h"
6 #include "systemctl-util.h"
7 #include "systemctl.h"
8
daemon_reload(enum action action,bool graceful)9 int daemon_reload(enum action action, bool graceful) {
10 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
11 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
12 const char *method;
13 sd_bus *bus;
14 int r;
15
16 r = acquire_bus(BUS_MANAGER, &bus);
17 if (r < 0)
18 return r;
19
20 polkit_agent_open_maybe();
21
22 switch (action) {
23
24 case ACTION_RELOAD:
25 method = "Reload";
26 break;
27
28 case ACTION_REEXEC:
29 method = "Reexecute";
30 break;
31
32 default:
33 return -EINVAL;
34 }
35
36 r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method);
37 if (r < 0)
38 return bus_log_create_error(r);
39
40 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are
41 * rerun which are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the
42 * generators can have their timeout, and for everything else there's the same time budget in
43 * place. */
44
45 r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
46
47 /* On reexecution, we expect a disconnect, not a reply */
48 if (IN_SET(r, -ETIMEDOUT, -ECONNRESET) && action == ACTION_REEXEC)
49 return 1;
50 if (r < 0) {
51 if (graceful) { /* If graceful mode is selected, debug log, but don't fail */
52 log_debug_errno(r, "Failed to reload daemon via the bus, ignoring: %s", bus_error_message(&error, r));
53 return 0;
54 }
55
56 return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
57 }
58
59 return 1;
60 }
61
verb_daemon_reload(int argc,char * argv[],void * userdata)62 int verb_daemon_reload(int argc, char *argv[], void *userdata) {
63 enum action a;
64 int r;
65
66 assert(argc >= 1);
67
68 if (streq(argv[0], "daemon-reexec"))
69 a = ACTION_REEXEC;
70 else if (streq(argv[0], "daemon-reload"))
71 a = ACTION_RELOAD;
72 else
73 assert_not_reached();
74
75 r = daemon_reload(a, /* graceful= */ false);
76 if (r < 0)
77 return r;
78
79 return 0;
80 }
81