[CRIU] [PATCH cr 04/10] restore: add interface for creating helper tasks (v2)

Andrey Vagin avagin at openvz.org
Tue Jun 19 08:46:55 EDT 2012


They will be used for restoring sid. For example, if a session
group leader is absent, a helper process is created with this id
and it will die after restoring all other tasks.

v2: check that me isn't NULL in the sig handler

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c    |   42 +++++++++++++++++++++++++++++++++++++++++-
 include/image.h |    1 +
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 7e5b003..9ba4d4d 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -341,8 +341,28 @@ err:
 
 static int restore_one_alive_task(int pid)
 {
+	struct pstree_item *pi;
 	pr_info("Restoring resources\n");
 
+	list_for_each_entry(pi, &me->children, list) {
+		int status, ret;
+
+		if (pi->state != TASK_HELPER)
+			continue;
+
+		ret = waitpid(pi->pid, &status, 0);
+		if (ret == -1) {
+			pr_err("waitpid(%d) failed\n", pi->pid);
+			return -1;
+		}
+
+		if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+			pr_err("%d exited with non-zero code (%d,%d)", pi->pid,
+				WEXITSTATUS(status), WTERMSIG(status));
+			return -1;
+		}
+	}
+
 	if (prepare_fds(me))
 		return -1;
 
@@ -405,6 +425,13 @@ static inline int sig_fatal(int sig)
 	return (sig > 0) && (sig < SIGMAX) && (SIG_FATAL_MASK & (1 << sig));
 }
 
+static int restore_one_fake(int pid)
+{
+	/* We should wait here, otherwise last_pid will be changed. */
+	futex_wait_while(&task_entries->start, CR_STATE_FORKING);
+	return 0;
+}
+
 static int restore_one_zombie(int pid, int exit_code)
 {
 	pr_info("Restoring zombie with %d code\n", exit_code);
@@ -473,6 +500,9 @@ static int restore_one_task(int pid)
 {
 	struct task_core_entry tc;
 
+	if (me->state == TASK_HELPER)
+		return restore_one_fake(pid);
+
 	if (check_core_header(pid, &tc))
 		return -1;
 
@@ -557,6 +587,16 @@ err:
 
 static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
 {
+	struct pstree_item *pi;
+
+	if (me)
+		list_for_each_entry(pi, &me->children, list) {
+			if (pi->state != TASK_HELPER)
+				continue;
+			if (pi->pid == siginfo->si_pid)
+				return;
+		}
+
 	if (siginfo->si_code & CLD_EXITED)
 		pr_err("%d exited, status=%d\n",
 			siginfo->si_pid, siginfo->si_status);
@@ -704,7 +744,7 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
 		return -1;
 	}
 
-	act.sa_flags |= SA_NOCLDWAIT | SA_NOCLDSTOP | SA_SIGINFO | SA_RESTART;
+	act.sa_flags |= SA_NOCLDSTOP | SA_SIGINFO | SA_RESTART;
 	act.sa_sigaction = sigchld_handler;
 	ret = sigaction(SIGCHLD, &act, &old_act);
 	if (ret < 0) {
diff --git a/include/image.h b/include/image.h
index cb95330..a5683f9 100644
--- a/include/image.h
+++ b/include/image.h
@@ -498,6 +498,7 @@ struct core_entry {
 #define TASK_ALIVE		0x1
 #define TASK_DEAD		0x2
 #define TASK_STOPPED		0x3 /* FIXME - implement */
+#define TASK_HELPER		0x4
 
 #endif /* CONFIG_X86_64 */
 
-- 
1.7.1



More information about the CRIU mailing list