mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
soccr/tcp: Restore socket's info before binding it
In TCP repair some stuff should be restored before calling connect/bind on socker and some -- after it. Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
efdcf3776a
commit
611dc707e2
3 changed files with 36 additions and 30 deletions
|
|
@ -285,35 +285,6 @@ int dump_one_tcp(int fd, struct inet_sk_desc *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_tcp_queue_seq(int sk, int queue, u32 seq)
|
||||
{
|
||||
pr_debug("\tSetting %d queue seq to %u\n", queue, seq);
|
||||
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR_QUEUE, &queue, sizeof(queue)) < 0) {
|
||||
pr_perror("Can't set repair queue");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sk, SOL_TCP, TCP_QUEUE_SEQ, &seq, sizeof(seq)) < 0) {
|
||||
pr_perror("Can't set queue seq");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int restore_tcp_seqs(int sk, TcpStreamEntry *tse)
|
||||
{
|
||||
if (set_tcp_queue_seq(sk, TCP_RECV_QUEUE,
|
||||
tse->inq_seq - tse->inq_len))
|
||||
return -1;
|
||||
if (set_tcp_queue_seq(sk, TCP_SEND_QUEUE,
|
||||
tse->outq_seq - tse->outq_len))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __send_tcp_queue(int sk, int queue, u32 len, struct cr_img *img)
|
||||
{
|
||||
int ret, err = -1, max_chunk;
|
||||
|
|
@ -548,7 +519,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
|
|||
|
||||
(void)data;
|
||||
|
||||
if (restore_tcp_seqs(sk, tse))
|
||||
if (libsoccr_set_sk_data_unbound(socr, &data, sizeof(data)))
|
||||
goto err_c;
|
||||
|
||||
if (inet_bind(sk, ii))
|
||||
|
|
|
|||
|
|
@ -315,3 +315,37 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_queue_seq(struct libsoccr_sk *sk, int queue, __u32 seq)
|
||||
{
|
||||
logd("\tSetting %d queue seq to %u\n", queue, seq);
|
||||
|
||||
if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_QUEUE, &queue, sizeof(queue)) < 0) {
|
||||
loge("Can't set repair queue");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sk->fd, SOL_TCP, TCP_QUEUE_SEQ, &seq, sizeof(seq)) < 0) {
|
||||
loge("Can't set queue seq");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk,
|
||||
struct libsoccr_sk_data *data, unsigned data_size)
|
||||
{
|
||||
if (!data || data_size < SOCR_DATA_MIN_SIZE)
|
||||
return -1;
|
||||
|
||||
if (set_queue_seq(sk, TCP_RECV_QUEUE,
|
||||
data->inq_seq - data->inq_len))
|
||||
return -2;
|
||||
if (set_queue_seq(sk, TCP_SEND_QUEUE,
|
||||
data->outq_seq - data->outq_len))
|
||||
return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,4 +53,5 @@ void libsoccr_resume(struct libsoccr_sk *sk);
|
|||
int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
|
||||
char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
|
||||
|
||||
int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue