From: Dongsheng Yang Date: Tue, 16 Sep 2014 08:54:42 +0000 (+0800) Subject: utils: move useful helper functions from lxccontainer to utils. X-Git-Tag: lxc-1.1.0.alpha3~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51d0854cd6360b953c37e3bf1b9a85ce031b2075;p=thirdparty%2Flxc.git utils: move useful helper functions from lxccontainer to utils. Function of enter_to_ns() is useful but currently is static for lxccontainer.c. This patch split it into two parts named as switch_to_newuser() and switch_to_newnet() into utils.c. Signed-off-by: Dongsheng Yang Acked-by: Serge E. Hallyn --- diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 4c3d4d584..47f60d9bf 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1476,56 +1476,15 @@ static bool lxcapi_clear_config_item(struct lxc_container *c, const char *key) return ret == 0; } -static inline bool enter_to_ns(struct lxc_container *c) { - int netns, userns, ret = 0, init_pid = 0;; - char new_netns_path[MAXPATHLEN]; - char new_userns_path[MAXPATHLEN]; - - if (!c->is_running(c)) - goto out; - - init_pid = c->init_pid(c); +static inline bool enter_to_ns(struct lxc_container *c) +{ + pid_t pid = c->init_pid(c); - /* Switch to new userns */ if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && access("/proc/self/ns/user", F_OK) == 0) { - ret = snprintf(new_userns_path, MAXPATHLEN, "/proc/%d/ns/user", init_pid); - if (ret < 0 || ret >= MAXPATHLEN) - goto out; - - userns = open(new_userns_path, O_RDONLY); - if (userns < 0) { - SYSERROR("failed to open %s", new_userns_path); - goto out; - } - - if (setns(userns, CLONE_NEWUSER)) { - SYSERROR("failed to setns for CLONE_NEWUSER"); - close(userns); - goto out; - } - close(userns); - } - - /* Switch to new netns */ - ret = snprintf(new_netns_path, MAXPATHLEN, "/proc/%d/ns/net", init_pid); - if (ret < 0 || ret >= MAXPATHLEN) - goto out; - - netns = open(new_netns_path, O_RDONLY); - if (netns < 0) { - SYSERROR("failed to open %s", new_netns_path); - goto out; - } - - if (setns(netns, CLONE_NEWNET)) { - SYSERROR("failed to setns for CLONE_NEWNET"); - close(netns); - goto out; + if (!switch_to_ns(pid, "user")) + return false; } - close(netns); - return true; -out: - return false; + return switch_to_ns(pid, "net"); } // used by qsort and bsearch functions for comparing names diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 6344f3d71..f9feebabe 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -761,6 +761,25 @@ struct lxc_container { */ bool (*remove_device_node)(struct lxc_container *c, const char *src_path, const char *dest_path); + /*! + * \brief Add specified netdev to the container. + * + * \param c Container. + * \param dev name of net device. + * + * \return \c true on success, else \c false. + */ + bool (*attach_interface)(struct lxc_container *c, const char *dev, const char *dst_dev); + + /*! + * \brief Remove specified netdev from the container. + * + * \param c Container. + * \param dev name of net device. + * + * \return \c true on success, else \c false. + */ + bool (*detach_interface)(struct lxc_container *c, const char *dev, const char *dst_dev); /*! * \brief Checkpoint a container. * diff --git a/src/lxc/utils.c b/src/lxc/utils.c index ed34706bf..fced21096 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -43,6 +43,7 @@ #include "utils.h" #include "log.h" #include "lxclock.h" +#include "namespace.h" lxc_log_define(lxc_utils, lxc); @@ -1260,6 +1261,31 @@ int detect_shared_rootfs(void) return 0; } +bool switch_to_ns(pid_t pid, const char *ns) { + int fd, ret; + char nspath[MAXPATHLEN]; + + /* Switch to new ns */ + ret = snprintf(nspath, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns); + if (ret < 0 || ret >= MAXPATHLEN) + return false; + + fd = open(nspath, O_RDONLY); + if (fd < 0) { + SYSERROR("failed to open %s", nspath); + return false; + } + + ret = setns(fd, 0); + if (ret) { + SYSERROR("failed to set process %d to %s of %d.", pid, ns, fd); + close(fd); + return false; + } + close(fd); + return true; +} + /* * looking at fs/proc_namespace.c, it appears we can * actually expect the rootfs entry to very specifically contain diff --git a/src/lxc/utils.h b/src/lxc/utils.h index cdfe56aef..5ffafca50 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -283,3 +283,4 @@ char *on_path(char *cmd, const char *rootfs); bool file_exists(const char *f); char *choose_init(const char *rootfs); int print_to_file(const char *file, const char *content); +bool switch_to_ns(pid_t pid, const char *ns);