[CRIU] [PATCH 10/12] cr-restore: read core before forking

Andrey Vagin avagin at openvz.org
Tue Dec 18 01:36:13 EST 2012


A task state is save in a core.
It will be used for determining a number of zombies.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index e6b7cdf..36fbfb3 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -740,21 +740,9 @@ out:
 	return ret < 0 ? ret : 0;
 }
 
-static int restore_one_task(int pid)
+static int restore_one_task(int pid, CoreEntry *core)
 {
-	int fd, ret;
-	CoreEntry *core;
-
-	fd = open_image_ro(CR_FD_CORE, pid);
-	if (fd < 0)
-		return -1;
-
-	ret = pb_read_one(fd, &core, PB_CORE);
-	close(fd);
-
-	if (ret < 0)
-		return -1;
-
+	int ret;
 	if (check_core(core)) {
 		ret = -1;
 		goto out;
@@ -783,6 +771,7 @@ struct cr_clone_arg {
 	char stack[PAGE_SIZE];
 	char stack_ptr[0];
 	struct pstree_item *item;
+	CoreEntry *core;
 	unsigned long clone_flags;
 	int fd;
 };
@@ -804,12 +793,25 @@ static void write_pidfile(char *pfname, int pid)
 
 static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone_flags)
 {
-	int ret = -1;
+	int fd, ret = -1;
 	struct cr_clone_arg ca;
 	pid_t pid = item->pid.virt;
 
 	pr_info("Forking task with %d pid (flags 0x%lx)\n", pid, ns_clone_flags);
 
+	if (item->state != TASK_HELPER) {
+		fd = open_image_ro(CR_FD_CORE, pid);
+		if (fd < 0)
+			return -1;
+
+		ret = pb_read_one(fd, &ca.core, PB_CORE);
+		close(fd);
+
+		if (ret < 0)
+			return -1;
+	} else
+		ca.core = NULL;
+
 	ca.item = item;
 	ca.clone_flags = ns_clone_flags;
 
@@ -845,12 +847,23 @@ static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone
 		if (netns_pre_create())
 			goto err_unlock;
 
+	if (ca.core)
+		item->state = ca.core->tc->task_state;
+
+	if (item->state == TASK_DEAD) {
+		atomic_inc(&task_entries->nr_zombies);
+		futex_inc(item->parent->rst->nr_zombies);
+	}
+
 	ret = clone(restore_task_with_children, ca.stack_ptr,
 			ca.clone_flags | SIGCHLD, &ca);
 
 	if (ret < 0)
 		pr_perror("Can't fork for %d", pid);
 
+	if (ca.core)
+		core_entry__free_unpacked(ca.core, NULL);
+
 	if (ca.clone_flags & CLONE_NEWPID)
 		item->pid.real = ret;
 
@@ -1095,7 +1108,7 @@ static int restore_task_with_children(void *_arg)
 		return restore_one_fake();
 
 	restore_finish_stage(CR_STATE_RESTORE_PGID);
-	return restore_one_task(current->pid.virt);
+	return restore_one_task(current->pid.virt, ca->core);
 }
 
 static inline int stage_participants(int next_stage)
-- 
1.7.11.7



More information about the CRIU mailing list