[CRIU] [PATCH RESEND 3/4] restore: Split restore_one_helper() and wait exiting zombie children
Kirill Tkhai
ktkhai at virtuozzo.com
Thu Dec 28 13:50:54 MSK 2017
Zombie is also can be choosen as a parent for task helper like
any other task.
If the task helper exits between restore_finish_stage(CR_STATE_RESTORE)
and zombie_prepare_signals()->SIG_UNBLOCK, the standard criu SIGCHLD
handler is called, and the restore fails:
(00.057762) 41: Error (criu/cr-restore.c:1557): 40 exited, status=0
(00.057815) Error (criu/cr-restore.c:2465): Restoring FAILED.
This patch makes restore_one_zombie() behave as restore_one_helper()
and to wait children exits before allowing SIGCHLD. This makes us
safe against races with exiting children.
See next patch for test details.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/cr-restore.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 5bebc3d61..7545572dc 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1111,6 +1111,8 @@ static int wait_on_helpers_zombies(void)
return 0;
}
+static int wait_exiting_children(void);
+
static int restore_one_zombie(CoreEntry *core)
{
int exit_code = core->tc->exit_code;
@@ -1129,7 +1131,7 @@ static int restore_one_zombie(CoreEntry *core)
prctl(PR_SET_NAME, (long)(void *)core->tc->comm, 0, 0, 0);
if (task_entries != NULL) {
- restore_finish_stage(task_entries, CR_STATE_RESTORE);
+ wait_exiting_children();
zombie_prepare_signals();
}
@@ -1233,21 +1235,10 @@ static bool child_death_expected(void)
return false;
}
-/*
- * Restore a helper process - artificially created by criu
- * to restore attributes of process tree.
- * - sessions for each leaders are dead
- * - process groups with dead leaders
- * - dead tasks for which /proc/<pid>/... is opened by restoring task
- * - whatnot
- */
-static int restore_one_helper(void)
+static int wait_exiting_children(void)
{
siginfo_t info;
- if (prepare_fds(current))
- return -1;
-
if (!child_death_expected()) {
/*
* Restoree has no children that should die, during restore,
@@ -1290,6 +1281,22 @@ static int restore_one_helper(void)
return 0;
}
+/*
+ * Restore a helper process - artificially created by criu
+ * to restore attributes of process tree.
+ * - sessions for each leaders are dead
+ * - process groups with dead leaders
+ * - dead tasks for which /proc/<pid>/... is opened by restoring task
+ * - whatnot
+ */
+static int restore_one_helper(void)
+{
+ if (prepare_fds(current))
+ return -1;
+
+ return wait_exiting_children();
+}
+
static int restore_one_task(int pid, CoreEntry *core)
{
int i, ret;
More information about the CRIU
mailing list