[CRIU] [PATCH 5/6] veth: Make --external support --veth-pair
Pavel Emelyanov
xemul at virtuozzo.com
Tue Sep 20 06:26:55 PDT 2016
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/crtools.c | 5 +-
criu/include/cr_options.h | 1 -
criu/net.c | 123 +++++++++++++++++++++++++---------------------
images/rpc.proto | 2 +-
4 files changed, 68 insertions(+), 63 deletions(-)
diff --git a/criu/crtools.c b/criu/crtools.c
index 6c3c3b5..53fce47 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -59,7 +59,6 @@ void init_opts(void)
/* Default options */
opts.final_state = TASK_DEAD;
INIT_LIST_HEAD(&opts.ext_unixsk_ids);
- INIT_LIST_HEAD(&opts.veth_pairs);
INIT_LIST_HEAD(&opts.ext_mounts);
INIT_LIST_HEAD(&opts.inherit_fds);
INIT_LIST_HEAD(&opts.external);
@@ -835,6 +834,7 @@ usage:
" dev[maj:min]:VAL\n"
" Formats of RES on restore:\n"
" dev[VAL]:DEVPATH\n"
+" veth[IFNAME]:OUTNAME{@BRIDGE}\n"
"\n"
"* Special resources support:\n"
" -x|--" USK_EXT_PARAM " [inode,...]\n"
@@ -845,9 +845,6 @@ usage:
" -r|--root PATH change the root filesystem (when run in mount namespace)\n"
" --evasive-devices use any path to a device file if the original one\n"
" is inaccessible\n"
-" --veth-pair IN=OUT map inside veth device name to outside one\n"
-" can optionally append @<bridge-name> to OUT for moving\n"
-" the outside veth to the named bridge\n"
" --link-remap allow one to link unlinked files back when possible\n"
" --ghost-limit size limit max size of deleted file contents inside image\n"
" --action-script FILE add an external action script\n"
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index 7711a7a..95dd878 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -72,7 +72,6 @@ struct cr_options {
char *root;
char *pidfile;
char *freeze_cgroup;
- struct list_head veth_pairs;
struct list_head ext_mounts;
struct list_head inherit_fds;
struct list_head external;
diff --git a/criu/net.c b/criu/net.c
index 080c617..564ca6d 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -29,6 +29,7 @@
#include "string.h"
#include "sysctl.h"
#include "kerndat.h"
+#include "external.h"
#include "protobuf.h"
#include "images/netdev.pb-c.h"
@@ -904,12 +905,25 @@ enum {
#define IFLA_NET_NS_FD 28
#endif
+static void veth_peer_info(NetDeviceEntry *nde, struct newlink_req *req)
+{
+ char key[100], *val;
+
+ snprintf(key, sizeof(key), "veth[%s]", nde->name);
+ val = external_lookup_by_key(key);
+ if (!IS_ERR_OR_NULL(val)) {
+ char *aux;
+
+ aux = strchrnul(val, '@');
+ addattr_l(&req->h, sizeof(*req), IFLA_IFNAME, val, aux - val - 1);
+ }
+}
+
static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req)
{
int ns_fd = get_service_fd(NS_FD_OFF);
struct rtattr *veth_data, *peer_data;
struct ifinfomsg ifm;
- struct veth_pair *n;
BUG_ON(ns_fd < 0);
@@ -920,12 +934,7 @@ static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req)
peer_data = NLMSG_TAIL(&req->h);
memset(&ifm, 0, sizeof(ifm));
addattr_l(&req->h, sizeof(*req), VETH_INFO_PEER, &ifm, sizeof(ifm));
- list_for_each_entry(n, &opts.veth_pairs, node) {
- if (!strcmp(nde->name, n->inside))
- break;
- }
- if (&n->node != &opts.veth_pairs)
- addattr_l(&req->h, sizeof(*req), IFLA_IFNAME, n->outside, strlen(n->outside));
+ veth_peer_info(nde, req);
addattr_l(&req->h, sizeof(*req), IFLA_NET_NS_FD, &ns_fd, sizeof(ns_fd));
peer_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)peer_data;
veth_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)veth_data;
@@ -1620,33 +1629,11 @@ void network_unlock(void)
int veth_pair_add(char *in, char *out)
{
- char *aux;
- struct veth_pair *n;
-
- n = xmalloc(sizeof(*n));
- if (n == NULL)
- return -1;
-
- n->inside = in;
- n->outside = out;
- /*
- * Does the out string specify a bridge for
- * moving the outside end of the veth pair to?
- */
- aux = strrchr(out, '@');
- if (aux) {
- *aux++ = '\0';
- n->bridge = aux;
- } else {
- n->bridge = NULL;
- }
+ char *e_str;
- list_add(&n->node, &opts.veth_pairs);
- if (n->bridge)
- pr_debug("Added %s:%s@%s veth map\n", in, out, aux);
- else
- pr_debug("Added %s:%s veth map\n", in, out);
- return 0;
+ e_str = xmalloc(200); /* For 3 IFNAMSIZ + 8 service characters */
+ snprintf(e_str, 200, "veth[%s]:%s", in, out);
+ return add_external(e_str);
}
/*
@@ -1727,20 +1714,26 @@ int collect_net_namespaces(bool for_dump)
struct ns_desc net_ns_desc = NS_DESC_ENTRY(CLONE_NEWNET, "net");
-int move_veth_to_bridge(void)
+static int move_to_bridge(struct external *ext, void *arg)
{
- int s;
+ int s = *(int *)arg;
int ret;
- struct veth_pair *n;
+ char *out, *br;
struct ifreq ifr;
- s = -1;
- ret = 0;
- list_for_each_entry(n, &opts.veth_pairs, node) {
- if (n->bridge == NULL)
- continue;
+ out = external_val(ext);
+ if (!out)
+ return -1;
+
+ br = strchr(out, '@');
+ if (!br)
+ return 0;
- pr_debug("\tMoving dev %s to bridge %s\n", n->outside, n->bridge);
+ *br = '\0';
+ br++;
+
+ {
+ pr_debug("\tMoving dev %s to bridge %s\n", out, br);
if (s == -1) {
s = socket(AF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC, 0);
@@ -1754,18 +1747,17 @@ int move_veth_to_bridge(void)
* Add the device to the bridge. This is equivalent to:
* $ brctl addif <bridge> <device>
*/
- ifr.ifr_ifindex = if_nametoindex(n->outside);
+ ifr.ifr_ifindex = if_nametoindex(out);
if (ifr.ifr_ifindex == 0) {
- pr_perror("Can't get index of %s", n->outside);
+ pr_perror("Can't get index of %s", out);
ret = -1;
- break;
+ goto out;
}
- strlcpy(ifr.ifr_name, n->bridge, IFNAMSIZ);
+ strlcpy(ifr.ifr_name, br, IFNAMSIZ);
ret = ioctl(s, SIOCBRADDIF, &ifr);
if (ret < 0) {
- pr_perror("Can't add interface %s to bridge %s",
- n->outside, n->bridge);
- break;
+ pr_perror("Can't add interface %s to bridge %s", out, br);
+ goto out;
}
/*
@@ -1773,24 +1765,41 @@ int move_veth_to_bridge(void)
* $ ip link set dev <device> up
*/
ifr.ifr_ifindex = 0;
- strlcpy(ifr.ifr_name, n->outside, IFNAMSIZ);
+ strlcpy(ifr.ifr_name, out, IFNAMSIZ);
ret = ioctl(s, SIOCGIFFLAGS, &ifr);
if (ret < 0) {
- pr_perror("Can't get flags of interface %s", n->outside);
- break;
+ pr_perror("Can't get flags of interface %s", out);
+ goto out;
}
+
+ ret = 0;
if (ifr.ifr_flags & IFF_UP)
- continue;
+ goto out;
+
ifr.ifr_flags |= IFF_UP;
ret = ioctl(s, SIOCSIFFLAGS, &ifr);
if (ret < 0) {
pr_perror("Can't set flags of interface %s to 0x%x",
- n->outside, ifr.ifr_flags);
- break;
+ out, ifr.ifr_flags);
+ goto out;
}
+
+ ret = 0;
}
+out:
+ br--;
+ *br = '@';
+ *(int *)arg = s;
+ return ret;
+}
+
+int move_veth_to_bridge(void)
+{
+ int sk = -1, ret;
+
+ ret = external_for_each_type("veth", move_to_bridge, &sk);
+ if (sk >= 0)
+ close(sk);
- if (s >= 0)
- close(s);
return ret;
}
diff --git a/images/rpc.proto b/images/rpc.proto
index 9b36178..0ae130c 100644
--- a/images/rpc.proto
+++ b/images/rpc.proto
@@ -71,7 +71,7 @@ message criu_opts {
optional int32 work_dir_fd = 17;
optional bool link_remap = 18;
- repeated criu_veth_pair veths = 19;
+ repeated criu_veth_pair veths = 19; /* DEPRECATED, use external instead */
optional uint32 cpu_cap = 20 [default = 0xffffffff];
optional bool force_irmap = 21;
--
2.5.0
More information about the CRIU
mailing list