[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