[v2,09/15] unix: Fixup queuer of promiscuous DGRAM receivers

Submitted by Kirill Tkhai on May 27, 2016, 1:07 p.m.

Details

Message ID 146435442659.31234.10388596592533336676.stgit@pro
State Rejected
Series "Support for packet's msg_name in receive queue of promiscous DGRAM sockets"
Headers show

Commit Message

Kirill Tkhai May 27, 2016, 1:07 p.m.
If packets in a receive queue of a sockets have more than 1 sender,
we should not name "queuer" one of them. Otherwise, we restore them
with the only msg_name.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/sk-unix.c |   26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 076100c..cf589b8 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -1386,6 +1386,26 @@  struct collect_image_info unix_sk_cinfo = {
 	.flags = COLLECT_SHARED,
 };
 
+static u32 sk_queuer(struct unix_sk_info *sk, struct unix_sk_info *maybe_queuer)
+{
+	if (maybe_queuer->peer != sk) {
+		pr_err("sk is not peer of passed queuer\n");
+		return 0;
+	}
+
+	/* Nothing is restored if queue is empty. Set fake queuer for that. */
+	if (sk->ue->type != SOCK_DGRAM || (sk->ue->uflags & USK_EMPTY_Q))
+		return maybe_queuer->ue->ino;
+
+	if ((sk->ue->uflags & USK_NONAME_SND) && maybe_queuer->ue->name.len == 0)
+		return maybe_queuer->ue->ino;
+
+	if (sk->ue->has_sender_ino && sk->ue->sender_ino == maybe_queuer->ue->ino)
+		return maybe_queuer->ue->ino;
+
+	return 0;
+}
+
 static int resolve_unix_peers(void *unused)
 {
 	struct unix_sk_info *ui, *peer;
@@ -1407,7 +1427,7 @@  static int resolve_unix_peers(void *unused)
 
 		ui->peer = peer;
 		if (!peer->queuer)
-			peer->queuer = ui->ue->ino;
+			peer->queuer = sk_queuer(peer, ui);
 		if (ui == peer)
 			/* socket connected to self %) */
 			continue;
@@ -1416,6 +1436,10 @@  static int resolve_unix_peers(void *unused)
 
 		/* socketpair or interconnected sockets */
 		peer->peer = ui;
+		ui->queuer = sk_queuer(ui, peer);
+
+		if (!peer->queuer || !ui->queuer)
+			continue;
 
 		/*
 		 * Select who will restore the pair. Check is identical to

Comments

Pavel Emelianov May 30, 2016, 11:46 a.m.
On 05/27/2016 04:07 PM, Kirill Tkhai wrote:
> If packets in a receive queue of a sockets have more than 1 sender,
> we should not name "queuer" one of them. Otherwise, we restore them
> with the only msg_name.

With which?

> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
> ---
>  criu/sk-unix.c |   26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/sk-unix.c b/criu/sk-unix.c
> index 076100c..cf589b8 100644
> --- a/criu/sk-unix.c
> +++ b/criu/sk-unix.c
> @@ -1386,6 +1386,26 @@ struct collect_image_info unix_sk_cinfo = {
>  	.flags = COLLECT_SHARED,
>  };
>  
> +static u32 sk_queuer(struct unix_sk_info *sk, struct unix_sk_info *maybe_queuer)
> +{
> +	if (maybe_queuer->peer != sk) {
> +		pr_err("sk is not peer of passed queuer\n");
> +		return 0;
> +	}
> +
> +	/* Nothing is restored if queue is empty. Set fake queuer for that. */
> +	if (sk->ue->type != SOCK_DGRAM || (sk->ue->uflags & USK_EMPTY_Q))
> +		return maybe_queuer->ue->ino;
> +
> +	if ((sk->ue->uflags & USK_NONAME_SND) && maybe_queuer->ue->name.len == 0)
> +		return maybe_queuer->ue->ino;
> +
> +	if (sk->ue->has_sender_ino && sk->ue->sender_ino == maybe_queuer->ue->ino)
> +		return maybe_queuer->ue->ino;
> +
> +	return 0;
> +}
> +
>  static int resolve_unix_peers(void *unused)
>  {
>  	struct unix_sk_info *ui, *peer;
> @@ -1407,7 +1427,7 @@ static int resolve_unix_peers(void *unused)
>  
>  		ui->peer = peer;
>  		if (!peer->queuer)
> -			peer->queuer = ui->ue->ino;
> +			peer->queuer = sk_queuer(peer, ui);
>  		if (ui == peer)
>  			/* socket connected to self %) */
>  			continue;
> @@ -1416,6 +1436,10 @@ static int resolve_unix_peers(void *unused)
>  
>  		/* socketpair or interconnected sockets */
>  		peer->peer = ui;
> +		ui->queuer = sk_queuer(ui, peer);
> +
> +		if (!peer->queuer || !ui->queuer)
> +			continue;
>  
>  		/*
>  		 * Select who will restore the pair. Check is identical to
> 
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
> .
>
Kirill Tkhai May 30, 2016, 12:36 p.m.
On 30.05.2016 14:46, Pavel Emelyanov wrote:
> On 05/27/2016 04:07 PM, Kirill Tkhai wrote:
>> If packets in a receive queue of a sockets have more than 1 sender,
>> we should not name "queuer" one of them. Otherwise, we restore them
>> with the only msg_name.
> 
> With which?

With the name of the queuer.
 
>> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
>> ---
>>  criu/sk-unix.c |   26 +++++++++++++++++++++++++-
>>  1 file changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/criu/sk-unix.c b/criu/sk-unix.c
>> index 076100c..cf589b8 100644
>> --- a/criu/sk-unix.c
>> +++ b/criu/sk-unix.c
>> @@ -1386,6 +1386,26 @@ struct collect_image_info unix_sk_cinfo = {
>>  	.flags = COLLECT_SHARED,
>>  };
>>  
>> +static u32 sk_queuer(struct unix_sk_info *sk, struct unix_sk_info *maybe_queuer)
>> +{
>> +	if (maybe_queuer->peer != sk) {
>> +		pr_err("sk is not peer of passed queuer\n");
>> +		return 0;
>> +	}
>> +
>> +	/* Nothing is restored if queue is empty. Set fake queuer for that. */
>> +	if (sk->ue->type != SOCK_DGRAM || (sk->ue->uflags & USK_EMPTY_Q))
>> +		return maybe_queuer->ue->ino;
>> +
>> +	if ((sk->ue->uflags & USK_NONAME_SND) && maybe_queuer->ue->name.len == 0)
>> +		return maybe_queuer->ue->ino;
>> +
>> +	if (sk->ue->has_sender_ino && sk->ue->sender_ino == maybe_queuer->ue->ino)
>> +		return maybe_queuer->ue->ino;
>> +
>> +	return 0;
>> +}
>> +
>>  static int resolve_unix_peers(void *unused)
>>  {
>>  	struct unix_sk_info *ui, *peer;
>> @@ -1407,7 +1427,7 @@ static int resolve_unix_peers(void *unused)
>>  
>>  		ui->peer = peer;
>>  		if (!peer->queuer)
>> -			peer->queuer = ui->ue->ino;
>> +			peer->queuer = sk_queuer(peer, ui);
>>  		if (ui == peer)
>>  			/* socket connected to self %) */
>>  			continue;
>> @@ -1416,6 +1436,10 @@ static int resolve_unix_peers(void *unused)
>>  
>>  		/* socketpair or interconnected sockets */
>>  		peer->peer = ui;
>> +		ui->queuer = sk_queuer(ui, peer);
>> +
>> +		if (!peer->queuer || !ui->queuer)
>> +			continue;
>>  
>>  		/*
>>  		 * Select who will restore the pair. Check is identical to
>>
>> _______________________________________________
>> CRIU mailing list
>> CRIU@openvz.org
>> https://lists.openvz.org/mailman/listinfo/criu
>> .
>>
>