]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl-set-default.c
update TODO
[thirdparty/systemd.git] / src / systemctl / systemctl-set-default.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "bus-error.h"
4 #include "bus-locator.h"
5 #include "proc-cmdline.h"
6 #include "systemctl-daemon-reload.h"
7 #include "systemctl-set-default.h"
8 #include "systemctl-util.h"
9 #include "systemctl.h"
10
11 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
12 char **ret = data;
13
14 if (streq(key, "systemd.unit")) {
15 if (proc_cmdline_value_missing(key, value))
16 return 0;
17 if (!unit_name_is_valid(value, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
18 log_warning("Unit name specified on %s= is not valid, ignoring: %s", key, value);
19 return 0;
20 }
21
22 return free_and_strdup_warn(ret, key);
23
24 } else if (!value) {
25 if (runlevel_to_target(key))
26 return free_and_strdup_warn(ret, key);
27 }
28
29 return 0;
30 }
31
32 static void emit_cmdline_warning(void) {
33 if (arg_quiet || arg_root)
34 /* don't bother checking the commandline if we're operating on a container */
35 return;
36
37 _cleanup_free_ char *override = NULL;
38 int r;
39
40 r = proc_cmdline_parse(parse_proc_cmdline_item, &override, 0);
41 if (r < 0)
42 log_debug_errno(r, "Failed to parse kernel command line, ignoring: %m");
43 if (override)
44 log_notice("Note: found \"%s\" on the kernel commandline, which overrides the default unit.",
45 override);
46 }
47
48 static int determine_default(char **ret_name) {
49 int r;
50
51 if (install_client_side()) {
52 r = unit_file_get_default(arg_runtime_scope, arg_root, ret_name);
53 if (r == -ERFKILL)
54 return log_error_errno(r, "Failed to get default target: Unit file is masked.");
55 if (r < 0)
56 return log_error_errno(r, "Failed to get default target: %m");
57 return 0;
58
59 } else {
60 sd_bus *bus;
61 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
62 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
63 const char *name;
64
65 r = acquire_bus(BUS_MANAGER, &bus);
66 if (r < 0)
67 return r;
68
69 r = bus_call_method(bus, bus_systemd_mgr, "GetDefaultTarget", &error, &reply, NULL);
70 if (r < 0)
71 return log_error_errno(r, "Failed to get default target: %s", bus_error_message(&error, r));
72
73 r = sd_bus_message_read(reply, "s", &name);
74 if (r < 0)
75 return bus_log_parse_error(r);
76
77 return free_and_strdup_warn(ret_name, name);
78 }
79 }
80
81 int verb_get_default(int argc, char *argv[], void *userdata) {
82 _cleanup_free_ char *name = NULL;
83 int r;
84
85 r = determine_default(&name);
86 if (r < 0)
87 return r;
88
89 printf("%s\n", name);
90
91 emit_cmdline_warning();
92
93 return 0;
94 }
95
96 int verb_set_default(int argc, char *argv[], void *userdata) {
97 _cleanup_free_ char *unit = NULL;
98 InstallChange *changes = NULL;
99 size_t n_changes = 0;
100 int r;
101
102 assert(argc >= 2);
103 assert(argv);
104
105 r = unit_name_mangle_with_suffix(argv[1], "set-default",
106 arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
107 ".target", &unit);
108 if (r < 0)
109 return log_error_errno(r, "Failed to mangle unit name: %m");
110
111 if (install_client_side()) {
112 r = unit_file_set_default(arg_runtime_scope, UNIT_FILE_FORCE, arg_root, unit, &changes, &n_changes);
113 install_changes_dump(r, "set default", changes, n_changes, arg_quiet);
114 if (r < 0)
115 goto finish;
116 } else {
117 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
118 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
119 sd_bus *bus;
120
121 polkit_agent_open_maybe();
122
123 r = acquire_bus(BUS_MANAGER, &bus);
124 if (r < 0)
125 return r;
126
127 r = bus_call_method(bus, bus_systemd_mgr, "SetDefaultTarget", &error, &reply, "sb", unit, 1);
128 if (r < 0)
129 return log_error_errno(r, "Failed to set default target: %s", bus_error_message(&error, r));
130
131 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
132 if (r < 0)
133 goto finish;
134
135 /* Try to reload if enabled */
136 if (!arg_no_reload) {
137 r = daemon_reload(ACTION_RELOAD, /* graceful= */ false);
138 if (r < 0)
139 goto finish;
140 }
141 }
142
143 emit_cmdline_warning();
144
145 if (!arg_quiet) {
146 _cleanup_free_ char *final = NULL;
147
148 r = determine_default(&final);
149 if (r < 0)
150 goto finish;
151
152 if (!streq(final, unit))
153 log_notice("Note: \"%s\" is the default unit (possibly a runtime override).", final);
154 }
155
156 finish:
157 install_changes_free(changes, n_changes);
158
159 return r < 0 ? r : 0;
160 }