[CRIU] [PATCH 1/2] tcp: dump and restore tcp_timestamp for each socket (v2)

Andrey Vagin avagin at openvz.org
Thu Feb 14 09:51:03 EST 2013


If a TCP socket will get live-migrated from one box to another the
timestamps (which are typically ON) will get screwed up -- the new
kernel will generate TS values that has nothing to do with what they
were on dump. The solution is to yet again fix the kernel and put a
"timestamp offset" on a socket.

v2: don't fail if TCP_TIMESTAMP is unsupported

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 protobuf/tcp-stream.proto |  1 +
 sk-tcp.c                  | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/protobuf/tcp-stream.proto b/protobuf/tcp-stream.proto
index f3355dc..8b28ddb 100644
--- a/protobuf/tcp-stream.proto
+++ b/protobuf/tcp-stream.proto
@@ -8,4 +8,5 @@ message tcp_stream_entry {
 	required uint32		snd_wscale	= 6;
 	required uint32		mss_clamp	= 7;
 	optional uint32		rcv_wscale	= 8;
+	optional uint32		timestamp	= 9;
 }
diff --git a/sk-tcp.c b/sk-tcp.c
index ab2b91c..1a39125 100644
--- a/sk-tcp.c
+++ b/sk-tcp.c
@@ -34,6 +34,10 @@ enum {
 	TCP_QUEUES_NR,
 };
 
+#ifndef TCP_TIMESTAMP
+#define TCP_TIMESTAMP	24
+#endif
+
 #ifndef TCPOPT_SACK_PERM
 #define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
 #endif
@@ -234,6 +238,7 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse)
 	int ret;
 	socklen_t auxl;
 	struct tcp_info ti;
+	int val;
 
 	auxl = sizeof(ti);
 	ret = getsockopt(sk, SOL_TCP, TCP_INFO, &ti, &auxl);
@@ -252,6 +257,21 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse)
 		tse->has_rcv_wscale = true;
 	}
 
+	if (ti.tcpi_options & TCPI_OPT_TIMESTAMPS) {
+		auxl = sizeof(val);
+		ret = getsockopt(sk, SOL_TCP, TCP_TIMESTAMP, &val, &auxl);
+		if (ret < 0) {
+			if (errno == ENOPROTOOPT)
+				pr_warn("The kernel doesn't support "
+					"the socket option TCP_TIMESTAMP\n");
+			else
+				goto err_sopt;
+		} else {
+			tse->has_timestamp = true;
+			tse->timestamp = val;
+		}
+	}
+
 	pr_info("\toptions: mss_clamp %x wscale %x tstamp %d sack %d\n",
 			(int)tse->mss_clamp,
 			ti.tcpi_options & TCPI_OPT_WSCALE ? (int)tse->snd_wscale : -1,
@@ -474,6 +494,14 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse)
 		return -1;
 	}
 
+	if (tse->has_timestamp) {
+		if (setsockopt(sk, SOL_TCP, TCP_TIMESTAMP,
+				&tse->timestamp, sizeof(tse->timestamp)) < 0) {
+			pr_perror("Can't set timestamp");
+			return -1;
+		}
+	}
+
 	return 0;
 }
 
-- 
1.7.11.7



More information about the CRIU mailing list