diff --git a/src/lxc/start.c b/src/lxc/start.c index bf1a589ba..bc6b2252b 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1585,6 +1585,18 @@ static int core_scheduling(struct lxc_handler *handler) return 0; } +static bool inherits_namespaces(const struct lxc_handler *handler) +{ + struct lxc_conf *conf = handler->conf; + + for (lxc_namespace_t i = 0; i < LXC_NS_MAX; i++) { + if (conf->ns_share[i]) + return true; + } + + return false; +} + /* lxc_spawn() performs crucial setup tasks and clone()s the new process which * exec()s the requested container binary. * Note that lxc_spawn() runs in the parent namespaces. Any operations performed @@ -1600,25 +1612,12 @@ static int lxc_spawn(struct lxc_handler *handler) bool wants_to_map_ids; struct list_head *id_map; const char *name = handler->name; - const char *lxcpath = handler->lxcpath; - bool share_ns = false; struct lxc_conf *conf = handler->conf; struct cgroup_ops *cgroup_ops = handler->cgroup_ops; id_map = &conf->id_map; wants_to_map_ids = !list_empty(id_map); - for (i = 0; i < LXC_NS_MAX; i++) { - if (!conf->ns_share[i]) - continue; - - handler->nsfd[i] = lxc_inherit_namespace(conf->ns_share[i], lxcpath, ns_info[i].proc_name); - if (handler->nsfd[i] < 0) - return -1; - - share_ns = true; - } - if (!lxc_sync_init(handler)) return -1; @@ -1629,10 +1628,6 @@ static int lxc_spawn(struct lxc_handler *handler) data_sock0 = handler->data_sock[0]; data_sock1 = handler->data_sock[1]; - ret = resolve_clone_flags(handler); - if (ret < 0) - goto out_sync_fini; - if (handler->ns_clone_flags & CLONE_NEWNET) { ret = lxc_find_gateway_addresses(handler); if (ret) { @@ -1647,7 +1642,7 @@ static int lxc_spawn(struct lxc_handler *handler) } /* Create a process in a new set of namespaces. */ - if (share_ns) { + if (inherits_namespaces(handler)) { pid_t attacher_pid; attacher_pid = lxc_clone(do_share_ns, handler, @@ -1992,6 +1987,28 @@ out_sync_fini: return -1; } +static int lxc_inherit_namespaces(struct lxc_handler *handler) +{ + const char *lxcpath = handler->lxcpath; + struct lxc_conf *conf = handler->conf; + + for (lxc_namespace_t i = 0; i < LXC_NS_MAX; i++) { + if (!conf->ns_share[i]) + continue; + + handler->nsfd[i] = lxc_inherit_namespace(conf->ns_share[i], + lxcpath, + ns_info[i].proc_name); + if (handler->nsfd[i] < 0) + return -1; + + TRACE("Recording inherited %s namespace with fd %d", + ns_info[i].proc_name, handler->nsfd[i]); + } + + return 0; +} + int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, void *data, const char *lxcpath, bool daemonize, int *error_num) { @@ -2034,6 +2051,20 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, goto out_abort; } + ret = resolve_clone_flags(handler); + if (ret < 0) { + ERROR("Failed to resolve clone flags"); + ret = -1; + goto out_abort; + } + + ret = lxc_inherit_namespaces(handler); + if (ret) { + SYSERROR("Failed to record inherited namespaces"); + ret = -1; + goto out_abort; + } + /* If the rootfs is not a blockdev, prevent the container from marking * it readonly. * If the container is unprivileged then skip rootfs pinning.