Commit f8464fda authored by Pavel Emelyanov's avatar Pavel Emelyanov

timers: Split posix timers restore into two stages

1st stage is -- creating the timers. It may fail if kernel
allocated IDs in a manner we don't expect or runs out of
memory.

2nd stage is -- arm the timers. It cannot fail, since we've
validated the timespecs in advance and should happen after
we've waited for all the other tasks to complete the restore.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b62df5c9
...@@ -64,7 +64,7 @@ struct rst_sched_param { ...@@ -64,7 +64,7 @@ struct rst_sched_param {
}; };
struct str_posix_timer { struct str_posix_timer {
int it_id; long it_id;
int clock_id; int clock_id;
int si_signo; int si_signo;
int it_sigev_notify; int it_sigev_notify;
......
...@@ -473,7 +473,7 @@ static int vma_remap(unsigned long src, unsigned long dst, unsigned long len) ...@@ -473,7 +473,7 @@ static int vma_remap(unsigned long src, unsigned long dst, unsigned long len)
return 0; return 0;
} }
static int restore_posix_timers(struct task_restore_core_args *args) static int create_posix_timers(struct task_restore_core_args *args)
{ {
int ret, i; int ret, i;
timer_t next_id; timer_t next_id;
...@@ -505,17 +505,22 @@ static int restore_posix_timers(struct task_restore_core_args *args) ...@@ -505,17 +505,22 @@ static int restore_posix_timers(struct task_restore_core_args *args)
return -1; return -1;
} }
} }
ret = sys_timer_settime(next_id, 0, &args->posix_timers[i].val, NULL);
if (ret < 0) {
pr_err("Can't set posix timer %lx\n", (long) next_id);
return ret;
}
} }
return 0; return 0;
} }
static void restore_posix_timers(struct task_restore_core_args *args)
{
int i;
struct restore_posix_timer *rt;
for (i = 0; i < args->timer_n; i++) {
rt = &args->posix_timers[i];
sys_timer_settime((timer_t)rt->spt.it_id, 0, &rt->val, NULL);
}
}
/* /*
* The main routine to restore task via sigreturn. * The main routine to restore task via sigreturn.
* This one is very special, we never return there * This one is very special, we never return there
...@@ -882,7 +887,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -882,7 +887,7 @@ long __export_restore_task(struct task_restore_core_args *args)
} }
} }
ret = restore_posix_timers(args); ret = create_posix_timers(args);
if (ret < 0) { if (ret < 0) {
pr_err("Can't restore posix timers %ld\n", ret); pr_err("Can't restore posix timers %ld\n", ret);
goto core_restore_end; goto core_restore_end;
...@@ -926,6 +931,8 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -926,6 +931,8 @@ long __export_restore_task(struct task_restore_core_args *args)
if (itimer_armed(args, 2)) if (itimer_armed(args, 2))
sys_setitimer(ITIMER_PROF, &args->itimers[2], NULL); sys_setitimer(ITIMER_PROF, &args->itimers[2], NULL);
restore_posix_timers(args);
ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE); ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE);
if (ret < 0) { if (ret < 0) {
ret = ((long)__LINE__ << 16) | ((-ret) & 0xffff); ret = ((long)__LINE__ << 16) | ((-ret) & 0xffff);
......
...@@ -1210,7 +1210,7 @@ int parse_posix_timers(pid_t pid, struct proc_posix_timers_stat *args) ...@@ -1210,7 +1210,7 @@ int parse_posix_timers(pid_t pid, struct proc_posix_timers_stat *args)
timer = xzalloc(sizeof(struct proc_posix_timer)); timer = xzalloc(sizeof(struct proc_posix_timer));
ret = sscanf(line1, "%s %d", str_name, &timer->spt.it_id); ret = sscanf(line1, "%s %ld", str_name, &timer->spt.it_id);
if (ret != 2 || str_name[0] != 'I') if (ret != 2 || str_name[0] != 'I')
goto parse_err_posix; goto parse_err_posix;
ret = sscanf(line2, "%s %d%s", str_name, &timer->spt.si_signo, siginfo_tmp); ret = sscanf(line2, "%s %d%s", str_name, &timer->spt.si_signo, siginfo_tmp);
......
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