[CRIU] [PATCH 1/2] sk-inet: detect corked sockets by getting a proper sock opt

Andrei Vagin avagin at openvz.org
Mon Dec 4 22:41:10 MSK 2017


From: Andrei Vagin <avagin at virtuozzo.com>

Now we block all sockets with non-zero idiag_wqueue, but it doesn't mean
that a CORK option is enabled for a socket. A packet can be in a network
stack and it is accounted into idiag_wqueue.

https://github.com/checkpoint-restore/criu/issues/409

Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
 criu/include/sk-inet.h |  1 +
 criu/sk-inet.c         | 30 +++++++++++++++++++++++++++---
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index 3b302ff70..180f48e35 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -28,6 +28,7 @@ struct inet_sk_desc {
 	unsigned int		src_addr[4];
 	unsigned int		dst_addr[4];
 	unsigned short		shutdown;
+	bool			cork;
 
 	int rfd;
 	int cpt_reuseaddr;
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index feae97c68..14a8e17c4 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -2,6 +2,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <netinet/udp.h>
 #include <libnl3/netlink/msg.h>
 #include <net/if.h>
 #include <sys/mman.h>
@@ -124,9 +125,14 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
 
 	if (sk->type == SOCK_DGRAM) {
 		if (sk->wqlen != 0) {
-			pr_err("Can't dump corked dgram socket %x\n",
+			if (sk->cork) {
+				pr_err("Can't dump corked dgram socket %x\n",
 					sk->sd.ino);
-			return 0;
+				return 0;
+			} else {
+				pr_warn("Write queue of the %x socket isn't empty\n",
+					sk->sd.ino);
+			}
 		}
 
 		if (sk->rqlen)
@@ -325,7 +331,7 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
 	InetSkEntry ie = INET_SK_ENTRY__INIT;
 	IpOptsEntry ipopts = IP_OPTS_ENTRY__INIT;
 	SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
-	int ret = -1, err = -1, proto;
+	int ret = -1, err = -1, proto, aux;
 
 	ret = do_dump_opt(lfd, SOL_SOCKET, SO_PROTOCOL,
 					&proto, sizeof(proto));
@@ -344,6 +350,24 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
 			goto err;
 	}
 
+	sk->cork = false;
+	switch (proto) {
+	case IPPROTO_UDP:
+	case IPPROTO_UDPLITE:
+		if (dump_opt(lfd, SOL_UDP, UDP_CORK, &aux))
+			return -1;
+		if (aux) {
+			sk->cork = true;
+			/*
+			 * FIXME: it is possible to dump a corked socket with
+			 * the empty send queue.
+			 */
+			pr_err("Can't dump corked dgram socket %x\n", sk->sd.ino);
+			goto err;
+		}
+		break;
+	}
+
 	if (!can_dump_inet_sk(sk))
 		goto err;
 
-- 
2.13.6



More information about the CRIU mailing list