[CRIU] [PATCH 09/12] soccr/tcp: Restore socket's info after binding it (v2)
Pavel Emelyanov
xemul at virtuozzo.com
Fri Aug 5 08:02:07 PDT 2016
With window parameters, we have stuff to restore before
queues and after queues.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/sk-tcp.c | 82 ++---------------------------------------------------------
soccr/soccr.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
soccr/soccr.h | 2 ++
3 files changed, 83 insertions(+), 80 deletions(-)
diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index 4161339..2007e52 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -68,10 +68,6 @@ enum {
#define TCP_REPAIR_WINDOW 29
#endif
-#ifndef TCPOPT_SACK_PERM
-#define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
-#endif
-
static LIST_HEAD(cpt_tcp_repair_sockets);
static LIST_HEAD(rst_tcp_repair_sockets);
@@ -389,80 +385,6 @@ static int restore_tcp_queues(int sk, TcpStreamEntry *tse, struct cr_img *img)
return 0;
}
-static int restore_tcp_opts(int sk, TcpStreamEntry *tse)
-{
- struct tcp_repair_opt opts[4];
- int onr = 0;
-
- pr_debug("\tRestoring TCP options\n");
-
- if (tse->opt_mask & TCPI_OPT_SACK) {
- pr_debug("\t\tWill turn SAK on\n");
- opts[onr].opt_code = TCPOPT_SACK_PERM;
- opts[onr].opt_val = 0;
- onr++;
- }
-
- if (tse->opt_mask & TCPI_OPT_WSCALE) {
- pr_debug("\t\tWill set snd_wscale to %u\n", tse->snd_wscale);
- pr_debug("\t\tWill set rcv_wscale to %u\n", tse->rcv_wscale);
- opts[onr].opt_code = TCPOPT_WINDOW;
- opts[onr].opt_val = tse->snd_wscale + (tse->rcv_wscale << 16);
- onr++;
- }
-
- if (tse->opt_mask & TCPI_OPT_TIMESTAMPS) {
- pr_debug("\t\tWill turn timestamps on\n");
- opts[onr].opt_code = TCPOPT_TIMESTAMP;
- opts[onr].opt_val = 0;
- onr++;
- }
-
- pr_debug("Will set mss clamp to %u\n", tse->mss_clamp);
- opts[onr].opt_code = TCPOPT_MAXSEG;
- opts[onr].opt_val = tse->mss_clamp;
- onr++;
-
- if (setsockopt(sk, SOL_TCP, TCP_REPAIR_OPTIONS,
- opts, onr * sizeof(struct tcp_repair_opt)) < 0) {
- pr_perror("Can't repair options");
- 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;
-}
-
-static int restore_tcp_window(int sk, TcpStreamEntry *tse)
-{
- struct tcp_repair_window opt = {
- .snd_wl1 = tse->snd_wl1,
- .snd_wnd = tse->snd_wnd,
- .max_window = tse->max_window,
- .rcv_wnd = tse->rcv_wnd,
- .rcv_wup = tse->rcv_wup,
- };
-
- if (!kdat.has_tcp_window || !tse->has_snd_wnd) {
- pr_warn_once("Window parameters are not restored\n");
- return 0;
- }
-
- if (setsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &opt, sizeof(opt))) {
- pr_perror("Unable to set window parameters");
- return -1;
- }
-
- return 0;
-}
-
static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_sk_info *ii)
{
int aux;
@@ -529,7 +451,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
if (inet_connect(sk, ii))
goto err_c;
- if (restore_tcp_opts(sk, tse))
+ if (libsoccr_set_sk_data_noq(socr, &data, sizeof(data)))
goto err_c;
if (restore_prepare_socket(sk))
@@ -538,7 +460,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
if (restore_tcp_queues(sk, tse, img))
goto err_c;
- if (restore_tcp_window(sk, tse))
+ if (libsoccr_set_sk_data(socr, &data, sizeof(data)))
goto err_c;
if (tse->has_nodelay && tse->nodelay) {
diff --git a/soccr/soccr.c b/soccr/soccr.c
index 6eeb368..61a39ad 100644
--- a/soccr/soccr.c
+++ b/soccr/soccr.c
@@ -349,3 +349,82 @@ int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk,
return 0;
}
+#ifndef TCPOPT_SACK_PERM
+#define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
+#endif
+
+int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
+ struct libsoccr_sk_data *data, unsigned data_size)
+{
+ struct tcp_repair_opt opts[4];
+ int onr = 0;
+
+ if (!data || data_size < SOCR_DATA_MIN_SIZE)
+ return -1;
+
+ logd("\tRestoring TCP options\n");
+
+ if (data->opt_mask & TCPI_OPT_SACK) {
+ logd("\t\tWill turn SAK on\n");
+ opts[onr].opt_code = TCPOPT_SACK_PERM;
+ opts[onr].opt_val = 0;
+ onr++;
+ }
+
+ if (data->opt_mask & TCPI_OPT_WSCALE) {
+ logd("\t\tWill set snd_wscale to %u\n", data->snd_wscale);
+ logd("\t\tWill set rcv_wscale to %u\n", data->rcv_wscale);
+ opts[onr].opt_code = TCPOPT_WINDOW;
+ opts[onr].opt_val = data->snd_wscale + (data->rcv_wscale << 16);
+ onr++;
+ }
+
+ if (data->opt_mask & TCPI_OPT_TIMESTAMPS) {
+ logd("\t\tWill turn timestamps on\n");
+ opts[onr].opt_code = TCPOPT_TIMESTAMP;
+ opts[onr].opt_val = 0;
+ onr++;
+ }
+
+ logd("Will set mss clamp to %u\n", data->mss_clamp);
+ opts[onr].opt_code = TCPOPT_MAXSEG;
+ opts[onr].opt_val = data->mss_clamp;
+ onr++;
+
+ if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_OPTIONS,
+ opts, onr * sizeof(struct tcp_repair_opt)) < 0) {
+ loge("Can't repair options");
+ return -2;
+ }
+
+ if (data->opt_mask & TCPI_OPT_TIMESTAMPS) {
+ if (setsockopt(sk->fd, SOL_TCP, TCP_TIMESTAMP,
+ &data->timestamp, sizeof(data->timestamp)) < 0) {
+ loge("Can't set timestamp");
+ return -3;
+ }
+ }
+
+ return 0;
+}
+
+int libsoccr_set_sk_data(struct libsoccr_sk *sk,
+ struct libsoccr_sk_data *data, unsigned data_size)
+{
+ if (data->flags & SOCCR_FLAGS_WINDOW) {
+ struct tcp_repair_window wopt = {
+ .snd_wl1 = data->snd_wl1,
+ .snd_wnd = data->snd_wnd,
+ .max_window = data->max_window,
+ .rcv_wnd = data->rcv_wnd,
+ .rcv_wup = data->rcv_wup,
+ };
+
+ if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_WINDOW, &wopt, sizeof(wopt))) {
+ loge("Unable to set window parameters");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/soccr/soccr.h b/soccr/soccr.h
index 3458a1b..86c43f2 100644
--- a/soccr/soccr.h
+++ b/soccr/soccr.h
@@ -54,4 +54,6 @@ int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
+int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
+int libsoccr_set_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
#endif
--
2.5.0
More information about the CRIU
mailing list