[CRIU] [PATCH 05/14] soccr/tcp: Add _pause and _resume to library and use it
Pavel Emelyanov
xemul at virtuozzo.com
Mon Apr 18 06:03:58 PDT 2016
The calls put socket into a mode where it can be saved or
restored. Add take one out of this mode.
TODO: In criu we turn repair off (resume the socket) from
restorer blob that cannot use the library. Need to somehow
fix it.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/include/sk-inet.h | 2 ++
criu/sk-tcp.c | 18 ++++++++++++------
soccr/soccr.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
soccr/soccr.h | 5 +++++
4 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index fe28376..bad0b6a 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -33,6 +33,8 @@ struct inet_sk_desc {
int rfd;
int cpt_reuseaddr;
struct list_head rlist;
+
+ void *priv;
};
struct inet_port;
diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index 29ad06d..28f27a5 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -122,6 +122,7 @@ static int refresh_inet_sk(struct inet_sk_desc *sk, struct tcp_info *ti)
static int tcp_repair_establised(int fd, struct inet_sk_desc *sk)
{
int ret;
+ struct libsoccr_sk *socr;
pr_info("\tTurning repair on for socket %x\n", sk->sd.ino);
/*
@@ -141,10 +142,11 @@ static int tcp_repair_establised(int fd, struct inet_sk_desc *sk)
goto err2;
}
- ret = tcp_repair_on(sk->rfd);
- if (ret < 0)
+ socr = libsoccr_pause(sk->rfd);
+ if (!socr)
goto err3;
+ sk->priv = socr;
list_add_tail(&sk->rlist, &cpt_tcp_repair_sockets);
return 0;
@@ -169,7 +171,8 @@ static void tcp_unlock_one(struct inet_sk_desc *sk)
pr_perror("Failed to unlock TCP connection");
}
- tcp_repair_off(sk->rfd);
+ libsoccr_resume(sk->priv);
+ sk->priv = NULL;
/*
* tcp_repair_off modifies SO_REUSEADDR so
@@ -610,7 +613,7 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse)
return 0;
}
-static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii)
+static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_sk_info *ii)
{
int aux;
struct cr_img *img;
@@ -698,12 +701,15 @@ int rst_tcp_socks_prep(void)
int restore_one_tcp(int fd, struct inet_sk_info *ii)
{
+ struct libsoccr_sk *sk;
+
pr_info("Restoring TCP connection\n");
- if (tcp_repair_on(fd))
+ sk = libsoccr_pause(fd);
+ if (!sk)
return -1;
- if (restore_tcp_conn_state(fd, ii))
+ if (restore_tcp_conn_state(fd, sk, ii))
return -1;
return 0;
diff --git a/soccr/soccr.c b/soccr/soccr.c
index 98b8f47..36b3887 100644
--- a/soccr/soccr.c
+++ b/soccr/soccr.c
@@ -1,3 +1,5 @@
+#include <netinet/tcp.h>
+#include <stdlib.h>
#include "soccr.h"
static void (*log)(unsigned int loglevel, const char *format, ...)
@@ -12,3 +14,50 @@ void libsoccr_set_log(unsigned int level, void (*fn)(unsigned int level, const c
#define loge(msg, ...) do { if (log && (log_level >= SOCCR_LOG_ERR)) log(SOCCR_LOG_ERR, msg, ##__VA_ARGS__); } while (0)
#define logd(msg, ...) do { if (log && (log_level >= SOCCR_LOG_DBG)) log(SOCCR_LOG_DBG, msg, ##__VA_ARGS__); } while (0)
+
+static int tcp_repair_on(int fd)
+{
+ int ret, aux = 1;
+
+ ret = setsockopt(fd, SOL_TCP, TCP_REPAIR, &aux, sizeof(aux));
+ if (ret < 0)
+ loge("Can't turn TCP repair mode ON");
+
+ return ret;
+}
+
+static void tcp_repair_off(int fd)
+{
+ int aux = 0, ret;
+
+ ret = setsockopt(fd, SOL_TCP, TCP_REPAIR, &aux, sizeof(aux));
+ if (ret < 0)
+ loge("Failed to turn off repair mode on socket: %m\n");
+}
+
+struct libsoccr_sk {
+ int fd;
+};
+
+struct libsoccr_sk *libsoccr_pause(int fd)
+{
+ struct libsoccr_sk *ret;
+
+ ret = malloc(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ if (tcp_repair_on(fd) < 0) {
+ free(ret);
+ return NULL;
+ }
+
+ ret->fd = fd;
+ return ret;
+}
+
+void libsoccr_resume(struct libsoccr_sk *sk)
+{
+ tcp_repair_off(sk->fd);
+ free(sk);
+}
diff --git a/soccr/soccr.h b/soccr/soccr.h
index 07d7947..f5bdd18 100644
--- a/soccr/soccr.h
+++ b/soccr/soccr.h
@@ -9,4 +9,9 @@ void libsoccr_set_log(unsigned int level, void (*fn)(unsigned int level, const c
#define SOCCR_LOG_ERR 1
#define SOCCR_LOG_DBG 2
+struct libsoccr_sk;
+
+struct libsoccr_sk *libsoccr_pause(int fd);
+void libsoccr_resume(struct libsoccr_sk *sk);
+
#endif
--
2.5.0
More information about the CRIU
mailing list