Commit c32046c9 authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

restore: die if init fails in --restore-detached mode

When in --restore-detached (i.e. root_as_sibling) mode, we ptrace(PTRACE_SEIZE)
the root task to receive its SIGCHLD in case one of its child tasks dies.
However, we don't receive a SIGCHLD if the root task itself dies, so we must
explicitly abort.
Signed-off-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Acked-by: 's avatarAndrew Vagin <avagin@parallels.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 2e5e3e4b
...@@ -1365,12 +1365,12 @@ static int restore_task_with_children(void *_arg) ...@@ -1365,12 +1365,12 @@ static int restore_task_with_children(void *_arg)
/* Determine PID in CRIU's namespace */ /* Determine PID in CRIU's namespace */
fd = get_service_fd(CR_PROC_FD_OFF); fd = get_service_fd(CR_PROC_FD_OFF);
if (fd < 0) if (fd < 0)
exit(1); goto err;
ret = readlinkat(fd, "self", buf, sizeof(buf) - 1); ret = readlinkat(fd, "self", buf, sizeof(buf) - 1);
if (ret < 0) { if (ret < 0) {
pr_perror("Unable to read the /proc/self link"); pr_perror("Unable to read the /proc/self link");
exit(1); goto err;
} }
buf[ret] = '\0'; buf[ret] = '\0';
...@@ -1385,26 +1385,26 @@ static int restore_task_with_children(void *_arg) ...@@ -1385,26 +1385,26 @@ static int restore_task_with_children(void *_arg)
if (current->state != TASK_HELPER) { if (current->state != TASK_HELPER) {
ret = clone_service_fd(current->rst->service_fd_id); ret = clone_service_fd(current->rst->service_fd_id);
if (ret) if (ret)
exit(1); goto err;
} }
pid = getpid(); pid = getpid();
if (current->pid.virt != pid) { if (current->pid.virt != pid) {
pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt); pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
exit(-1); goto err;
} }
ret = log_init_by_pid(); ret = log_init_by_pid();
if (ret < 0) if (ret < 0)
exit(1); goto err;
/* Restore root task */ /* Restore root task */
if (current->parent == NULL) { if (current->parent == NULL) {
if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0) if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0)
exit(1); goto err;
if (prepare_namespace(current, ca->clone_flags)) if (prepare_namespace(current, ca->clone_flags))
exit(1); goto err_fini_mnt;
/* /*
* We need non /proc proc mount for restoring pid and mount * We need non /proc proc mount for restoring pid and mount
...@@ -1412,22 +1412,22 @@ static int restore_task_with_children(void *_arg) ...@@ -1412,22 +1412,22 @@ static int restore_task_with_children(void *_arg)
* Thus -- mount proc at custom location for any new namespace * Thus -- mount proc at custom location for any new namespace
*/ */
if (mount_proc()) if (mount_proc())
goto err; goto err_fini_mnt;
if (close_old_fds(current)) if (close_old_fds(current))
exit(1); goto err_fini_mnt;
if (root_prepare_shared()) if (root_prepare_shared())
goto err; goto err_fini_mnt;
} }
if (prepare_mappings(pid)) if (prepare_mappings(pid))
goto err; goto err_fini_mnt;
if (!(ca->clone_flags & CLONE_FILES)) { if (!(ca->clone_flags & CLONE_FILES)) {
ret = close_old_fds(current); ret = close_old_fds(current);
if (ret) if (ret)
exit(1); goto err_fini_mnt;
} }
/* /*
...@@ -1437,13 +1437,13 @@ static int restore_task_with_children(void *_arg) ...@@ -1437,13 +1437,13 @@ static int restore_task_with_children(void *_arg)
* just have it inherited. * just have it inherited.
*/ */
if (prepare_task_cgroup(current) < 0) if (prepare_task_cgroup(current) < 0)
return -1; goto err_fini_mnt;
if (prepare_sigactions() < 0) if (prepare_sigactions() < 0)
return -1; goto err_fini_mnt;
if (create_children_and_session()) if (create_children_and_session())
goto err; goto err_fini_mnt;
/* /*
* This must be done after forking to allow child * This must be done after forking to allow child
...@@ -1454,24 +1454,28 @@ static int restore_task_with_children(void *_arg) ...@@ -1454,24 +1454,28 @@ static int restore_task_with_children(void *_arg)
close_service_fd(CGROUP_YARD); close_service_fd(CGROUP_YARD);
if (restore_task_mnt_ns(current)) if (restore_task_mnt_ns(current))
goto err; goto err_fini_mnt;
if (unmap_guard_pages()) if (unmap_guard_pages())
goto err; goto err_fini_mnt;
restore_pgid(); restore_pgid();
if (restore_finish_stage(CR_STATE_FORKING) < 0) if (restore_finish_stage(CR_STATE_FORKING) < 0)
goto err; goto err_fini_mnt;
if (current->parent == NULL && fini_mnt_ns()) if (current->parent == NULL && fini_mnt_ns())
exit (1); goto err_fini_mnt;
return restore_one_task(current->pid.virt, ca->core); return restore_one_task(current->pid.virt, ca->core);
err:
err_fini_mnt:
if (current->parent == NULL) if (current->parent == NULL)
fini_mnt_ns(); fini_mnt_ns();
err:
if (current->parent == NULL)
futex_abort_and_wake(&task_entries->nr_in_progress);
exit(1); exit(1);
} }
......
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