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