diff options
Diffstat (limited to 'src/nspawn/nspawn.c')
-rw-r--r-- | src/nspawn/nspawn.c | 236 |
1 files changed, 18 insertions, 218 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index c106b58859..fcabe24601 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -102,6 +102,7 @@ #include "nspawn-network.h" #include "nspawn-expose-ports.h" #include "nspawn-cgroup.h" +#include "nspawn-register.h" typedef enum ContainerStatus { CONTAINER_TERMINATED, @@ -1515,220 +1516,6 @@ static int drop_capabilities(void) { return capability_bounding_set_drop(~arg_retain, false); } -static int register_machine(pid_t pid, int local_ifindex) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; - int r; - - if (!arg_register) - return 0; - - r = sd_bus_default_system(&bus); - if (r < 0) - return log_error_errno(r, "Failed to open system bus: %m"); - - if (arg_keep_unit) { - r = sd_bus_call_method( - bus, - "org.freedesktop.machine1", - "/org/freedesktop/machine1", - "org.freedesktop.machine1.Manager", - "RegisterMachineWithNetwork", - &error, - NULL, - "sayssusai", - arg_machine, - SD_BUS_MESSAGE_APPEND_ID128(arg_uuid), - "nspawn", - "container", - (uint32_t) pid, - strempty(arg_directory), - local_ifindex > 0 ? 1 : 0, local_ifindex); - } else { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; - char **i; - unsigned j; - - r = sd_bus_message_new_method_call( - bus, - &m, - "org.freedesktop.machine1", - "/org/freedesktop/machine1", - "org.freedesktop.machine1.Manager", - "CreateMachineWithNetwork"); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_message_append( - m, - "sayssusai", - arg_machine, - SD_BUS_MESSAGE_APPEND_ID128(arg_uuid), - "nspawn", - "container", - (uint32_t) pid, - strempty(arg_directory), - local_ifindex > 0 ? 1 : 0, local_ifindex); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_message_open_container(m, 'a', "(sv)"); - if (r < 0) - return bus_log_create_error(r); - - if (!isempty(arg_slice)) { - r = sd_bus_message_append(m, "(sv)", "Slice", "s", arg_slice); - if (r < 0) - return bus_log_create_error(r); - } - - r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict"); - if (r < 0) - return bus_log_create_error(r); - - /* If you make changes here, also make sure to update - * systemd-nspawn@.service, to keep the device - * policies in sync regardless if we are run with or - * without the --keep-unit switch. */ - r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9, - /* Allow the container to - * access and create the API - * device nodes, so that - * PrivateDevices= in the - * container can work - * fine */ - "/dev/null", "rwm", - "/dev/zero", "rwm", - "/dev/full", "rwm", - "/dev/random", "rwm", - "/dev/urandom", "rwm", - "/dev/tty", "rwm", - "/dev/net/tun", "rwm", - /* Allow the container - * access to ptys. However, - * do not permit the - * container to ever create - * these device nodes. */ - "/dev/pts/ptmx", "rw", - "char-pts", "rw"); - if (r < 0) - return bus_log_create_error(r); - - for (j = 0; j < arg_n_custom_mounts; j++) { - CustomMount *cm = &arg_custom_mounts[j]; - - if (cm->type != CUSTOM_MOUNT_BIND) - continue; - - r = is_device_node(cm->source); - if (r < 0) - return log_error_errno(r, "Failed to stat %s: %m", cm->source); - - if (r) { - r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1, - cm->source, cm->read_only ? "r" : "rw"); - if (r < 0) - return log_error_errno(r, "Failed to append message arguments: %m"); - } - } - - if (arg_kill_signal != 0) { - r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", arg_kill_signal); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed"); - if (r < 0) - return bus_log_create_error(r); - } - - STRV_FOREACH(i, arg_property) { - r = sd_bus_message_open_container(m, 'r', "sv"); - if (r < 0) - return bus_log_create_error(r); - - r = bus_append_unit_property_assignment(m, *i); - if (r < 0) - return r; - - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); - } - - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_call(bus, m, 0, &error, NULL); - } - - if (r < 0) { - log_error("Failed to register machine: %s", bus_error_message(&error, r)); - return r; - } - - return 0; -} - -static int terminate_machine(pid_t pid) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; - const char *path; - int r; - - if (!arg_register) - return 0; - - /* If we are reusing the unit, then just exit, systemd will do - * the right thing when we exit. */ - if (arg_keep_unit) - return 0; - - r = sd_bus_default_system(&bus); - if (r < 0) - return log_error_errno(r, "Failed to open system bus: %m"); - - r = sd_bus_call_method( - bus, - "org.freedesktop.machine1", - "/org/freedesktop/machine1", - "org.freedesktop.machine1.Manager", - "GetMachineByPID", - &error, - &reply, - "u", - (uint32_t) pid); - if (r < 0) { - /* Note that the machine might already have been - * cleaned up automatically, hence don't consider it a - * failure if we cannot get the machine object. */ - log_debug("Failed to get machine: %s", bus_error_message(&error, r)); - return 0; - } - - r = sd_bus_message_read(reply, "o", &path); - if (r < 0) - return bus_log_parse_error(r); - - r = sd_bus_call_method( - bus, - "org.freedesktop.machine1", - path, - "org.freedesktop.machine1.Machine", - "Terminate", - &error, - NULL, - NULL); - if (r < 0) { - log_debug("Failed to terminate machine: %s", bus_error_message(&error, r)); - return 0; - } - - return 0; -} - static int reset_audit_loginuid(void) { _cleanup_free_ char *p = NULL; int r; @@ -3904,9 +3691,21 @@ int main(int argc, char *argv[]) { goto finish; } - r = register_machine(pid, ifi); - if (r < 0) - goto finish; + if (arg_register) { + r = register_machine( + arg_machine, + pid, + arg_directory, + arg_uuid, + ifi, + arg_slice, + arg_custom_mounts, arg_n_custom_mounts, + arg_kill_signal, + arg_property, + arg_keep_unit); + if (r < 0) + goto finish; + } r = sync_cgroup(pid, arg_unified_cgroup_hierarchy); if (r < 0) @@ -4000,7 +3799,8 @@ int main(int argc, char *argv[]) { putc('\n', stdout); /* Kill if it is not dead yet anyway */ - terminate_machine(pid); + if (arg_register && !arg_keep_unit) + terminate_machine(pid); /* Normally redundant, but better safe than sorry */ kill(pid, SIGKILL); |