Commit 04c48fef authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b752e05e
...@@ -8,4 +8,5 @@ message tcp_stream_entry { ...@@ -8,4 +8,5 @@ message tcp_stream_entry {
required uint32 snd_wscale = 6; required uint32 snd_wscale = 6;
required uint32 mss_clamp = 7; required uint32 mss_clamp = 7;
optional uint32 rcv_wscale = 8; optional uint32 rcv_wscale = 8;
optional uint32 timestamp = 9;
} }
...@@ -34,6 +34,10 @@ enum { ...@@ -34,6 +34,10 @@ enum {
TCP_QUEUES_NR, TCP_QUEUES_NR,
}; };
#ifndef TCP_TIMESTAMP
#define TCP_TIMESTAMP 24
#endif
#ifndef TCPOPT_SACK_PERM #ifndef TCPOPT_SACK_PERM
#define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED #define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
#endif #endif
...@@ -234,6 +238,7 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse) ...@@ -234,6 +238,7 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse)
int ret; int ret;
socklen_t auxl; socklen_t auxl;
struct tcp_info ti; struct tcp_info ti;
int val;
auxl = sizeof(ti); auxl = sizeof(ti);
ret = getsockopt(sk, SOL_TCP, TCP_INFO, &ti, &auxl); ret = getsockopt(sk, SOL_TCP, TCP_INFO, &ti, &auxl);
...@@ -252,6 +257,21 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse) ...@@ -252,6 +257,21 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse)
tse->has_rcv_wscale = true; 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", pr_info("\toptions: mss_clamp %x wscale %x tstamp %d sack %d\n",
(int)tse->mss_clamp, (int)tse->mss_clamp,
ti.tcpi_options & TCPI_OPT_WSCALE ? (int)tse->snd_wscale : -1, ti.tcpi_options & TCPI_OPT_WSCALE ? (int)tse->snd_wscale : -1,
...@@ -474,6 +494,14 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse) ...@@ -474,6 +494,14 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse)
return -1; 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; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment