[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