[CRIU] [PATCH 04/12] soccr/tcp: Introduce blob with connection info and getter for it (v2)

Pavel Emelyanov xemul at virtuozzo.com
Fri Aug 5 08:00:05 PDT 2016


As an API for dumping and restoring the data the structure
with __u32-s is used. Getting one (and restoring) also involve
the size of the structure so that both -- caller and library --
can know which "version" of it the other one is using.

As a starting point all the fields that tcp_entry carries are
used.

Also note, that only tcp connection info is handled by the
library. Stuff like addresses and ports, socket options and
other are left for the caller to care for.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/sk-tcp.c | 11 +++++++++++
 soccr/soccr.c | 16 ++++++++++++++++
 soccr/soccr.h | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+)

diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index a13954b..763d754 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -354,11 +354,22 @@ static int tcp_get_window(int sk, TcpStreamEntry *tse)
 
 static int dump_tcp_conn_state(struct inet_sk_desc *sk)
 {
+	struct libsoccr_sk *socr = sk->priv;
 	int ret, aux;
 	struct tcp_info ti;
 	struct cr_img *img;
 	TcpStreamEntry tse = TCP_STREAM_ENTRY__INIT;
 	char *in_buf, *out_buf;
+	struct libsoccr_sk_data data;
+
+	ret = libsoccr_get_sk_data(socr, &data, sizeof(data));
+	if (ret < 0)
+		goto err_r;
+	if (ret != sizeof(data)) {
+		pr_err("This libsocr is not supported (%d vs %d)\n",
+				ret, (int)sizeof(data));
+		goto err_r;
+	}
 
 	ret = refresh_inet_sk(sk, &ti);
 	if (ret < 0)
diff --git a/soccr/soccr.c b/soccr/soccr.c
index 36b3887..130f604 100644
--- a/soccr/soccr.c
+++ b/soccr/soccr.c
@@ -1,5 +1,6 @@
 #include <netinet/tcp.h>
 #include <stdlib.h>
+#include <string.h>
 #include "soccr.h"
 
 static void (*log)(unsigned int loglevel, const char *format, ...)
@@ -61,3 +62,18 @@ void libsoccr_resume(struct libsoccr_sk *sk)
 	tcp_repair_off(sk->fd);
 	free(sk);
 }
+
+/*
+ * This is how much data we've had in the initial libsoccr
+ */
+#define SOCR_DATA_MIN_SIZE	(16 * sizeof(__u32))
+
+int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size)
+{
+	if (!data || data_size < SOCR_DATA_MIN_SIZE)
+		return -1;
+
+	memset(data, 0, data_size);
+
+	return sizeof(struct libsoccr_sk_data);
+}
diff --git a/soccr/soccr.h b/soccr/soccr.h
index f5bdd18..a55d01e 100644
--- a/soccr/soccr.h
+++ b/soccr/soccr.h
@@ -11,7 +11,45 @@ void libsoccr_set_log(unsigned int level, void (*fn)(unsigned int level, const c
 
 struct libsoccr_sk;
 
+struct libsoccr_sk_data {
+	__u32	inq_len;
+	__u32	inq_seq;
+	__u32	outq_len;
+	__u32	outq_seq;
+	__u32	unsq_len;
+	__u32	opt_mask;
+	__u32	mss_clamp;
+	__u32	snd_wscale;
+	__u32	rcv_wscale;
+	__u32	timestamp;
+
+	__u32	flags; /* SOCCR_FLAGS_... below */
+	__u32	snd_wl1;
+	__u32	snd_wnd;
+	__u32	max_window;
+	__u32	rcv_wnd;
+	__u32	rcv_wup;
+};
+
+/*
+ * The flags below denote which data on libsoccr_sk_data was get
+ * from the kernel and is required for restore. Not present data
+ * is zeroified by the library.
+ *
+ * Ideally the caller should carry the whole _data structure between 
+ * calls, but for optimization purposes it may analyze the flags
+ * field and drop the unneeded bits.
+ */
+
+/*
+ * Window parameters. Mark snd_wl1, snd_wnd, max_window, rcv_wnd
+ * and rcv_wup fields.
+ */
+#define SOCCR_FLAGS_WINDOW	0x1
+
 struct libsoccr_sk *libsoccr_pause(int fd);
 void libsoccr_resume(struct libsoccr_sk *sk);
 
+int libsoccr_get_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