mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +00:00
restorer: Pass self-vmas via memory, not temp file
Reserve more mem for bootrstrap code and put all self vmas at its tail. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
committed by
Cyrill Gorcunov
parent
471d3c429c
commit
85f18ef02f
65
cr-restore.c
65
cr-restore.c
@@ -1628,12 +1628,13 @@ static int prepare_creds(int pid, struct task_restore_core_args *args)
|
|||||||
static void sigreturn_restore(pid_t pid)
|
static void sigreturn_restore(pid_t pid)
|
||||||
{
|
{
|
||||||
long restore_code_len, restore_task_vma_len;
|
long restore_code_len, restore_task_vma_len;
|
||||||
long restore_thread_vma_len;
|
long restore_thread_vma_len, self_vmas_len;
|
||||||
|
|
||||||
void *mem = MAP_FAILED;
|
void *mem = MAP_FAILED;
|
||||||
void *restore_thread_exec_start;
|
void *restore_thread_exec_start;
|
||||||
void *restore_task_exec_start;
|
void *restore_task_exec_start;
|
||||||
void *restore_code_start;
|
void *restore_code_start;
|
||||||
|
struct vma_entry *self_vma;
|
||||||
|
|
||||||
long new_sp, exec_mem_hint;
|
long new_sp, exec_mem_hint;
|
||||||
long ret;
|
long ret;
|
||||||
@@ -1641,14 +1642,11 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
struct task_restore_core_args *task_args;
|
struct task_restore_core_args *task_args;
|
||||||
struct thread_restore_args *thread_args;
|
struct thread_restore_args *thread_args;
|
||||||
|
|
||||||
char self_vmas_path[PATH_MAX];
|
|
||||||
|
|
||||||
LIST_HEAD(self_vma_list);
|
LIST_HEAD(self_vma_list);
|
||||||
struct vma_area *vma_area;
|
struct vma_area *vma_area;
|
||||||
int fd_self_vmas = -1;
|
|
||||||
int fd_fdinfo = -1;
|
int fd_fdinfo = -1;
|
||||||
int fd_core = -1;
|
int fd_core = -1;
|
||||||
int num, i;
|
int i;
|
||||||
|
|
||||||
int *fd_core_threads;
|
int *fd_core_threads;
|
||||||
|
|
||||||
@@ -1663,6 +1661,8 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
self_vmas_len = (ret + 1) * sizeof(*self_vma);
|
||||||
|
|
||||||
/* pr_info_vma_list(&self_vma_list); */
|
/* pr_info_vma_list(&self_vma_list); */
|
||||||
|
|
||||||
BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1);
|
BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1);
|
||||||
@@ -1682,33 +1682,6 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_image_path(self_vmas_path, sizeof(self_vmas_path),
|
|
||||||
FMT_FNAME_VMAS, pid))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
fd_self_vmas = open(self_vmas_path, O_CREAT | O_RDWR | O_TRUNC, CR_FD_PERM);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a temporary file used to pass vma info to
|
|
||||||
* restorer code, thus unlink it early to make it disappear
|
|
||||||
* as soon as we close it
|
|
||||||
*/
|
|
||||||
// unlink(self_vmas_path);
|
|
||||||
|
|
||||||
if (fd_self_vmas < 0) {
|
|
||||||
pr_perror("Can't open %s", self_vmas_path);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
num = 0;
|
|
||||||
list_for_each_entry(vma_area, &self_vma_list, list) {
|
|
||||||
ret = write(fd_self_vmas, &vma_area->vma, sizeof(vma_area->vma));
|
|
||||||
if (ret != sizeof(vma_area->vma)) {
|
|
||||||
pr_perror("\nUnable to write vma entry (%d written)", num);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
restore_code_len = sizeof(restorer_blob);
|
restore_code_len = sizeof(restorer_blob);
|
||||||
restore_code_len = round_up(restore_code_len, 16);
|
restore_code_len = round_up(restore_code_len, 16);
|
||||||
@@ -1738,6 +1711,7 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
exec_mem_hint = restorer_get_vma_hint(pid, &self_vma_list,
|
exec_mem_hint = restorer_get_vma_hint(pid, &self_vma_list,
|
||||||
restore_task_vma_len +
|
restore_task_vma_len +
|
||||||
restore_thread_vma_len +
|
restore_thread_vma_len +
|
||||||
|
self_vmas_len +
|
||||||
SHMEMS_SIZE + TASK_ENTRIES_SIZE);
|
SHMEMS_SIZE + TASK_ENTRIES_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",
|
||||||
@@ -1748,8 +1722,6 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
pr_info("Found bootstrap VMA hint at: %lx (needs ~%ldK)\n", exec_mem_hint,
|
pr_info("Found bootstrap VMA hint at: %lx (needs ~%ldK)\n", exec_mem_hint,
|
||||||
KBYTES(restore_task_vma_len + restore_thread_vma_len));
|
KBYTES(restore_task_vma_len + restore_thread_vma_len));
|
||||||
|
|
||||||
free_mappings(&self_vma_list);
|
|
||||||
|
|
||||||
/* VMA we need to run task_restore code */
|
/* VMA we need to run task_restore code */
|
||||||
mem = mmap((void *)exec_mem_hint,
|
mem = mmap((void *)exec_mem_hint,
|
||||||
restore_task_vma_len + restore_thread_vma_len,
|
restore_task_vma_len + restore_thread_vma_len,
|
||||||
@@ -1806,12 +1778,28 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
goto err;
|
goto err;
|
||||||
task_args->task_entries = mem;
|
task_args->task_entries = mem;
|
||||||
|
|
||||||
|
mem += TASK_ENTRIES_SIZE;
|
||||||
|
self_vma = mmap(mem, self_vmas_len, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
|
||||||
|
if (self_vma != mem) {
|
||||||
|
pr_perror("Can't map self vmas");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
task_args->self_vmas = self_vma;
|
||||||
|
|
||||||
|
list_for_each_entry(vma_area, &self_vma_list, list) {
|
||||||
|
*self_vma = vma_area->vma;
|
||||||
|
self_vma++;
|
||||||
|
}
|
||||||
|
|
||||||
|
self_vma->start = 0;
|
||||||
|
free_mappings(&self_vma_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arguments for task restoration.
|
* Arguments for task restoration.
|
||||||
*/
|
*/
|
||||||
task_args->pid = pid;
|
task_args->pid = pid;
|
||||||
task_args->fd_core = fd_core;
|
task_args->fd_core = fd_core;
|
||||||
task_args->fd_self_vmas = fd_self_vmas;
|
|
||||||
task_args->logfd = log_get_fd();
|
task_args->logfd = log_get_fd();
|
||||||
task_args->sigchld_act = sigchld_act;
|
task_args->sigchld_act = sigchld_act;
|
||||||
task_args->fd_fdinfo = fd_fdinfo;
|
task_args->fd_fdinfo = fd_fdinfo;
|
||||||
@@ -1860,13 +1848,13 @@ static void sigreturn_restore(pid_t pid)
|
|||||||
pr_info("task_args: %p\n"
|
pr_info("task_args: %p\n"
|
||||||
"task_args->pid: %d\n"
|
"task_args->pid: %d\n"
|
||||||
"task_args->fd_core: %d\n"
|
"task_args->fd_core: %d\n"
|
||||||
"task_args->fd_self_vmas: %d\n"
|
|
||||||
"task_args->nr_threads: %d\n"
|
"task_args->nr_threads: %d\n"
|
||||||
"task_args->clone_restore_fn: %p\n"
|
"task_args->clone_restore_fn: %p\n"
|
||||||
"task_args->thread_args: %p\n",
|
"task_args->thread_args: %p\n",
|
||||||
task_args, task_args->pid,
|
task_args, task_args->pid,
|
||||||
task_args->fd_core, task_args->fd_self_vmas,
|
task_args->fd_core,
|
||||||
task_args->nr_threads, task_args->clone_restore_fn,
|
task_args->nr_threads,
|
||||||
|
task_args->clone_restore_fn,
|
||||||
task_args->thread_args);
|
task_args->thread_args);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1889,7 +1877,6 @@ err:
|
|||||||
free_mappings(&self_vma_list);
|
free_mappings(&self_vma_list);
|
||||||
close_safe(&fd_core);
|
close_safe(&fd_core);
|
||||||
close_safe(&fd_fdinfo);
|
close_safe(&fd_fdinfo);
|
||||||
close_safe(&fd_self_vmas);
|
|
||||||
|
|
||||||
/* Just to be sure */
|
/* Just to be sure */
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@@ -72,7 +72,6 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
|
|||||||
#define FMT_FNAME_PIPES "pipes-%d.img"
|
#define FMT_FNAME_PIPES "pipes-%d.img"
|
||||||
#define FMT_FNAME_PSTREE "pstree-%d.img"
|
#define FMT_FNAME_PSTREE "pstree-%d.img"
|
||||||
#define FMT_FNAME_SHMEM "shmem-%d.img"
|
#define FMT_FNAME_SHMEM "shmem-%d.img"
|
||||||
#define FMT_FNAME_VMAS "vmas-%d.img"
|
|
||||||
#define FMT_FNAME_SIGACTS "sigacts-%d.img"
|
#define FMT_FNAME_SIGACTS "sigacts-%d.img"
|
||||||
#define FMT_FNAME_UNIXSK "unixsk-%d.img"
|
#define FMT_FNAME_UNIXSK "unixsk-%d.img"
|
||||||
#define FMT_FNAME_INETSK "inetsk-%d.img"
|
#define FMT_FNAME_INETSK "inetsk-%d.img"
|
||||||
|
@@ -66,7 +66,6 @@ struct task_restore_core_args {
|
|||||||
int pid; /* task pid */
|
int pid; /* task pid */
|
||||||
int fd_core; /* opened core file */
|
int fd_core; /* opened core file */
|
||||||
int fd_fdinfo; /* opened files dump file */
|
int fd_fdinfo; /* opened files dump file */
|
||||||
int fd_self_vmas; /* opened file with running VMAs to unmap */
|
|
||||||
int logfd;
|
int logfd;
|
||||||
bool restore_threads; /* if to restore threads */
|
bool restore_threads; /* if to restore threads */
|
||||||
u32 rst_lock;
|
u32 rst_lock;
|
||||||
@@ -77,6 +76,7 @@ struct task_restore_core_args {
|
|||||||
struct thread_restore_args *thread_args; /* array of thread arguments */
|
struct thread_restore_args *thread_args; /* array of thread arguments */
|
||||||
struct shmems *shmems;
|
struct shmems *shmems;
|
||||||
struct task_entries *task_entries;
|
struct task_entries *task_entries;
|
||||||
|
struct vma_entry *self_vmas;
|
||||||
rt_sigaction_t sigchld_act;
|
rt_sigaction_t sigchld_act;
|
||||||
|
|
||||||
struct itimerval itimers[3];
|
struct itimerval itimers[3];
|
||||||
|
18
restorer.c
18
restorer.c
@@ -355,7 +355,6 @@ long restore_task(struct task_restore_core_args *args)
|
|||||||
restorer_set_logfd(args->logfd);
|
restorer_set_logfd(args->logfd);
|
||||||
|
|
||||||
core_entry = first_on_heap(core_entry, args->mem_zone.heap);
|
core_entry = first_on_heap(core_entry, args->mem_zone.heap);
|
||||||
vma_entry = next_on_heap(vma_entry, core_entry);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
write_hex_n((long)args);
|
write_hex_n((long)args);
|
||||||
@@ -371,18 +370,7 @@ long restore_task(struct task_restore_core_args *args)
|
|||||||
goto core_restore_end;
|
goto core_restore_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note no magic constant on fd_self_vmas */
|
for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) {
|
||||||
ret = sys_lseek(args->fd_self_vmas, 0, SEEK_SET);
|
|
||||||
while (1) {
|
|
||||||
ret = sys_read(args->fd_self_vmas, vma_entry, sizeof(*vma_entry));
|
|
||||||
if (!ret)
|
|
||||||
break;
|
|
||||||
if (ret != sizeof(*vma_entry)) {
|
|
||||||
write_num_n(__LINE__);
|
|
||||||
write_num_n(ret);
|
|
||||||
goto core_restore_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
|
if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -392,11 +380,13 @@ long restore_task(struct task_restore_core_args *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_close(args->fd_self_vmas);
|
sys_munmap(args->self_vmas,
|
||||||
|
((void *)(vma_entry + 1) - ((void *)args->self_vmas)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OK, lets try to map new one.
|
* OK, lets try to map new one.
|
||||||
*/
|
*/
|
||||||
|
vma_entry = next_on_heap(vma_entry, core_entry);
|
||||||
sys_lseek(args->fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET);
|
sys_lseek(args->fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET);
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = sys_read(args->fd_core, vma_entry, sizeof(*vma_entry));
|
ret = sys_read(args->fd_core, vma_entry, sizeof(*vma_entry));
|
||||||
|
Reference in New Issue
Block a user