Skip to content

Commit

Permalink
start: pass namespaces as environment variables
Browse files Browse the repository at this point in the history
Unblocks lxc#2015.
Closes lxc#1766.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
  • Loading branch information
Christian Brauner committed Dec 10, 2017
1 parent 1be2970 commit ef570db
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 18 deletions.
10 changes: 10 additions & 0 deletions doc/lxc.container.conf.sgml.in
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</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
Expand All @@ -1638,6 +1643,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
This setting affects the container name, section (always 'lxc') and
the hook type (i.e. 'clone' or 'pre-mount') which are passed via
LXC_HOOK_ARGS when 1 is set.
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 stopp hook.
</para>
</listitem>
</varlistentry>
Expand Down
14 changes: 7 additions & 7 deletions src/lxc/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/lxc/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down
45 changes: 34 additions & 11 deletions src/lxc/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,8 +708,8 @@ int lxc_init(const char *name, struct lxc_handler *handler)
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;

Expand All @@ -718,16 +718,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;

Expand All @@ -737,8 +758,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]);
Expand Down

0 comments on commit ef570db

Please sign in to comment.