/src/systemd/src/systemctl/systemctl-daemon-reload.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | 0 | int daemon_reload(enum action action, bool graceful) { |
10 | 0 | _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; |
11 | 0 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; |
12 | 0 | const char *method; |
13 | 0 | sd_bus *bus; |
14 | 0 | int r; |
15 | |
|
16 | 0 | r = acquire_bus(BUS_MANAGER, &bus); |
17 | 0 | if (r < 0) |
18 | 0 | return r; |
19 | | |
20 | 0 | polkit_agent_open_maybe(); |
21 | |
|
22 | 0 | switch (action) { |
23 | | |
24 | 0 | case ACTION_RELOAD: |
25 | 0 | method = "Reload"; |
26 | 0 | break; |
27 | | |
28 | 0 | case ACTION_REEXEC: |
29 | 0 | method = "Reexecute"; |
30 | 0 | break; |
31 | | |
32 | 0 | default: |
33 | 0 | return -EINVAL; |
34 | 0 | } |
35 | | |
36 | 0 | r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method); |
37 | 0 | if (r < 0) |
38 | 0 | 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 | 0 | r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL); |
46 | | |
47 | | /* On reexecution, we expect a disconnect, not a reply */ |
48 | 0 | if (IN_SET(r, -ETIMEDOUT, -ECONNRESET) && action == ACTION_REEXEC) |
49 | 0 | return 1; |
50 | 0 | if (r < 0) { |
51 | 0 | if (graceful) { /* If graceful mode is selected, debug log, but don't fail */ |
52 | 0 | log_debug_errno(r, "Failed to reload daemon via the bus, ignoring: %s", bus_error_message(&error, r)); |
53 | 0 | return 0; |
54 | 0 | } |
55 | | |
56 | 0 | return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r)); |
57 | 0 | } |
58 | | |
59 | 0 | return 1; |
60 | 0 | } |
61 | | |
62 | 0 | int verb_daemon_reload(int argc, char *argv[], void *userdata) { |
63 | 0 | enum action a; |
64 | 0 | int r; |
65 | |
|
66 | 0 | assert(argc >= 1); |
67 | |
|
68 | 0 | if (streq(argv[0], "daemon-reexec")) |
69 | 0 | a = ACTION_REEXEC; |
70 | 0 | else if (streq(argv[0], "daemon-reload")) |
71 | 0 | a = ACTION_RELOAD; |
72 | 0 | else |
73 | 0 | assert_not_reached(); |
74 | |
|
75 | 0 | r = daemon_reload(a, /* graceful= */ false); |
76 | 0 | if (r < 0) |
77 | 0 | return r; |
78 | | |
79 | 0 | return 0; |
80 | 0 | } |