[CRIU] [PATCH 4/5] net: add --macvlan-pair rewriting option

Tycho Andersen tycho.andersen at canonical.com
Tue Jun 14 09:45:31 PDT 2016


Allow users to rewrite which device on the outside a particular interface
on the inside is attached to.

Note that this is optional: in the case where nothing is supplied, CRIU
will attempt to reattach the container's interface to the device with the
same ifindex that existed on dump. We could error out in this case, but
perhaps this is more user friendly.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 Documentation/criu.txt    |  4 ++++
 criu/crtools.c            | 18 ++++++++++++++++++
 criu/include/cr_options.h |  1 +
 criu/include/net.h        |  7 +++++++
 criu/net.c                | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+)

diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index 55f05c0..9a96502 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -354,6 +354,10 @@ migrated to a less capable processor and one need to *restore*
 this application, by default *criu* will refuse to proceed without
 relaxing capability with *--cpu-cap*=*none* parameter.
 
+*--macvlan-pair* '<IN>'*=*'<OUT>'::
+    Similar to *--veth-pair*, except '<OUT>' is the interface to attach the
+    macvlan device to.
+
 *check*
 ~~~~~~~
 Checks whether the kernel supports the features that *criu* needs to
diff --git a/criu/crtools.c b/criu/crtools.c
index a6d5d94..d989523 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -65,6 +65,7 @@ void init_opts(void)
 	INIT_LIST_HEAD(&opts.join_ns);
 	INIT_LIST_HEAD(&opts.new_cgroup_roots);
 	INIT_LIST_HEAD(&opts.irmap_scan_paths);
+	INIT_LIST_HEAD(&opts.macvlan_pairs);
 
 	opts.cpu_cap = CPU_CAP_DEFAULT;
 	opts.manage_cgroups = CG_MODE_DEFAULT;
@@ -324,6 +325,7 @@ int main(int argc, char *argv[], char *envp[])
 		{ "cgroup-props",		required_argument,	0, 1080	},
 		{ "cgroup-props-file",		required_argument,	0, 1081	},
 		{ "cgroup-dump-controller",	required_argument,	0, 1082	},
+		{ "veth-pair",			required_argument,	0, 1083	},
 		{ },
 	};
 
@@ -635,6 +637,19 @@ int main(int argc, char *argv[], char *envp[])
 			if (!cgp_add_dump_controller(optarg))
 				return 1;
 			break;
+		case 1083:
+			{
+				char *aux;
+
+				aux = strchr(optarg, '=');
+				if (aux == NULL)
+					goto bad_arg;
+
+				*aux = '\0';
+				if (macvlan_pair_add(optarg, aux + 1))
+					return 1;
+			}
+			break;
 		case 'V':
 			pr_msg("Version: %s\n", CRIU_VERSION);
 			if (strcmp(CRIU_GITID, "0"))
@@ -931,6 +946,9 @@ usage:
 "			    --join-ns user:PID,UID,GID to specify uid and gid.\n"
 "			Please NOTE: join-ns with user-namespace is not fully tested.\n"
 "			It may be dangerous to use this feature\n"
+"  --macvlan-pair IN=OUT\n"
+"                       Similar to --veth-pair, except OUT is the interface to\n"
+"                       attach the macvlan device to."
 "Check options:\n"
 "  without any arguments, \"criu check\" checks availability of absolutely required\n"
 "  kernel features; if any of these features is missing dump and restore will fail\n"
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index e36c362..48bc834 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -111,6 +111,7 @@ struct cr_options {
 	unsigned int		timeout;
 	unsigned int		empty_ns;
 	bool			lazy_pages;
+	struct list_head	macvlan_pairs;
 };
 
 extern struct cr_options opts;
diff --git a/criu/include/net.h b/criu/include/net.h
index b4a6e99..97bc826 100644
--- a/criu/include/net.h
+++ b/criu/include/net.h
@@ -17,6 +17,12 @@ struct veth_pair {
 	char *bridge;
 };
 
+struct macvlan_pair {
+	struct list_head node;
+	char *inside;
+	int ifi_outside;
+};
+
 extern int collect_net_namespaces(bool for_dump);
 
 extern int network_lock(void);
@@ -30,6 +36,7 @@ extern int read_ns_sys_file(char *path, char *buf, int len);
 extern int restore_link_parms(NetDeviceEntry *nde, int nlsk);
 
 extern int veth_pair_add(char *in, char *out);
+extern int macvlan_pair_add(char *in, char *out);
 extern int move_veth_to_bridge(void);
 
 #endif /* __CR_NET_H__ */
diff --git a/criu/net.c b/criu/net.c
index 793b625..c420225 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1082,6 +1082,24 @@ static int restore_link(NetDeviceEntry *nde, int nlsk)
 	case ND_TYPE__BRIDGE:
 		return restore_one_link(nde, nlsk, bridge_link_info);
 	case ND_TYPE__MACVLAN: {
+		struct macvlan_pair *n;
+
+		/* We need to rewrite the NetDeviceEntry before going into
+		 * populate_newlink_req() because that is what sets up
+		 * IFLA_LINK.
+		 */
+		list_for_each_entry(n, &opts.macvlan_pairs, node) {
+			if (strcmp(n->inside, nde->name))
+				continue;
+
+			if (!nde->has_link) {
+				pr_warn("enabling IFLA_LINK for %s which didn't have one\n", nde->name);
+				nde->has_link = true;
+			}
+
+			nde->link = n->ifi_outside;
+		}
+
 		if (root_ns_mask & CLONE_NEWNET) {
 			struct newlink_req req;
 
@@ -1770,6 +1788,26 @@ int veth_pair_add(char *in, char *out)
 	return 0;
 }
 
+int macvlan_pair_add(char *in, char *out)
+{
+	struct macvlan_pair *n;
+
+	n = xmalloc(sizeof(*n));
+	if (n == NULL)
+		return -1;
+
+	n->inside = in;
+	n->ifi_outside = if_nametoindex(out);
+	if (n->ifi_outside == 0) {
+		pr_perror("can't get index of %s", out);
+		xfree(n);
+		return -1;
+	}
+
+	list_add(&n->node, &opts.macvlan_pairs);
+	return 0;
+}
+
 /*
  * The setns() syscall (called by switch_ns()) can be extremely
  * slow. If we call it two or more times from the same task the
-- 
2.7.4



More information about the CRIU mailing list