]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/nspawn/nspawn-register.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "bus-unit-util.h"
8 #include "bus-wait-for-jobs.h"
9 #include "nspawn-register.h"
11 #include "stat-util.h"
15 static int append_machine_properties(
26 r
= sd_bus_message_append(m
, "(sv)", "DevicePolicy", "s", "closed");
28 return bus_log_create_error(r
);
30 /* If you make changes here, also make sure to update systemd-nspawn@.service, to keep the device policies in
31 * sync regardless if we are run with or without the --keep-unit switch. */
32 r
= sd_bus_message_append(m
, "(sv)", "DeviceAllow", "a(ss)", 2,
33 /* Allow the container to
34 * access and create the API
35 * device nodes, so that
36 * PrivateDevices= in the
39 "/dev/net/tun", "rwm",
40 /* Allow the container
41 * access to ptys. However,
43 * container to ever create
44 * these device nodes. */
47 return bus_log_create_error(r
);
49 for (j
= 0; j
< n_mounts
; j
++) {
50 CustomMount
*cm
= mounts
+ j
;
52 if (cm
->type
!= CUSTOM_MOUNT_BIND
)
55 r
= is_device_node(cm
->source
);
57 /* The bind source might only appear as the image is put together, hence don't complain */
58 log_debug_errno(r
, "Bind mount source %s not found, ignoring: %m", cm
->source
);
62 return log_error_errno(r
, "Failed to stat %s: %m", cm
->source
);
65 r
= sd_bus_message_append(m
, "(sv)", "DeviceAllow", "a(ss)", 1,
66 cm
->source
, cm
->read_only
? "r" : "rw");
68 return log_error_errno(r
, "Failed to append message arguments: %m");
72 if (kill_signal
!= 0) {
73 r
= sd_bus_message_append(m
, "(sv)", "KillSignal", "i", kill_signal
);
75 return bus_log_create_error(r
);
77 r
= sd_bus_message_append(m
, "(sv)", "KillMode", "s", "mixed");
79 return bus_log_create_error(r
);
85 static int append_controller_property(sd_bus
*bus
, sd_bus_message
*m
) {
92 r
= sd_bus_get_unique_name(bus
, &unique
);
94 return log_error_errno(r
, "Failed to get unique name: %m");
96 r
= sd_bus_message_append(m
, "(sv)", "Controller", "s", unique
);
98 return bus_log_create_error(r
);
103 int register_machine(
105 const char *machine_name
,
107 const char *directory
,
115 sd_bus_message
*properties_message
,
117 const char *service
) {
119 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
125 r
= sd_bus_call_method(
127 "org.freedesktop.machine1",
128 "/org/freedesktop/machine1",
129 "org.freedesktop.machine1.Manager",
130 "RegisterMachineWithNetwork",
135 SD_BUS_MESSAGE_APPEND_ID128(uuid
),
140 local_ifindex
> 0 ? 1 : 0, local_ifindex
);
142 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
144 r
= sd_bus_message_new_method_call(
147 "org.freedesktop.machine1",
148 "/org/freedesktop/machine1",
149 "org.freedesktop.machine1.Manager",
150 "CreateMachineWithNetwork");
152 return bus_log_create_error(r
);
154 r
= sd_bus_message_append(
158 SD_BUS_MESSAGE_APPEND_ID128(uuid
),
163 local_ifindex
> 0 ? 1 : 0, local_ifindex
);
165 return bus_log_create_error(r
);
167 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
169 return bus_log_create_error(r
);
171 if (!isempty(slice
)) {
172 r
= sd_bus_message_append(m
, "(sv)", "Slice", "s", slice
);
174 return bus_log_create_error(r
);
177 r
= append_controller_property(bus
, m
);
181 r
= append_machine_properties(
189 if (properties_message
) {
190 r
= sd_bus_message_copy(m
, properties_message
, true);
192 return bus_log_create_error(r
);
195 r
= bus_append_unit_property_assignment_many(m
, UNIT_SERVICE
, properties
);
199 r
= sd_bus_message_close_container(m
);
201 return bus_log_create_error(r
);
203 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
207 return log_error_errno(r
, "Failed to register machine: %s", bus_error_message(&error
, r
));
212 int terminate_machine(
214 const char *machine_name
) {
216 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
221 r
= sd_bus_call_method(
223 "org.freedesktop.machine1",
224 "/org/freedesktop/machine1",
225 "org.freedesktop.machine1.Manager",
232 log_debug("Failed to terminate machine: %s", bus_error_message(&error
, r
));
239 const char *machine_name
,
246 sd_bus_message
*properties_message
) {
248 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
249 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
250 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
251 _cleanup_free_
char *scope
= NULL
;
252 const char *description
, *object
;
257 r
= bus_wait_for_jobs_new(bus
, &w
);
259 return log_error_errno(r
, "Could not watch job: %m");
261 r
= unit_name_mangle_with_suffix(machine_name
, 0, ".scope", &scope
);
263 return log_error_errno(r
, "Failed to mangle scope name: %m");
265 r
= sd_bus_message_new_method_call(
268 "org.freedesktop.systemd1",
269 "/org/freedesktop/systemd1",
270 "org.freedesktop.systemd1.Manager",
271 "StartTransientUnit");
273 return bus_log_create_error(r
);
275 r
= sd_bus_message_append(m
, "ss", scope
, "fail");
277 return bus_log_create_error(r
);
280 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
282 return bus_log_create_error(r
);
284 description
= strjoina("Container ", machine_name
);
286 r
= sd_bus_message_append(m
, "(sv)(sv)(sv)(sv)(sv)(sv)",
287 "PIDs", "au", 1, pid
,
288 "Description", "s", description
,
290 "CollectMode", "s", "inactive-or-failed",
292 "Slice", "s", isempty(slice
) ? SPECIAL_MACHINE_SLICE
: slice
);
294 return bus_log_create_error(r
);
296 r
= append_controller_property(bus
, m
);
300 if (properties_message
) {
301 r
= sd_bus_message_copy(m
, properties_message
, true);
303 return bus_log_create_error(r
);
306 r
= append_machine_properties(
314 r
= bus_append_unit_property_assignment_many(m
, UNIT_SCOPE
, properties
);
318 r
= sd_bus_message_close_container(m
);
320 return bus_log_create_error(r
);
322 /* No auxiliary units */
323 r
= sd_bus_message_append(
328 return bus_log_create_error(r
);
330 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
332 return log_error_errno(r
, "Failed to allocate scope: %s", bus_error_message(&error
, r
));
334 r
= sd_bus_message_read(reply
, "o", &object
);
336 return bus_log_parse_error(r
);
338 r
= bus_wait_for_jobs_one(w
, object
, false);
347 const char *machine_name
) {
349 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
350 _cleanup_free_
char *scope
= NULL
;
353 r
= unit_name_mangle_with_suffix(machine_name
, 0, ".scope", &scope
);
355 return log_error_errno(r
, "Failed to mangle scope name: %m");
357 r
= sd_bus_call_method(
359 "org.freedesktop.systemd1",
360 "/org/freedesktop/systemd1",
361 "org.freedesktop.systemd1.Manager",
368 log_debug_errno(r
, "Failed to abandon scope '%s', ignoring: %s", scope
, bus_error_message(&error
, r
));
369 sd_bus_error_free(&error
);
372 r
= sd_bus_call_method(
374 "org.freedesktop.systemd1",
375 "/org/freedesktop/systemd1",
376 "org.freedesktop.systemd1.Manager",
385 log_debug_errno(r
, "Failed to SIGKILL scope '%s', ignoring: %s", scope
, bus_error_message(&error
, r
));
386 sd_bus_error_free(&error
);
389 r
= sd_bus_call_method(
391 "org.freedesktop.systemd1",
392 "/org/freedesktop/systemd1",
393 "org.freedesktop.systemd1.Manager",
400 log_debug_errno(r
, "Failed to drop reference to scope '%s', ignoring: %s", scope
, bus_error_message(&error
, r
));