]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
start: pass namespaces as environment variables
authorChristian Brauner <christian.brauner@ubuntu.com>
Sun, 10 Dec 2017 12:53:32 +0000 (13:53 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 14 Dec 2017 10:52:09 +0000 (11:52 +0100)
Unblocks #2013.
Unblocks #2015.
Closes #1766.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
doc/lxc.container.conf.sgml.in
src/lxc/namespace.c
src/lxc/namespace.h
src/lxc/start.c

index 9d4b4cb365a41e7d56755dd178e266ef800dfb10..43df6a632569336bd3b9347531dacba81d64b441 100644 (file)
@@ -1674,6 +1674,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
           used. </para></listitem>
           <listitem><para> LXC_LOG_LEVEL: the container's log level. </para></listitem>
           <listitem><para> LXC_NAME: is the container's name. </para></listitem>
+          <listitem><para> LXC_[NAMESPACE IDENTIFIER]_NS: path under
+          /proc/PID/fd/ to a file descriptor referring to the container's
+          namespace. For each preserved namespace type there will be a separate
+          environment variable. These environment variables will only be set if
+          <option>lxc.hook.version</option> is set to 1. </para></listitem>
           <listitem><para> LXC_ROOTFS_MOUNT: the path to the mounted root filesystem. </para></listitem>
           <listitem><para> LXC_ROOTFS_PATH: this is the lxc.rootfs.path entry
           for the container. Note this is likely not where the mounted rootfs is
@@ -1705,6 +1710,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
             independently of the value used for this config item.) The section
             will be set in LXC_HOOK_SECTION and the hook type will be set in
             LXC_HOOK_TYPE.
+            It also affects how the paths to file descriptors referring to the
+            container's namespaces are passed. If set to 1 then for each
+            namespace a separate environment variable LXC_[NAMESPACE
+            IDENTIFIER]_NS will be set. If set to 0 then the paths will be
+            passed as arguments to the stop hook.
             </para>
           </listitem>
         </varlistentry>
index da434052ae889c28d0c7eb54a58417798f7d75f5..d716676ed9391b790cee5f63b326622ce9ac2d9b 100644 (file)
@@ -87,13 +87,13 @@ pid_t lxc_clone(int (*fn)(void *), void *arg, int flags)
  *        linux/fs/namespace.c:mntns_install().
  */
 const struct ns_info ns_info[LXC_NS_MAX] = {
-       [LXC_NS_USER] = {"user", CLONE_NEWUSER, "CLONE_NEWUSER"},
-       [LXC_NS_MNT] = {"mnt", CLONE_NEWNS, "CLONE_NEWNS"},
-       [LXC_NS_PID] = {"pid", CLONE_NEWPID, "CLONE_NEWPID"},
-       [LXC_NS_UTS] = {"uts", CLONE_NEWUTS, "CLONE_NEWUTS"},
-       [LXC_NS_IPC] = {"ipc", CLONE_NEWIPC, "CLONE_NEWIPC"},
-       [LXC_NS_NET] = {"net", CLONE_NEWNET, "CLONE_NEWNET"},
-       [LXC_NS_CGROUP] = {"cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP"}
+       [LXC_NS_USER]    = { "user",   CLONE_NEWUSER,   "CLONE_NEWUSER",   "LXC_USER_NS"    },
+       [LXC_NS_MNT]    =  { "mnt",    CLONE_NEWNS,     "CLONE_NEWNS",     "LXC_MNT_NS"     },
+       [LXC_NS_PID]    =  { "pid",    CLONE_NEWPID,    "CLONE_NEWPID",    "LXC_PID_NS"     },
+       [LXC_NS_UTS]    =  { "uts",    CLONE_NEWUTS,    "CLONE_NEWUTS",    "LXC_UTS_NS"     },
+       [LXC_NS_IPC]    =  { "ipc",    CLONE_NEWIPC,    "CLONE_NEWIPC",    "LXC_IPC_NS"     },
+       [LXC_NS_NET]    =  { "net",    CLONE_NEWNET,    "CLONE_NEWNET",    "LXC_NET_NS"     },
+       [LXC_NS_CGROUP] =  { "cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP", "LXC_CGROUP_NS"  }
 };
 
 int lxc_namespace_2_cloneflag(const char *namespace)
index 02ec08885d0ee9bfc6cfe028709ac7191f69d97e..7644fcd60cf05795f962806bc02a51925a774dc0 100644 (file)
@@ -68,6 +68,7 @@ extern const struct ns_info {
        const char *proc_name;
        int clone_flag;
        const char *flag_name;
+       const char *env_name;
 } ns_info[LXC_NS_MAX];
 
 #if defined(__ia64__)
index d6cd543224272dfedce19836d0fcfaa6ce58bafc..b29540603be134abc227c2f6b756570b56400d24 100644 (file)
@@ -716,8 +716,8 @@ out_close_maincmd_fd:
 void lxc_fini(const char *name, struct lxc_handler *handler)
 {
        int i, rc;
+       pid_t self;
        struct lxc_list *cur, *next;
-       pid_t self = getpid();
        char *namespaces[LXC_NS_MAX + 1];
        size_t namespace_count = 0;
 
@@ -726,16 +726,37 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
         */
        lxc_set_state(name, handler, STOPPING);
 
+       self = getpid();
        for (i = 0; i < LXC_NS_MAX; i++) {
-               if (handler->nsfd[i] != -1) {
-                       rc = asprintf(&namespaces[namespace_count], "%s:/proc/%d/fd/%d",
-                                     ns_info[i].proc_name, self, handler->nsfd[i]);
-                       if (rc == -1) {
-                               SYSERROR("Failed to allocate memory.");
-                               break;
-                       }
-                       ++namespace_count;
+               if (handler->nsfd[i] < 0)
+                       continue;
+
+               if (handler->conf->hooks_version == 0)
+                       rc = asprintf(&namespaces[namespace_count],
+                                     "%s:/proc/%d/fd/%d", ns_info[i].proc_name,
+                                     self, handler->nsfd[i]);
+               else
+                       rc = asprintf(&namespaces[namespace_count],
+                                     "/proc/%d/fd/%d", self, handler->nsfd[i]);
+               if (rc == -1) {
+                       SYSERROR("Failed to allocate memory.");
+                       break;
                }
+
+               if (handler->conf->hooks_version == 0) {
+                       namespace_count++;
+                       continue;
+               }
+
+               rc = setenv(ns_info[i].env_name, namespaces[namespace_count], 1);
+               if (rc < 0)
+                       SYSERROR("Failed to set environment variable %s=%s",
+                                ns_info[i].env_name, namespaces[namespace_count]);
+               else
+                       TRACE("Set environment variable %s=%s",
+                             ns_info[i].env_name, namespaces[namespace_count]);
+
+               namespace_count++;
        }
        namespaces[namespace_count] = NULL;
 
@@ -745,8 +766,10 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
        if (!handler->conf->reboot && setenv("LXC_TARGET", "stop", 1))
                SYSERROR("Failed to set environment variable: LXC_TARGET=stop.");
 
-       if (run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, namespaces))
-               ERROR("Failed to run lxc.hook.stop for container \"%s\".", name);
+       if (handler->conf->hooks_version == 0)
+               rc = run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, namespaces);
+       else
+               rc = run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, NULL);
 
        while (namespace_count--)
                free(namespaces[namespace_count]);