]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
daf71ef6 LP |
2 | |
3 | #include "bus-error.h" | |
4 | #include "bus-locator.h" | |
5 | #include "bus-wait-for-units.h" | |
6 | #include "systemctl-clean-or-freeze.h" | |
7 | #include "systemctl-util.h" | |
8 | #include "systemctl.h" | |
9 | ||
10 | int clean_or_freeze_unit(int argc, char *argv[], void *userdata) { | |
11 | _cleanup_(bus_wait_for_units_freep) BusWaitForUnits *w = NULL; | |
12 | _cleanup_strv_free_ char **names = NULL; | |
13 | int r, ret = EXIT_SUCCESS; | |
14 | char **name; | |
15 | const char *method; | |
16 | sd_bus *bus; | |
17 | ||
18 | r = acquire_bus(BUS_FULL, &bus); | |
19 | if (r < 0) | |
20 | return r; | |
21 | ||
22 | polkit_agent_open_maybe(); | |
23 | ||
24 | if (!arg_clean_what) { | |
25 | arg_clean_what = strv_new("cache", "runtime"); | |
26 | if (!arg_clean_what) | |
27 | return log_oom(); | |
28 | } | |
29 | ||
30 | r = expand_unit_names(bus, strv_skip(argv, 1), NULL, &names, NULL); | |
31 | if (r < 0) | |
32 | return log_error_errno(r, "Failed to expand names: %m"); | |
33 | ||
34 | if (!arg_no_block) { | |
35 | r = bus_wait_for_units_new(bus, &w); | |
36 | if (r < 0) | |
37 | return log_error_errno(r, "Failed to allocate unit waiter: %m"); | |
38 | } | |
39 | ||
40 | if (streq(argv[0], "clean")) | |
41 | method = "CleanUnit"; | |
42 | else if (streq(argv[0], "freeze")) | |
43 | method = "FreezeUnit"; | |
44 | else if (streq(argv[0], "thaw")) | |
45 | method = "ThawUnit"; | |
46 | else | |
47 | assert_not_reached("Unhandled method"); | |
48 | ||
49 | STRV_FOREACH(name, names) { | |
50 | _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; | |
51 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; | |
52 | ||
53 | if (w) { | |
54 | /* If we shall wait for the cleaning to complete, let's add a ref on the unit first */ | |
55 | r = bus_call_method(bus, bus_systemd_mgr, "RefUnit", &error, NULL, "s", *name); | |
56 | if (r < 0) { | |
57 | log_error_errno(r, "Failed to add reference to unit %s: %s", *name, bus_error_message(&error, r)); | |
58 | if (ret == EXIT_SUCCESS) | |
59 | ret = r; | |
60 | continue; | |
61 | } | |
62 | } | |
63 | ||
64 | r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method); | |
65 | if (r < 0) | |
66 | return bus_log_create_error(r); | |
67 | ||
68 | r = sd_bus_message_append(m, "s", *name); | |
69 | if (r < 0) | |
70 | return bus_log_create_error(r); | |
71 | ||
72 | if (streq(method, "CleanUnit")) { | |
73 | r = sd_bus_message_append_strv(m, arg_clean_what); | |
74 | if (r < 0) | |
75 | return bus_log_create_error(r); | |
76 | } | |
77 | ||
78 | r = sd_bus_call(bus, m, 0, &error, NULL); | |
79 | if (r < 0) { | |
80 | log_error_errno(r, "Failed to %s unit %s: %s", argv[0], *name, bus_error_message(&error, r)); | |
81 | if (ret == EXIT_SUCCESS) { | |
82 | ret = r; | |
83 | continue; | |
84 | } | |
85 | } | |
86 | ||
87 | if (w) { | |
88 | r = bus_wait_for_units_add_unit(w, *name, BUS_WAIT_REFFED|BUS_WAIT_FOR_MAINTENANCE_END, NULL, NULL); | |
89 | if (r < 0) | |
90 | return log_error_errno(r, "Failed to watch unit %s: %m", *name); | |
91 | } | |
92 | } | |
93 | ||
94 | r = bus_wait_for_units_run(w); | |
95 | if (r < 0) | |
96 | return log_error_errno(r, "Failed to wait for units: %m"); | |
97 | if (r == BUS_WAIT_FAILURE) | |
98 | ret = EXIT_FAILURE; | |
99 | ||
100 | return ret; | |
101 | } |