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) ...@@ -343,6 +343,7 @@ static int restore_one_fake(int pid)
{ {
/* We should wait here, otherwise last_pid will be changed. */ /* 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_FORKING);
futex_wait_while(&task_entries->start, CR_STATE_RESTORE_PGID);
return 0; return 0;
} }
...@@ -704,13 +705,16 @@ static int restore_task_with_children(void *_arg) ...@@ -704,13 +705,16 @@ static int restore_task_with_children(void *_arg)
exit(1); exit(1);
} }
if (me->state != TASK_HELPER) {
futex_dec_and_wake(&task_entries->nr_in_progress); futex_dec_and_wake(&task_entries->nr_in_progress);
futex_wait_while(&task_entries->start, CR_STATE_FORKING); futex_wait_while(&task_entries->start, CR_STATE_FORKING);
}
restore_pgid(); 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); return restore_one_task(me->pid.virt);
} }
...@@ -774,6 +778,15 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts) ...@@ -774,6 +778,15 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
if (ret < 0) if (ret < 0)
goto out; 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->nr_in_progress, task_entries->nr);
futex_set_and_wake(&task_entries->start, CR_STATE_RESTORE); futex_set_and_wake(&task_entries->start, CR_STATE_RESTORE);
...@@ -829,6 +842,7 @@ static int prepare_task_entries() ...@@ -829,6 +842,7 @@ static int prepare_task_entries()
} }
task_entries->nr = 0; task_entries->nr = 0;
task_entries->nr_tasks = 0; task_entries->nr_tasks = 0;
task_entries->nr_helpers = 0;
futex_set(&task_entries->start, CR_STATE_FORKING); futex_set(&task_entries->start, CR_STATE_FORKING);
return 0; return 0;
...@@ -848,6 +862,8 @@ static int restore_all_tasks(pid_t pid, struct cr_options *opts) ...@@ -848,6 +862,8 @@ static int restore_all_tasks(pid_t pid, struct cr_options *opts)
if (prepare_pstree_ids() < 0) if (prepare_pstree_ids() < 0)
return -1; return -1;
futex_set(&task_entries->nr_in_progress, task_entries->nr_tasks + task_entries->nr_helpers);
return restore_root_task(root_item, opts); return restore_root_task(root_item, opts);
} }
......
...@@ -211,13 +211,14 @@ struct shmems { ...@@ -211,13 +211,14 @@ struct shmems {
enum { enum {
CR_STATE_FORKING, CR_STATE_FORKING,
CR_STATE_RESTORE_PGID,
CR_STATE_RESTORE, CR_STATE_RESTORE,
CR_STATE_RESTORE_SIGCHLD, CR_STATE_RESTORE_SIGCHLD,
CR_STATE_COMPLETE CR_STATE_COMPLETE
}; };
struct task_entries { struct task_entries {
int nr, nr_tasks; int nr, nr_tasks, nr_helpers;
futex_t nr_in_progress; futex_t nr_in_progress;
futex_t start; futex_t start;
}; };
......
...@@ -197,9 +197,6 @@ int prepare_pstree(void) ...@@ -197,9 +197,6 @@ int prepare_pstree(void)
task_entries->nr_tasks++; task_entries->nr_tasks++;
} }
if (!ret)
futex_set(&task_entries->nr_in_progress, task_entries->nr_tasks);
close(ps_fd); close(ps_fd);
return ret; return ret;
} }
...@@ -228,6 +225,7 @@ int prepare_pstree_ids(void) ...@@ -228,6 +225,7 @@ int prepare_pstree_ids(void)
helper->state = TASK_HELPER; helper->state = TASK_HELPER;
helper->parent = root_item; helper->parent = root_item;
list_add_tail(&helper->list, &helpers); list_add_tail(&helper->list, &helpers);
task_entries->nr_helpers++;
pr_info("Add a helper %d for restoring SID %d\n", pr_info("Add a helper %d for restoring SID %d\n",
helper->pid.virt, helper->sid); 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