[CRIU] [PATCH] net: Do not toggle TCP_REPAIR while restoring TCP send queues

Andrew Vagin avagin at parallels.com
Sat Feb 7 11:54:48 PST 2015


On Fri, Feb 06, 2015 at 11:10:12AM -0800, Amey Deshpande wrote:
> For an established TCP connection, the send queue is restored in two
> steps: in step (1), we retransmit the data that was sent before but not
> yet acknowledged, and in step (2), we transmit the data that was never
> sent outside before.  The TCP_REPAIR option is disabled before step (2)
> and re-enabled after step (2) (without this patch).
> 
> If the amount of data to be sent in step (2) is large, the TCP_REPAIR
> flag on the socket can remain off for some time (O(milliseconds)).  If a
> listen() is called on another socket bound to the same port during this
> time window, it fails. This is because -- turning TCP_REPAIR off clears
> the SO_REUSEADDR flag on the socket.
> 
> There are several possible ways to prevent this problem from happening:
> - The simplest option is to *not* toggle TCP_REPAIR option while
>   restoring the TCP queues.

We can't do this.
https://github.com/xemul/criu/commit/98efb3c904788e90d5a6a6fff876659b9a7f2016

> - Another way would be to explicitly enable SO_REUSEADDR on the
>   socket after turning TCP_REPAIR off.  This still leaves a small time
>   window, and such race could still occur.
> - A more involved solution would use a mutex per port number, so
>   that a listen() on a port number does not happen while SO_REUSEADDR for
>   another socket on the same port is off.

I would prefer this way.

Thanks,
Andrey

> 
> This patch removes the toggling of TCP_REPAIR option during restoring
> TCP send queues.
> 
> Signed-off-by: Amey Deshpande <ameyd at google.com>
> ---
>  sk-tcp.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/sk-tcp.c b/sk-tcp.c
> index 3f1556d..02ed1f9 100644
> --- a/sk-tcp.c
> +++ b/sk-tcp.c
> @@ -534,11 +534,8 @@ static int restore_tcp_queues(int sk, TcpStreamEntry *tse, struct cr_img *img)
>  	 * they can be restored without any tricks.
>  	 */
>  	len = tse->unsq_len;
> -	tcp_repair_off(sk);
>  	if (len && __send_tcp_queue(sk, TCP_SEND_QUEUE, len, img))
>  		return -1;
> -	if (tcp_repair_on(sk))
> -		return -1;
>  
>  	return 0;
>  }
> -- 
> 2.2.0.rc0.207.ga3a616c
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list