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

Andrei Vagin avagin at virtuozzo.com
Fri Dec 15 09:14:12 MSK 2017


Applied

On Mon, Dec 04, 2017 at 10:41:10PM +0300, Andrei Vagin wrote:
> 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