[CRIU] [PATCH 3/9] restore: add a function to wait when other tasks finish a stage

Andrei Vagin avagin at openvz.org
Tue Feb 14 15:59:26 PST 2017


From: Andrei Vagin <avagin at virtuozzo.com>

It is used now to close descriptors of mount namespaces
and will be used for network namespaces too.

Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
 criu/cr-restore.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index d75aa0d..745e20d 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -121,6 +121,7 @@ static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core)
 static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
 static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
 
+static void restore_wait_other_tasks();
 
 static int crtools_prepare_shared(void)
 {
@@ -1466,7 +1467,7 @@ static int restore_task_with_children(void *_arg)
 		 * Wait when all tasks passed the CR_STATE_FORKING stage.
 		 * It means that all tasks entered into their namespaces.
 		 */
-		futex_wait_while_gt(&task_entries->nr_in_progress, 1);
+		restore_wait_other_tasks();
 
 		fini_restore_mntns();
 	}
@@ -1510,6 +1511,26 @@ static inline int stage_participants(int next_stage)
 	return -1;
 }
 
+static inline int stage_current_participants(int next_stage)
+{
+	switch (next_stage) {
+	case CR_STATE_FORKING:
+		return 1;
+	case CR_STATE_RESTORE:
+		/*
+		 * Each thread has to be reported about this stage,
+		 * so if we want to wait all other tast, we have to
+		 * exclude all threads of the current process.
+		 * It is supposed that we will wait other tasks,
+		 * before creating threads of the current task.
+		 */
+		return current->nr_threads;
+	}
+
+	BUG();
+	return -1;
+}
+
 static int restore_wait_inprogress_tasks()
 {
 	int ret;
@@ -1538,6 +1559,18 @@ static int restore_switch_stage(int next_stage)
 	return restore_wait_inprogress_tasks();
 }
 
+/* Wait all tasks except the current one */
+static void restore_wait_other_tasks()
+{
+	int participants, stage;
+
+	stage = futex_get(&task_entries->start);
+	participants = stage_current_participants(stage);
+
+	futex_wait_while_gt(&task_entries->nr_in_progress,
+				participants);
+}
+
 static int attach_to_tasks(bool root_seized)
 {
 	struct pstree_item *item;
-- 
2.7.4



More information about the CRIU mailing list