Commit e58fae8f by Dongsheng Yang Committed by Serge Hallyn

container: introduce two functions named as {at/de}tach_interface().

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. Changelog: 10/15/2014 (serge): return error if ifname is NULL. Signed-off-by: 's avatarDongsheng Yang <yangds.fnst@cn.fujitsu.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 51d0854c
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <lxc/lxccontainer.h> #include <lxc/lxccontainer.h>
#include <lxc/version.h> #include <lxc/version.h>
#include <lxc/network.h>
#include "config.h" #include "config.h"
#include "lxc.h" #include "lxc.h"
...@@ -3426,6 +3427,99 @@ static bool lxcapi_remove_device_node(struct lxc_container *c, const char *src_p ...@@ -3426,6 +3427,99 @@ 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); 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;
if (am_unpriv()) {
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
return false;
}
if (!ifname) {
ERROR("No source interface name given");
return false;
}
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 *dst_ifname)
{
pid_t pid, pid_outside;
if (am_unpriv()) {
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
return false;
}
if (!ifname) {
ERROR("No source interface name given");
return false;
}
pid_outside = getpid();
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_isup(ifname);
if (ret < 0)
exit(ret);
/* netdev of ifname is up. */
if (ret) {
ret = lxc_netdev_down(ifname);
if (ret)
exit(ret);
}
ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_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 { struct criu_opts {
/* The type of criu invocation, one of "dump" or "restore" */ /* The type of criu invocation, one of "dump" or "restore" */
char *action; char *action;
...@@ -4051,6 +4145,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath ...@@ -4051,6 +4145,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->may_control = lxcapi_may_control; c->may_control = lxcapi_may_control;
c->add_device_node = lxcapi_add_device_node; c->add_device_node = lxcapi_add_device_node;
c->remove_device_node = lxcapi_remove_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->checkpoint = lxcapi_checkpoint;
c->restore = lxcapi_restore; c->restore = lxcapi_restore;
......
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