Commit 27b20dfc authored by Andrey Vagin's avatar Andrey Vagin Committed by Cyrill Gorcunov

restore: clean up code, which synchronizes resume of tasks (v2)

I added two mechanism of synchronization. The second one is better.
This patch deletes the first one.

Before we had an entry (pid and lock) for each tasks and all this
entries were shared between all processes. Now we don't need "lock"
and we use pids from crtools to kill all processes if someone failed.

v2: s/malloc/xmalloc
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent a038cbd9
......@@ -79,18 +79,16 @@ struct pipe_list_entry {
static struct task_entries *task_entries;
static void task_add_entry(int pid)
{
int *nr = &task_entries->nr;
struct task_entry *e = &task_entries->entries[*nr];
(*nr)++;
BUG_ON((*nr) * sizeof(struct task_entry) +
sizeof(struct task_entries) > TASK_ENTRIES_SIZE);
static struct task_pids {
int nr;
int arr[];
} *task_pids;
e->pid = pid;
e->done = 0;
static void task_add_pid(int pid)
{
BUG_ON(sizeof(struct task_pids) + task_pids->nr * sizeof(int) > PAGE_SIZE);
task_pids->arr[task_pids->nr] = pid;
task_pids->nr++;
}
static struct shmem_id *shmem_ids;
......@@ -372,6 +370,11 @@ static int prepare_shared(int ps_fd)
pr_info("Preparing info about shared resources\n");
task_pids = xmalloc(PAGE_SIZE);
if (task_pids == NULL)
return -1;
task_pids->nr = 0;
shmems = mmap(NULL, SHMEMS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, 0, 0);
if (shmems == MAP_FAILED) {
pr_perror("Can't map shmem");
......@@ -417,7 +420,9 @@ static int prepare_shared(int ps_fd)
if (ret < 0)
break;
task_add_entry(e.pid);
task_add_pid(e.pid);
task_entries->nr++;
lseek(ps_fd, e.nr_children * sizeof(u32) + e.nr_threads * sizeof(u32), SEEK_CUR);
}
......@@ -1128,12 +1133,7 @@ static int restore_one_zobie(int pid, int exit_code)
pr_info("Restoring zombie with %d code\n", exit_code);
if (task_entries != NULL) {
struct task_entry *task_entry;
task_entry = task_get_entry(task_entries, pid);
cr_wait_dec(&task_entries->nr_in_progress);
cr_wait_set(&task_entry->done, 1);
cr_wait_while(&task_entries->start, CR_STATE_RESTORE);
zombie_prepare_signals();
......@@ -1410,17 +1410,11 @@ static int restore_root_task(int fd, struct cr_options *opts)
ret = cr_wait_until_greater(&task_entries->nr_in_progress, 0);
if (ret < 0) {
pr_err("Someone can't be restored\n");
for (i = 0; i < task_entries->nr; i++)
kill(task_entries->entries[i].pid, SIGKILL);
for (i = 0; i < task_pids->nr; i++)
kill(task_pids->arr[i], SIGKILL);
return 1;
}
for (i = 0; i < task_entries->nr; i++) {
pr_info("Wait while the task %d restored\n",
task_entries->entries[i].pid);
cr_wait_while(&task_entries->entries[i].done, 0);
}
cr_wait_set(&task_entries->nr_in_progress, task_entries->nr);
cr_wait_set(&task_entries->start, CR_STATE_RESTORE_SIGCHLD);
cr_wait_until(&task_entries->nr_in_progress, 0);
......
......@@ -202,16 +202,10 @@ enum {
CR_STATE_COMPLETE
};
struct task_entry {
int pid;
u32 done; // futex
};
struct task_entries {
int nr;
u32 nr_in_progress;
u32 start; //futex
struct task_entry entries[0];
};
......@@ -232,16 +226,4 @@ find_shmem_by_pid(struct shmems *shmems, unsigned long start, int pid)
return NULL;
}
static always_inline struct task_entry *
task_get_entry(struct task_entries *base, int pid)
{
int i;
for (i = 0; i < base->nr; i++)
if (base->entries[i].pid == pid)
return &base->entries[i];
return NULL;
}
#endif /* CR_RESTORER_H__ */
......@@ -624,10 +624,7 @@ long restore_task(struct task_restore_core_args *args)
restore_creds(&args->creds);
task_entry = task_get_entry(args->task_entries, my_pid);
cr_wait_dec(&args->task_entries->nr_in_progress);
cr_wait_set(&task_entry->done, 1);
write_num(sys_getpid());
write_string_n(": Restored");
......
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