Commit 73e303c8 authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst: Fix rst_tcp_sock memory management

In current scheme we grow an array with realloc()-s then
memcpy() the result into rst_mem. I propose to get rid
or realloc-s (we already have objects for the data we
need to keep) and memcpy-s (and put objects directly
into rst_mem at the end).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7166e3c9
...@@ -2647,9 +2647,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2647,9 +2647,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
struct vma_area *vma; struct vma_area *vma;
unsigned long tgt_vmas; unsigned long tgt_vmas;
void *tcp_socks_mem;
unsigned long tcp_socks;
void *timerfd_mem; void *timerfd_mem;
unsigned long timerfd_mem_cpos; unsigned long timerfd_mem_cpos;
...@@ -2717,17 +2714,12 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2717,17 +2714,12 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
} }
/* /*
* Copy tcp sockets fds to rst memory -- restorer will * Get all the tcp sockets fds into rst memory -- restorer
* turn repair off before going sigreturn * will turn repair off before going sigreturn
*/ */
if (rst_tcp_socks_prep())
tcp_socks = rst_mem_cpos(RM_PRIVATE);
tcp_socks_mem = rst_mem_alloc(rst_tcp_socks_len(), RM_PRIVATE);
if (!tcp_socks_mem)
goto err_nv; goto err_nv;
memcpy(tcp_socks_mem, rst_tcp_socks, rst_tcp_socks_len());
/* /*
* Copy timerfd params for restorer args, we need to proceed * Copy timerfd params for restorer args, we need to proceed
* timer setting at the very late. * timer setting at the very late.
...@@ -2886,7 +2878,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2886,7 +2878,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
remap_array(posix_timers, posix_timers_nr, posix_timers_cpos); remap_array(posix_timers, posix_timers_nr, posix_timers_cpos);
remap_array(timerfd, rst_timerfd_nr, timerfd_mem_cpos); remap_array(timerfd, rst_timerfd_nr, timerfd_mem_cpos);
remap_array(siginfo, siginfo_nr, siginfo_cpos); remap_array(siginfo, siginfo_nr, siginfo_cpos);
remap_array(tcp_socks, rst_tcp_socks_nr, tcp_socks); remap_array(tcp_socks, rst_tcp_socks_nr, rst_tcp_socks_cpos);
remap_array(rings, mm->n_aios, aio_rings); remap_array(rings, mm->n_aios, aio_rings);
remap_array(rlims, rlims_nr, rlims_cpos); remap_array(rlims, rlims_nr, rlims_cpos);
remap_array(helpers, n_helpers, helpers_pos); remap_array(helpers, n_helpers, helpers_pos);
......
...@@ -40,25 +40,18 @@ struct inet_sk_info { ...@@ -40,25 +40,18 @@ struct inet_sk_info {
InetSkEntry *ie; InetSkEntry *ie;
struct file_desc d; struct file_desc d;
struct inet_port *port; struct inet_port *port;
/*
* This is an fd by which the socket is opened.
* It will be carried down to restorer code to
* repair-off the socket at the very end.
*/
int sk_fd;
struct list_head rlist; struct list_head rlist;
}; };
extern int inet_bind(int sk, struct inet_sk_info *); extern int inet_bind(int sk, struct inet_sk_info *);
extern int inet_connect(int sk, struct inet_sk_info *); extern int inet_connect(int sk, struct inet_sk_info *);
struct rst_tcp_sock {
int sk;
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) static inline void tcp_repair_off(int fd)
{ {
int aux = 0, ret; int aux = 0, ret;
...@@ -78,7 +71,15 @@ extern int restore_one_tcp(int sk, struct inet_sk_info *si); ...@@ -78,7 +71,15 @@ extern int restore_one_tcp(int sk, struct inet_sk_info *si);
#define SK_EST_PARAM "tcp-established" #define SK_EST_PARAM "tcp-established"
extern int check_tcp(void); extern int check_tcp(void);
extern int rst_tcp_socks_add(int fd, bool reuseaddr);
extern mutex_t *inet_get_reuseaddr_lock(struct inet_sk_info *ii); extern mutex_t *inet_get_reuseaddr_lock(struct inet_sk_info *ii);
int rst_tcp_socks_prep(void);
extern unsigned long rst_tcp_socks_cpos;
extern unsigned int rst_tcp_socks_nr;
struct rst_tcp_sock {
int sk;
bool reuseaddr;
};
#endif /* __CR_SK_INET_H__ */ #endif /* __CR_SK_INET_H__ */
...@@ -450,9 +450,9 @@ static int post_open_inet_sk(struct file_desc *d, int sk) ...@@ -450,9 +450,9 @@ static int post_open_inet_sk(struct file_desc *d, int sk)
* after unlocking connections. * after unlocking connections.
*/ */
if (tcp_connection(ii->ie)) { if (tcp_connection(ii->ie)) {
if (rst_tcp_socks_add(sk, ii->ie->opts->reuseaddr)) pr_debug("Schedule %d socket for repair off\n", sk);
return -1; BUG_ON(ii->sk_fd != -1);
ii->sk_fd = sk;
return 0; return 0;
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#include "cr-show.h" #include "cr-show.h"
#include "kerndat.h" #include "kerndat.h"
#include "rst-malloc.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/tcp-stream.pb-c.h" #include "protobuf/tcp-stream.pb-c.h"
...@@ -653,26 +654,25 @@ err: ...@@ -653,26 +654,25 @@ err:
return -1; return -1;
} }
/* unsigned long rst_tcp_socks_cpos;
* rst_tcp_socks contains sockets in repair mode, unsigned int rst_tcp_socks_nr = 0;
* which will be off in restorer before resuming.
*/
struct rst_tcp_sock *rst_tcp_socks = NULL;
int rst_tcp_socks_nr = 0;
int rst_tcp_socks_add(int fd, bool reuseaddr) int rst_tcp_socks_prep(void)
{ {
struct rst_tcp_sock *cur; struct inet_sk_info *ii;
rst_tcp_socks_nr++; rst_tcp_socks_cpos = rst_mem_cpos(RM_PRIVATE);
rst_tcp_socks = xrealloc(rst_tcp_socks, rst_tcp_socks_len()); list_for_each_entry(ii, &rst_tcp_repair_sockets, rlist) {
if (!rst_tcp_socks) struct rst_tcp_sock *rs;
return -1;
pr_debug("Schedule %d socket for repair off\n", fd); rs = rst_mem_alloc(sizeof(*rs), RM_PRIVATE);
cur = &rst_tcp_socks[rst_tcp_socks_nr - 1]; if (!rs)
cur->sk = fd; return -1;
cur->reuseaddr = reuseaddr;
rs->sk = ii->sk_fd;
rs->reuseaddr = ii->ie->opts->reuseaddr;
rst_tcp_socks_nr++;
}
return 0; return 0;
} }
...@@ -693,6 +693,7 @@ int restore_one_tcp(int fd, struct inet_sk_info *ii) ...@@ -693,6 +693,7 @@ int restore_one_tcp(int fd, struct inet_sk_info *ii)
void tcp_locked_conn_add(struct inet_sk_info *ii) void tcp_locked_conn_add(struct inet_sk_info *ii)
{ {
list_add_tail(&ii->rlist, &rst_tcp_repair_sockets); list_add_tail(&ii->rlist, &rst_tcp_repair_sockets);
ii->sk_fd = -1;
} }
void rst_unlock_tcp_connections(void) void rst_unlock_tcp_connections(void)
......
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