[CRIU] [PATCH 3/4] soccr: Move queue pointers from _data
Pavel Emelyanov
xemul at virtuozzo.com
Wed Dec 14 01:41:29 PST 2016
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/sk-tcp.c | 9 +--------
soccr/soccr.c | 46 ++++++++++++++++++++++++++++++++++++++++------
soccr/soccr.h | 12 +++++++++---
3 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index f7eef52..bfc5cb9 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -257,12 +257,7 @@ static int read_tcp_queue(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
if (read_img_buf(img, buf, len) < 0)
goto err;
- if (queue == TCP_SEND_QUEUE)
- data->outq_data = buf;
- else
- data->inq_data = buf;
-
- return 0;
+ return libsoccr_set_queue_bytes(sk, queue, buf, SOCCR_MEM_EXCL);
err:
xfree(buf);
@@ -379,8 +374,6 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
return 0;
err_c:
- xfree(data.inq_data);
- xfree(data.outq_data);
tcp_stream_entry__free_unpacked(tse, NULL);
close_image(img);
err:
diff --git a/soccr/soccr.c b/soccr/soccr.c
index d0c8668..11ac28c 100644
--- a/soccr/soccr.c
+++ b/soccr/soccr.c
@@ -104,10 +104,14 @@ static int tcp_repair_off(int fd)
struct libsoccr_sk {
int fd;
+ unsigned flags;
char *recv_queue;
char *send_queue;
};
+#define SK_FLAG_FREE_RQ 0x1
+#define SK_FLAG_FREE_SQ 0x2
+
struct libsoccr_sk *libsoccr_pause(int fd)
{
struct libsoccr_sk *ret;
@@ -121,6 +125,7 @@ struct libsoccr_sk *libsoccr_pause(int fd)
return NULL;
}
+ ret->flags = 0;
ret->recv_queue = NULL;
ret->send_queue = NULL;
ret->fd = fd;
@@ -130,8 +135,10 @@ struct libsoccr_sk *libsoccr_pause(int fd)
void libsoccr_resume(struct libsoccr_sk *sk)
{
tcp_repair_off(sk->fd);
- free(sk->send_queue);
- free(sk->recv_queue);
+ if (sk->flags & SK_FLAG_FREE_RQ)
+ free(sk->recv_queue);
+ if (sk->flags & SK_FLAG_FREE_SQ)
+ free(sk->send_queue);
free(sk);
}
@@ -345,6 +352,8 @@ int libsoccr_save(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigne
if (get_window(sk, data))
return -4;
+ sk->flags |= SK_FLAG_FREE_SQ | SK_FLAG_FREE_RQ;
+
if (get_queue(sk->fd, TCP_RECV_QUEUE, &data->inq_seq, data->inq_len, &sk->recv_queue))
return -4;
@@ -623,7 +632,7 @@ static int restore_fin_in_snd_queue(int sk, int acked)
return ret;
}
-static int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size,
+static int libsoccr_restore_queue(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size,
int queue, char *buf);
int libsoccr_restore(struct libsoccr_sk *sk,
@@ -634,10 +643,10 @@ int libsoccr_restore(struct libsoccr_sk *sk,
if (libsoccr_set_sk_data_noq(sk, data, data_size))
return -1;
- if (libsoccr_set_queue_bytes(sk, data, sizeof(*data), TCP_RECV_QUEUE, data->inq_data))
+ if (libsoccr_restore_queue(sk, data, sizeof(*data), TCP_RECV_QUEUE, sk->recv_queue))
return -1;
- if (libsoccr_set_queue_bytes(sk, data, sizeof(*data), TCP_SEND_QUEUE, data->outq_data))
+ if (libsoccr_restore_queue(sk, data, sizeof(*data), TCP_SEND_QUEUE, sk->send_queue))
return -1;
if (data->flags & SOCCR_FLAGS_WINDOW) {
@@ -749,9 +758,12 @@ static int send_queue(struct libsoccr_sk *sk, int queue, char *buf, __u32 len)
return __send_queue(sk, queue, buf, len);
}
-static int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size,
+static int libsoccr_restore_queue(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size,
int queue, char *buf)
{
+ if (!buf)
+ return 0;
+
if (!data || data_size < SOCR_DATA_MIN_SIZE)
return -1;
@@ -793,3 +805,25 @@ static int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, struct libsoccr_sk_d
return -5;
}
+
+#define SET_Q_FLAGS (SOCCR_MEM_EXCL)
+int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, int queue_id, char *bytes, unsigned flags)
+{
+ if (flags & ~SET_Q_FLAGS)
+ return -1;
+
+ switch (queue_id) {
+ case TCP_RECV_QUEUE:
+ sk->recv_queue = bytes;
+ if (flags & SOCCR_MEM_EXCL)
+ sk->flags |= SK_FLAG_FREE_RQ;
+ break;
+ case TCP_SEND_QUEUE:
+ sk->send_queue = bytes;
+ if (flags & SOCCR_MEM_EXCL)
+ sk->flags |= SK_FLAG_FREE_SQ;
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/soccr/soccr.h b/soccr/soccr.h
index 1e4bfb3..cd73271 100644
--- a/soccr/soccr.h
+++ b/soccr/soccr.h
@@ -91,9 +91,6 @@ struct libsoccr_sk_data {
__u32 rcv_wnd;
__u32 rcv_wup;
- char *inq_data;
- char *outq_data;
-
union libsoccr_addr src_addr;
union libsoccr_addr dst_addr;
};
@@ -196,6 +193,8 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, unsigned fl
* sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
*
* h = libsoccr_pause(sk)
+ * libsoccr_set_queue_bytes(h, TCP_SEND_QUEUE, outq);
+ * libsoccr_set_queue_bytes(h, TCP_RECV_QUEUE, inq);
* libsoccr_restore(h, &data, sizeof(data))
*
* libsoccr_resume(h)
@@ -205,6 +204,13 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, unsigned fl
*/
/*
+ * Set a pointer on the send/recv queue data.
+ * If flags have SOCCR_MEM_EXCL, the buffer is stolen by the library and is
+ * free()-ed after libsoccr_resume().
+ */
+int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, int queue_id, char *bytes, unsigned flags);
+
+/*
* Performs restore actions on bind()-ed socket
*/
int libsoccr_restore(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
--
2.5.0
More information about the CRIU
mailing list