Commit 717994a4 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

restore: Don't parse pstree twice

This file is parsed once to find who to fork and then for the 2nd
time to find threads to create.

Remove the 2nd parse holding the info found on the 1st stage in
local *me variable.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 36dc98ad
...@@ -99,9 +99,10 @@ static struct pipe_info *pipes; ...@@ -99,9 +99,10 @@ static struct pipe_info *pipes;
static int nr_pipes; static int nr_pipes;
static pid_t pstree_pid; static pid_t pstree_pid;
struct pstree_item *me;
static int restore_task_with_children(void *); static int restore_task_with_children(void *);
static void sigreturn_restore(pid_t pstree_pid, pid_t pid); static void sigreturn_restore(pid_t pid);
static void show_saved_shmems(void) static void show_saved_shmems(void)
{ {
...@@ -738,7 +739,7 @@ static int prepare_and_sigreturn(int pid) ...@@ -738,7 +739,7 @@ static int prepare_and_sigreturn(int pid)
return -1; return -1;
close(fd_new); close(fd_new);
sigreturn_restore(pstree_pid, pid); sigreturn_restore(pid);
return 0; return 0;
} }
...@@ -1288,22 +1289,24 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) ...@@ -1288,22 +1289,24 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
static int restore_task_with_children(void *_arg) static int restore_task_with_children(void *_arg)
{ {
struct cr_clone_arg *ca = _arg; struct cr_clone_arg *ca = _arg;
int *pids;
int fd, ret, i; int fd, ret, i;
struct pstree_entry e; struct pstree_entry e;
sigset_t blockmask; sigset_t blockmask;
int pid;
close_safe(&ca->fd); close_safe(&ca->fd);
pid = getpid();
if (ca->pid != pid) { me = xzalloc(sizeof(*me));
pr_err("%d: Pid do not match expected %d\n", pid, ca->pid); if (me == NULL)
exit(-1);
me->pid = getpid();
if (ca->pid != me->pid) {
pr_err("%d: Pid do not match expected %d\n", me->pid, ca->pid);
exit(-1); exit(-1);
} }
if (ca->clone_flags) { if (ca->clone_flags) {
ret = prepare_namespace(pid, ca->clone_flags); ret = prepare_namespace(me->pid, ca->clone_flags);
if (ret) if (ret)
exit(-1); exit(-1);
} }
...@@ -1317,15 +1320,15 @@ static int restore_task_with_children(void *_arg) ...@@ -1317,15 +1320,15 @@ static int restore_task_with_children(void *_arg)
sigdelset(&blockmask, SIGCHLD); sigdelset(&blockmask, SIGCHLD);
ret = sigprocmask(SIG_BLOCK, &blockmask, NULL); ret = sigprocmask(SIG_BLOCK, &blockmask, NULL);
if (ret) { if (ret) {
pr_perror("%d: Can't block signals", pid); pr_perror("%d: Can't block signals", me->pid);
exit(1); exit(1);
} }
pr_info("%d: Starting restore\n", pid); pr_info("%d: Starting restore\n", me->pid);
fd = open_image_ro_nocheck(FMT_FNAME_PSTREE, pstree_pid); fd = open_image_ro_nocheck(FMT_FNAME_PSTREE, pstree_pid);
if (fd < 0) { if (fd < 0) {
pr_perror("%d: Can't reopen pstree image", pid); pr_perror("%d: Can't reopen pstree image", me->pid);
exit(1); exit(1);
} }
...@@ -1335,36 +1338,44 @@ static int restore_task_with_children(void *_arg) ...@@ -1335,36 +1338,44 @@ static int restore_task_with_children(void *_arg)
if (ret < 0) if (ret < 0)
exit(1); exit(1);
if (e.pid == pid) if (e.pid != me->pid) {
break;
lseek(fd, e.nr_children * sizeof(u32) + e.nr_threads * sizeof(u32), SEEK_CUR); lseek(fd, e.nr_children * sizeof(u32) + e.nr_threads * sizeof(u32), SEEK_CUR);
continue;
} }
if (e.nr_children > 0) {
i = e.nr_children * sizeof(int); i = e.nr_children * sizeof(int);
pids = xmalloc(i); me->nr_children = e.nr_children;
if (!pids) me->children = xmalloc(i);
if (!me->children)
exit(1);
ret = read_img_buf(fd, me->children, i);
if (ret < 0)
exit(1); exit(1);
ret = read(fd, pids, i); i = e.nr_threads * sizeof(int);
if (ret != i) { me->nr_threads = e.nr_threads;
pr_perror("%d: Can't read children pids", pid); me->threads = xmalloc(i);
if (!me->threads)
exit(1); exit(1);
ret = read_img_buf(fd, me->threads, i);
if (ret < 0)
exit(1);
break;
} }
close(fd); close(fd);
pr_info("%d: Restoring %d children:\n", pid, e.nr_children); pr_info("%d: Restoring %d children:\n", me->pid, e.nr_children);
for (i = 0; i < e.nr_children; i++) { for (i = 0; i < me->nr_children; i++) {
ret = fork_with_pid(pids[i], 0); ret = fork_with_pid(me->children[i], 0);
if (ret < 0) if (ret < 0)
exit(1); exit(1);
} }
} else
close(fd);
return restore_one_task(pid); return restore_one_task(me->pid);
} }
static int restore_root_task(int fd, struct cr_options *opts) static int restore_root_task(int fd, struct cr_options *opts)
...@@ -1593,7 +1604,7 @@ static int prepare_creds(int pid, struct task_restore_core_args *args) ...@@ -1593,7 +1604,7 @@ static int prepare_creds(int pid, struct task_restore_core_args *args)
return ret > 0 ? 0 : -1; return ret > 0 ? 0 : -1;
} }
static void sigreturn_restore(pid_t pstree_pid, 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;
...@@ -1617,11 +1628,9 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1617,11 +1628,9 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
int fd_self_vmas = -1; int fd_self_vmas = -1;
int fd_fdinfo = -1; int fd_fdinfo = -1;
int fd_core = -1; int fd_core = -1;
int num; int num, i;
struct pstree_entry pstree_entry;
int *fd_core_threads; int *fd_core_threads;
int fd_pstree = -1;
int pid_dir; int pid_dir;
pr_info("%d: Restore via sigreturn\n", pid); pr_info("%d: Restore via sigreturn\n", pid);
...@@ -1646,10 +1655,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1646,10 +1655,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE); BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE);
BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE); BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE);
fd_pstree = open_image_ro_nocheck(FMT_FNAME_PSTREE, pstree_pid);
if (fd_pstree < 0)
goto err;
fd_core = open_image_ro_nocheck(FMT_FNAME_CORE_OUT, pid); fd_core = open_image_ro_nocheck(FMT_FNAME_CORE_OUT, pid);
if (fd_core < 0) { if (fd_core < 0) {
pr_perror("Can't open core-out-%d", pid); pr_perror("Can't open core-out-%d", pid);
...@@ -1700,24 +1705,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1700,24 +1705,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
/* /*
* Thread statistics * Thread statistics
*/ */
lseek(fd_pstree, MAGIC_OFFSET, SEEK_SET);
while (1) {
ret = read_img_eof(fd_pstree, &pstree_entry);
if (ret <= 0) {
pr_perror("Pid %d not found in process tree", pid);
goto err;
}
if (pstree_entry.pid != pid) {
lseek(fd_pstree,
(pstree_entry.nr_children +
pstree_entry.nr_threads) *
sizeof(u32), SEEK_CUR);
continue;
}
if (!pstree_entry.nr_threads)
break;
/* /*
* Compute how many memory we will need * Compute how many memory we will need
...@@ -1726,14 +1713,12 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1726,14 +1713,12 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
* per thread. * per thread.
*/ */
restore_thread_vma_len = sizeof(*thread_args) * pstree_entry.nr_threads; restore_thread_vma_len = sizeof(*thread_args) * me->nr_threads;
restore_thread_vma_len = round_up(restore_thread_vma_len, 16); restore_thread_vma_len = round_up(restore_thread_vma_len, 16);
pr_info("%d: %d threads require %ldK of memory\n", pr_info("%d: %d threads require %ldK of memory\n",
pid, pstree_entry.nr_threads, pid, me->nr_threads,
KBYTES(restore_thread_vma_len)); KBYTES(restore_thread_vma_len));
break;
}
restore_thread_vma_len = round_up(restore_thread_vma_len, PAGE_SIZE); restore_thread_vma_len = round_up(restore_thread_vma_len, PAGE_SIZE);
...@@ -1831,23 +1816,18 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1831,23 +1816,18 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
cr_mutex_init(&task_args->rst_lock); cr_mutex_init(&task_args->rst_lock);
if (pstree_entry.nr_threads) {
int i;
/* /*
* Now prepare run-time data for threads restore. * Now prepare run-time data for threads restore.
*/ */
task_args->nr_threads = pstree_entry.nr_threads; task_args->nr_threads = me->nr_threads;
task_args->clone_restore_fn = (void *)restore_thread_exec_start; task_args->clone_restore_fn = (void *)restore_thread_exec_start;
task_args->thread_args = thread_args; task_args->thread_args = thread_args;
/* /*
* Fill up per-thread data. * Fill up per-thread data.
*/ */
lseek(fd_pstree, sizeof(u32) * pstree_entry.nr_children, SEEK_CUR); for (i = 0; i < me->nr_threads; i++) {
for (i = 0; i < pstree_entry.nr_threads; i++) { thread_args[i].pid = me->threads[i];
if (read_img(fd_pstree, &thread_args[i].pid) < 0)
goto err;
/* skip self */ /* skip self */
if (thread_args[i].pid == pid) if (thread_args[i].pid == pid)
...@@ -1866,7 +1846,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1866,7 +1846,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
thread_args[i].mem_zone.rt_sigframe); thread_args[i].mem_zone.rt_sigframe);
} }
}
pr_info("task_args: %p\n" pr_info("task_args: %p\n"
"task_args->pid: %d\n" "task_args->pid: %d\n"
...@@ -1880,8 +1859,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1880,8 +1859,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
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);
close_safe(&fd_pstree);
/* /*
* An indirect call to task_restore, note it never resturns * An indirect call to task_restore, note it never resturns
* and restoreing core is extremely destructive. * and restoreing core is extremely destructive.
...@@ -1900,7 +1877,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1900,7 +1877,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
err: err:
free_mappings(&self_vma_list); free_mappings(&self_vma_list);
close_safe(&fd_pstree);
close_safe(&fd_core); close_safe(&fd_core);
close_safe(&fd_self_vmas); close_safe(&fd_self_vmas);
......
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