mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-04 08:15:37 +00:00
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: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
16
cr-restore.c
16
cr-restore.c
@@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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 {
|
|||||||
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);
|
|||||||
#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)
|
|||||||
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
sk-tcp.c
31
sk-tcp.c
@@ -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:
|
|||||||
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;
|
||||||
|
|
||||||
|
rs = rst_mem_alloc(sizeof(*rs), RM_PRIVATE);
|
||||||
|
if (!rs)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pr_debug("Schedule %d socket for repair off\n", fd);
|
rs->sk = ii->sk_fd;
|
||||||
cur = &rst_tcp_socks[rst_tcp_socks_nr - 1];
|
rs->reuseaddr = ii->ie->opts->reuseaddr;
|
||||||
cur->sk = fd;
|
rst_tcp_socks_nr++;
|
||||||
cur->reuseaddr = reuseaddr;
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
|
Reference in New Issue
Block a user