Commit b8b113bf authored by Pavel Emelyanov's avatar Pavel Emelyanov

soccr/tcp: Add _pause and _resume to library and use it

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: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent e3f270ac
......@@ -32,6 +32,8 @@ struct inet_sk_desc {
int rfd;
int cpt_reuseaddr;
struct list_head rlist;
void *priv;
};
struct inet_port;
......
......@@ -137,6 +137,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);
/*
......@@ -156,10 +157,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;
......@@ -184,7 +186,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
......@@ -679,7 +682,7 @@ static int restore_tcp_window(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;
......@@ -769,12 +772,15 @@ int prepare_tcp_socks(struct task_restore_args *ta)
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;
......
#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);
}
......@@ -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
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