]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/nspawn/nspawn-register.c
net_id: add missing naming scheme name for v254
[thirdparty/systemd.git] / src / nspawn / nspawn-register.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
b7103bc5
LP
2
3#include "sd-bus.h"
4
b7103bc5 5#include "bus-error.h"
9b71e4ab 6#include "bus-locator.h"
20b16441 7#include "bus-unit-util.h"
8fcde012 8#include "bus-util.h"
e45c81b8 9#include "bus-wait-for-jobs.h"
b7103bc5 10#include "nspawn-register.h"
411d8c72 11#include "nspawn-settings.h"
910384c8 12#include "special.h"
8fcde012
LP
13#include "stat-util.h"
14#include "strv.h"
b7103bc5 15
cd2dfc6f
LP
16static int append_machine_properties(
17 sd_bus_message *m,
18 CustomMount *mounts,
19 unsigned n_mounts,
411d8c72
NR
20 int kill_signal,
21 bool coredump_receive) {
cd2dfc6f
LP
22
23 unsigned j;
24 int r;
25
26 assert(m);
27
28 r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
29 if (r < 0)
30 return bus_log_create_error(r);
31
32 /* If you make changes here, also make sure to update systemd-nspawn@.service, to keep the device policies in
33 * sync regardless if we are run with or without the --keep-unit switch. */
34 r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
35 /* Allow the container to
36 * access and create the API
37 * device nodes, so that
38 * PrivateDevices= in the
39 * container can work
40 * fine */
41 "/dev/net/tun", "rwm",
42 /* Allow the container
43 * access to ptys. However,
44 * do not permit the
45 * container to ever create
46 * these device nodes. */
47 "char-pts", "rw");
48 if (r < 0)
49 return bus_log_create_error(r);
50
51 for (j = 0; j < n_mounts; j++) {
52 CustomMount *cm = mounts + j;
53
54 if (cm->type != CUSTOM_MOUNT_BIND)
55 continue;
56
57 r = is_device_node(cm->source);
58 if (r == -ENOENT) {
59 /* The bind source might only appear as the image is put together, hence don't complain */
60 log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
61 continue;
62 }
63 if (r < 0)
64 return log_error_errno(r, "Failed to stat %s: %m", cm->source);
65
66 if (r) {
67 r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
68 cm->source, cm->read_only ? "r" : "rw");
69 if (r < 0)
70 return log_error_errno(r, "Failed to append message arguments: %m");
71 }
72 }
73
74 if (kill_signal != 0) {
75 r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
76 if (r < 0)
77 return bus_log_create_error(r);
78
79 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
80 if (r < 0)
81 return bus_log_create_error(r);
82 }
83
411d8c72
NR
84 if (coredump_receive) {
85 r = sd_bus_message_append(m, "(sv)", "CoredumpReceive", "b", true);
86 if (r < 0)
87 return bus_log_create_error(r);
88 }
89
cd2dfc6f
LP
90 return 0;
91}
92
abdb9b08
LP
93static int append_controller_property(sd_bus *bus, sd_bus_message *m) {
94 const char *unique;
95 int r;
96
97 assert(bus);
98 assert(m);
99
100 r = sd_bus_get_unique_name(bus, &unique);
101 if (r < 0)
102 return log_error_errno(r, "Failed to get unique name: %m");
103
104 r = sd_bus_message_append(m, "(sv)", "Controller", "s", unique);
105 if (r < 0)
106 return bus_log_create_error(r);
107
108 return 0;
109}
110
b7103bc5 111int register_machine(
abdb9b08 112 sd_bus *bus,
b7103bc5
LP
113 const char *machine_name,
114 pid_t pid,
115 const char *directory,
116 sd_id128_t uuid,
117 int local_ifindex,
118 const char *slice,
119 CustomMount *mounts,
120 unsigned n_mounts,
121 int kill_signal,
122 char **properties,
de40a303 123 sd_bus_message *properties_message,
6aadfa4c 124 bool keep_unit,
411d8c72
NR
125 const char *service,
126 StartMode start_mode) {
b7103bc5 127
4afd3348 128 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
b7103bc5
LP
129 int r;
130
abdb9b08 131 assert(bus);
b7103bc5
LP
132
133 if (keep_unit) {
1ecaac5c 134 r = bus_call_method(
b7103bc5 135 bus,
1ecaac5c 136 bus_machine_mgr,
b7103bc5
LP
137 "RegisterMachineWithNetwork",
138 &error,
139 NULL,
140 "sayssusai",
141 machine_name,
142 SD_BUS_MESSAGE_APPEND_ID128(uuid),
6aadfa4c 143 service,
b7103bc5
LP
144 "container",
145 (uint32_t) pid,
146 strempty(directory),
147 local_ifindex > 0 ? 1 : 0, local_ifindex);
148 } else {
4afd3348 149 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
b7103bc5 150
1ecaac5c 151 r = bus_message_new_method_call(bus, &m, bus_machine_mgr, "CreateMachineWithNetwork");
b7103bc5
LP
152 if (r < 0)
153 return bus_log_create_error(r);
154
155 r = sd_bus_message_append(
156 m,
157 "sayssusai",
158 machine_name,
159 SD_BUS_MESSAGE_APPEND_ID128(uuid),
6aadfa4c 160 service,
b7103bc5
LP
161 "container",
162 (uint32_t) pid,
163 strempty(directory),
164 local_ifindex > 0 ? 1 : 0, local_ifindex);
165 if (r < 0)
166 return bus_log_create_error(r);
167
168 r = sd_bus_message_open_container(m, 'a', "(sv)");
169 if (r < 0)
170 return bus_log_create_error(r);
171
172 if (!isempty(slice)) {
173 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
174 if (r < 0)
175 return bus_log_create_error(r);
176 }
177
abdb9b08
LP
178 r = append_controller_property(bus, m);
179 if (r < 0)
180 return r;
181
cd2dfc6f
LP
182 r = append_machine_properties(
183 m,
184 mounts,
185 n_mounts,
411d8c72
NR
186 kill_signal,
187 start_mode == START_BOOT);
b7103bc5 188 if (r < 0)
cd2dfc6f 189 return r;
b7103bc5 190
de40a303
LP
191 if (properties_message) {
192 r = sd_bus_message_copy(m, properties_message, true);
193 if (r < 0)
194 return bus_log_create_error(r);
195 }
196
89ada3ba 197 r = bus_append_unit_property_assignment_many(m, UNIT_SERVICE, properties);
8673cf13
LP
198 if (r < 0)
199 return r;
b7103bc5
LP
200
201 r = sd_bus_message_close_container(m);
202 if (r < 0)
203 return bus_log_create_error(r);
204
205 r = sd_bus_call(bus, m, 0, &error, NULL);
206 }
4ae25393
YW
207 if (r < 0)
208 return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
b7103bc5
LP
209
210 return 0;
211}
212
0bb0a9fa 213int unregister_machine(
11d81e50
LP
214 sd_bus *bus,
215 const char *machine_name) {
216
4afd3348 217 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
b7103bc5
LP
218 int r;
219
abdb9b08 220 assert(bus);
b7103bc5 221
1ecaac5c 222 r = bus_call_method(bus, bus_machine_mgr, "UnregisterMachine", &error, NULL, "s", machine_name);
4ae25393 223 if (r < 0)
0bb0a9fa 224 log_debug("Failed to unregister machine: %s", bus_error_message(&error, r));
b7103bc5
LP
225
226 return 0;
227}
cd2dfc6f
LP
228
229int allocate_scope(
abdb9b08 230 sd_bus *bus,
cd2dfc6f
LP
231 const char *machine_name,
232 pid_t pid,
233 const char *slice,
234 CustomMount *mounts,
235 unsigned n_mounts,
236 int kill_signal,
de40a303 237 char **properties,
7eda208f 238 sd_bus_message *properties_message,
411d8c72
NR
239 bool allow_pidfd,
240 StartMode start_mode) {
cd2dfc6f 241
df61bc5e 242 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
cd2dfc6f 243 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
0a5706d1 244 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
cd2dfc6f 245 _cleanup_free_ char *scope = NULL;
0a5706d1 246 const char *description, *object;
cd2dfc6f
LP
247 int r;
248
abdb9b08 249 assert(bus);
cd2dfc6f 250
0a5706d1
ZJS
251 r = bus_wait_for_jobs_new(bus, &w);
252 if (r < 0)
253 return log_error_errno(r, "Could not watch job: %m");
254
df7c4eb6 255 r = unit_name_mangle_with_suffix(machine_name, "as machine name", 0, ".scope", &scope);
cd2dfc6f
LP
256 if (r < 0)
257 return log_error_errno(r, "Failed to mangle scope name: %m");
258
1ecaac5c 259 r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "StartTransientUnit");
cd2dfc6f
LP
260 if (r < 0)
261 return bus_log_create_error(r);
262
263 r = sd_bus_message_append(m, "ss", scope, "fail");
264 if (r < 0)
265 return bus_log_create_error(r);
266
267 /* Properties */
268 r = sd_bus_message_open_container(m, 'a', "(sv)");
269 if (r < 0)
270 return bus_log_create_error(r);
271
272 description = strjoina("Container ", machine_name);
273
7eda208f
LP
274 if (allow_pidfd) {
275 _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
276 r = pidref_set_pid(&pidref, pid);
277 if (r < 0)
278 return log_error_errno(r, "Failed to allocate PID reference: %m");
279
280 r = bus_append_scope_pidref(m, &pidref);
281 } else
282 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
283 if (r < 0)
284 return bus_log_create_error(r);
285
286 r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
cd2dfc6f
LP
287 "Description", "s", description,
288 "Delegate", "b", 1,
1d78fea2
LP
289 "CollectMode", "s", "inactive-or-failed",
290 "AddRef", "b", 1,
910384c8 291 "Slice", "s", isempty(slice) ? SPECIAL_MACHINE_SLICE : slice);
cd2dfc6f
LP
292 if (r < 0)
293 return bus_log_create_error(r);
294
abdb9b08
LP
295 r = append_controller_property(bus, m);
296 if (r < 0)
297 return r;
298
de40a303
LP
299 if (properties_message) {
300 r = sd_bus_message_copy(m, properties_message, true);
301 if (r < 0)
302 return bus_log_create_error(r);
303 }
304
cd2dfc6f
LP
305 r = append_machine_properties(
306 m,
307 mounts,
308 n_mounts,
411d8c72
NR
309 kill_signal,
310 start_mode == START_BOOT);
cd2dfc6f
LP
311 if (r < 0)
312 return r;
313
89ada3ba 314 r = bus_append_unit_property_assignment_many(m, UNIT_SCOPE, properties);
cd2dfc6f
LP
315 if (r < 0)
316 return r;
317
318 r = sd_bus_message_close_container(m);
319 if (r < 0)
320 return bus_log_create_error(r);
321
322 /* No auxiliary units */
323 r = sd_bus_message_append(
324 m,
325 "a(sa(sv))",
326 0);
327 if (r < 0)
328 return bus_log_create_error(r);
329
0a5706d1 330 r = sd_bus_call(bus, m, 0, &error, &reply);
7eda208f
LP
331 if (r < 0) {
332 /* If this failed with a property we couldn't write, this is quite likely because the server
333 * doesn't support PIDFDs yet, let's try without. */
334 if (allow_pidfd &&
335 sd_bus_error_has_names(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY, SD_BUS_ERROR_PROPERTY_READ_ONLY))
411d8c72 336 return allocate_scope(bus, machine_name, pid, slice, mounts, n_mounts, kill_signal, properties, properties_message, /* allow_pidfd= */ false, start_mode);
7eda208f 337
4ae25393 338 return log_error_errno(r, "Failed to allocate scope: %s", bus_error_message(&error, r));
7eda208f 339 }
cd2dfc6f 340
0a5706d1
ZJS
341 r = sd_bus_message_read(reply, "o", &object);
342 if (r < 0)
343 return bus_log_parse_error(r);
344
86980de6 345 r = bus_wait_for_jobs_one(w, object, false, NULL);
0a5706d1
ZJS
346 if (r < 0)
347 return r;
348
cd2dfc6f
LP
349 return 0;
350}
1d78fea2
LP
351
352int terminate_scope(
353 sd_bus *bus,
354 const char *machine_name) {
355
356 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
357 _cleanup_free_ char *scope = NULL;
358 int r;
359
df7c4eb6 360 r = unit_name_mangle_with_suffix(machine_name, "to terminate", 0, ".scope", &scope);
1d78fea2
LP
361 if (r < 0)
362 return log_error_errno(r, "Failed to mangle scope name: %m");
363
1ecaac5c 364 r = bus_call_method(bus, bus_systemd_mgr, "AbandonScope", &error, NULL, "s", scope);
1d78fea2
LP
365 if (r < 0) {
366 log_debug_errno(r, "Failed to abandon scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
367 sd_bus_error_free(&error);
368 }
369
1ecaac5c 370 r = bus_call_method(
1d78fea2 371 bus,
1ecaac5c 372 bus_systemd_mgr,
1d78fea2
LP
373 "KillUnit",
374 &error,
375 NULL,
376 "ssi",
377 scope,
378 "all",
379 (int32_t) SIGKILL);
380 if (r < 0) {
381 log_debug_errno(r, "Failed to SIGKILL scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
382 sd_bus_error_free(&error);
383 }
384
1ecaac5c 385 r = bus_call_method(bus, bus_systemd_mgr, "UnrefUnit", &error, NULL, "s", scope);
1d78fea2
LP
386 if (r < 0)
387 log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
388
389 return 0;
390}