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 { ...@@ -79,18 +79,16 @@ struct pipe_list_entry {
static struct task_entries *task_entries; static struct task_entries *task_entries;
static void task_add_entry(int pid) static struct task_pids {
{ int nr;
int *nr = &task_entries->nr; int arr[];
struct task_entry *e = &task_entries->entries[*nr]; } *task_pids;
(*nr)++;
BUG_ON((*nr) * sizeof(struct task_entry) +
sizeof(struct task_entries) > TASK_ENTRIES_SIZE);
e->pid = pid; static void task_add_pid(int pid)
e->done = 0; {
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; static struct shmem_id *shmem_ids;
...@@ -372,6 +370,11 @@ static int prepare_shared(int ps_fd) ...@@ -372,6 +370,11 @@ static int prepare_shared(int ps_fd)
pr_info("Preparing info about shared resources\n"); 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); shmems = mmap(NULL, SHMEMS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, 0, 0);
if (shmems == MAP_FAILED) { if (shmems == MAP_FAILED) {
pr_perror("Can't map shmem"); pr_perror("Can't map shmem");
...@@ -417,7 +420,9 @@ static int prepare_shared(int ps_fd) ...@@ -417,7 +420,9 @@ static int prepare_shared(int ps_fd)
if (ret < 0) if (ret < 0)
break; 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); 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) ...@@ -1128,12 +1133,7 @@ static int restore_one_zobie(int pid, int exit_code)
pr_info("Restoring zombie with %d code\n", exit_code); pr_info("Restoring zombie with %d code\n", exit_code);
if (task_entries != NULL) { 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_dec(&task_entries->nr_in_progress);
cr_wait_set(&task_entry->done, 1);
cr_wait_while(&task_entries->start, CR_STATE_RESTORE); cr_wait_while(&task_entries->start, CR_STATE_RESTORE);
zombie_prepare_signals(); zombie_prepare_signals();
...@@ -1410,17 +1410,11 @@ static int restore_root_task(int fd, struct cr_options *opts) ...@@ -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); ret = cr_wait_until_greater(&task_entries->nr_in_progress, 0);
if (ret < 0) { if (ret < 0) {
pr_err("Someone can't be restored\n"); pr_err("Someone can't be restored\n");
for (i = 0; i < task_entries->nr; i++) for (i = 0; i < task_pids->nr; i++)
kill(task_entries->entries[i].pid, SIGKILL); kill(task_pids->arr[i], SIGKILL);
return 1; 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->nr_in_progress, task_entries->nr);
cr_wait_set(&task_entries->start, CR_STATE_RESTORE_SIGCHLD); cr_wait_set(&task_entries->start, CR_STATE_RESTORE_SIGCHLD);
cr_wait_until(&task_entries->nr_in_progress, 0); cr_wait_until(&task_entries->nr_in_progress, 0);
......
...@@ -202,16 +202,10 @@ enum { ...@@ -202,16 +202,10 @@ enum {
CR_STATE_COMPLETE CR_STATE_COMPLETE
}; };
struct task_entry {
int pid;
u32 done; // futex
};
struct task_entries { struct task_entries {
int nr; int nr;
u32 nr_in_progress; u32 nr_in_progress;
u32 start; //futex u32 start; //futex
struct task_entry entries[0];
}; };
...@@ -232,16 +226,4 @@ find_shmem_by_pid(struct shmems *shmems, unsigned long start, int pid) ...@@ -232,16 +226,4 @@ find_shmem_by_pid(struct shmems *shmems, unsigned long start, int pid)
return NULL; 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__ */ #endif /* CR_RESTORER_H__ */
...@@ -624,10 +624,7 @@ long restore_task(struct task_restore_core_args *args) ...@@ -624,10 +624,7 @@ long restore_task(struct task_restore_core_args *args)
restore_creds(&args->creds); 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_dec(&args->task_entries->nr_in_progress);
cr_wait_set(&task_entry->done, 1);
write_num(sys_getpid()); write_num(sys_getpid());
write_string_n(": Restored"); 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