mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +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:
committed by
Pavel Emelyanov
parent
b752e05e41
commit
04c48fefbc
@@ -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;
|
||||||
}
|
}
|
||||||
|
28
sk-tcp.c
28
sk-tcp.c
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user