Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

criu: move timers dump/restore code into separate file #2356

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions criu/Makefile.crtools
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ obj-y += servicefd.o
obj-y += pie-util-vdso.o
obj-y += vdso.o
obj-y += timens.o
obj-y += timer.o
obj-$(CONFIG_HAS_LIBBPF) += bpfmap.o
obj-$(CONFIG_COMPAT) += pie-util-vdso-elf32.o
CFLAGS_pie-util-vdso-elf32.o += -DCONFIG_VDSO_32
Expand Down
1 change: 1 addition & 0 deletions criu/cr-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#include "pidfd-store.h"
#include "apparmor.h"
#include "asm/dump.h"
#include "timer.h"

/*
* Architectures can overwrite this function to restore register sets that
Expand Down
242 changes: 1 addition & 241 deletions criu/cr-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
#include "restore.h"

#include "cr-errno.h"
#include "timer.h"

#ifndef arch_export_restore_thread
#define arch_export_restore_thread __export_restore_thread
Expand All @@ -118,7 +119,6 @@ static int restore_task_with_children(void *);
static int sigreturn_restore(pid_t pid, struct task_restore_args *ta, unsigned long alen, CoreEntry *core);
static int prepare_restorer_blob(void);
static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core);
static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);

/*
Expand Down Expand Up @@ -882,7 +882,6 @@ static int prepare_proc_misc(pid_t pid, TaskCoreEntry *tc, struct task_restore_a
return 0;
}

static int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core);
static int prepare_mm(pid_t pid, struct task_restore_args *args);

static int restore_one_alive_task(int pid, CoreEntry *core)
Expand Down Expand Up @@ -2719,245 +2718,6 @@ static long restorer_get_vma_hint(struct list_head *tgt_vma_list, struct list_he
return -1;
}

static inline int timeval_valid(struct timeval *tv)
{
return (tv->tv_sec >= 0) && ((unsigned long)tv->tv_usec < USEC_PER_SEC);
}

static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val)
{
if (ie->isec == 0 && ie->iusec == 0) {
memzero_p(val);
return 0;
}

val->it_interval.tv_sec = ie->isec;
val->it_interval.tv_usec = ie->iusec;

if (!timeval_valid(&val->it_interval)) {
pr_err("Invalid timer interval\n");
return -1;
}

if (ie->vsec == 0 && ie->vusec == 0) {
/*
* Remaining time was too short. Set it to
* interval to make the timer armed and work.
*/
val->it_value.tv_sec = ie->isec;
val->it_value.tv_usec = ie->iusec;
} else {
val->it_value.tv_sec = ie->vsec;
val->it_value.tv_usec = ie->vusec;
}

if (!timeval_valid(&val->it_value)) {
pr_err("Invalid timer value\n");
return -1;
}

pr_info("Restored %s timer to %ld.%ld -> %ld.%ld\n", n, val->it_value.tv_sec, val->it_value.tv_usec,
val->it_interval.tv_sec, val->it_interval.tv_usec);

return 0;
}

/*
* Legacy itimers restore from CR_FD_ITIMERS
*/

static int prepare_itimers_from_fd(int pid, struct task_restore_args *args)
{
int ret = -1;
struct cr_img *img;
ItimerEntry *ie;

if (!deprecated_ok("Itimers"))
return -1;

img = open_image(CR_FD_ITIMERS, O_RSTR, pid);
if (!img)
return -1;

ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("real", ie, &args->itimers[0]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;

ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("virt", ie, &args->itimers[1]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;

ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("prof", ie, &args->itimers[2]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
out:
close_image(img);
return ret;
}

static int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core)
{
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);
}

static inline int decode_posix_timer(PosixTimerEntry *pte, struct restore_posix_timer *pt)
{
pt->val.it_interval.tv_sec = pte->isec;
pt->val.it_interval.tv_nsec = pte->insec;

if (!timespec_valid(&pt->val.it_interval)) {
pr_err("Invalid timer interval(posix)\n");
return -1;
}

if (pte->vsec == 0 && pte->vnsec == 0) {
/*
* Remaining time was too short. Set it to
* interval to make the timer armed and work.
*/
pt->val.it_value.tv_sec = pte->isec;
pt->val.it_value.tv_nsec = pte->insec;
} else {
pt->val.it_value.tv_sec = pte->vsec;
pt->val.it_value.tv_nsec = pte->vnsec;
}

if (!timespec_valid(&pt->val.it_value)) {
pr_err("Invalid timer value(posix)\n");
return -1;
}

pt->spt.it_id = pte->it_id;
pt->spt.clock_id = pte->clock_id;
pt->spt.si_signo = pte->si_signo;
pt->spt.it_sigev_notify = pte->it_sigev_notify;
pt->spt.sival_ptr = decode_pointer(pte->sival_ptr);
pt->spt.notify_thread_id = pte->notify_thread_id;
pt->overrun = pte->overrun;

return 0;
}

static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
{
return ((struct restore_posix_timer *)p1)->spt.it_id - ((struct restore_posix_timer *)p2)->spt.it_id;
}

static void sort_posix_timers(struct task_restore_args *ta)
{
void *tmem;

/*
* 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 (ta->posix_timers_n > 0) {
tmem = rst_mem_remap_ptr((unsigned long)ta->posix_timers, RM_PRIVATE);
qsort(tmem, ta->posix_timers_n, 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, struct task_restore_args *ta)
{
struct cr_img *img;
int ret = -1;
struct restore_posix_timer *t;

if (!deprecated_ok("Posix timers"))
return -1;

img = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
if (!img)
return -1;

ta->posix_timers_n = 0;
while (1) {
PosixTimerEntry *pte;

ret = pb_read_one_eof(img, &pte, PB_POSIX_TIMER);
if (ret <= 0)
break;

t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
break;

ret = decode_posix_timer(pte, t);
if (ret < 0)
break;

posix_timer_entry__free_unpacked(pte, NULL);
ta->posix_timers_n++;
}

close_image(img);
if (!ret)
sort_posix_timers(ta);

return ret;
}

static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core)
{
int i, ret = -1;
TaskTimersEntry *tte = core->tc->timers;
struct restore_posix_timer *t;

ta->posix_timers = (struct restore_posix_timer *)rst_mem_align_cpos(RM_PRIVATE);

if (!tte)
return prepare_posix_timers_from_fd(pid, ta);

ta->posix_timers_n = tte->n_posix;
for (i = 0; i < ta->posix_timers_n; 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(ta);
out:
return ret;
}

static int prepare_mm(pid_t pid, struct task_restore_args *args)
{
int exe_fd, i, ret = -1;
Expand Down
5 changes: 0 additions & 5 deletions criu/include/parasite-syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ struct parasite_ctl;
struct parasite_thread_ctl;

extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *);
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *);

struct proc_posix_timers_stat;
extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl,
struct pstree_item *);

extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc);
extern int parasite_dump_creds(struct parasite_ctl *ctl, CredsEntry *ce);
Expand Down
17 changes: 17 additions & 0 deletions criu/include/timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __CR_TIMER_H__
#define __CR_TIMER_H__

#include "images/core.pb-c.h"

struct task_restore_args;
struct pstree_item;
struct parasite_ctl;
struct proc_posix_timers_stat;

extern int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core);
extern int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);

extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *item);
extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl,
struct pstree_item *item);

Check warning on line 16 in criu/include/timer.h

View workflow job for this annotation

GitHub Actions / build

#endif
Loading
Loading