2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 22:05:36 +00:00

tcp: dump and restore tcp_timestamp for each socket (v2)

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@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Andrey Vagin
2013-02-14 20:27:39 +04:00
committed by Pavel Emelyanov
parent b752e05e41
commit 04c48fefbc
2 changed files with 29 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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;
}