From: Christian Brauner Date: Sun, 10 Dec 2017 12:53:32 +0000 (+0100) Subject: start: pass namespaces as environment variables X-Git-Tag: lxc-3.0.0.beta1~111^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18b3b9c17f40f5925225449e1fb1978a419aac49;p=thirdparty%2Flxc.git start: pass namespaces as environment variables Unblocks #2013. Unblocks #2015. Closes #1766. Signed-off-by: Christian Brauner --- diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index 9d4b4cb36..43df6a632 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -1674,6 +1674,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA used. LXC_LOG_LEVEL: the container's log level. LXC_NAME: is the container's name. + 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 + is set to 1. LXC_ROOTFS_MOUNT: the path to the mounted root filesystem. 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. diff --git a/src/lxc/namespace.c b/src/lxc/namespace.c index da434052a..d716676ed 100644 --- a/src/lxc/namespace.c +++ b/src/lxc/namespace.c @@ -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) diff --git a/src/lxc/namespace.h b/src/lxc/namespace.h index 02ec08885..7644fcd60 100644 --- a/src/lxc/namespace.h +++ b/src/lxc/namespace.h @@ -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__) diff --git a/src/lxc/start.c b/src/lxc/start.c index d6cd54322..b29540603 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -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]);