diff --git a/cr-restore.c b/cr-restore.c index 748514db0..03eb4148c 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -2002,6 +2002,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) int siginfo_nr = 0; int *siginfo_priv_nr; + void *tcp_socks_mem; + unsigned long tcp_socks; + unsigned long vdso_rt_vma_size = 0; unsigned long vdso_rt_size = 0; @@ -2068,12 +2071,18 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ret = 0; } + tcp_socks = rst_mem_cpos(); + tcp_socks_mem = rst_mem_alloc(rst_tcp_socks_len()); + if (!tcp_socks_mem) + goto err; + + memcpy(tcp_socks_mem, rst_tcp_socks, rst_tcp_socks_len()); + restore_bootstrap_len = restorer_len + restore_task_vma_len + restore_thread_vma_len + SHMEMS_SIZE + TASK_ENTRIES_SIZE + self_vmas_len + vmas_len + - rst_tcp_socks_size + rst_mem_len; /* @@ -2172,10 +2181,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) goto err; mem += vmas_len; - if (rst_tcp_socks_remap(mem)) + if (rst_mem_remap(mem)) goto err; - task_args->rst_tcp_socks = mem; - task_args->rst_tcp_socks_size = rst_tcp_socks_size; task_args->timer_n = posix_timers_nr; task_args->posix_timers = rst_mem_raddr(posix_timers_info_chunk); @@ -2183,9 +2190,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) task_args->siginfo_nr = siginfo_nr; task_args->siginfo = rst_mem_raddr(siginfo_chunk); - mem += rst_tcp_socks_size; - if (rst_mem_remap(mem)) - goto err; + task_args->tcp_socks_nr = rst_tcp_socks_nr; + task_args->tcp_socks = rst_mem_raddr(tcp_socks); /* * Arguments for task restoration. diff --git a/include/restorer.h b/include/restorer.h index aef9da02c..7b3d7af8e 100644 --- a/include/restorer.h +++ b/include/restorer.h @@ -146,8 +146,8 @@ struct task_restore_core_args { int nr_rlim; struct rlimit rlims[RLIM_NLIMITS]; - struct rst_tcp_sock *rst_tcp_socks; - int rst_tcp_socks_size; + struct rst_tcp_sock *tcp_socks; + int tcp_socks_nr; struct vdso_symtable vdso_sym_rt; /* runtime vdso symbols */ unsigned long vdso_rt_parked_at; /* safe place to keep vdso */ diff --git a/include/sk-inet.h b/include/sk-inet.h index 406595c3c..f7edd1198 100644 --- a/include/sk-inet.h +++ b/include/sk-inet.h @@ -49,6 +49,14 @@ struct rst_tcp_sock { bool reuseaddr; }; +extern struct rst_tcp_sock *rst_tcp_socks; +extern int rst_tcp_socks_nr; + +static inline unsigned long rst_tcp_socks_len(void) +{ + return rst_tcp_socks_nr * sizeof(struct rst_tcp_sock); +} + static inline void tcp_repair_off(int fd) { int aux = 0, ret; @@ -70,9 +78,6 @@ int restore_one_tcp(int sk, struct inet_sk_info *si); void show_tcp_stream(int fd); int check_tcp(void); - -extern int rst_tcp_socks_size; -extern int rst_tcp_socks_remap(void *addr); extern int rst_tcp_socks_add(int fd, bool reuseaddr); #endif /* __CR_SK_INET_H__ */ diff --git a/pie/restorer.c b/pie/restorer.c index 6d29ac54a..22d7195a9 100644 --- a/pie/restorer.c +++ b/pie/restorer.c @@ -384,17 +384,12 @@ static void rst_tcp_repair_off(struct rst_tcp_sock *rts) pr_perror("Failed to restore of SO_REUSEADDR on socket (%d)", ret); } -static void rst_tcp_socks_all(struct rst_tcp_sock *arr, int size) +static void rst_tcp_socks_all(struct task_restore_core_args *ta) { int i; - if (size == 0) - return; - - for (i =0; arr[i].sk >= 0; i++) - rst_tcp_repair_off(arr + i); - - sys_munmap(arr, size); + for (i = 0; i < ta->tcp_socks_nr; i++) + rst_tcp_repair_off(&ta->tcp_socks[i]); } static int vma_remap(unsigned long src, unsigned long dst, unsigned long len) @@ -885,7 +880,7 @@ long __export_restore_task(struct task_restore_core_args *args) goto core_restore_end; } - rst_tcp_socks_all(args->rst_tcp_socks, args->rst_tcp_socks_size); + rst_tcp_socks_all(args); /* * Writing to last-pid is CAP_SYS_ADMIN protected, diff --git a/sk-tcp.c b/sk-tcp.c index 80466b3d2..dc4f00dd9 100644 --- a/sk-tcp.c +++ b/sk-tcp.c @@ -18,6 +18,7 @@ #include "netfilter.h" #include "image.h" #include "namespaces.h" +#include "xmalloc.h" #include "config.h" #include "protobuf.h" @@ -555,47 +556,23 @@ err: * rst_tcp_socks contains sockets in repair mode, * which will be off in restorer before resuming. */ -static struct rst_tcp_sock *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].sk = -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"); - return -1; - } - - memcpy(addr, rst_tcp_socks, rst_tcp_socks_size); - - return 0; -} +struct rst_tcp_sock *rst_tcp_socks = NULL; +int rst_tcp_socks_nr = 0; int rst_tcp_socks_add(int fd, bool reuseaddr) { - /* + 2 = ( new one + guard (-1) ) */ - if ((rst_tcp_socks_num + 2) * sizeof(struct rst_tcp_sock) > 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; - } + struct rst_tcp_sock *cur; + + rst_tcp_socks_nr++; + rst_tcp_socks = xrealloc(rst_tcp_socks, rst_tcp_socks_len()); + if (!rst_tcp_socks) + return -1; pr_debug("Schedule %d socket for repair off\n", fd); - rst_tcp_socks[rst_tcp_socks_num].sk = fd; - rst_tcp_socks[rst_tcp_socks_num].reuseaddr = reuseaddr; - rst_tcp_socks_num++; + cur = &rst_tcp_socks[rst_tcp_socks_nr - 1]; + cur->sk = fd; + cur->reuseaddr = reuseaddr; + return 0; }