[CRIU] [PATCH v4 06/12] gc: implement unlocking of tcp connections

Eugene Batalov eabatalov89 at gmail.com
Sun Sep 11 10:14:45 PDT 2016


The logic is the same as on criu restore.

First we read ps tree dump to get information about all its
tcp connections. If ps tree shares net ns with host then
we simply run iptables to unlock all ps tree tcp connections.
If ps tree has unshared net ns then we do nothing because we know
that this net ns is already destroyed with its ps tree and all
incoming ps tree TCP packets are just dropped (no destination tcp stack
exists).

Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
---
 criu/cr-gc.c           | 10 ++++++++++
 criu/include/net.h     |  1 +
 criu/include/sk-inet.h |  2 +-
 criu/net.c             | 12 ++++++++++++
 criu/sk-tcp.c          |  9 ++++++---
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/criu/cr-gc.c b/criu/cr-gc.c
index e248e66..afb0f80 100644
--- a/criu/cr-gc.c
+++ b/criu/cr-gc.c
@@ -9,6 +9,8 @@
 #include "mount.h"
 #include "namespaces.h"
 #include "util.h"
+#include "sockets.h"
+#include "net.h"
 
 static int root_mntns = -1;
 
@@ -55,6 +57,9 @@ static int gc_do(void)
 	if (gc_link_remaps() < 0)
 		return -1;
 
+	if (gc_network_unlock() < 0)
+		return -1;
+
 	return 0;
 }
 
@@ -97,6 +102,11 @@ int cr_gc(void)
 		goto exit;
 	}
 
+	if (collect_inet_sockets()) {
+		ret = -1;
+		goto exit;
+	}
+
 	if (gc_do())
 		ret = -1;
 
diff --git a/criu/include/net.h b/criu/include/net.h
index ede380f..5e6260a 100644
--- a/criu/include/net.h
+++ b/criu/include/net.h
@@ -19,6 +19,7 @@ extern int collect_net_namespaces(bool for_dump);
 
 extern int network_lock(void);
 extern void network_unlock(void);
+extern int gc_network_unlock(void);
 
 extern struct ns_desc net_ns_desc;
 
diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index 9d2bda6..c82ffd4 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -65,7 +65,7 @@ static inline void tcp_repair_off(int fd)
 }
 
 extern void tcp_locked_conn_add(struct inet_sk_info *);
-extern void rst_unlock_tcp_connections(void);
+extern int rst_unlock_tcp_connections(void);
 extern void cpt_unlock_tcp_connections(void);
 
 extern int dump_one_tcp(int sk, struct inet_sk_desc *sd);
diff --git a/criu/net.c b/criu/net.c
index 080c617..754fbda 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1618,6 +1618,18 @@ void network_unlock(void)
 	}
 }
 
+int gc_network_unlock(void)
+{
+	/*
+	 * Unshared ps tree net ns is destroyed after successful dump.
+	 * No need to call network_unlock_internal.
+	 * Also don't call ACT_NET_UNLOCK script because we don't
+	 * resume/restore ps tree - this call would break
+	 * ACT_NET_UNLOCK semantics.
+	 */
+	return rst_unlock_tcp_connections();
+}
+
 int veth_pair_add(char *in, char *out)
 {
 	char *aux;
diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index 8cdc9f5..3b68b7c 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -785,16 +785,19 @@ void tcp_locked_conn_add(struct inet_sk_info *ii)
 	ii->sk_fd = -1;
 }
 
-void rst_unlock_tcp_connections(void)
+int rst_unlock_tcp_connections(void)
 {
 	struct inet_sk_info *ii;
 
 	/* Network will be unlocked by network-unlock scripts */
 	if (root_ns_mask & CLONE_NEWNET)
-		return;
+		return 0;
 
 	list_for_each_entry(ii, &rst_tcp_repair_sockets, rlist)
-		nf_unlock_connection_info(ii);
+		if (nf_unlock_connection_info(ii))
+			return -1;
+
+	return 0;
 }
 
 int check_tcp(void)
-- 
1.9.1



More information about the CRIU mailing list