nspawn: split down SYSTEMD_NSPAWN_SHARE_SYSTEM (#4023)
authorLuca Bruno <luca.bruno@coreos.com>
Thu, 25 Aug 2016 22:08:26 +0000 (22:08 +0000)
committerLennart Poettering <lennart@poettering.net>
Thu, 25 Aug 2016 22:08:26 +0000 (00:08 +0200)
This commit follows further on the deprecation path for --share-system,
by splitting and gating each share-able namespace behind its own
environment flag.

src/nspawn/nspawn.c

index 24d2431..6d04209 100644 (file)
@@ -169,7 +169,6 @@ static CustomMount *arg_custom_mounts = NULL;
 static unsigned arg_n_custom_mounts = 0;
 static char **arg_setenv = NULL;
 static bool arg_quiet = false;
-static bool arg_share_system = false;
 static bool arg_register = true;
 static bool arg_keep_unit = false;
 static char **arg_network_interfaces = NULL;
@@ -195,6 +194,7 @@ static char **arg_parameters = NULL;
 static const char *arg_container_service_name = "systemd-nspawn";
 static bool arg_notify_ready = false;
 static bool arg_use_cgns = true;
+static unsigned long arg_clone_ns_flags = CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS;
 
 static void help(void) {
         printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
@@ -352,6 +352,17 @@ static int detect_unified_cgroup_hierarchy(void) {
         return 0;
 }
 
+static void parse_share_ns_env(const char *name, unsigned long ns_flag) {
+        int r;
+
+        r = getenv_bool(name);
+        if (r == -ENXIO)
+                return;
+        if (r < 0)
+                log_warning_errno(r, "Failed to parse %s from environment, defaulting to false.", name);
+        arg_clone_ns_flags = (arg_clone_ns_flags & ~ns_flag) | (r > 0 ? 0 : ns_flag);
+}
+
 static int parse_argv(int argc, char *argv[]) {
 
         enum {
@@ -824,8 +835,8 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_SHARE_SYSTEM:
                         /* We don't officially support this anymore, except for compat reasons. People should use the
-                         * $SYSTEMD_NSPAWN_SHARE_SYSTEM environment variable instead. */
-                        arg_share_system = true;
+                         * $SYSTEMD_NSPAWN_SHARE_* environment variables instead. */
+                        arg_clone_ns_flags = 0;
                         break;
 
                 case ARG_REGISTER:
@@ -1029,20 +1040,22 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
-        if (getenv_bool("SYSTEMD_NSPAWN_SHARE_SYSTEM") > 0)
-                arg_share_system = true;
+        parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_IPC", CLONE_NEWIPC);
+        parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_PID", CLONE_NEWPID);
+        parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS);
+        parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_SYSTEM", CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS);
 
-        if (arg_share_system)
+        if (arg_clone_ns_flags != (CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS)) {
                 arg_register = false;
+                if (arg_start_mode != START_PID1) {
+                        log_error("--boot cannot be used without namespacing.");
+                        return -EINVAL;
+                }
+        }
 
         if (arg_userns_mode == USER_NAMESPACE_PICK)
                 arg_userns_chown = true;
 
-        if (arg_start_mode != START_PID1 && arg_share_system) {
-                log_error("--boot and SYSTEMD_NSPAWN_SHARE_SYSTEM=1 may not be combined.");
-                return -EINVAL;
-        }
-
         if (arg_keep_unit && cg_pid_get_owner_uid(0, NULL) >= 0) {
                 log_error("--keep-unit may not be used when invoked from a user session.");
                 return -EINVAL;
@@ -1310,9 +1323,6 @@ static int setup_boot_id(const char *dest) {
         const char *from, *to;
         int r;
 
-        if (arg_share_system)
-                return 0;
-
         /* Generate a new randomized boot ID, so that each boot-up of
          * the container gets a new one */
 
@@ -1530,7 +1540,7 @@ static int on_address_change(sd_netlink *rtnl, sd_netlink_message *m, void *user
 
 static int setup_hostname(void) {
 
-        if (arg_share_system)
+        if ((arg_clone_ns_flags & CLONE_NEWUTS) == 0)
                 return 0;
 
         if (sethostname_idempotent(arg_machine) < 0)
@@ -1681,7 +1691,7 @@ static int reset_audit_loginuid(void) {
         _cleanup_free_ char *p = NULL;
         int r;
 
-        if (arg_share_system)
+        if ((arg_clone_ns_flags & CLONE_NEWPID) == 0)
                 return 0;
 
         r = read_one_line_file("/proc/self/loginuid", &p);
@@ -3088,7 +3098,7 @@ static int outer_child(
                 return fd;
 
         pid = raw_clone(SIGCHLD|CLONE_NEWNS|
-                        (arg_share_system ? 0 : CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS) |
+                        arg_clone_ns_flags |
                         (arg_private_network ? CLONE_NEWNET : 0) |
                         (arg_userns_mode != USER_NAMESPACE_NO ? CLONE_NEWUSER : 0));
         if (pid < 0)