[CRIU] [crtools-bot for Pavel Emelyanov ] restore: Don't parse pstree twice

Cyrill Gorcunov gorcunov at openvz.org
Fri Feb 10 11:29:21 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit 717994a4fd836ec580fb51a3dddf2cd4fffb6582
Author: Pavel Emelyanov <xemul at parallels.com>
Date:   Fri Feb 10 20:18:08 2012 +0400

    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: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-restore.c |  176 +++++++++++++++++++++++++---------------------------------
 1 files changed, 76 insertions(+), 100 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 91a71f6..cc6cd9a 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -99,9 +99,10 @@ static struct pipe_info *pipes;
 static int nr_pipes;
 
 static pid_t pstree_pid;
+struct pstree_item *me;
 
 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)
 {
@@ -738,7 +739,7 @@ static int prepare_and_sigreturn(int pid)
 		return -1;
 
 	close(fd_new);
-	sigreturn_restore(pstree_pid, pid);
+	sigreturn_restore(pid);
 
 	return 0;
 }
@@ -1288,22 +1289,24 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
 static int restore_task_with_children(void *_arg)
 {
 	struct cr_clone_arg *ca = _arg;
-	int *pids;
 	int fd, ret, i;
 	struct pstree_entry e;
 	sigset_t blockmask;
-	int pid;
 
 	close_safe(&ca->fd);
-	pid = getpid();
 
-	if (ca->pid != pid) {
-		pr_err("%d: Pid do not match expected %d\n", pid, ca->pid);
+	me = xzalloc(sizeof(*me));
+	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);
 	}
 
 	if (ca->clone_flags) {
-		ret = prepare_namespace(pid, ca->clone_flags);
+		ret = prepare_namespace(me->pid, ca->clone_flags);
 		if (ret)
 			exit(-1);
 	}
@@ -1317,15 +1320,15 @@ static int restore_task_with_children(void *_arg)
 	sigdelset(&blockmask, SIGCHLD);
 	ret = sigprocmask(SIG_BLOCK, &blockmask, NULL);
 	if (ret) {
-		pr_perror("%d: Can't block signals", pid);
+		pr_perror("%d: Can't block signals", me->pid);
 		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);
 	if (fd < 0) {
-		pr_perror("%d: Can't reopen pstree image", pid);
+		pr_perror("%d: Can't reopen pstree image", me->pid);
 		exit(1);
 	}
 
@@ -1335,36 +1338,44 @@ static int restore_task_with_children(void *_arg)
 		if (ret < 0)
 			exit(1);
 
-		if (e.pid == pid)
-			break;
-
-		lseek(fd, e.nr_children * sizeof(u32) + e.nr_threads * sizeof(u32), SEEK_CUR);
-	}
+		if (e.pid != me->pid) {
+			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);
-		pids = xmalloc(i);
-		if (!pids)
+		me->nr_children = e.nr_children;
+		me->children = xmalloc(i);
+		if (!me->children)
 			exit(1);
 
-		ret = read(fd, pids, i);
-		if (ret != i) {
-			pr_perror("%d: Can't read children pids", pid);
+		ret = read_img_buf(fd, me->children, i);
+		if (ret < 0)
 			exit(1);
-		}
 
-		close(fd);
+		i = e.nr_threads * sizeof(int);
+		me->nr_threads = e.nr_threads;
+		me->threads = xmalloc(i);
+		if (!me->threads)
+			exit(1);
 
-		pr_info("%d: Restoring %d children:\n", pid, e.nr_children);
-		for (i = 0; i < e.nr_children; i++) {
-			ret = fork_with_pid(pids[i], 0);
-			if (ret < 0)
-				exit(1);
-		}
-	} else
-		close(fd);
+		ret = read_img_buf(fd, me->threads, i);
+		if (ret < 0)
+			exit(1);
+
+		break;
+	}
 
-	return restore_one_task(pid);
+	close(fd);
+
+	pr_info("%d: Restoring %d children:\n", me->pid, e.nr_children);
+	for (i = 0; i < me->nr_children; i++) {
+		ret = fork_with_pid(me->children[i], 0);
+		if (ret < 0)
+			exit(1);
+	}
+
+	return restore_one_task(me->pid);
 }
 
 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)
 	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_thread_vma_len;
@@ -1617,11 +1628,9 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
 	int fd_self_vmas = -1;
 	int fd_fdinfo = -1;
 	int fd_core = -1;
-	int num;
+	int num, i;
 
-	struct pstree_entry pstree_entry;
 	int *fd_core_threads;
-	int fd_pstree = -1;
 	int pid_dir;
 
 	pr_info("%d: Restore via sigreturn\n", 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(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);
 	if (fd_core < 0) {
 		pr_perror("Can't open core-out-%d", pid);
@@ -1700,40 +1705,20 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
 	/*
 	 * 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
-		 * to restore all threads, every thread
-		 * requires own stack and heap, it's ~40K
-		 * per thread.
-		 */
+	/*
+	 * Compute how many memory we will need
+	 * to restore all threads, every thread
+	 * requires own stack and heap, it's ~40K
+	 * per thread.
+	 */
 
-		restore_thread_vma_len = sizeof(*thread_args) * pstree_entry.nr_threads;
-		restore_thread_vma_len = round_up(restore_thread_vma_len, 16);
+	restore_thread_vma_len = sizeof(*thread_args) * me->nr_threads;
+	restore_thread_vma_len = round_up(restore_thread_vma_len, 16);
 
-		pr_info("%d: %d threads require %ldK of memory\n",
-			pid, pstree_entry.nr_threads,
+	pr_info("%d: %d threads require %ldK of memory\n",
+			pid, me->nr_threads,
 			KBYTES(restore_thread_vma_len));
-		break;
-	}
 
 	restore_thread_vma_len = round_up(restore_thread_vma_len, PAGE_SIZE);
 
@@ -1831,41 +1816,35 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
 
 	cr_mutex_init(&task_args->rst_lock);
 
-	if (pstree_entry.nr_threads) {
-		int i;
-
-		/*
-		 * Now prepare run-time data for threads restore.
-		 */
-		task_args->nr_threads		= pstree_entry.nr_threads;
-		task_args->clone_restore_fn	= (void *)restore_thread_exec_start;
-		task_args->thread_args		= thread_args;
+	/*
+	 * Now prepare run-time data for threads restore.
+	 */
+	task_args->nr_threads		= me->nr_threads;
+	task_args->clone_restore_fn	= (void *)restore_thread_exec_start;
+	task_args->thread_args		= thread_args;
 
-		/*
-		 * Fill up per-thread data.
-		 */
-		lseek(fd_pstree, sizeof(u32) * pstree_entry.nr_children, SEEK_CUR);
-		for (i = 0; i < pstree_entry.nr_threads; i++) {
-			if (read_img(fd_pstree, &thread_args[i].pid) < 0)
-				goto err;
+	/*
+	 * Fill up per-thread data.
+	 */
+	for (i = 0; i < me->nr_threads; i++) {
+		thread_args[i].pid = me->threads[i];
 
-			/* skip self */
-			if (thread_args[i].pid == pid)
-				continue;
+		/* skip self */
+		if (thread_args[i].pid == pid)
+			continue;
 
-			/* Core files are to be opened */
-			thread_args[i].fd_core = open_image_ro_nocheck(FMT_FNAME_CORE, thread_args[i].pid);
-			if (thread_args[i].fd_core < 0)
-				goto err;
+		/* Core files are to be opened */
+		thread_args[i].fd_core = open_image_ro_nocheck(FMT_FNAME_CORE, thread_args[i].pid);
+		if (thread_args[i].fd_core < 0)
+			goto err;
 
-			thread_args[i].rst_lock = &task_args->rst_lock;
+		thread_args[i].rst_lock = &task_args->rst_lock;
 
-			pr_info("Thread %4d stack %8p heap %8p rt_sigframe %8p\n",
+		pr_info("Thread %4d stack %8p heap %8p rt_sigframe %8p\n",
 				i, thread_args[i].mem_zone.stack,
 				thread_args[i].mem_zone.heap,
 				thread_args[i].mem_zone.rt_sigframe);
 
-		}
 	}
 
 	pr_info("task_args: %p\n"
@@ -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->thread_args);
 
-	close_safe(&fd_pstree);
-
 	/*
 	 * An indirect call to task_restore, note it never resturns
 	 * and restoreing core is extremely destructive.
@@ -1900,7 +1877,6 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
 
 err:
 	free_mappings(&self_vma_list);
-	close_safe(&fd_pstree);
 	close_safe(&fd_core);
 	close_safe(&fd_self_vmas);
 


More information about the CRIU mailing list