1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include "bus-locator.h"
7 #include "bus-unit-util.h"
9 #include "bus-wait-for-jobs.h"
10 #include "nspawn-register.h"
11 #include "nspawn-settings.h"
13 #include "stat-util.h"
16 static int append_machine_properties(
21 bool coredump_receive
) {
28 r
= sd_bus_message_append(m
, "(sv)", "DevicePolicy", "s", "closed");
30 return bus_log_create_error(r
);
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
41 "/dev/net/tun", "rwm",
42 /* Allow the container
43 * access to ptys. However,
45 * container to ever create
46 * these device nodes. */
49 return bus_log_create_error(r
);
51 for (j
= 0; j
< n_mounts
; j
++) {
52 CustomMount
*cm
= mounts
+ j
;
54 if (cm
->type
!= CUSTOM_MOUNT_BIND
)
57 r
= is_device_node(cm
->source
);
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
);
64 return log_error_errno(r
, "Failed to stat %s: %m", cm
->source
);
67 r
= sd_bus_message_append(m
, "(sv)", "DeviceAllow", "a(ss)", 1,
68 cm
->source
, cm
->read_only
? "r" : "rw");
70 return log_error_errno(r
, "Failed to append message arguments: %m");
74 if (kill_signal
!= 0) {
75 r
= sd_bus_message_append(m
, "(sv)", "KillSignal", "i", kill_signal
);
77 return bus_log_create_error(r
);
79 r
= sd_bus_message_append(m
, "(sv)", "KillMode", "s", "mixed");
81 return bus_log_create_error(r
);
84 if (coredump_receive
) {
85 r
= sd_bus_message_append(m
, "(sv)", "CoredumpReceive", "b", true);
87 return bus_log_create_error(r
);
93 static int append_controller_property(sd_bus
*bus
, sd_bus_message
*m
) {
100 r
= sd_bus_get_unique_name(bus
, &unique
);
102 return log_error_errno(r
, "Failed to get unique name: %m");
104 r
= sd_bus_message_append(m
, "(sv)", "Controller", "s", unique
);
106 return bus_log_create_error(r
);
111 static int can_set_coredump_receive(sd_bus
*bus
) {
112 _cleanup_(sd_bus_error_free
) sd_bus_error e
= SD_BUS_ERROR_NULL
;
113 _cleanup_free_
char *path
= NULL
;
118 path
= unit_dbus_path_from_name(SPECIAL_INIT_SCOPE
);
122 r
= sd_bus_get_property_trivial(
124 "org.freedesktop.systemd1",
126 "org.freedesktop.systemd1.Scope",
130 if (r
< 0 && !sd_bus_error_has_names(&e
, SD_BUS_ERROR_UNKNOWN_PROPERTY
, SD_BUS_ERROR_PROPERTY_READ_ONLY
))
131 log_warning_errno(r
, "Failed to determine if CoredumpReceive= can be set, assuming it cannot be: %s",
132 bus_error_message(&e
, r
));
137 int register_machine(
139 const char *machine_name
,
141 const char *directory
,
149 sd_bus_message
*properties_message
,
152 StartMode start_mode
) {
154 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
163 "RegisterMachineWithNetwork",
168 SD_BUS_MESSAGE_APPEND_ID128(uuid
),
173 local_ifindex
> 0 ? 1 : 0, local_ifindex
);
175 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
177 r
= bus_message_new_method_call(bus
, &m
, bus_machine_mgr
, "CreateMachineWithNetwork");
179 return bus_log_create_error(r
);
181 r
= sd_bus_message_append(
185 SD_BUS_MESSAGE_APPEND_ID128(uuid
),
190 local_ifindex
> 0 ? 1 : 0, local_ifindex
);
192 return bus_log_create_error(r
);
194 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
196 return bus_log_create_error(r
);
198 if (!isempty(slice
)) {
199 r
= sd_bus_message_append(m
, "(sv)", "Slice", "s", slice
);
201 return bus_log_create_error(r
);
204 r
= append_controller_property(bus
, m
);
208 r
= append_machine_properties(
213 start_mode
== START_BOOT
&& can_set_coredump_receive(bus
) > 0);
217 if (properties_message
) {
218 r
= sd_bus_message_copy(m
, properties_message
, true);
220 return bus_log_create_error(r
);
223 r
= bus_append_unit_property_assignment_many(m
, UNIT_SERVICE
, properties
);
227 r
= sd_bus_message_close_container(m
);
229 return bus_log_create_error(r
);
231 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
234 return log_error_errno(r
, "Failed to register machine: %s", bus_error_message(&error
, r
));
239 int unregister_machine(
241 const char *machine_name
) {
243 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
248 r
= bus_call_method(bus
, bus_machine_mgr
, "UnregisterMachine", &error
, NULL
, "s", machine_name
);
250 log_debug("Failed to unregister machine: %s", bus_error_message(&error
, r
));
257 const char *machine_name
,
264 sd_bus_message
*properties_message
,
266 StartMode start_mode
) {
268 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
269 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
270 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
271 _cleanup_free_
char *scope
= NULL
;
272 const char *description
, *object
;
277 r
= bus_wait_for_jobs_new(bus
, &w
);
279 return log_error_errno(r
, "Could not watch job: %m");
281 r
= unit_name_mangle_with_suffix(machine_name
, "as machine name", 0, ".scope", &scope
);
283 return log_error_errno(r
, "Failed to mangle scope name: %m");
285 r
= bus_message_new_method_call(bus
, &m
, bus_systemd_mgr
, "StartTransientUnit");
287 return bus_log_create_error(r
);
289 r
= sd_bus_message_append(m
, "ss", scope
, "fail");
291 return bus_log_create_error(r
);
294 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
296 return bus_log_create_error(r
);
298 description
= strjoina("Container ", machine_name
);
301 _cleanup_(pidref_done
) PidRef pidref
= PIDREF_NULL
;
302 r
= pidref_set_pid(&pidref
, pid
);
304 return log_error_errno(r
, "Failed to allocate PID reference: %m");
306 r
= bus_append_scope_pidref(m
, &pidref
);
308 r
= sd_bus_message_append(m
, "(sv)", "PIDs", "au", 1, pid
);
310 return bus_log_create_error(r
);
312 r
= sd_bus_message_append(m
, "(sv)(sv)(sv)(sv)(sv)",
313 "Description", "s", description
,
315 "CollectMode", "s", "inactive-or-failed",
317 "Slice", "s", isempty(slice
) ? SPECIAL_MACHINE_SLICE
: slice
);
319 return bus_log_create_error(r
);
321 r
= append_controller_property(bus
, m
);
325 if (properties_message
) {
326 r
= sd_bus_message_copy(m
, properties_message
, true);
328 return bus_log_create_error(r
);
331 r
= append_machine_properties(
336 start_mode
== START_BOOT
&& can_set_coredump_receive(bus
) > 0);
340 r
= bus_append_unit_property_assignment_many(m
, UNIT_SCOPE
, properties
);
344 r
= sd_bus_message_close_container(m
);
346 return bus_log_create_error(r
);
348 /* No auxiliary units */
349 r
= sd_bus_message_append(
354 return bus_log_create_error(r
);
356 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
358 /* If this failed with a property we couldn't write, this is quite likely because the server
359 * doesn't support PIDFDs yet, let's try without. */
361 sd_bus_error_has_names(&error
, SD_BUS_ERROR_UNKNOWN_PROPERTY
, SD_BUS_ERROR_PROPERTY_READ_ONLY
))
362 return allocate_scope(bus
, machine_name
, pid
, slice
, mounts
, n_mounts
, kill_signal
, properties
, properties_message
, /* allow_pidfd= */ false, start_mode
);
364 return log_error_errno(r
, "Failed to allocate scope: %s", bus_error_message(&error
, r
));
367 r
= sd_bus_message_read(reply
, "o", &object
);
369 return bus_log_parse_error(r
);
371 r
= bus_wait_for_jobs_one(w
, object
, false, NULL
);
380 const char *machine_name
) {
382 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
383 _cleanup_free_
char *scope
= NULL
;
386 r
= unit_name_mangle_with_suffix(machine_name
, "to terminate", 0, ".scope", &scope
);
388 return log_error_errno(r
, "Failed to mangle scope name: %m");
390 r
= bus_call_method(bus
, bus_systemd_mgr
, "AbandonScope", &error
, NULL
, "s", scope
);
392 log_debug_errno(r
, "Failed to abandon scope '%s', ignoring: %s", scope
, bus_error_message(&error
, r
));
393 sd_bus_error_free(&error
);
407 log_debug_errno(r
, "Failed to SIGKILL scope '%s', ignoring: %s", scope
, bus_error_message(&error
, r
));
408 sd_bus_error_free(&error
);
411 r
= bus_call_method(bus
, bus_systemd_mgr
, "UnrefUnit", &error
, NULL
, "s", scope
);
413 log_debug_errno(r
, "Failed to drop reference to scope '%s', ignoring: %s", scope
, bus_error_message(&error
, r
));