[CRIU] [PATCH] tcp: refresh a data about tcp connection after blocking it (v3)

Andrey Vagin avagin at openvz.org
Thu Nov 15 09:33:33 EST 2012


We have a window between getting info about tcp connections
and blocking them. States of tcp connections can be changes,
so they should be refreshed after blocking.

https://bugzilla.openvz.org/show_bug.cgi?id=2419

v2: clean up
v3: don't update lengthes of queues for listen sockets,
    they don't used.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 sk-tcp.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/sk-tcp.c b/sk-tcp.c
index 9e01a08..e6e703e 100644
--- a/sk-tcp.c
+++ b/sk-tcp.c
@@ -51,6 +51,40 @@ static int tcp_repair_on(int fd)
 	return ret;
 }
 
+static int refresh_inet_sk(int fd, struct inet_sk_desc *sk)
+{
+	int size;
+	struct tcp_info info;
+
+	if (sk->state == TCP_CLOSE)
+		return 0;
+
+	if (dump_opt(fd, SOL_TCP, TCP_INFO, &info)) {
+		pr_perror("Failt to obtain TCP_INFO");
+		return -1;
+	}
+
+	sk->state = info.tcpi_state;
+
+	if (sk->state != TCP_LISTEN) {
+		if (ioctl(fd, SIOCOUTQ, &size) == -1) {
+			pr_perror("Unable to get size of snd queue");
+			return -1;
+		}
+
+		sk->wqlen = size;
+
+		if (ioctl(fd, SIOCINQ, &size) == -1) {
+			pr_perror("Unable to get size of recv queue");
+			return -1;
+		}
+
+		sk->rqlen = size;
+	}
+
+	return 0;
+}
+
 static int tcp_repair_establised(int fd, struct inet_sk_desc *sk)
 {
 	int ret;
@@ -71,6 +105,11 @@ static int tcp_repair_establised(int fd, struct inet_sk_desc *sk)
 		ret = nf_lock_connection(sk);
 		if (ret < 0)
 			goto err2;
+
+		/* A state of a tcp connection could be changed */
+		ret = refresh_inet_sk(sk->rfd, sk);
+		if (ret < 0)
+			goto err2;
 	}
 
 	ret = tcp_repair_on(sk->rfd);
-- 
1.7.11.7



More information about the CRIU mailing list