nspawn: split out machined registration code to nspawn-register.[ch]
This commit is contained in:
+18
-218
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user