diff options
-rw-r--r-- | man/systemd-nspawn.xml | 53 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 92 |
2 files changed, 114 insertions, 31 deletions
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index ca99da4909..47c3183eee 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -204,9 +204,12 @@ <listitem><para>Automatically search for an init binary and invoke it instead of a shell or a user supplied - program. If this option is used, arguments - specified on the command line are used - as arguments for the init binary. + program. If this option is used, + arguments specified on the command + line are used as arguments for the + init binary. This option may not be + combined with + <option>--share-system</option>. </para></listitem> </varlistentry> @@ -424,8 +427,7 @@ output by the tool itself. When this switch is used, then the only output by nspawn will be the console output - of the container OS - itself.</para></listitem> + of the container OS itself.</para></listitem> </varlistentry> <varlistentry> @@ -440,15 +442,42 @@ interact more easily with processes outside of the container. Note that using this option makes it impossible - to start up a full Operating System in the - container, as an init system cannot - operate in this mode. It is only - useful to run specific programs or - applications this way, without - involving an init - system in the container.</para></listitem> + to start up a full Operating System in + the container, as an init system + cannot operate in this mode. It is + only useful to run specific programs + or applications this way, without + involving an init system in the + container. This option implies + <option>--register=no</option>. This + option may not be combined with + <option>--boot</option>.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--register=</option></term> + + <listitem><para>Controls whether the + container is registered with + <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Takes + a boolean argument, defaults to + <literal>yes</literal>. This option + should be enabled when the container + runs a full Operating System (more + specifically: an init system), and is + useful to ensure the container is + accesible via + <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> + and shown by tools such as + <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If + the container does not run an init + system it is recommended to set this + option to <literal>no</literal>. Note + that <option>--share-system</option> + implies + <option>--register=no</option>. + </para></listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 759f9c1aef..0a81f97298 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -119,6 +119,7 @@ static char **arg_bind_ro = NULL; static char **arg_setenv = NULL; static bool arg_quiet = false; static bool arg_share_system = false; +static bool arg_register = true; static int help(void) { @@ -150,6 +151,7 @@ static int help(void) { " the container\n" " --bind-ro=PATH[:PATH] Similar, but creates a read-only bind mount\n" " --setenv=NAME=VALUE Pass an environment variable to PID 1\n" + " --register=BOOLEAN Register container as machine\n" " -q --quiet Do not show status information\n", program_invocation_short_name); @@ -169,7 +171,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_BIND, ARG_BIND_RO, ARG_SETENV, - ARG_SHARE_SYSTEM + ARG_SHARE_SYSTEM, + ARG_REGISTER }; static const struct option options[] = { @@ -193,6 +196,7 @@ static int parse_argv(int argc, char *argv[]) { { "selinux-apifs-context", required_argument, NULL, 'L' }, { "quiet", no_argument, NULL, 'q' }, { "share-system", no_argument, NULL, ARG_SHARE_SYSTEM }, + { "register", required_argument, NULL, ARG_REGISTER }, {} }; @@ -255,17 +259,23 @@ static int parse_argv(int argc, char *argv[]) { break; case 'M': - if (!hostname_is_valid(optarg)) { - log_error("Invalid machine name: %s", optarg); - return -EINVAL; - } + if (isempty(optarg)) { + free(arg_machine); + arg_machine = NULL; + } else { - free(arg_machine); - arg_machine = strdup(optarg); - if (!arg_machine) - return log_oom(); + if (!hostname_is_valid(optarg)) { + log_error("Invalid machine name: %s", optarg); + return -EINVAL; + } - break; + free(arg_machine); + arg_machine = strdup(optarg); + if (!arg_machine) + return log_oom(); + + break; + } case 'Z': arg_selinux_context = optarg; @@ -390,6 +400,16 @@ static int parse_argv(int argc, char *argv[]) { arg_share_system = true; break; + case ARG_REGISTER: + r = parse_boolean(optarg); + if (r < 0) { + log_error("Failed to parse --register= argument: %s", optarg); + return r; + } + + arg_register = r; + break; + case '?': return -EINVAL; @@ -398,6 +418,14 @@ static int parse_argv(int argc, char *argv[]) { } } + if (arg_share_system) + arg_register = false; + + if (arg_boot && arg_share_system) { + log_error("--boot and --share-system may not be combined."); + return -EINVAL; + } + return 1; } @@ -636,6 +664,9 @@ static int setup_boot_id(const char *dest) { assert(dest); + if (arg_share_system) + return 0; + /* Generate a new randomized boot ID, so that each boot-up of * the container gets a new one */ @@ -861,6 +892,9 @@ static int setup_kmsg(const char *dest, int kmsg_socket) { static int setup_hostname(void) { + if (arg_share_system) + return 0; + if (sethostname(arg_machine, strlen(arg_machine)) < 0) return -errno; @@ -1043,6 +1077,9 @@ static int register_machine(pid_t pid) { _cleanup_bus_unref_ sd_bus *bus = NULL; int r; + if (!arg_register) + return 0; + r = sd_bus_default_system(&bus); if (r < 0) { log_error("Failed to open system bus: %s", strerror(-r)); @@ -1080,6 +1117,9 @@ static int terminate_machine(pid_t pid) { const char *path; int r; + if (!arg_register) + return 0; + r = sd_bus_default_system(&bus); if (r < 0) { log_error("Failed to open system bus: %s", strerror(-r)); @@ -1146,7 +1186,6 @@ int main(int argc, char *argv[]) { _cleanup_close_pipe_ int kmsg_socket_pair[2] = { -1, -1 }; _cleanup_fdset_free_ FDSet *fds = NULL; _cleanup_free_ char *kdbus_domain = NULL; - const char *ns; log_parse_environment(); log_open(); @@ -1248,12 +1287,26 @@ int main(int argc, char *argv[]) { goto finish; } - ns = strappenda("machine-", arg_machine); - kdbus_fd = bus_kernel_create_domain(ns, &kdbus_domain); - if (r < 0) - log_debug("Failed to create kdbus domain: %s", strerror(-r)); - else - log_debug("Successfully created kdbus domain as %s", kdbus_domain); + + if (access("/dev/kdbus/control", F_OK) >= 0) { + + if (arg_share_system) { + kdbus_domain = strdup("/dev/kdbus"); + if (!kdbus_domain) { + log_oom(); + goto finish; + } + } else { + const char *ns; + + ns = strappenda("machine-", arg_machine); + kdbus_fd = bus_kernel_create_domain(ns, &kdbus_domain); + if (r < 0) + log_debug("Failed to create kdbus domain: %s", strerror(-r)); + else + log_debug("Successfully created kdbus domain as %s", kdbus_domain); + } + } if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) { log_error("Failed to create kmsg socket pair: %m"); @@ -1438,7 +1491,8 @@ int main(int argc, char *argv[]) { umask(0022); - loopback_setup(); + if (arg_private_network) + loopback_setup(); if (drop_capabilities() < 0) { log_error("drop_capabilities() failed: %m"); @@ -1644,7 +1698,7 @@ int main(int argc, char *argv[]) { } else if (status.si_code == CLD_KILLED || status.si_code == CLD_DUMPED) { - log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status)); + log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status)); r = EXIT_FAILURE; break; } else { |