[CRIU] [PATCH 11/13] cr-restore: read core before forking
Andrey Vagin
avagin at openvz.org
Thu Dec 20 06:54:19 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 1f53b8e..127164d 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