[CRIU] [PATCH v4 8/8] optimization: do not restore configs for devices if value is default

Pavel Tikhomirov ptikhomirov at parallels.com
Wed Oct 8 06:21:42 PDT 2014


because namespace default options are set before devices creation,
devices will gain default options(except lo).

Signed-off-by: Pavel Tikhomirov <ptikhomirov at parallels.com>
---
 net.c | 56 ++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/net.c b/net.c
index 68ba5a2..24261be 100644
--- a/net.c
+++ b/net.c
@@ -81,15 +81,25 @@ char *devconfs[] = {
 #define NET_DEV_CONF_SIZE 27
 #define NET_CONF_PATH "net/ipv4/conf"
 
-static int ipv4_conf_op(char *tgt, int *conf, int op)
+static int ipv4_conf_op(char *tgt, int *conf, int op, NetnsEntry **netns)
 {
 	int ret;
-	int i, j;
+	int i, j, shift = 0;
 	struct sysctl_req req[NET_DEV_CONF_SIZE + 1];
 	int sdir = strlen(tgt) + strlen(NET_CONF_PATH) + 1;
 
 	for (i = 0; devconfs[i]; i++) {
 		char *path;
+
+		/*
+		 * If dev conf value is the same as default skip restoring it
+		 */
+		if (netns && conf[i] == (*netns)->def_conf[i]) {
+			shift++;
+			pr_debug("DEBUG Skip %s/%s, val =%d\n", tgt, devconfs[i], conf[i]);
+			continue;
+		}
+
 		int size = sdir + strlen(devconfs[i]) + 2;
 
 		path = xmalloc(size);
@@ -99,17 +109,17 @@ static int ipv4_conf_op(char *tgt, int *conf, int op)
 		}
 		snprintf(path, size, "%s/%s/%s", NET_CONF_PATH, tgt, devconfs[i]);
 
-		req[i].name = path;
-		req[i].arg = &conf[i];
-		req[i].type = CTL_32;
+		req[i - shift].name = path;
+		req[i - shift].arg = &conf[i];
+		req[i - shift].type = CTL_32;
 	}
-	req[i].name = NULL;
+	req[i - shift].name = NULL;
 
 	ret = sysctl_op(req, op);
 	if (ret < 0)
 		pr_err("Failed to read %s/<confs>\n", tgt);
 free:
-	for (j = 0; j < i; j++)
+	for (j = 0; j < i - shift; j++)
 		xfree(req[j].name);
 	if (ret < 0)
 		return -1;
@@ -153,7 +163,7 @@ static int dump_one_netdev(int type, struct ifinfomsg *ifi,
 	if (!netdev.conf)
 		return -1;
 
-	ret = ipv4_conf_op(netdev.name, netdev.conf, CTL_READ);
+	ret = ipv4_conf_op(netdev.name, netdev.conf, CTL_READ, NULL);
 	if (ret < 0) {
 		pr_err("failed to get net device ipv4 conf");
 		goto err_free;
@@ -451,7 +461,7 @@ static int restore_link(NetDeviceEntry *nde, int nlsk)
 	return -1;
 }
 
-static int restore_links(int pid)
+static int restore_links(int pid, NetnsEntry **netns)
 {
 	int fd, nlsk, ret;
 	NetDeviceEntry *nde;
@@ -478,7 +488,12 @@ static int restore_links(int pid)
 			goto exit;
 		}
 
-		ret = ipv4_conf_op(nde->name, nde->conf, CTL_WRITE);
+		/*
+		 * lo creates with namespace and before default is set
+		 * so we cant optimize its restore
+		 */
+		ret = strcmp(nde->name, "lo");
+		ret = ipv4_conf_op(nde->name, nde->conf, CTL_WRITE, ret == 0 ? NULL : netns);
 		if (ret < 0)
 			pr_err("failed to set net device ipv4 conf\n");
 exit:
@@ -560,10 +575,10 @@ static int dump_netns_conf(struct cr_fdset *fds)
 		return -1;
 	}
 
-	ret = ipv4_conf_op("default", netns.def_conf, CTL_READ);
+	ret = ipv4_conf_op("default", netns.def_conf, CTL_READ, NULL);
 	if (ret < 0)
 		goto err_free;
-	ret = ipv4_conf_op("all", netns.all_conf, CTL_READ);
+	ret = ipv4_conf_op("all", netns.all_conf, CTL_READ, NULL);
 	if (ret < 0)
 		goto err_free;
 
@@ -612,11 +627,10 @@ static inline int restore_iptables(int pid)
 	return ret;
 }
 
-static int restore_netns_conf(int pid)
+static int restore_netns_conf(int pid, NetnsEntry **netns)
 {
 	int ret;
 	int fd;
-	NetnsEntry *netns;
 
 	fd = open_image(CR_FD_NETNS, O_RSTR, pid);
 	if (fd < 0) {
@@ -624,19 +638,18 @@ static int restore_netns_conf(int pid)
 		return -1;
 	}
 
-	ret = pb_read_one(fd, &netns, PB_NETNS);
+	ret = pb_read_one(fd, netns, PB_NETNS);
 	if (ret < 0) {
 		pr_err("Can not read netns object\n");
 		close(fd);
 		return -1;
 	}
 
-	ret = ipv4_conf_op("default", netns->def_conf, CTL_WRITE);
+	ret = ipv4_conf_op("default", (*netns)->def_conf, CTL_WRITE, NULL);
 	if (ret < 0)
 		goto err;
-	ret = ipv4_conf_op("all", netns->all_conf, CTL_WRITE);
+	ret = ipv4_conf_op("all", (*netns)->all_conf, CTL_WRITE, NULL);
 err:
-	netns_entry__free_unpacked(netns, NULL);
 	close(fd);
 	if (ret < 0)
 		return -1;
@@ -717,10 +730,13 @@ int dump_net_ns(int pid, int ns_id)
 int prepare_net_ns(int pid)
 {
 	int ret;
+	NetnsEntry *netns;
 
-	ret = restore_netns_conf(pid);
+	ret = restore_netns_conf(pid, &netns);
 	if (!ret)
-		ret = restore_links(pid);
+		ret = restore_links(pid, &netns);
+	netns_entry__free_unpacked(netns, NULL);
+
 	if (!ret)
 		ret = restore_ifaddr(pid);
 	if (!ret)
-- 
1.9.3



More information about the CRIU mailing list