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 {
};
struct str_posix_timer {
int it_id;
long it_id;
int clock_id;
int si_signo;
int it_sigev_notify;
......
......@@ -473,7 +473,7 @@ static int vma_remap(unsigned long src, unsigned long dst, unsigned long len)
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;
timer_t next_id;
......@@ -505,17 +505,22 @@ static int restore_posix_timers(struct task_restore_core_args *args)
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;
}
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.
* This one is very special, we never return there
......@@ -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) {
pr_err("Can't restore posix timers %ld\n", ret);
goto core_restore_end;
......@@ -926,6 +931,8 @@ long __export_restore_task(struct task_restore_core_args *args)
if (itimer_armed(args, 2))
sys_setitimer(ITIMER_PROF, &args->itimers[2], NULL);
restore_posix_timers(args);
ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE);
if (ret < 0) {
ret = ((long)__LINE__ << 16) | ((-ret) & 0xffff);
......
......@@ -1210,7 +1210,7 @@ int parse_posix_timers(pid_t pid, struct proc_posix_timers_stat *args)
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')
goto parse_err_posix;
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