Commit 5c457864 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restore: wait while restroring pgid (v2)

Pgid leader should become such before any other task tries
to enter this group (with setpgid). Thus we introduce a yet
another global sync point -- before it all pgid leaders call
setpgid after it all the others do it.

v2: wait while helpers restored pgid
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 63dcf183
......@@ -343,6 +343,7 @@ 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);
futex_wait_while(&task_entries->start, CR_STATE_RESTORE_PGID);
return 0;
}
......@@ -704,13 +705,16 @@ static int restore_task_with_children(void *_arg)
exit(1);
}
if (me->state != TASK_HELPER) {
futex_dec_and_wake(&task_entries->nr_in_progress);
futex_wait_while(&task_entries->start, CR_STATE_FORKING);
}
restore_pgid();
if (me->state != TASK_HELPER) {
futex_dec_and_wake(&task_entries->nr_in_progress);
futex_wait_while(&task_entries->start, CR_STATE_RESTORE_PGID);
}
return restore_one_task(me->pid.virt);
}
......@@ -774,6 +778,15 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
if (ret < 0)
goto out;
futex_set_and_wake(&task_entries->nr_in_progress, task_entries->nr_tasks);
futex_set_and_wake(&task_entries->start, CR_STATE_RESTORE_PGID);
pr_info("Wait until all tasks restored pgid\n");
futex_wait_while_gt(&task_entries->nr_in_progress, 0);
ret = (int)futex_get(&task_entries->nr_in_progress);
if (ret < 0)
goto out;
futex_set_and_wake(&task_entries->nr_in_progress, task_entries->nr);
futex_set_and_wake(&task_entries->start, CR_STATE_RESTORE);
......@@ -829,6 +842,7 @@ static int prepare_task_entries()
}
task_entries->nr = 0;
task_entries->nr_tasks = 0;
task_entries->nr_helpers = 0;
futex_set(&task_entries->start, CR_STATE_FORKING);
return 0;
......@@ -848,6 +862,8 @@ static int restore_all_tasks(pid_t pid, struct cr_options *opts)
if (prepare_pstree_ids() < 0)
return -1;
futex_set(&task_entries->nr_in_progress, task_entries->nr_tasks + task_entries->nr_helpers);
return restore_root_task(root_item, opts);
}
......
......@@ -211,13 +211,14 @@ struct shmems {
enum {
CR_STATE_FORKING,
CR_STATE_RESTORE_PGID,
CR_STATE_RESTORE,
CR_STATE_RESTORE_SIGCHLD,
CR_STATE_COMPLETE
};
struct task_entries {
int nr, nr_tasks;
int nr, nr_tasks, nr_helpers;
futex_t nr_in_progress;
futex_t start;
};
......
......@@ -197,9 +197,6 @@ int prepare_pstree(void)
task_entries->nr_tasks++;
}
if (!ret)
futex_set(&task_entries->nr_in_progress, task_entries->nr_tasks);
close(ps_fd);
return ret;
}
......@@ -228,6 +225,7 @@ int prepare_pstree_ids(void)
helper->state = TASK_HELPER;
helper->parent = root_item;
list_add_tail(&helper->list, &helpers);
task_entries->nr_helpers++;
pr_info("Add a helper %d for restoring SID %d\n",
helper->pid.virt, helper->sid);
......
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