[CRIU] [PATCH 3/4] soccr: Move queue pointers from _data
Andrei Vagin
avagin at virtuozzo.com
Wed Dec 14 10:39:25 PST 2016
On Wed, Dec 14, 2016 at 12:41:29PM +0300, Pavel Emelyanov wrote:
>
> 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;
return 0;
> + 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