start: cleanup namespace handling

parent 1fd0f41e
...@@ -421,7 +421,7 @@ int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath) ...@@ -421,7 +421,7 @@ int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req, static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler) struct lxc_handler *handler)
{ {
struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->clone_flags) }; struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->ns_clone_flags) };
return lxc_cmd_rsp_send(fd, &rsp); return lxc_cmd_rsp_send(fd, &rsp);
} }
......
...@@ -143,10 +143,10 @@ static void lxc_put_nsfds(struct lxc_handler *handler) ...@@ -143,10 +143,10 @@ static void lxc_put_nsfds(struct lxc_handler *handler)
} }
/* lxc_preserve_namespaces: open /proc/@pid/ns/@ns for each namespace specified /* lxc_preserve_namespaces: open /proc/@pid/ns/@ns for each namespace specified
* in clone_flags. * in ns_clone_flags.
* Return true on success, false on failure. * Return true on success, false on failure.
*/ */
static bool lxc_preserve_namespaces(struct lxc_handler *handler, int clone_flags, pid_t pid) static bool lxc_preserve_namespaces(struct lxc_handler *handler, int ns_clone_flags, pid_t pid)
{ {
int i; int i;
...@@ -154,7 +154,7 @@ static bool lxc_preserve_namespaces(struct lxc_handler *handler, int clone_flags ...@@ -154,7 +154,7 @@ static bool lxc_preserve_namespaces(struct lxc_handler *handler, int clone_flags
handler->nsfd[i] = -EBADF; handler->nsfd[i] = -EBADF;
for (i = 0; i < LXC_NS_MAX; i++) { for (i = 0; i < LXC_NS_MAX; i++) {
if ((clone_flags & ns_info[i].clone_flag) == 0) if ((ns_clone_flags & ns_info[i].clone_flag) == 0)
continue; continue;
handler->nsfd[i] = lxc_preserve_ns(pid, ns_info[i].proc_name); handler->nsfd[i] = lxc_preserve_ns(pid, ns_info[i].proc_name);
...@@ -590,7 +590,7 @@ void lxc_zero_handler(struct lxc_handler *handler) ...@@ -590,7 +590,7 @@ void lxc_zero_handler(struct lxc_handler *handler)
memset(handler, 0, sizeof(struct lxc_handler)); memset(handler, 0, sizeof(struct lxc_handler));
handler->clone_flags = -1; handler->ns_clone_flags = -1;
handler->pinfd = -1; handler->pinfd = -1;
...@@ -1038,7 +1038,7 @@ static int do_start(void *data) ...@@ -1038,7 +1038,7 @@ static int do_start(void *data)
/* Unshare CLONE_NEWNET after CLONE_NEWUSER. See /* Unshare CLONE_NEWNET after CLONE_NEWUSER. See
* https://github.com/lxc/lxd/issues/1978. * https://github.com/lxc/lxd/issues/1978.
*/ */
if ((handler->clone_flags & (CLONE_NEWNET | CLONE_NEWUSER)) == if ((handler->ns_clone_flags & (CLONE_NEWNET | CLONE_NEWUSER)) ==
(CLONE_NEWNET | CLONE_NEWUSER)) { (CLONE_NEWNET | CLONE_NEWUSER)) {
ret = unshare(CLONE_NEWNET); ret = unshare(CLONE_NEWNET);
if (ret < 0) { if (ret < 0) {
...@@ -1148,7 +1148,7 @@ static int do_start(void *data) ...@@ -1148,7 +1148,7 @@ static int do_start(void *data)
* *
* 8:cpuset:/ * 8:cpuset:/
*/ */
if (handler->clone_flags & CLONE_NEWCGROUP) { if (handler->ns_clone_flags & CLONE_NEWCGROUP) {
ret = unshare(CLONE_NEWCGROUP); ret = unshare(CLONE_NEWCGROUP);
if (ret < 0) { if (ret < 0) {
INFO("Failed to unshare CLONE_NEWCGROUP"); INFO("Failed to unshare CLONE_NEWCGROUP");
...@@ -1389,10 +1389,10 @@ int resolve_clone_flags(struct lxc_handler *handler) ...@@ -1389,10 +1389,10 @@ int resolve_clone_flags(struct lxc_handler *handler)
for (i = 0; i < LXC_NS_MAX; i++) { for (i = 0; i < LXC_NS_MAX; i++) {
if (conf->ns_keep != 0) { if (conf->ns_keep != 0) {
if ((conf->ns_keep & ns_info[i].clone_flag) == 0) if ((conf->ns_keep & ns_info[i].clone_flag) == 0)
handler->clone_flags |= ns_info[i].clone_flag; handler->ns_clone_flags |= ns_info[i].clone_flag;
} else if (conf->ns_clone != 0) { } else if (conf->ns_clone != 0) {
if ((conf->ns_clone & ns_info[i].clone_flag) > 0) if ((conf->ns_clone & ns_info[i].clone_flag) > 0)
handler->clone_flags |= ns_info[i].clone_flag; handler->ns_clone_flags |= ns_info[i].clone_flag;
} else { } else {
if (i == LXC_NS_USER && lxc_list_empty(&handler->conf->id_map)) if (i == LXC_NS_USER && lxc_list_empty(&handler->conf->id_map))
continue; continue;
...@@ -1403,13 +1403,13 @@ int resolve_clone_flags(struct lxc_handler *handler) ...@@ -1403,13 +1403,13 @@ int resolve_clone_flags(struct lxc_handler *handler)
if (i == LXC_NS_CGROUP && !cgns_supported()) if (i == LXC_NS_CGROUP && !cgns_supported())
continue; continue;
handler->clone_flags |= ns_info[i].clone_flag; handler->ns_clone_flags |= ns_info[i].clone_flag;
} }
if (!conf->ns_share[i]) if (!conf->ns_share[i])
continue; continue;
handler->clone_flags &= ~ns_info[i].clone_flag; handler->ns_clone_flags &= ~ns_info[i].clone_flag;
TRACE("Sharing %s namespace", ns_info[i].proc_name); TRACE("Sharing %s namespace", ns_info[i].proc_name);
} }
...@@ -1444,7 +1444,7 @@ static inline int do_share_ns(void *arg) ...@@ -1444,7 +1444,7 @@ static inline int do_share_ns(void *arg)
DEBUG("Inherited %s namespace", ns_info[i].proc_name); DEBUG("Inherited %s namespace", ns_info[i].proc_name);
} }
flags = handler->on_clone_flags; flags = handler->ns_on_clone_flags;
flags |= CLONE_PARENT; flags |= CLONE_PARENT;
handler->pid = lxc_raw_clone_cb(do_start, handler, flags); handler->pid = lxc_raw_clone_cb(do_start, handler, flags);
if (handler->pid < 0) if (handler->pid < 0)
...@@ -1502,7 +1502,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1502,7 +1502,7 @@ static int lxc_spawn(struct lxc_handler *handler)
return -1; return -1;
} }
if (handler->clone_flags & CLONE_NEWNET) { if (handler->ns_clone_flags & CLONE_NEWNET) {
if (!lxc_list_empty(&conf->network)) { if (!lxc_list_empty(&conf->network)) {
/* Find gateway addresses from the link device, which is /* Find gateway addresses from the link device, which is
...@@ -1552,17 +1552,17 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1552,17 +1552,17 @@ static int lxc_spawn(struct lxc_handler *handler)
} }
/* Create a process in a new set of namespaces. */ /* Create a process in a new set of namespaces. */
handler->on_clone_flags = handler->clone_flags; handler->ns_on_clone_flags = handler->ns_clone_flags;
if (handler->clone_flags & CLONE_NEWUSER) { if (handler->ns_clone_flags & CLONE_NEWUSER) {
/* If CLONE_NEWUSER and CLONE_NEWNET was requested, we need to /* If CLONE_NEWUSER and CLONE_NEWNET was requested, we need to
* clone a new user namespace first and only later unshare our * clone a new user namespace first and only later unshare our
* network namespace to ensure that network devices ownership is * network namespace to ensure that network devices ownership is
* set up correctly. * set up correctly.
*/ */
handler->on_clone_flags &= ~CLONE_NEWNET; handler->ns_on_clone_flags &= ~CLONE_NEWNET;
} }
/* The cgroup namespace gets unshare()ed not clone()ed. */ /* The cgroup namespace gets unshare()ed not clone()ed. */
handler->on_clone_flags &= ~CLONE_NEWCGROUP; handler->ns_on_clone_flags &= ~CLONE_NEWCGROUP;
if (share_ns) { if (share_ns) {
pid_t attacher_pid; pid_t attacher_pid;
...@@ -1581,7 +1581,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1581,7 +1581,7 @@ static int lxc_spawn(struct lxc_handler *handler)
} }
} else { } else {
handler->pid = lxc_raw_clone_cb(do_start, handler, handler->pid = lxc_raw_clone_cb(do_start, handler,
handler->on_clone_flags); handler->ns_on_clone_flags);
} }
if (handler->pid < 0) { if (handler->pid < 0) {
SYSERROR(LXC_CLONE_ERROR); SYSERROR(LXC_CLONE_ERROR);
...@@ -1590,10 +1590,10 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1590,10 +1590,10 @@ static int lxc_spawn(struct lxc_handler *handler)
TRACE("Cloned child process %d", handler->pid); TRACE("Cloned child process %d", handler->pid);
for (i = 0; i < LXC_NS_MAX; i++) for (i = 0; i < LXC_NS_MAX; i++)
if (handler->on_clone_flags & ns_info[i].clone_flag) if (handler->ns_on_clone_flags & ns_info[i].clone_flag)
INFO("Cloned %s", ns_info[i].flag_name); INFO("Cloned %s", ns_info[i].flag_name);
if (!lxc_preserve_namespaces(handler, handler->on_clone_flags, handler->pid)) { if (!lxc_preserve_namespaces(handler, handler->ns_on_clone_flags, handler->pid)) {
ERROR("Failed to preserve cloned namespaces for lxc.hook.stop"); ERROR("Failed to preserve cloned namespaces for lxc.hook.stop");
goto out_delete_net; goto out_delete_net;
} }
...@@ -1651,7 +1651,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1651,7 +1651,7 @@ static int lxc_spawn(struct lxc_handler *handler)
DEBUG("Preserved net namespace via fd %d", ret); DEBUG("Preserved net namespace via fd %d", ret);
/* Create the network configuration. */ /* Create the network configuration. */
if (handler->clone_flags & CLONE_NEWNET) { if (handler->ns_clone_flags & CLONE_NEWNET) {
ret = lxc_network_move_created_netdev_priv(handler->lxcpath, ret = lxc_network_move_created_netdev_priv(handler->lxcpath,
handler->name, handler->name,
&conf->network, &conf->network,
...@@ -1709,7 +1709,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1709,7 +1709,7 @@ static int lxc_spawn(struct lxc_handler *handler)
cgroup_disconnect(); cgroup_disconnect();
cgroups_connected = false; cgroups_connected = false;
if (handler->clone_flags & CLONE_NEWCGROUP) { if (handler->ns_clone_flags & CLONE_NEWCGROUP) {
/* Now we're ready to preserve the cgroup namespace */ /* Now we're ready to preserve the cgroup namespace */
ret = lxc_preserve_ns(handler->pid, "cgroup"); ret = lxc_preserve_ns(handler->pid, "cgroup");
if (ret < 0) { if (ret < 0) {
...@@ -1784,7 +1784,7 @@ out_delete_net: ...@@ -1784,7 +1784,7 @@ out_delete_net:
if (cgroups_connected) if (cgroups_connected)
cgroup_disconnect(); cgroup_disconnect();
if (handler->clone_flags & CLONE_NEWNET) if (handler->ns_clone_flags & CLONE_NEWNET)
lxc_delete_network(handler); lxc_delete_network(handler);
out_abort: out_abort:
......
...@@ -37,14 +37,32 @@ ...@@ -37,14 +37,32 @@
#include "state.h" #include "state.h"
struct lxc_handler { struct lxc_handler {
/* The clone flags that were requested. */ /* Record the clone for namespaces flags that the container requested.
int clone_flags; *
* @ns_clone_flags
/* The clone flags to actually use when calling lxc_clone(). They may * - All clone flags that were requested.
* differ from clone_flags because of ordering requirements (e.g. *
* CLONE_NEWNET and CLONE_NEWUSER). * @ns_on_clone_flags
* - The clone flags for namespaces to actually use when calling
* lxc_clone(): After the container has started ns_on_clone_flags will
* list the clone flags that were unshare()ed rather then clone()ed
* because of ordering requirements (e.g. e.g. CLONE_NEWNET and
* CLONE_NEWUSER) or implementation details.
*
* @ns_keep_flags;
* - The clone flags for the namespaces that the container will inherit
* from the parent. They are not recorded in the handler itself but
* are present in the container's config.
*
* @ns_share_flags;
* - The clone flags for the namespaces that the container will share
* with another process. They are not recorded in the handler itself
* but are present in the container's config.
*/ */
int on_clone_flags; struct /* lxc_ns */ {
int ns_clone_flags;
int ns_on_clone_flags;
};
/* File descriptor to pin the rootfs for privileged containers. */ /* File descriptor to pin the rootfs for privileged containers. */
int pinfd; int pinfd;
......
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