Skip to content

Commit

Permalink
Merge branch 'checkpoint-restore:criu-dev' into sk-inet-ip-transparent
Browse files Browse the repository at this point in the history
  • Loading branch information
juntongdeng committed Apr 1, 2024
2 parents 7c2c8a8 + 00d7cdc commit 168b077
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 422 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2.1
jobs:
test-local-gcc:
machine:
image: ubuntu-2004:202010-01
image: default
working_directory: ~/criu
steps:
- checkout
Expand All @@ -11,7 +11,7 @@ jobs:
command: sudo -E make -C scripts/ci local
test-local-clang:
machine:
image: ubuntu-2004:202010-01
image: default
working_directory: ~/criu
steps:
- checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-22.04]
steps:
- uses: actions/checkout@v2
- name: Run Docker Test (${{ matrix.os }})
Expand Down
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
6 changes: 6 additions & 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 Expand Up @@ -157,6 +158,11 @@ static int dump_sched_info(int pid, ThreadCoreEntry *tc)
tc->has_sched_policy = true;
tc->sched_policy = ret;

/* The reset-on-fork flag might be used in combination
* with SCHED_FIFO or SCHED_RR to reset the scheduling
* policy/priority in child processes.
*/
ret &= ~SCHED_RESET_ON_FORK;
if ((ret == SCHED_RR) || (ret == SCHED_FIFO)) {
ret = syscall(__NR_sched_getparam, pid, &sp);
if (ret < 0) {
Expand Down
244 changes: 2 additions & 242 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 Expand Up @@ -3057,7 +2817,7 @@ static int validate_sched_parm(struct rst_sched_param *sp)
if ((sp->nice < -20) || (sp->nice > 19))
return 0;

switch (sp->policy) {
switch (sp->policy & ~SCHED_RESET_ON_FORK) {
case SCHED_RR:
case SCHED_FIFO:
return ((sp->prio > 0) && (sp->prio < 100));
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);
#endif
2 changes: 1 addition & 1 deletion criu/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ static int premap_priv_vmas(struct pstree_item *t, struct vm_area_list *vmas, vo
do {
if (pr->pe->vaddr + pr->pe->nr_pages * PAGE_SIZE <= vma->e->start)
continue;
if (pr->pe->vaddr > vma->e->end)
if (pr->pe->vaddr >= vma->e->end)
vma->e->status |= VMA_NO_PROT_WRITE;
break;
} while (pr->advance(pr));
Expand Down
Loading

0 comments on commit 168b077

Please sign in to comment.