From 35e560de00a244760743f34785735a6e20cf32b7 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 15 Apr 2014 21:59:55 +0400 Subject: [PATCH] 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 --- cr-restore.c | 108 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 38 deletions(-) diff --git a/cr-restore.c b/cr-restore.c index 76b4995f2..c6fa804e6 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -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) &&