[CRIU] [PATCH v2 1/2] unix: Add support for restoring receive queue for unix DGRAM sockets

Pavel Emelyanov xemul at parallels.com
Mon Nov 30 01:03:48 PST 2015


On 11/26/2015 08:54 PM, Kirill Tkhai wrote:
> Restore a receive queue in cases of:
> 
> 1)socketpair with closed second end;
> 2)peer-less "listening" socket, who is a peer for others.

Listening socket cannot receive any messages, it only can
accept() new connections.

> The only hack we use here is the connect with AF_UNSPEC family,
> which clears peer of restoring socket. See unix_dgram_connect()
> for the details.
> 
> This also makes socket_close_data test working.
> 
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> 
> v2: 1)Add a commentary near connect()
>     2)Delete test/zdtm/live/static/socket_close_data.desc
> ---
>  sk-unix.c                                    |   34 ++++++++++++++++++++++++++
>  test/zdtm/live/static/socket_close_data.desc |    1 -
>  2 files changed, 34 insertions(+), 1 deletion(-)
>  delete mode 100644 test/zdtm/live/static/socket_close_data.desc
> 
> diff --git a/sk-unix.c b/sk-unix.c
> index 91e4263..7ca4723 100644
> --- a/sk-unix.c
> +++ b/sk-unix.c
> @@ -1133,6 +1133,40 @@ static int open_unixsk_standalone(struct unix_sk_info *ui)
>  
>  		close(sks[1]);
>  		sk = sks[0];
> +	} else if (ui->ue->type == SOCK_DGRAM && !ui->ue->peer) {

Is the 2nd check required? We're in open_unixsk_standalone() which is
for peer-less sockets.

Also, what about STREAM sockets with closed peer? Do they deserve the same
queue restoring hack?

> +		struct sockaddr_un addr;
> +		int sks[2];
> +
> +		if (socketpair(PF_UNIX, ui->ue->type, 0, sks) < 0) {
> +			pr_perror("Can't create socketpair");
> +			return -1;
> +		}
> +
> +		sk = sks[0];
> +		addr.sun_family = AF_UNSPEC;
> +
> +		/*
> +		 * socketpair() assigns sks[1] as a peer of sks[0]
> +		 * (and vice versa). But in this case (not zero peer)
> +		 * it's impossible for other sockets to connect
> +		 * to sks[1] (see unix_dgram_connect()->unix_may_send()).
> +		 * The below is hack: we use that connect with AF_UNSPEC
> +		 * clears socket's peer.
> +		 */
> +		if (connect(sk, &addr, sizeof(addr.sun_family))) {
> +			pr_perror("Can't clear socket's peer");
> +			return -1;
> +		}
> +
> +		/*
> +		 * This must be after the connect() hack, because
> +		 * connect() flushes receive queue.
> +		 */
> +		if (restore_sk_queue(sks[1], ui->ue->id)) {
> +			pr_perror("Can't restore socket queue");
> +			return -1;
> +		}
> +		close(sks[1]);
>  	} else {
>  		if (ui->ue->uflags & USK_CALLBACK) {
>  			sk = run_plugins(RESTORE_UNIX_SK, ui->ue->ino);
> diff --git a/test/zdtm/live/static/socket_close_data.desc b/test/zdtm/live/static/socket_close_data.desc
> deleted file mode 100644
> index 95c58b4..0000000
> --- a/test/zdtm/live/static/socket_close_data.desc
> +++ /dev/null
> @@ -1 +0,0 @@
> -{'flags': 'noauto'}
> 
> .
> 



More information about the CRIU mailing list