[lxc-devel] [PATCH 6/9] container: introduce two functions named as {at/de}tach_interface().

Dongsheng Yang yangds.fnst at cn.fujitsu.com
Tue Sep 16 11:15:30 UTC 2014


Currently, we depends on ip command to attach interface to container.
It means we only implemented it by python.

This patch implement adding and removing interface by c and added
them in struct container.

Signed-off-by: Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
---
 src/lxc/lxccontainer.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/lxccontainer.h | 19 ++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ee8f491..483082a 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -39,6 +39,7 @@
 
 #include <lxc/lxccontainer.h>
 #include <lxc/version.h>
+#include <lxc/network.h>
 
 #include "config.h"
 #include "lxc.h"
@@ -3496,6 +3497,82 @@ static bool lxcapi_remove_device_node(struct lxc_container *c, const char *src_p
 	return add_remove_device_node(c, src_path, dest_path, false);
 }
 
+static bool lxcapi_attach_interface(struct lxc_container *c, const char *ifname,
+				const char *dst_ifname)
+{
+	int ret = 0;
+	char path[PATH_MAX];
+
+	/**
+	 * FIXME: Currently, I do not have a good idea to detach a physical
+	 * network device in container. To avoid make the attaching not fetal
+	 * Just output a message to user here.
+	 **/
+	sprintf(path, "/sys/class/net/%s/device", ifname);
+	if (dir_exists(path)) {
+		ERROR("Please do not pass a physical network to container.\n"
+		"\tMaybe making your interface bridged and passing a virtual network\n"
+		"\tattached in this bridge to container is an alternative to you.");
+		goto err;
+	}
+
+	ret = lxc_netdev_isup(ifname);
+	if (ret < 0)
+		goto err;
+
+	/* netdev of ifname is up. */
+	if (ret) {
+		ret = lxc_netdev_down(ifname);
+		if (ret)
+			goto err;
+	}
+
+	ret = lxc_netdev_move_by_name(ifname, c->init_pid(c), dst_ifname);
+	if (ret)
+		goto err;
+
+	return true;
+err:
+	/* -EINVAL means there is no netdev named as ifanme. */
+	if (ret == -EINVAL) {
+		ERROR("No network device named as %s.", ifname);
+	}
+	return false;
+}
+
+static bool lxcapi_detach_interface(struct lxc_container *c, const char *ifname,
+					const char *dest_ifname)
+{
+	pid_t pid;
+
+	pid = fork();
+	if (pid < 0) {
+		ERROR("failed to fork task to get interfaces information");
+		return false;
+	}
+
+	if (pid == 0) { // child
+		int ret = 0;
+		if (!enter_to_ns(c)) {
+			ERROR("failed to enter namespace");
+			exit(-1);
+		}
+
+		ret = lxc_netdev_delete_by_name(ifname);
+
+		/* -EINVAL means there is no netdev named as ifanme. */
+		if (ret == -EINVAL) {
+			ERROR("No network device named as %s.", ifname);
+		}
+		exit(ret);
+	}
+
+	if (wait_for_pid(pid) != 0)
+		return false;
+
+	return true;
+}
+
 struct criu_opts {
 	/* The type of criu invocation, one of "dump" or "restore" */
 	char *action;
@@ -4091,6 +4168,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
 	c->may_control = lxcapi_may_control;
 	c->add_device_node = lxcapi_add_device_node;
 	c->remove_device_node = lxcapi_remove_device_node;
+	c->attach_interface = lxcapi_attach_interface;
+	c->detach_interface = lxcapi_detach_interface;
 	c->checkpoint = lxcapi_checkpoint;
 	c->restore = lxcapi_restore;
 
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 6344f3d..f9feeba 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -762,6 +762,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.
 	 *
 	 * \param c Container.
-- 
1.8.4.2



More information about the lxc-devel mailing list