[CRIU] [PATCH 4/5] inet: prevent dumping of sockets if they are not collected

Andrey Vagin avagin at openvz.org
Wed Mar 27 09:23:16 EDT 2013


If inet sockets are not collected and a dumped task has one, crtools
should return an errror instead of dumping it as unconnected socket.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 include/sockets.h |  3 +++
 sk-inet.c         | 28 +++++++++++++++++++++++++---
 sockets.c         | 12 ++++++++++++
 3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/include/sockets.h b/include/sockets.h
index 66726c9..5de94a1 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -27,6 +27,9 @@ struct socket_desc {
 };
 
 extern bool netlink_collected;
+extern bool tcp_collected[2];
+extern bool udp_collected[2];
+extern bool udplite_collected[2];
 
 extern int dump_socket(struct fd_parms *p, int lfd, const int fdinfo);
 extern int dump_socket_opts(int sk, SkOptsEntry *soe);
diff --git a/sk-inet.c b/sk-inet.c
index 66366ac..0e6bf43 100644
--- a/sk-inet.c
+++ b/sk-inet.c
@@ -23,6 +23,10 @@
 #define PB_ALEN_INET	1
 #define PB_ALEN_INET6	4
 
+bool tcp_collected[2];
+bool udp_collected[2];
+bool udplite_collected[2];
+
 static LIST_HEAD(inet_ports);
 
 struct inet_port {
@@ -160,7 +164,8 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
 	return 1;
 }
 
-static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p)
+static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p,
+					 unsigned int proto)
 {
 	struct inet_sk_desc *sk;
 	char address;
@@ -188,10 +193,11 @@ static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p)
 
 	ret  = do_dump_opt(lfd, SOL_SOCKET, SO_DOMAIN, &sk->sd.family, sizeof(sk->sd.family));
 	ret |= do_dump_opt(lfd, SOL_SOCKET, SO_TYPE, &sk->type, sizeof(sk->type));
-	ret |= do_dump_opt(lfd, SOL_SOCKET, SO_PROTOCOL, &sk->proto, sizeof(sk->proto));
 	if (ret)
 		goto err;
 
+	sk->proto = proto;
+
 	if (sk->proto == IPPROTO_TCP) {
 		struct tcp_info info;
 
@@ -230,7 +236,23 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
 
 	sk = (struct inet_sk_desc *)lookup_socket(p->stat.st_ino, family);
 	if (!sk) {
-		sk = gen_uncon_sk(lfd, p);
+		int proto;
+		bool v6 = (family == AF_INET6);
+
+		ret = do_dump_opt(lfd, SOL_SOCKET, SO_PROTOCOL,
+						&proto, sizeof(proto));
+		if (ret)
+			goto err;
+
+		if ((proto == IPPROTO_TCP     && !tcp_collected[v6]) ||
+		    (proto == IPPROTO_UDP     && !udp_collected[v6]) ||
+		    (proto == IPPROTO_UDPLITE && !tcp_collected[v6])) {
+			pr_err("Sockets (family %d proto %d) are not collected\n",
+				family, proto);
+			goto err;
+		}
+
+		sk = gen_uncon_sk(lfd, p, proto);
 		if (!sk)
 			goto err;
 	}
diff --git a/sockets.c b/sockets.c
index 0b992f5..07e9cf0 100644
--- a/sockets.c
+++ b/sockets.c
@@ -463,6 +463,8 @@ int collect_sockets(int pid)
 	tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
 	if (tmp)
 		err = tmp;
+	else
+		tcp_collected[0] = true;
 
 	/* Collect IPv4 UDP sockets */
 	req.r.i.sdiag_family	= AF_INET;
@@ -472,6 +474,8 @@ int collect_sockets(int pid)
 	tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
 	if (tmp)
 		err = tmp;
+	else
+		udp_collected[0] = true;
 
 	/* Collect IPv4 UDP-lite sockets */
 	req.r.i.sdiag_family	= AF_INET;
@@ -481,6 +485,8 @@ int collect_sockets(int pid)
 	tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
 	if (tmp)
 		err = tmp;
+	else
+		udplite_collected[0] = true;
 
 	/* Collect IPv6 TCP sockets */
 	req.r.i.sdiag_family	= AF_INET6;
@@ -491,6 +497,8 @@ int collect_sockets(int pid)
 	tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
 	if (tmp)
 		err = tmp;
+	else
+		tcp_collected[1] = true;
 
 	/* Collect IPv6 UDP sockets */
 	req.r.i.sdiag_family	= AF_INET6;
@@ -500,6 +508,8 @@ int collect_sockets(int pid)
 	tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
 	if (tmp)
 		err = tmp;
+	else
+		udp_collected[1] = true;
 
 	/* Collect IPv6 UDP-lite sockets */
 	req.r.i.sdiag_family	= AF_INET6;
@@ -509,6 +519,8 @@ int collect_sockets(int pid)
 	tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
 	if (tmp)
 		err = tmp;
+	else
+		udplite_collected[1] = true;
 
 	req.r.p.sdiag_family	= AF_PACKET;
 	req.r.p.sdiag_protocol	= 0;
-- 
1.7.11.7



More information about the CRIU mailing list