Commit 53211331 authored by Andrei Vagin's avatar Andrei Vagin

sk-inet: detect corked sockets by getting a proper sock opt

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/409Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 8bc39c78
...@@ -28,6 +28,7 @@ struct inet_sk_desc { ...@@ -28,6 +28,7 @@ struct inet_sk_desc {
unsigned int src_addr[4]; unsigned int src_addr[4];
unsigned int dst_addr[4]; unsigned int dst_addr[4];
unsigned short shutdown; unsigned short shutdown;
bool cork;
int rfd; int rfd;
int cpt_reuseaddr; int cpt_reuseaddr;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <netinet/udp.h>
#include <libnl3/netlink/msg.h> #include <libnl3/netlink/msg.h>
#include <net/if.h> #include <net/if.h>
#include <sys/mman.h> #include <sys/mman.h>
...@@ -123,9 +124,14 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk) ...@@ -123,9 +124,14 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
if (sk->type == SOCK_DGRAM) { if (sk->type == SOCK_DGRAM) {
if (sk->wqlen != 0) { 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); 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) if (sk->rqlen)
...@@ -317,7 +323,7 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa ...@@ -317,7 +323,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; InetSkEntry ie = INET_SK_ENTRY__INIT;
IpOptsEntry ipopts = IP_OPTS_ENTRY__INIT; IpOptsEntry ipopts = IP_OPTS_ENTRY__INIT;
SkOptsEntry skopts = SK_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, ret = do_dump_opt(lfd, SOL_SOCKET, SO_PROTOCOL,
&proto, sizeof(proto)); &proto, sizeof(proto));
...@@ -336,6 +342,24 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa ...@@ -336,6 +342,24 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
goto err; 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)) if (!can_dump_inet_sk(sk))
goto err; goto err;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment