From: Christian Brauner Date: Sat, 28 Oct 2017 20:07:27 +0000 (+0200) Subject: confile: add lxc.namespace. X-Git-Tag: lxc-3.0.0.beta1~201^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=28d9e29e18dcdae5bb9efb5613069d9fa658ea26;p=thirdparty%2Flxc.git confile: add lxc.namespace. This commit also gets rid of ~10 unnecessarily file descriptors that were kept open. Before we kept open: - A set of file descriptors that refer to the monitor's namespaces. These were only used to reattach to the monitor's namespace in lxc_spawn() and were never used anywhere else. So close them and don't keep them around. - A list of inherited file descriptors. - A list of file descriptors referring to the containers's namespaces to pass to lxc.hook.stop. This list duplicated inherited file descriptors. Let's simply use a single list in the handler that has all file descriptors we need and get rid of all other ones. As an illustration. Starting a container 1. Without this patch and looking at the fds that the monitor keeps open (26): chb@conventiont|~ > ls -al /proc/27219/fd total 0 dr-x------ 2 root root 0 Oct 29 14:30 . dr-xr-xr-x 9 root root 0 Oct 29 14:30 .. lrwx------ 1 root root 64 Oct 29 14:30 0 -> /dev/null lrwx------ 1 root root 64 Oct 29 14:30 1 -> /dev/null lrwx------ 1 root root 64 Oct 29 14:30 10 -> anon_inode:[signalfd] lrwx------ 1 root root 64 Oct 29 14:30 11 -> /dev/ptmx lrwx------ 1 root root 64 Oct 29 14:30 12 -> /dev/pts/10 lr-x------ 1 root root 64 Oct 29 14:30 13 -> net:[4026532553] lrwx------ 1 root root 64 Oct 29 14:30 15 -> socket:[7909181] lrwx------ 1 root root 64 Oct 29 14:30 16 -> socket:[7909182] lr-x------ 1 root root 64 Oct 29 14:30 17 -> uts:[4026531838] lr-x------ 1 root root 64 Oct 29 14:30 18 -> ipc:[4026531839] lr-x------ 1 root root 64 Oct 29 14:30 19 -> net:[4026532009] lrwx------ 1 root root 64 Oct 29 14:30 2 -> /dev/null lr-x------ 1 root root 64 Oct 29 14:30 20 -> mnt:[4026532611] lr-x------ 1 root root 64 Oct 29 14:30 21 -> pid:[4026532612] lr-x------ 1 root root 64 Oct 29 14:30 22 -> uts:[4026532548] lr-x------ 1 root root 64 Oct 29 14:30 23 -> ipc:[4026532549] lr-x------ 1 root root 64 Oct 29 14:30 24 -> net:[4026532553] l-wx------ 1 root root 64 Oct 29 14:30 3 -> /var/log/lxc/a1.log lr-x------ 1 root root 64 Oct 29 14:30 4 -> uts:[4026532548] lr-x------ 1 root root 64 Oct 29 14:30 5 -> ipc:[4026532549] lr-x------ 1 root root 64 Oct 29 14:30 6 -> net:[4026532553] lrwx------ 1 root root 64 Oct 29 14:30 7 -> anon_inode:[eventpoll] lrwx------ 1 root root 64 Oct 29 14:30 9 -> socket:[7911594] 2. With this patch and looking at the fds that the monitor keeps open (19): chb@conventiont|~ > ls -al /proc/28465/fd total 0 dr-x------ 2 root root 0 Oct 29 14:31 . dr-xr-xr-x 9 root root 0 Oct 29 14:31 .. lrwx------ 1 root root 64 Oct 29 14:31 0 -> /dev/null lrwx------ 1 root root 64 Oct 29 14:31 1 -> /dev/null lr-x------ 1 root root 64 Oct 29 14:31 10 -> net:[4026532820] lrwx------ 1 root root 64 Oct 29 14:31 12 -> socket:[7912349] lrwx------ 1 root root 64 Oct 29 14:31 13 -> socket:[7912350] lr-x------ 1 root root 64 Oct 29 14:31 14 -> mnt:[4026532611] lr-x------ 1 root root 64 Oct 29 14:31 15 -> pid:[4026532813] lr-x------ 1 root root 64 Oct 29 14:31 16 -> uts:[4026532612] lr-x------ 1 root root 64 Oct 29 14:31 17 -> ipc:[4026532613] lr-x------ 1 root root 64 Oct 29 14:31 18 -> net:[4026532820] lrwx------ 1 root root 64 Oct 29 14:31 2 -> /dev/null l-wx------ 1 root root 64 Oct 29 14:31 3 -> /var/log/lxc/a1.log lrwx------ 1 root root 64 Oct 29 14:31 4 -> anon_inode:[signalfd] lrwx------ 1 root root 64 Oct 29 14:31 5 -> /dev/ptmx lrwx------ 1 root root 64 Oct 29 14:31 6 -> /dev/pts/10 lrwx------ 1 root root 64 Oct 29 14:31 7 -> anon_inode:[eventpoll] lrwx------ 1 root root 64 Oct 29 14:31 9 -> socket:[7913041] Relates to #1881. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 8a66f2d02..2cea7c4a3 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2461,21 +2461,19 @@ struct lxc_conf *lxc_conf_init(void) lxc_list_init(&new->aliens); lxc_list_init(&new->environment); lxc_list_init(&new->limits); - for (i=0; ihooks[i]); lxc_list_init(&new->groups); new->lsm_aa_profile = NULL; new->lsm_se_context = NULL; new->tmp_umount_proc = 0; - for (i = 0; i < LXC_NS_MAX; i++) - new->inherit_ns_fd[i] = -1; - /* if running in a new user namespace, init and COMMAND * default to running as UID/GID 0 when using lxc-execute */ new->init_uid = 0; new->init_gid = 0; memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup)); + memset(&new->inherit_ns, 0, sizeof(char *) * LXC_NS_MAX); return new; } @@ -3155,7 +3153,7 @@ int lxc_setup_child(struct lxc_handler *handler) return -1; } - if (lxc_conf->inherit_ns_fd[LXC_NS_UTS] == -1) { + if (handler->nsfd[LXC_NS_UTS] == -1) { if (setup_utsname(lxc_conf->utsname)) { ERROR("failed to setup the utsname for '%s'", name); return -1; diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 63e71e2d8..063b58980 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -285,8 +285,6 @@ struct lxc_conf { int loglevel; /* loglevel as specifed in config (if any) */ int logfd; - int inherit_ns_fd[LXC_NS_MAX]; - unsigned int start_auto; unsigned int start_delay; int start_order; @@ -348,6 +346,8 @@ struct lxc_conf { * that union. */ struct lxc_cgroup cgroup_meta; + + char *inherit_ns[LXC_NS_MAX]; }; #ifdef HAVE_TLS diff --git a/src/lxc/confile.c b/src/lxc/confile.c index d94a30719..c4d4c2394 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -102,6 +102,7 @@ lxc_config_define(monitor); lxc_config_define(mount); lxc_config_define(mount_auto); lxc_config_define(mount_fstab); +lxc_config_define(namespace); lxc_config_define(net); lxc_config_define(net_flags); lxc_config_define(net_hwaddr); @@ -178,6 +179,7 @@ static struct lxc_config_t config[] = { { "lxc.mount.auto", false, set_config_mount_auto, get_config_mount_auto, clr_config_mount_auto, }, { "lxc.mount.entry", false, set_config_mount, get_config_mount, clr_config_mount, }, { "lxc.mount.fstab", false, set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, }, + { "lxc.namespace", false, set_config_namespace, get_config_namespace, clr_config_namespace, }, /* [START]: REMOVE IN LXC 3.0 */ { "lxc.network.type", true, set_config_network_legacy_type, get_config_network_legacy_item, clr_config_network_legacy_item, }, @@ -1976,6 +1978,23 @@ static int set_config_uts_name(const char *key, const char *value, return 0; } +static int set_config_namespace(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +{ + int ns_idx; + const char *namespace; + + if (lxc_config_value_empty(value)) + return clr_config_namespace(key, lxc_conf, data); + + namespace = key + sizeof("lxc.namespace.") - 1; + ns_idx = lxc_namespace_2_ns_idx(namespace); + if (ns_idx < 0) + return ns_idx; + + return set_config_string_item(&lxc_conf->inherit_ns[ns_idx], value); +} + struct parse_line_conf { struct lxc_conf *conf; bool from_include; @@ -3268,6 +3287,28 @@ static int get_config_noop(const char *key, char *retv, int inlen, return 0; } +static int get_config_namespace(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + int len, ns_idx; + const char *namespace; + int fulllen = 0; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + namespace = key + sizeof("lxc.namespace.") - 1; + ns_idx = lxc_namespace_2_ns_idx(namespace); + if (ns_idx < 0) + return ns_idx; + + strprint(retv, inlen, "%s", c->inherit_ns[ns_idx]); + + return fulllen; +} + /* Callbacks to clear config items. */ static inline int clr_config_personality(const char *key, struct lxc_conf *c, void *data) @@ -3606,6 +3647,23 @@ static inline int clr_config_noop(const char *key, struct lxc_conf *c, return 0; } +static int clr_config_namespace(const char *key, struct lxc_conf *lxc_conf, + void *data) +{ + int ns_idx; + const char *namespace; + + namespace = key + sizeof("lxc.namespace.") - 1; + ns_idx = lxc_namespace_2_ns_idx(namespace); + if (ns_idx < 0) + return ns_idx; + + free(lxc_conf->inherit_ns[ns_idx]); + lxc_conf->inherit_ns[ns_idx] = NULL; + + return 0; +} + static int get_config_includefiles(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c index 9db4bc6d3..3d843ba77 100644 --- a/src/lxc/confile_utils.c +++ b/src/lxc/confile_utils.c @@ -29,8 +29,9 @@ #include "confile.h" #include "confile_utils.h" #include "error.h" -#include "log.h" #include "list.h" +#include "log.h" +#include "lxccontainer.h" #include "network.h" #include "parse.h" #include "utils.h" @@ -700,3 +701,77 @@ bool parse_limit_value(const char **value, rlim_t *res) return true; } + +static int lxc_container_name_to_pid(const char *lxcname_or_pid, + const char *lxcpath) +{ + int ret; + signed long int pid; + char *err = NULL; + + pid = strtol(lxcname_or_pid, &err, 10); + if (*err != '\0' || pid < 1) { + struct lxc_container *c; + + c = lxc_container_new(lxcname_or_pid, lxcpath); + if (!c) { + ERROR("\"%s\" is not a valid pid nor a container name", + lxcname_or_pid); + return -1; + } + + if (!c->may_control(c)) { + ERROR("Insufficient privileges to control container " + "\"%s\"", c->name); + lxc_container_put(c); + return -1; + } + + pid = c->init_pid(c); + if (pid < 1) { + ERROR("Container \"%s\" is not running", c->name); + lxc_container_put(c); + return -1; + } + + lxc_container_put(c); + } + + ret = kill(pid, 0); + if (ret < 0) { + ERROR("%s - Failed to send signal to pid %d", strerror(errno), + (int)pid); + return -EPERM; + } + + return pid; +} + +int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath, + const char *namespace) +{ + int fd, pid; + char *dup, *lastslash; + + lastslash = strrchr(lxcname_or_pid, '/'); + if (lastslash) { + dup = strdup(lxcname_or_pid); + if (!dup) + return -ENOMEM; + + *lastslash = '\0'; + pid = lxc_container_name_to_pid(lastslash, dup); + free(dup); + } else { + pid = lxc_container_name_to_pid(lxcname_or_pid, lxcpath); + } + + if (pid < 0) + return -EINVAL; + + fd = lxc_preserve_ns(pid, namespace); + if (fd < 0) + return -EINVAL; + + return fd; +} diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h index ee9376e24..33822faf2 100644 --- a/src/lxc/confile_utils.h +++ b/src/lxc/confile_utils.h @@ -86,5 +86,7 @@ extern int lxc_get_conf_str(char *retv, int inlen, const char *value); extern int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v); extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v); extern bool parse_limit_value(const char **value, rlim_t *res); +extern int lxc_inherit_namespace(const char *lxcname_or_pid, + const char *lxcpath, const char *namespace); #endif /* __LXC_CONFILE_UTILS_H */ diff --git a/src/lxc/namespace.c b/src/lxc/namespace.c index e760c0d9a..da434052a 100644 --- a/src/lxc/namespace.c +++ b/src/lxc/namespace.c @@ -96,15 +96,26 @@ const struct ns_info ns_info[LXC_NS_MAX] = { [LXC_NS_CGROUP] = {"cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP"} }; -int lxc_namespace_2_cloneflag(char *namespace) +int lxc_namespace_2_cloneflag(const char *namespace) { int i; for (i = 0; i < LXC_NS_MAX; i++) if (!strcasecmp(ns_info[i].proc_name, namespace)) return ns_info[i].clone_flag; - ERROR("Invalid namespace name: %s.", namespace); - return -1; + ERROR("Invalid namespace name \"%s\"", namespace); + return -EINVAL; +} + +int lxc_namespace_2_ns_idx(const char *namespace) +{ + int i; + for (i = 0; i < LXC_NS_MAX; i++) + if (!strcmp(ns_info[i].proc_name, namespace)) + return i; + + ERROR("Invalid namespace name \"%s\"", namespace); + return -EINVAL; } int lxc_fill_namespace_flags(char *flaglist, int *flags) diff --git a/src/lxc/namespace.h b/src/lxc/namespace.h index 4916950c1..02ec08885 100644 --- a/src/lxc/namespace.h +++ b/src/lxc/namespace.h @@ -81,7 +81,8 @@ int clone(int (*fn)(void *), void *child_stack, extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags); -extern int lxc_namespace_2_cloneflag(char *namespace); +extern int lxc_namespace_2_cloneflag(const char *namespace); +extern int lxc_namespace_2_ns_idx(const char *namespace); extern int lxc_fill_namespace_flags(char *flaglist, int *flags); #endif diff --git a/src/lxc/network.c b/src/lxc/network.c index da6259447..c0ca99d40 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -2302,14 +2302,14 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler) *netns_path = '\0'; - if (handler->netnsfd < 0) { + if (handler->nsfd[LXC_NS_NET] < 0) { DEBUG("Cannot not guarantee safe deletion of network devices. " "Manual cleanup maybe needed"); return false; } ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d", - getpid(), handler->netnsfd); + getpid(), handler->nsfd[LXC_NS_NET]); if (ret < 0 || ret >= sizeof(netns_path)) return false; @@ -2621,7 +2621,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler) int oldfd; char ifname[IFNAMSIZ]; struct lxc_list *iterator; - int netnsfd = handler->netnsfd; + int netnsfd = handler->nsfd[LXC_NS_NET]; struct lxc_conf *conf = handler->conf; /* We need CAP_NET_ADMIN in the parent namespace in order to setns() to diff --git a/src/lxc/start.c b/src/lxc/start.c index e3827c2b7..ee8a4551e 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -155,6 +155,7 @@ static bool preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags, pid_t pid) for (i = 0; i < LXC_NS_MAX; i++) { if ((clone_flags & ns_info[i].clone_flag) == 0) continue; + ns_fd[i] = lxc_preserve_ns(pid, ns_info[i].proc_name); if (ns_fd[i] < 0) goto error; @@ -236,15 +237,6 @@ restart: (i < len_fds && fd == fds_to_ignore[i])) continue; - if (conf) { - for (i = 0; i < LXC_NS_MAX; i++) - if (conf->inherit_ns_fd[i] == fd) - break; - - if (i < LXC_NS_MAX) - continue; - } - if (current_config && fd == current_config->logfd) continue; @@ -254,10 +246,10 @@ restart: if (closeall) { close(fd); closedir(dir); - INFO("Closed inherited fd: %d.", fd); + INFO("Closed inherited fd %d", fd); goto restart; } - WARN("Inherited fd: %d.", fd); + WARN("Inherited fd %d", fd); } /* Only enable syslog at this point to avoid the above logging function @@ -722,16 +714,13 @@ void lxc_fini(const char *name, struct lxc_handler *handler) while (namespace_count--) free(namespaces[namespace_count]); + for (i = 0; i < LXC_NS_MAX; i++) { - if (handler->nsfd[i] != -1) { - close(handler->nsfd[i]); - handler->nsfd[i] = -1; - } - } + if (handler->nsfd[i] < 0) + continue; - if (handler->netnsfd >= 0) { - close(handler->netnsfd); - handler->netnsfd = -1; + close(handler->nsfd[i]); + handler->nsfd[i] = -1; } cgroup_destroy(handler); @@ -1123,27 +1112,27 @@ void resolve_clone_flags(struct lxc_handler *handler) if (!lxc_list_empty(&handler->conf->id_map)) handler->clone_flags |= CLONE_NEWUSER; - if (handler->conf->inherit_ns_fd[LXC_NS_NET] == -1) { + if (!handler->conf->inherit_ns[LXC_NS_NET]) { if (!lxc_requests_empty_network(handler)) handler->clone_flags |= CLONE_NEWNET; } else { - INFO("Inheriting a NET namespace."); + INFO("Inheriting net namespace"); } - if (handler->conf->inherit_ns_fd[LXC_NS_IPC] == -1) + if (!handler->conf->inherit_ns[LXC_NS_IPC]) handler->clone_flags |= CLONE_NEWIPC; else - INFO("Inheriting an IPC namespace."); + INFO("Inheriting ipc namespace"); - if (handler->conf->inherit_ns_fd[LXC_NS_UTS] == -1) + if (!handler->conf->inherit_ns[LXC_NS_UTS]) handler->clone_flags |= CLONE_NEWUTS; else - INFO("Inheriting a UTS namespace."); + INFO("Inheriting uts namespace"); - if (handler->conf->inherit_ns_fd[LXC_NS_PID] == -1) + if (!handler->conf->inherit_ns[LXC_NS_PID]) handler->clone_flags |= CLONE_NEWPID; else - INFO("Inheriting a PID namespace."); + INFO("Inheriting pid namespace"); } /* lxc_spawn() performs crucial setup tasks and clone()s the new process which @@ -1162,15 +1151,24 @@ static int lxc_spawn(struct lxc_handler *handler) struct lxc_list *id_map; int preserve_mask = 0; const char *name = handler->name; + const char *lxcpath = handler->lxcpath; bool cgroups_connected = false; + struct lxc_conf *conf = handler->conf; - id_map = &handler->conf->id_map; + id_map = &conf->id_map; wants_to_map_ids = !lxc_list_empty(id_map); memset(saved_ns_fd, -1, sizeof(int) * LXC_NS_MAX); - for (i = 0; i < LXC_NS_MAX; i++) - if (handler->conf->inherit_ns_fd[i] != -1) - preserve_mask |= ns_info[i].clone_flag; + for (i = 0; i < LXC_NS_MAX; i++) { + if (!conf->inherit_ns[i]) + continue; + + preserve_mask |= ns_info[i].clone_flag; + + handler->nsfd[i] = lxc_inherit_namespace(conf->inherit_ns[i], lxcpath, ns_info[i].proc_name); + if (handler->nsfd[i] < 0) + return -1; + } if (lxc_sync_init(handler)) return -1; @@ -1185,7 +1183,7 @@ static int lxc_spawn(struct lxc_handler *handler) resolve_clone_flags(handler); if (handler->clone_flags & CLONE_NEWNET) { - if (!lxc_list_empty(&handler->conf->network)) { + if (!lxc_list_empty(&conf->network)) { /* Find gateway addresses from the link device, which is * no longer accessible inside the container. Do this @@ -1226,16 +1224,24 @@ static int lxc_spawn(struct lxc_handler *handler) * If the container is unprivileged then skip rootfs pinning. */ if (!wants_to_map_ids) { - handler->pinfd = pin_rootfs(handler->conf->rootfs.path); + handler->pinfd = pin_rootfs(conf->rootfs.path); if (handler->pinfd == -1) INFO("Failed to pin the rootfs for container \"%s\".", handler->name); } if (!preserve_ns(saved_ns_fd, preserve_mask, getpid())) goto out_delete_net; + else + TRACE("Preserved inherited namespaces"); - if (attach_ns(handler->conf->inherit_ns_fd) < 0) - goto out_delete_net; + for (i = 0; i < LXC_NS_MAX; i++) { + if (handler->nsfd[i] < 0) + continue; + + ret = setns(handler->nsfd[i], 0); + if (ret < 0) + goto out_delete_net; + } /* Create a process in a new set of namespaces. */ flags = handler->clone_flags; @@ -1260,13 +1266,17 @@ static int lxc_spawn(struct lxc_handler *handler) for (i = 0; i < LXC_NS_MAX; i++) if (flags & ns_info[i].clone_flag) - INFO("Cloned %s.", ns_info[i].flag_name); + INFO("Cloned %s", ns_info[i].flag_name); - if (!preserve_ns(handler->nsfd, handler->clone_flags | preserve_mask, handler->pid)) - INFO("Failed to preserve namespace for lxc.hook.stop."); + if (!preserve_ns(handler->nsfd, handler->clone_flags, handler->pid)) { + ERROR("Failed to preserve cloned namespaces for lxc.hook.stop"); + goto out_delete_net; + } - if (attach_ns(saved_ns_fd)) - WARN("Failed to restore saved namespaces."); + if (attach_ns(saved_ns_fd)) { + ERROR("Failed to restore saved namespaces"); + goto out_delete_net; + } lxc_sync_fini_child(handler); @@ -1302,24 +1312,18 @@ static int lxc_spawn(struct lxc_handler *handler) if (!cgroup_chown(handler)) goto out_delete_net; - handler->netnsfd = lxc_preserve_ns(handler->pid, "net"); - if (handler->netnsfd < 0) { - ERROR("Failed to preserve network namespace"); - goto out_delete_net; - } - /* Create the network configuration. */ if (handler->clone_flags & CLONE_NEWNET) { if (lxc_network_move_created_netdev_priv(handler->lxcpath, handler->name, - &handler->conf->network, + &conf->network, handler->pid)) { ERROR("Failed to create the configured network."); goto out_delete_net; } if (lxc_create_network_unpriv(handler->lxcpath, handler->name, - &handler->conf->network, + &conf->network, handler->pid)) { ERROR("Failed to create the configured network."); goto out_delete_net; @@ -1337,7 +1341,7 @@ static int lxc_spawn(struct lxc_handler *handler) if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE)) goto out_delete_net; - if (!lxc_list_empty(&handler->conf->limits) && setup_resource_limits(&handler->conf->limits, handler->pid)) { + if (!lxc_list_empty(&conf->limits) && setup_resource_limits(&conf->limits, handler->pid)) { ERROR("failed to setup resource limits for '%s'", name); goto out_delete_net; } @@ -1359,7 +1363,7 @@ static int lxc_spawn(struct lxc_handler *handler) SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr); /* Run any host-side start hooks */ - if (run_lxc_hooks(name, "start-host", handler->conf, handler->lxcpath, NULL)) { + if (run_lxc_hooks(name, "start-host", conf, handler->lxcpath, NULL)) { ERROR("Failed to run lxc.hook.start-host for container \"%s\".", name); return -1; } @@ -1384,7 +1388,7 @@ static int lxc_spawn(struct lxc_handler *handler) * been recorded. The corresponding structs have now all been filled. So * log them for debugging purposes. */ - lxc_log_configured_netdevs(handler->conf); + lxc_log_configured_netdevs(conf); /* Read tty fds allocated by child. */ if (lxc_recv_ttys_from_child(handler) < 0) { @@ -1428,11 +1432,6 @@ out_abort: handler->pinfd = -1; } - if (handler->netnsfd >= 0) { - close(handler->netnsfd); - handler->netnsfd = -1; - } - return -1; } @@ -1451,7 +1450,6 @@ int __lxc_start(const char *name, struct lxc_handler *handler, handler->ops = ops; handler->data = data; handler->backgrounded = backgrounded; - handler->netnsfd = -1; if (!attach_block_device(handler->conf)) { ERROR("Failed to attach block device."); diff --git a/src/lxc/start.h b/src/lxc/start.h index be724bcaf..c67322693 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h @@ -40,9 +40,6 @@ struct lxc_handler { /* The clone flags that were requested. */ int clone_flags; - /* File descriptors referring to the network namespace of the container. */ - int netnsfd; - /* File descriptor to pin the rootfs for privileged containers. */ int pinfd; diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c index 69e00471e..356f70430 100644 --- a/src/lxc/tools/lxc_start.c +++ b/src/lxc/tools/lxc_start.c @@ -89,53 +89,6 @@ err: return err; } -static int pid_from_lxcname(const char *lxcname_or_pid, const char *lxcpath) { - char *eptr; - int pid = strtol(lxcname_or_pid, &eptr, 10); - if (*eptr != '\0' || pid < 1) { - struct lxc_container *s; - s = lxc_container_new(lxcname_or_pid, lxcpath); - if (!s) { - SYSERROR("'%s' is not a valid pid nor a container name", lxcname_or_pid); - return -1; - } - - if (!s->may_control(s)) { - SYSERROR("Insufficient privileges to control container '%s'", s->name); - lxc_container_put(s); - return -1; - } - - pid = s->init_pid(s); - if (pid < 1) { - SYSERROR("Is container '%s' running?", s->name); - lxc_container_put(s); - return -1; - } - - lxc_container_put(s); - } - if (kill(pid, 0) < 0) { - SYSERROR("Can't send signal to pid %d", pid); - return -1; - } - - return pid; -} - -static int open_ns(int pid, const char *ns_proc_name) { - int fd; - char path[MAXPATHLEN]; - snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns_proc_name); - - fd = open(path, O_RDONLY); - if (fd < 0) { - SYSERROR("failed to open %s", path); - return -1; - } - return fd; -} - static int my_parser(struct lxc_arguments* args, int c, char* arg) { switch (c) { @@ -201,16 +154,18 @@ Options :\n\ int main(int argc, char *argv[]) { - int err = EXIT_FAILURE; + int i; struct lxc_conf *conf; struct lxc_log log; + const char *lxcpath; char *const *args; + struct lxc_container *c; + int err = EXIT_FAILURE; char *rcfile = NULL; char *const default_args[] = { "/sbin/init", NULL, }; - struct lxc_container *c; lxc_list_init(&defines); @@ -236,14 +191,13 @@ int main(int argc, char *argv[]) exit(err); lxc_log_options_no_override(); - if (access(my_args.lxcpath[0], O_RDONLY) < 0) { + lxcpath = my_args.lxcpath[0]; + if (access(lxcpath, O_RDONLY) < 0) { if (!my_args.quiet) - fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]); + fprintf(stderr, "You lack access to %s\n", lxcpath); exit(err); } - const char *lxcpath = my_args.lxcpath[0]; - /* REMOVE IN LXC 3.0 */ setenv("LXC_UPDATE_CONFIG_FORMAT", "1", 0); @@ -333,19 +287,26 @@ int main(int argc, char *argv[]) } } - int i; for (i = 0; i < LXC_NS_MAX; i++) { - if (my_args.share_ns[i] == NULL) + const char *key, *value; + + value = my_args.share_ns[i]; + if (!value) continue; - int pid = pid_from_lxcname(my_args.share_ns[i], lxcpath); - if (pid < 1) - goto out; + if (i == LXC_NS_NET) + key = "lxc.namespace.net"; + else if (i == LXC_NS_IPC) + key = "lxc.namespace.ipc"; + else if (i == LXC_NS_UTS) + key = "lxc.namespace.uts"; + else if (i == LXC_NS_PID) + key = "lxc.namespace.pid"; + else + continue; - int fd = open_ns(pid, ns_info[i].proc_name); - if (fd < 0) + if (!c->set_config_item(c, key, value)) goto out; - conf->inherit_ns_fd[i] = fd; } if (!my_args.daemonize) {