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

Kirill Tkhai ktkhai at odin.com
Mon Nov 30 02:05:36 PST 2015


On 30.11.2015 12:03, Pavel Emelyanov wrote:
> 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.

DGRAM sockets can's listen at all. The word "listening" is in the quote,
because it's a turn of speech. It's peer-less, and it only receives
messages (though, it still may do sendto()).

>> 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.

I don't think it's really need. It will be removed in next iteration. Thanks.

But don't we have to do the same for TCP_ESTABLISHED case in the same function?
 
> Also, what about STREAM sockets with closed peer? Do they deserve the same
> queue restoring hack?

Currently there is no way to change STREAM socket's state from TCP_ESTABLISHED
to TCP_CLOSE without its killing. Thus, these sockets can't be reused from
userspace (they can't become listening). DGRAM sockets are another animals,
and they are always in TCP_CLOSE state, either they are connected or not.

So, STREAM sockets don't have such problem.
 
>> +		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