Commit c27ff2ba authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

tcp: unset TCP_REPAIR at the last moment after unlocking network (v2)

TCP_REPAIR should be droppet when a network is unlocked.
A network should be unlocked at the last moment, because
after this moment restore must not failed, otherwise a state of
a tcp connection can be changed and a state of one side in our image
will be invalid.

v2: use xremalloc instead of mmap and remmap
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7e22e60f
...@@ -1293,7 +1293,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v ...@@ -1293,7 +1293,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
restore_task_vma_len + restore_task_vma_len +
restore_thread_vma_len + restore_thread_vma_len +
self_vmas_len + vmas_len + self_vmas_len + vmas_len +
SHMEMS_SIZE + TASK_ENTRIES_SIZE); SHMEMS_SIZE + TASK_ENTRIES_SIZE +
rst_tcp_socks_size);
if (exec_mem_hint == -1) { if (exec_mem_hint == -1) {
pr_err("No suitable area for task_restore bootstrap (%ldK)\n", pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
restore_task_vma_len + restore_thread_vma_len); restore_task_vma_len + restore_thread_vma_len);
...@@ -1369,6 +1370,12 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v ...@@ -1369,6 +1370,12 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
if (!task_args->tgt_vmas) if (!task_args->tgt_vmas)
goto err; goto err;
mem += vmas_len;
if (rst_tcp_socks_remap(mem))
goto err;
task_args->rst_tcp_socks = mem;
task_args->rst_tcp_socks_size = rst_tcp_socks_size;
/* /*
* Arguments for task restoration. * Arguments for task restoration.
*/ */
......
...@@ -110,6 +110,9 @@ struct task_restore_core_args { ...@@ -110,6 +110,9 @@ struct task_restore_core_args {
bool has_futex; bool has_futex;
u64 futex_rla; u64 futex_rla;
u32 futex_rla_len; u32 futex_rla_len;
int *rst_tcp_socks;
int rst_tcp_socks_size;
} __aligned(sizeof(long)); } __aligned(sizeof(long));
struct pt_regs { struct pt_regs {
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include "sockets.h"
#include "files.h"
#include "list.h"
#include "protobuf.h" #include "protobuf.h"
#include "../protobuf/sk-inet.pb-c.h" #include "../protobuf/sk-inet.pb-c.h"
...@@ -62,4 +65,7 @@ struct cr_options; ...@@ -62,4 +65,7 @@ struct cr_options;
void show_tcp_stream(int fd, struct cr_options *); void show_tcp_stream(int fd, struct cr_options *);
int check_tcp_repair(void); int check_tcp_repair(void);
extern int rst_tcp_socks_size;
extern int rst_tcp_socks_remap(void *addr);
#endif #endif
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "restorer-log.h" #include "restorer-log.h"
#include "util.h" #include "util.h"
#include "image.h" #include "image.h"
#include "sk-inet.h"
#include "crtools.h" #include "crtools.h"
#include "lock.h" #include "lock.h"
...@@ -281,6 +282,19 @@ static u64 restore_mapping(const VmaEntry *vma_entry) ...@@ -281,6 +282,19 @@ static u64 restore_mapping(const VmaEntry *vma_entry)
return addr; return addr;
} }
static void rst_tcp_socks_all(int *arr, int size)
{
int i;
if (size == 0)
return;
for (i =0; arr[i] >= 0; i++)
tcp_repair_off(arr[i]);
sys_munmap(arr, size);
}
/* /*
* The main routine to restore task via sigreturn. * The main routine to restore task via sigreturn.
* This one is very special, we never return there * This one is very special, we never return there
...@@ -631,10 +645,12 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -631,10 +645,12 @@ long __export_restore_task(struct task_restore_core_args *args)
futex_dec_and_wake(&args->task_entries->nr_in_progress); futex_dec_and_wake(&args->task_entries->nr_in_progress);
sys_close(args->logfd);
futex_wait_while(&args->task_entries->start, CR_STATE_RESTORE_SIGCHLD); futex_wait_while(&args->task_entries->start, CR_STATE_RESTORE_SIGCHLD);
rst_tcp_socks_all(args->rst_tcp_socks, args->rst_tcp_socks_size);
sys_close(args->logfd);
/* /*
* The code that prepared the itimers makes shure the * The code that prepared the itimers makes shure the
* code below doesn't fail due to bad timing values. * code below doesn't fail due to bad timing values.
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <linux/sockios.h> #include <linux/sockios.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include "crtools.h" #include "crtools.h"
#include "util.h" #include "util.h"
...@@ -459,6 +461,51 @@ err: ...@@ -459,6 +461,51 @@ err:
return -1; return -1;
} }
/*
* rst_tcp_socks contains sockets in repair mode,
* which will be off in restorer before resuming.
*/
static int *rst_tcp_socks = NULL;
static int rst_tcp_socks_num = 0;
int rst_tcp_socks_size = 0;
int rst_tcp_socks_remap(void *addr)
{
void *ret;
if (!rst_tcp_socks) {
BUG_ON(rst_tcp_socks_size);
return 0;
}
rst_tcp_socks[rst_tcp_socks_num] = -1;
ret = mmap(addr, rst_tcp_socks_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (ret != addr) {
pr_perror("mmap() failed\n");
return -1;
}
memcpy(addr, rst_tcp_socks, rst_tcp_socks_size);
return 0;
}
static int rst_tcp_socks_add(int fd)
{
/* + 2 = ( new one + guard (-1) ) */
if ((rst_tcp_socks_num + 2) * sizeof(int) > rst_tcp_socks_size) {
rst_tcp_socks_size += PAGE_SIZE;
rst_tcp_socks = xrealloc(rst_tcp_socks, rst_tcp_socks_size);
if (rst_tcp_socks == NULL)
return -1;
}
rst_tcp_socks[rst_tcp_socks_num++] = fd;
return 0;
}
int restore_one_tcp(int fd, struct inet_sk_info *ii) int restore_one_tcp(int fd, struct inet_sk_info *ii)
{ {
pr_info("Restoring TCP connection\n"); pr_info("Restoring TCP connection\n");
...@@ -466,6 +513,9 @@ int restore_one_tcp(int fd, struct inet_sk_info *ii) ...@@ -466,6 +513,9 @@ int restore_one_tcp(int fd, struct inet_sk_info *ii)
if (tcp_repair_on(fd)) if (tcp_repair_on(fd))
return -1; return -1;
if (rst_tcp_socks_add(fd))
return -1;
if (restore_tcp_conn_state(fd, ii)) if (restore_tcp_conn_state(fd, ii))
return -1; return -1;
......
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