[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