[1/2] tcp: Add tcp-close option to restore connected TCP sockets in closed state

Submitted by Pavel Begunkov (Silence) on June 2, 2017, 6:30 a.m.

Details

Message ID 20170602063023.751-1-asml.silence@gmail.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Pavel Begunkov (Silence) June 2, 2017, 6:30 a.m.
From: Pavel Begunkov <asml.silence@gmail.com>

New restore option 'tcp-close' was introduced. It restores all connected
TCP sockets in TCP_CLOSE state. Here we consider tcp sockets in
TCP_ESTABLISHED, TCP_FIN_WAIT2, TCP_FIN_WAIT1, TCP_CLOSE_WAIT,
TCP_LAST_ACK, TCP_CLOSING, TCP_SYN_SENT states as connected sockets.
This is consistent with current CRIU usage of these states. Thus this
option doesn't affect sockets with original states of TCP_LISTEN and
TCP_CLOSE.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
---
 Documentation/criu.txt    | 3 +++
 criu/crtools.c            | 5 +++++
 criu/include/cr_options.h | 1 +
 criu/include/sk-inet.h    | 1 +
 criu/sk-inet.c            | 2 +-
 criu/sk-tcp.c             | 6 ++++++
 6 files changed, 17 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index 6758e9b8..16284cc4 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -264,6 +264,9 @@  For example, the command line for the above example should look like this:
     The TCP stack on the client side is expected to handle the
     re-connect gracefully.
 
+*--tcp-close*::
+    Restore connected TCP sockets in closed state.
+
 *--evasive-devices*::
     Use any path to a device file if the original one is inaccessible.
 
diff --git a/criu/crtools.c b/criu/crtools.c
index b20d2ec0..958f730a 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -293,6 +293,7 @@  int main(int argc, char *argv[], char *envp[])
 		BOOL_OPT("display-stats", &opts.display_stats),
 		BOOL_OPT("weak-sysctls", &opts.weak_sysctls),
 		{ "status-fd",			required_argument,	0, 1088 },
+		{ SK_CLOSE_PARAM, 		no_argument,		0, 1089 },
 		BOOL_OPT("remote", &opts.remote),
 		{ },
 	};
@@ -575,6 +576,9 @@  int main(int argc, char *argv[], char *envp[])
 				return 1;
 			}
 			break;
+		case 1089:
+			opts.tcp_close = true;
+			break;
 		case 'V':
 			pr_msg("Version: %s\n", CRIU_VERSION);
 			if (strcmp(CRIU_GITID, "0"))
@@ -860,6 +864,7 @@  usage:
 "* Special resources support:\n"
 "     --" SK_EST_PARAM "  checkpoint/restore established TCP connections\n"
 "     --" SK_INFLIGHT_PARAM "   skip (ignore) in-flight TCP connections\n"
+"     --" SK_CLOSE_PARAM "        restore connected TCP sockets in closed state\n"
 "  -r|--root PATH        change the root filesystem (when run in mount namespace)\n"
 "  --evasive-devices     use any path to a device file if the original one\n"
 "                        is inaccessible\n"
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index 94fc7177..02f11204 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -63,6 +63,7 @@  struct cr_options {
 	int			shell_job;
 	int			handle_file_locks;
 	int			tcp_established_ok;
+	bool			tcp_close;
 	int			evasive_devices;
 	int			link_remap_ok;
 	int			log_file_per_pid;
diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index bf6fb1d7..3b302ff7 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -75,6 +75,7 @@  extern int restore_one_tcp(int sk, struct inet_sk_info *si);
 
 #define SK_EST_PARAM	"tcp-established"
 #define SK_INFLIGHT_PARAM "skip-in-flight"
+#define SK_CLOSE_PARAM	"tcp-close"
 
 struct task_restore_args;
 int prepare_tcp_socks(struct task_restore_args *);
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 93486733..52ede0ed 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -663,7 +663,7 @@  static int open_inet_sk(struct file_desc *d, int *new_fd)
 		goto err;
 
 	if (tcp_connection(ie)) {
-		if (!opts.tcp_established_ok) {
+		if (!opts.tcp_established_ok && !opts.tcp_close) {
 			pr_err("Connected TCP socket in image\n");
 			goto err;
 		}
diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index 3acc7109..20ea528b 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -8,6 +8,7 @@ 
 
 #include "../soccr/soccr.h"
 
+#include "cr_options.h"
 #include "util.h"
 #include "common/list.h"
 #include "log.h"
@@ -407,6 +408,11 @@  int restore_one_tcp(int fd, struct inet_sk_info *ii)
 
 	pr_info("Restoring TCP connection\n");
 
+	if (opts.tcp_close &&
+		ii->ie->state != TCP_LISTEN && ii->ie->state != TCP_CLOSE) {
+		return 0;
+	}
+
 	sk = libsoccr_pause(fd);
 	if (!sk)
 		return -1;

Comments

Pavel Emelianov June 16, 2017, 10:58 a.m.
On 06/02/2017 09:30 AM, silence wrote:
> From: Pavel Begunkov <asml.silence@gmail.com>
> 
> New restore option 'tcp-close' was introduced. It restores all connected
> TCP sockets in TCP_CLOSE state. Here we consider tcp sockets in
> TCP_ESTABLISHED, TCP_FIN_WAIT2, TCP_FIN_WAIT1, TCP_CLOSE_WAIT,
> TCP_LAST_ACK, TCP_CLOSING, TCP_SYN_SENT states as connected sockets.
> This is consistent with current CRIU usage of these states. Thus this
> option doesn't affect sockets with original states of TCP_LISTEN and
> TCP_CLOSE.
> 
> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>

Acked-by: Pavel Emelyanov <xemul@virtuozzo.com>

Andrey, would you pick up this one?

> ---
>  Documentation/criu.txt    | 3 +++
>  criu/crtools.c            | 5 +++++
>  criu/include/cr_options.h | 1 +
>  criu/include/sk-inet.h    | 1 +
>  criu/sk-inet.c            | 2 +-
>  criu/sk-tcp.c             | 6 ++++++
>  6 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/criu.txt b/Documentation/criu.txt
> index 6758e9b8..16284cc4 100644
> --- a/Documentation/criu.txt
> +++ b/Documentation/criu.txt
> @@ -264,6 +264,9 @@ For example, the command line for the above example should look like this:
>      The TCP stack on the client side is expected to handle the
>      re-connect gracefully.
>  
> +*--tcp-close*::
> +    Restore connected TCP sockets in closed state.
> +
>  *--evasive-devices*::
>      Use any path to a device file if the original one is inaccessible.
>  
> diff --git a/criu/crtools.c b/criu/crtools.c
> index b20d2ec0..958f730a 100644
> --- a/criu/crtools.c
> +++ b/criu/crtools.c
> @@ -293,6 +293,7 @@ int main(int argc, char *argv[], char *envp[])
>  		BOOL_OPT("display-stats", &opts.display_stats),
>  		BOOL_OPT("weak-sysctls", &opts.weak_sysctls),
>  		{ "status-fd",			required_argument,	0, 1088 },
> +		{ SK_CLOSE_PARAM, 		no_argument,		0, 1089 },
>  		BOOL_OPT("remote", &opts.remote),
>  		{ },
>  	};
> @@ -575,6 +576,9 @@ int main(int argc, char *argv[], char *envp[])
>  				return 1;
>  			}
>  			break;
> +		case 1089:
> +			opts.tcp_close = true;
> +			break;
>  		case 'V':
>  			pr_msg("Version: %s\n", CRIU_VERSION);
>  			if (strcmp(CRIU_GITID, "0"))
> @@ -860,6 +864,7 @@ usage:
>  "* Special resources support:\n"
>  "     --" SK_EST_PARAM "  checkpoint/restore established TCP connections\n"
>  "     --" SK_INFLIGHT_PARAM "   skip (ignore) in-flight TCP connections\n"
> +"     --" SK_CLOSE_PARAM "        restore connected TCP sockets in closed state\n"
>  "  -r|--root PATH        change the root filesystem (when run in mount namespace)\n"
>  "  --evasive-devices     use any path to a device file if the original one\n"
>  "                        is inaccessible\n"
> diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
> index 94fc7177..02f11204 100644
> --- a/criu/include/cr_options.h
> +++ b/criu/include/cr_options.h
> @@ -63,6 +63,7 @@ struct cr_options {
>  	int			shell_job;
>  	int			handle_file_locks;
>  	int			tcp_established_ok;
> +	bool			tcp_close;
>  	int			evasive_devices;
>  	int			link_remap_ok;
>  	int			log_file_per_pid;
> diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
> index bf6fb1d7..3b302ff7 100644
> --- a/criu/include/sk-inet.h
> +++ b/criu/include/sk-inet.h
> @@ -75,6 +75,7 @@ extern int restore_one_tcp(int sk, struct inet_sk_info *si);
>  
>  #define SK_EST_PARAM	"tcp-established"
>  #define SK_INFLIGHT_PARAM "skip-in-flight"
> +#define SK_CLOSE_PARAM	"tcp-close"
>  
>  struct task_restore_args;
>  int prepare_tcp_socks(struct task_restore_args *);
> diff --git a/criu/sk-inet.c b/criu/sk-inet.c
> index 93486733..52ede0ed 100644
> --- a/criu/sk-inet.c
> +++ b/criu/sk-inet.c
> @@ -663,7 +663,7 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
>  		goto err;
>  
>  	if (tcp_connection(ie)) {
> -		if (!opts.tcp_established_ok) {
> +		if (!opts.tcp_established_ok && !opts.tcp_close) {
>  			pr_err("Connected TCP socket in image\n");
>  			goto err;
>  		}
> diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
> index 3acc7109..20ea528b 100644
> --- a/criu/sk-tcp.c
> +++ b/criu/sk-tcp.c
> @@ -8,6 +8,7 @@
>  
>  #include "../soccr/soccr.h"
>  
> +#include "cr_options.h"
>  #include "util.h"
>  #include "common/list.h"
>  #include "log.h"
> @@ -407,6 +408,11 @@ int restore_one_tcp(int fd, struct inet_sk_info *ii)
>  
>  	pr_info("Restoring TCP connection\n");
>  
> +	if (opts.tcp_close &&
> +		ii->ie->state != TCP_LISTEN && ii->ie->state != TCP_CLOSE) {
> +		return 0;
> +	}
> +
>  	sk = libsoccr_pause(fd);
>  	if (!sk)
>  		return -1;
>
Andrey Vagin June 16, 2017, 6:12 p.m.
Applied, thanks!

On Fri, Jun 16, 2017 at 01:58:53PM +0300, Pavel Emelyanov wrote:
> On 06/02/2017 09:30 AM, silence wrote:
> > From: Pavel Begunkov <asml.silence@gmail.com>
> > 
> > New restore option 'tcp-close' was introduced. It restores all connected
> > TCP sockets in TCP_CLOSE state. Here we consider tcp sockets in
> > TCP_ESTABLISHED, TCP_FIN_WAIT2, TCP_FIN_WAIT1, TCP_CLOSE_WAIT,
> > TCP_LAST_ACK, TCP_CLOSING, TCP_SYN_SENT states as connected sockets.
> > This is consistent with current CRIU usage of these states. Thus this
> > option doesn't affect sockets with original states of TCP_LISTEN and
> > TCP_CLOSE.
> > 
> > Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> > Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
> 
> Acked-by: Pavel Emelyanov <xemul@virtuozzo.com>
> 
> Andrey, would you pick up this one?
> 
> > ---
> >  Documentation/criu.txt    | 3 +++
> >  criu/crtools.c            | 5 +++++
> >  criu/include/cr_options.h | 1 +
> >  criu/include/sk-inet.h    | 1 +
> >  criu/sk-inet.c            | 2 +-
> >  criu/sk-tcp.c             | 6 ++++++
> >  6 files changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/criu.txt b/Documentation/criu.txt
> > index 6758e9b8..16284cc4 100644
> > --- a/Documentation/criu.txt
> > +++ b/Documentation/criu.txt
> > @@ -264,6 +264,9 @@ For example, the command line for the above example should look like this:
> >      The TCP stack on the client side is expected to handle the
> >      re-connect gracefully.
> >  
> > +*--tcp-close*::
> > +    Restore connected TCP sockets in closed state.
> > +
> >  *--evasive-devices*::
> >      Use any path to a device file if the original one is inaccessible.
> >  
> > diff --git a/criu/crtools.c b/criu/crtools.c
> > index b20d2ec0..958f730a 100644
> > --- a/criu/crtools.c
> > +++ b/criu/crtools.c
> > @@ -293,6 +293,7 @@ int main(int argc, char *argv[], char *envp[])
> >  		BOOL_OPT("display-stats", &opts.display_stats),
> >  		BOOL_OPT("weak-sysctls", &opts.weak_sysctls),
> >  		{ "status-fd",			required_argument,	0, 1088 },
> > +		{ SK_CLOSE_PARAM, 		no_argument,		0, 1089 },
> >  		BOOL_OPT("remote", &opts.remote),
> >  		{ },
> >  	};
> > @@ -575,6 +576,9 @@ int main(int argc, char *argv[], char *envp[])
> >  				return 1;
> >  			}
> >  			break;
> > +		case 1089:
> > +			opts.tcp_close = true;
> > +			break;
> >  		case 'V':
> >  			pr_msg("Version: %s\n", CRIU_VERSION);
> >  			if (strcmp(CRIU_GITID, "0"))
> > @@ -860,6 +864,7 @@ usage:
> >  "* Special resources support:\n"
> >  "     --" SK_EST_PARAM "  checkpoint/restore established TCP connections\n"
> >  "     --" SK_INFLIGHT_PARAM "   skip (ignore) in-flight TCP connections\n"
> > +"     --" SK_CLOSE_PARAM "        restore connected TCP sockets in closed state\n"
> >  "  -r|--root PATH        change the root filesystem (when run in mount namespace)\n"
> >  "  --evasive-devices     use any path to a device file if the original one\n"
> >  "                        is inaccessible\n"
> > diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
> > index 94fc7177..02f11204 100644
> > --- a/criu/include/cr_options.h
> > +++ b/criu/include/cr_options.h
> > @@ -63,6 +63,7 @@ struct cr_options {
> >  	int			shell_job;
> >  	int			handle_file_locks;
> >  	int			tcp_established_ok;
> > +	bool			tcp_close;
> >  	int			evasive_devices;
> >  	int			link_remap_ok;
> >  	int			log_file_per_pid;
> > diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
> > index bf6fb1d7..3b302ff7 100644
> > --- a/criu/include/sk-inet.h
> > +++ b/criu/include/sk-inet.h
> > @@ -75,6 +75,7 @@ extern int restore_one_tcp(int sk, struct inet_sk_info *si);
> >  
> >  #define SK_EST_PARAM	"tcp-established"
> >  #define SK_INFLIGHT_PARAM "skip-in-flight"
> > +#define SK_CLOSE_PARAM	"tcp-close"
> >  
> >  struct task_restore_args;
> >  int prepare_tcp_socks(struct task_restore_args *);
> > diff --git a/criu/sk-inet.c b/criu/sk-inet.c
> > index 93486733..52ede0ed 100644
> > --- a/criu/sk-inet.c
> > +++ b/criu/sk-inet.c
> > @@ -663,7 +663,7 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
> >  		goto err;
> >  
> >  	if (tcp_connection(ie)) {
> > -		if (!opts.tcp_established_ok) {
> > +		if (!opts.tcp_established_ok && !opts.tcp_close) {
> >  			pr_err("Connected TCP socket in image\n");
> >  			goto err;
> >  		}
> > diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
> > index 3acc7109..20ea528b 100644
> > --- a/criu/sk-tcp.c
> > +++ b/criu/sk-tcp.c
> > @@ -8,6 +8,7 @@
> >  
> >  #include "../soccr/soccr.h"
> >  
> > +#include "cr_options.h"
> >  #include "util.h"
> >  #include "common/list.h"
> >  #include "log.h"
> > @@ -407,6 +408,11 @@ int restore_one_tcp(int fd, struct inet_sk_info *ii)
> >  
> >  	pr_info("Restoring TCP connection\n");
> >  
> > +	if (opts.tcp_close &&
> > +		ii->ie->state != TCP_LISTEN && ii->ie->state != TCP_CLOSE) {
> > +		return 0;
> > +	}
> > +
> >  	sk = libsoccr_pause(fd);
> >  	if (!sk)
> >  		return -1;
> > 
>