chiark / gitweb /
nspawn: require /etc/os-release only for init
[elogind.git] / src / nspawn / nspawn.c
index c91f6cce21faf264a2f1680b0e337d1a53ba26a6..be8161c351917c5cb3a38defea971e4d13fd4858 100644 (file)
@@ -41,7 +41,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <sys/eventfd.h>
-#if HAVE_SELINUX
+#ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
 #endif
 
@@ -80,8 +80,8 @@ static char *arg_directory = NULL;
 static char *arg_user = NULL;
 static sd_id128_t arg_uuid = {};
 static char *arg_machine = NULL;
-static char *process_label = NULL;
-static char *file_label = NULL;
+static char *arg_process_label = NULL;
+static char *arg_apifs_label = NULL;
 static const char *arg_slice = NULL;
 static bool arg_private_network = false;
 static bool arg_read_only = false;
@@ -117,6 +117,7 @@ static uint64_t arg_retain =
 static char **arg_bind = NULL;
 static char **arg_bind_ro = NULL;
 static char **arg_setenv = NULL;
+static bool arg_quiet = false;
 
 static int help(void) {
 
@@ -130,8 +131,10 @@ static int help(void) {
                "     --uuid=UUID            Set a specific machine UUID for the container\n"
                "  -M --machine=NAME         Set the machine name for the container\n"
                "  -S --slice=SLICE          Place the container in the specified slice\n"
-               "  -L --file-label=LABEL     Set the MAC file label to be used by tmpfs file systems in container\n"
-               "  -Z --process-label=LABEL  Set the MAC label to be used by processes in container\n"
+               "  -L --apifs-label=LABEL    Set the MAC file label to be used by API/tmpfs file\n"
+               "                            systems in the container\n"
+               "  -Z --process-label=LABEL  Set the MAC label to be used by processes in\n"
+               "                            the container\n"
                "     --private-network      Disable network in container\n"
                "     --read-only            Mount the root directory read-only\n"
                "     --capability=CAP       In addition to the default, retain specified\n"
@@ -142,7 +145,8 @@ static int help(void) {
                "     --bind=PATH[:PATH]     Bind mount a file or directory from the host into\n"
                "                            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",
+               "     --setenv=NAME=VALUE    Pass an environment variable to PID 1\n"
+               "  -q --quiet                Do not show status information\n",
                program_invocation_short_name);
 
         return 0;
@@ -181,7 +185,8 @@ static int parse_argv(int argc, char *argv[]) {
                 { "slice",           required_argument, NULL, 'S'                 },
                 { "setenv",          required_argument, NULL, ARG_SETENV          },
                 { "process-label",   required_argument, NULL, 'Z'                 },
-                { "file-label",      required_argument, NULL, 'L'                 },
+                { "apifs-label",     required_argument, NULL, 'L'                 },
+                { "quiet",           no_argument,       NULL, 'q'                 },
                 {}
         };
 
@@ -190,7 +195,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:q", options, NULL)) >= 0) {
 
                 switch (c) {
 
@@ -257,17 +262,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'L':
-                        file_label = strdup(optarg);
-                        if (!file_label)
-                                return log_oom();
-
+                        arg_apifs_label = optarg;
                         break;
 
                 case 'Z':
-                        process_label = strdup(optarg);
-                        if (!process_label)
-                                return log_oom();
-
+                        arg_process_label = optarg;
                         break;
 
                 case ARG_READ_ONLY:
@@ -377,6 +376,10 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case 'q':
+                        arg_quiet = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -419,7 +422,10 @@ static int mount_all(const char *dest) {
 
         for (k = 0; k < ELEMENTSOF(mount_table); k++) {
                 _cleanup_free_ char *where = NULL;
+#ifdef HAVE_SELINUX
                 _cleanup_free_ char *options = NULL;
+#endif
+                const char *o;
                 int t;
 
                 where = strjoin(dest, "/", mount_table[k].where, NULL);
@@ -443,21 +449,22 @@ static int mount_all(const char *dest) {
                 mkdir_p(where, 0755);
 
 #ifdef HAVE_SELINUX
-                if (file_label && (streq_ptr(mount_table[k].what, "tmpfs") ||
-                              streq_ptr(mount_table[k].what, "devpts")))
-                        options = strjoin(mount_table[k].options, ",context=\"", file_label, "\"", NULL);
-                else
+                if (arg_apifs_label && (streq_ptr(mount_table[k].what, "tmpfs") || streq_ptr(mount_table[k].what, "devpts"))) {
+                        options = strjoin(mount_table[k].options, ",context=\"", arg_apifs_label, "\"", NULL);
+                        if (!options)
+                                return log_oom();
+
+                        o = options;
+                } else
 #endif
-                        options = strjoin(mount_table[k].options, NULL);
+                        o = mount_table[k].options;
 
-                if (!options)
-                        return log_oom();
 
                 if (mount(mount_table[k].what,
                           where,
                           mount_table[k].type,
                           mount_table[k].flags,
-                          options) < 0 &&
+                          o) < 0 &&
                     mount_table[k].fatal) {
 
                         log_error("mount(%s) failed: %m", where);
@@ -1025,7 +1032,7 @@ static int register_machine(pid_t pid) {
         _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
 
-        r = sd_bus_open_system(&bus);
+        r = sd_bus_default_system(&bus);
         if (r < 0) {
                 log_error("Failed to open system bus: %s", strerror(-r));
                 return r;
@@ -1193,7 +1200,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if (path_is_os_tree(arg_directory) <= 0) {
+        if (arg_boot && path_is_os_tree(arg_directory) <= 0) {
                 log_error("Directory %s doesn't look like an OS root directory (/etc/os-release is missing). Refusing.", arg_directory);
                 goto finish;
         }
@@ -1222,7 +1229,8 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        log_info("Spawning container %s on %s. Press ^] three times within 1s to abort execution.", arg_machine, arg_directory);
+        if (!arg_quiet)
+                log_info("Spawning container %s on %s. Press ^] three times within 1s to abort execution.", arg_machine, arg_directory);
 
         if (unlockpt(master) < 0) {
                 log_error("Failed to unlock tty: %m");
@@ -1526,10 +1534,10 @@ int main(int argc, char *argv[]) {
                         } else
                                 env_use = (char**) envp;
 
-#if HAVE_SELINUX
-                        if (process_label)
-                                if (setexeccon(process_label) < 0)
-                                        log_error("setexeccon(\"%s\") failed: %m", process_label);
+#ifdef HAVE_SELINUX
+                        if (arg_process_label)
+                                if (setexeccon(arg_process_label) < 0)
+                                        log_error("setexeccon(\"%s\") failed: %m", arg_process_label);
 #endif
                         if (arg_boot) {
                                 char **a;
@@ -1579,7 +1587,8 @@ int main(int argc, char *argv[]) {
                         break;
                 }
 
-                putc('\n', stdout);
+                if (!arg_quiet)
+                        putc('\n', stdout);
 
                 /* Kill if it is not dead yet anyway */
                 terminate_machine(pid);
@@ -1602,16 +1611,21 @@ int main(int argc, char *argv[]) {
                                 break;
                         }
 
-                        log_debug("Container %s exited successfully.", arg_machine);
+                        if (!arg_quiet)
+                                log_debug("Container %s exited successfully.", arg_machine);
                         break;
                 } else if (status.si_code == CLD_KILLED &&
                            status.si_status == SIGINT) {
-                        log_info("Container %s has been shut down.", arg_machine);
+
+                        if (!arg_quiet)
+                                log_info("Container %s has been shut down.", arg_machine);
                         r = 0;
                         break;
                 } else if (status.si_code == CLD_KILLED &&
                            status.si_status == SIGHUP) {
-                        log_info("Container %s is being rebooted.", arg_machine);
+
+                        if (!arg_quiet)
+                                log_info("Container %s is being rebooted.", arg_machine);
                         continue;
                 } else if (status.si_code == CLD_KILLED ||
                            status.si_code == CLD_DUMPED) {