start: pass namespaces as environment variables

Unblocks #2013. Unblocks #2015. Closes #1766. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 3f60c2f7
...@@ -1674,6 +1674,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -1674,6 +1674,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
used. </para></listitem> used. </para></listitem>
<listitem><para> LXC_LOG_LEVEL: the container's log level. </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_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_MOUNT: the path to the mounted root filesystem. </para></listitem>
<listitem><para> LXC_ROOTFS_PATH: this is the lxc.rootfs.path entry <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 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 ...@@ -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 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 will be set in LXC_HOOK_SECTION and the hook type will be set in
LXC_HOOK_TYPE. 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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
...@@ -87,13 +87,13 @@ pid_t lxc_clone(int (*fn)(void *), void *arg, int flags) ...@@ -87,13 +87,13 @@ pid_t lxc_clone(int (*fn)(void *), void *arg, int flags)
* linux/fs/namespace.c:mntns_install(). * linux/fs/namespace.c:mntns_install().
*/ */
const struct ns_info ns_info[LXC_NS_MAX] = { const struct ns_info ns_info[LXC_NS_MAX] = {
[LXC_NS_USER] = {"user", CLONE_NEWUSER, "CLONE_NEWUSER"}, [LXC_NS_USER] = { "user", CLONE_NEWUSER, "CLONE_NEWUSER", "LXC_USER_NS" },
[LXC_NS_MNT] = {"mnt", CLONE_NEWNS, "CLONE_NEWNS"}, [LXC_NS_MNT] = { "mnt", CLONE_NEWNS, "CLONE_NEWNS", "LXC_MNT_NS" },
[LXC_NS_PID] = {"pid", CLONE_NEWPID, "CLONE_NEWPID"}, [LXC_NS_PID] = { "pid", CLONE_NEWPID, "CLONE_NEWPID", "LXC_PID_NS" },
[LXC_NS_UTS] = {"uts", CLONE_NEWUTS, "CLONE_NEWUTS"}, [LXC_NS_UTS] = { "uts", CLONE_NEWUTS, "CLONE_NEWUTS", "LXC_UTS_NS" },
[LXC_NS_IPC] = {"ipc", CLONE_NEWIPC, "CLONE_NEWIPC"}, [LXC_NS_IPC] = { "ipc", CLONE_NEWIPC, "CLONE_NEWIPC", "LXC_IPC_NS" },
[LXC_NS_NET] = {"net", CLONE_NEWNET, "CLONE_NEWNET"}, [LXC_NS_NET] = { "net", CLONE_NEWNET, "CLONE_NEWNET", "LXC_NET_NS" },
[LXC_NS_CGROUP] = {"cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP"} [LXC_NS_CGROUP] = { "cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP", "LXC_CGROUP_NS" }
}; };
int lxc_namespace_2_cloneflag(const char *namespace) int lxc_namespace_2_cloneflag(const char *namespace)
......
...@@ -68,6 +68,7 @@ extern const struct ns_info { ...@@ -68,6 +68,7 @@ extern const struct ns_info {
const char *proc_name; const char *proc_name;
int clone_flag; int clone_flag;
const char *flag_name; const char *flag_name;
const char *env_name;
} ns_info[LXC_NS_MAX]; } ns_info[LXC_NS_MAX];
#if defined(__ia64__) #if defined(__ia64__)
......
...@@ -716,8 +716,8 @@ out_close_maincmd_fd: ...@@ -716,8 +716,8 @@ out_close_maincmd_fd:
void lxc_fini(const char *name, struct lxc_handler *handler) void lxc_fini(const char *name, struct lxc_handler *handler)
{ {
int i, rc; int i, rc;
pid_t self;
struct lxc_list *cur, *next; struct lxc_list *cur, *next;
pid_t self = getpid();
char *namespaces[LXC_NS_MAX + 1]; char *namespaces[LXC_NS_MAX + 1];
size_t namespace_count = 0; size_t namespace_count = 0;
...@@ -726,16 +726,37 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -726,16 +726,37 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
*/ */
lxc_set_state(name, handler, STOPPING); lxc_set_state(name, handler, STOPPING);
self = getpid();
for (i = 0; i < LXC_NS_MAX; i++) { for (i = 0; i < LXC_NS_MAX; i++) {
if (handler->nsfd[i] != -1) { if (handler->nsfd[i] < 0)
rc = asprintf(&namespaces[namespace_count], "%s:/proc/%d/fd/%d", continue;
ns_info[i].proc_name, self, handler->nsfd[i]);
if (rc == -1) { if (handler->conf->hooks_version == 0)
SYSERROR("Failed to allocate memory."); rc = asprintf(&namespaces[namespace_count],
break; "%s:/proc/%d/fd/%d", ns_info[i].proc_name,
} self, handler->nsfd[i]);
++namespace_count; 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; namespaces[namespace_count] = NULL;
...@@ -745,8 +766,10 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -745,8 +766,10 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
if (!handler->conf->reboot && setenv("LXC_TARGET", "stop", 1)) if (!handler->conf->reboot && setenv("LXC_TARGET", "stop", 1))
SYSERROR("Failed to set environment variable: LXC_TARGET=stop."); SYSERROR("Failed to set environment variable: LXC_TARGET=stop.");
if (run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, namespaces)) if (handler->conf->hooks_version == 0)
ERROR("Failed to run lxc.hook.stop for container \"%s\".", name); 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--) while (namespace_count--)
free(namespaces[namespace_count]); free(namespaces[namespace_count]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment