Blob Blame History Raw
From 2fdef836a59938b169ca3c8f2c813b35258f1ed5 Mon Sep 17 00:00:00 2001
From: Adrian Reber <areber@redhat.com>
Date: Tue, 14 Jun 2016 10:13:00 +0300
Subject: [PATCH] criu: add an option to skip in-flight connections

Trying to migrate containers with tomcat and running ab as a test client
(ab -n 1000000 -c 20 http://url/to/test) criu sometimes exited with an
error if in-flight connections were detected. Criu can handle sockets
listening and with established connection. In-flight connections can
happen on sockets which do not yet have a full established connection
(SYN, SYN-ACK, and the last ACK is missing).

This adds a new option to criu:

 --skip-in-flight  this option skips in-flight TCP connections.
                   if TCP connections are found which are not yet completely
                   established, criu will ignore these connections in favor
                   of erroring out.

With this option criu will skip sockets in this state and let's the client
handle the re-connection.

Signed-off-by: Adrian Reber <areber@redhat.com>
Acked-by: Andrew Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/crtools.c            | 9 +++++++++
 criu/include/cr_options.h | 1 +
 criu/include/sk-inet.h    | 1 +
 criu/sk-inet.c            | 7 +++++++
 4 files changed, 18 insertions(+)

diff --git a/criu/crtools.c b/criu/crtools.c
index b527374..e7da5c7 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -279,6 +279,7 @@ int main(int argc, char *argv[], char *envp[])
 		{ "extra",			no_argument,		0, 1077	},
 		{ "experimental",		no_argument,		0, 1078	},
 		{ "all",			no_argument,		0, 1079	},
+		{ SK_INFLIGHT_PARAM,		no_argument,		0, 1083	},
 		{ },
 	};
 
@@ -583,6 +584,10 @@ int main(int argc, char *argv[], char *envp[])
 			opts.check_extra_features = true;
 			opts.check_experimental_features = true;
 			break;
+		case 1083:
+			pr_msg("Will skip in-flight TCP connections\n");
+			opts.tcp_skip_in_flight = true;
+			break;
 		case 'V':
 			pr_msg("Version: %s\n", CRIU_VERSION);
 			if (strcmp(CRIU_GITID, "0"))
@@ -791,6 +796,10 @@ int main(int argc, char *argv[], char *envp[])
 "* Special resources support:\n"
 "  -x|--" USK_EXT_PARAM "inode,.." "      allow external unix connections (optionally can be assign socket's inode that allows one-sided dump)\n"
 "     --" SK_EST_PARAM "  checkpoint/restore established TCP connections\n"
+"     --" SK_INFLIGHT_PARAM "   this option skips in-flight TCP connections.\n"
+"                        if TCP connections are found which are not yet completely\n"
+"                        established, criu will ignore these connections in favor\n"
+"                        of erroring out.\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 32c9d4f..bf9feee 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -109,6 +109,7 @@ struct cr_options {
 	char			*lsm_profile;
 	unsigned int		timeout;
 	unsigned int		empty_ns;
+	bool			tcp_skip_in_flight;
 };
 
 extern struct cr_options opts;
diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index 4707a6e..9d2bda6 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -72,6 +72,7 @@ extern int dump_one_tcp(int sk, struct inet_sk_desc *sd);
 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"
 
 extern int check_tcp(void);
 extern mutex_t *inet_get_reuseaddr_lock(struct inet_sk_info *ii);
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 20c6535..dfcfae6 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -144,6 +144,11 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
 	switch (sk->state) {
 	case TCP_LISTEN:
 		if (sk->rqlen != 0) {
+			if (opts.tcp_skip_in_flight) {
+				pr_info("Skipping in-flight connection (l) for %x\n",
+						sk->sd.ino);
+				break;
+			}
 			/*
 			 * Currently the ICONS nla reports the conn
 			 * requests for listen sockets. Need to pick
@@ -151,6 +156,8 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
 			 */
 			pr_err("In-flight connection (l) for %x\n",
 					sk->sd.ino);
+			pr_err("In-flight connections can be ignored with the"
+					"--%s option.\n", SK_INFLIGHT_PARAM);
 			return 0;
 		}
 		break;