timers: Reshuffle new and legacy restoration code

Make explicit checks and helpers for legacy images.
This should facilitate its removal some day in the
future.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Pavel Emelyanov 2014-04-15 21:59:55 +04:00
parent 87da9b83ce
commit 35e560de00

View file

@ -1733,21 +1733,15 @@ static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val)
return 0;
}
static int prepare_itimers(int pid, CoreEntry *core, struct task_restore_args *args)
/*
* Legacy itimers restore from CR_FD_ITIMERS
*/
static int prepare_itimers_from_fd(int pid, struct task_restore_args *args)
{
int fd, ret = -1;
ItimerEntry *ie;
if (core->tc->timers) {
TaskTimersEntry *tte = core->tc->timers;
ret = decode_itimer("real", tte->real, &args->itimers[0]);
ret |= decode_itimer("virt", tte->virt, &args->itimers[1]);
ret |= decode_itimer("prof", tte->prof, &args->itimers[2]);
return ret;
}
fd = open_image(CR_FD_ITIMERS, O_RSTR, pid);
if (fd < 0)
return fd;
@ -1780,6 +1774,21 @@ out:
return ret;
}
static int prepare_itimers(int pid, CoreEntry *core, struct task_restore_args *args)
{
int ret = 0;
TaskTimersEntry *tte = core->tc->timers;
if (!tte)
return prepare_itimers_from_fd(pid, args);
ret |= decode_itimer("real", tte->real, &args->itimers[0]);
ret |= decode_itimer("virt", tte->virt, &args->itimers[1]);
ret |= decode_itimer("prof", tte->prof, &args->itimers[2]);
return ret;
}
static inline int timespec_valid(struct timespec *ts)
{
return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC);
@ -1829,32 +1838,32 @@ static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
static unsigned long posix_timers_cpos;
static unsigned int posix_timers_nr;
static int prepare_posix_timers(int pid, CoreEntry *core)
static void sort_posix_timers(void)
{
/*
* This is required for restorer's create_posix_timers(),
* it will probe them one-by-one for the desired ID, since
* kernel doesn't provide another API for timer creation
* with given ID.
*/
if (posix_timers_nr > 0)
qsort(rst_mem_remap_ptr(posix_timers_cpos, RM_PRIVATE),
posix_timers_nr,
sizeof(struct restore_posix_timer),
cmp_posix_timer_proc_id);
}
/*
* Legacy posix timers restoration from CR_FD_POSIX_TIMERS
*/
static int prepare_posix_timers_from_fd(int pid)
{
int fd = -1;
int ret = -1;
struct restore_posix_timer *t;
posix_timers_cpos = rst_mem_cpos(RM_PRIVATE);
if (core->tc->timers) {
int i;
TaskTimersEntry *tte = core->tc->timers;
posix_timers_nr = tte->n_posix;
for (i = 0; i < posix_timers_nr; i++) {
t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
goto out;
if (decode_posix_timer(tte->posix[i], t))
goto out;
}
ret = 0;
goto out;
}
fd = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
if (fd < 0) {
if (errno == ENOENT) /* backward compatibility */
@ -1883,16 +1892,39 @@ static int prepare_posix_timers(int pid, CoreEntry *core)
}
close_safe(&fd);
out:
if (posix_timers_nr > 0)
qsort(rst_mem_remap_ptr(posix_timers_cpos, RM_PRIVATE),
posix_timers_nr,
sizeof(struct restore_posix_timer),
cmp_posix_timer_proc_id);
if (!ret)
sort_posix_timers();
return ret;
}
static int prepare_posix_timers(int pid, CoreEntry *core)
{
int i, ret = -1;
TaskTimersEntry *tte = core->tc->timers;
struct restore_posix_timer *t;
posix_timers_cpos = rst_mem_cpos(RM_PRIVATE);
if (!tte)
return prepare_posix_timers_from_fd(pid);
posix_timers_nr = tte->n_posix;
for (i = 0; i < posix_timers_nr; i++) {
t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
goto out;
if (decode_posix_timer(tte->posix[i], t))
goto out;
}
ret = 0;
sort_posix_timers();
out:
return ret;
}
static inline int verify_cap_size(CredsEntry *ce)
{
return ((ce->n_cap_inh == CR_CAP_SIZE) && (ce->n_cap_eff == CR_CAP_SIZE) &&