- cr-dump.c: call rmfork_dump_mm_iov for kernel-side page dump - cr-restore.c: pass rmfork_meta_off to restorer task args - config.c: fix BOOL_OPT cast for skip_pages/enable_rmfork - restorer.h: add enable_rmfork and rmfork_meta_off fields - mem.c: skip page restore in prepare_mappings for rmfork - rseq.h: fix double-include guard - tty.c: const-correctness fix for strrchr result Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --- criu/config.c | 4 ++-- criu/cr-dump.c | 10 ++++++---- criu/cr-restore.c | 11 ++++++----- criu/include/linux/rseq.h | 2 +- criu/include/restorer.h | 3 +++ criu/mem.c | 5 +++++ criu/tty.c | 2 +- 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/criu/config.c b/criu/config.c index 007ee127b..fa428e0d9 100644 --- a/criu/config.c +++ b/criu/config.c @@ -671,8 +671,8 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd, { "external", required_argument, 0, 1073 }, { "empty-ns", required_argument, 0, 1074 }, { "lazy-pages", no_argument, 0, 1076 }, - BOOL_OPT("skip-pages", &opts.skip_pages), - BOOL_OPT("enable-rmfork", &opts.enable_rmfork), + BOOL_OPT("skip-pages", (int *)&opts.skip_pages), + BOOL_OPT("enable-rmfork", (int *)&opts.enable_rmfork), BOOL_OPT("extra", &opts.check_extra_features), BOOL_OPT("experimental", &opts.check_experimental_features), { "all", no_argument, 0, 1079 }, diff --git a/criu/cr-dump.c b/criu/cr-dump.c index 57cb129aa..4be2a9115 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -1696,10 +1696,12 @@ static int dump_one_task(struct pstree_item *item, InventoryEntry *parent_ie) if (opts.enable_rmfork) { pr_info("rmfork: dumping pages via kernel for pid=%d\n", pid); - ret = rmfork_dump_mm_iov(pid, vpid(item), NULL, 0); - if (ret < 0) { - pr_err("rmfork: kernel dump failed for pid=%d\n", pid); - goto err_cure; + { + long rm_ret = rmfork_dump_mm_iov(pid, vpid(item), NULL, 0); + if (rm_ret < 0) { + pr_err("rmfork: kernel dump failed for pid=%d\n", pid); + goto err_cure; + } } } else { ret = parasite_dump_pages_seized(item, &vmas, &mdc, parasite_ctl); diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 691595ff7..72046efa7 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -707,13 +707,14 @@ static int restore_one_alive_task(int pid, CoreEntry *core) return -1; /* - * RMFork: restore memory from kernel ubmem instead of pages.img. - * Must be called after VMAs are set up, before normal pages restore. + * RMFork: pass meta offset to restorer blob so it can call + * the kernel rmfork syscall instead of reading pages.img. */ if (opts.enable_rmfork) { - pid_t my_pid = getpid(); - if (rmfork_restore_iov(my_pid, 0, NULL, 0) < 0) { - pr_err("rmfork: kernel restore failed for pid=%d\n", my_pid); + ta->enable_rmfork = true; + ta->rmfork_meta_off = rmfork_get_meta_off(); + if (ta->rmfork_meta_off == 0) { + pr_err("rmfork: no meta offset available for restore\n"); return -1; } } diff --git a/criu/include/linux/rseq.h b/criu/include/linux/rseq.h index 5ceefbf8e..668967f98 100644 --- a/criu/include/linux/rseq.h +++ b/criu/include/linux/rseq.h @@ -14,7 +14,7 @@ #include "common/config.h" -#ifdef CONFIG_HAS_NO_LIBC_RSEQ_DEFS +#if defined(CONFIG_HAS_NO_LIBC_RSEQ_DEFS) && !defined(_LINUX_RSEQ_H) /* * linux/rseq.h * diff --git a/criu/include/restorer.h b/criu/include/restorer.h index 56bea0fcc..a6290724a 100644 --- a/criu/include/restorer.h +++ b/criu/include/restorer.h @@ -168,6 +168,9 @@ struct task_restore_args { struct restore_vma_io *vma_ios; unsigned int vma_ios_n; + bool enable_rmfork; + unsigned long rmfork_meta_off; + struct restore_posix_timer *posix_timers; unsigned int posix_timers_n; bool posix_timer_cr_ids; diff --git a/criu/mem.c b/criu/mem.c index b06a0d850..07425b501 100644 --- a/criu/mem.c +++ b/criu/mem.c @@ -1352,6 +1352,10 @@ int prepare_mappings(struct pstree_item *t) rsti(t)->premmapped_addr = addr; rsti(t)->premmapped_len = vmas->rst_priv_size; + /* RMFork: memory restored by kernel via rmfork syscall */ + if (opts.enable_rmfork) + goto skip_page_restore; + ret = open_page_read(vpid(t), &pr, PR_TASK); if (ret <= 0) return -1; @@ -1393,6 +1397,7 @@ int prepare_mappings(struct pstree_item *t) pr_info("Shrunk premap area to %p(%lx)\n", rsti(t)->premmapped_addr, rsti(t)->premmapped_len); } +skip_page_restore: out: return ret; } diff --git a/criu/tty.c b/criu/tty.c index ae23094b7..9a4520d53 100644 --- a/criu/tty.c +++ b/criu/tty.c @@ -259,7 +259,7 @@ static int pts_fd_get_index(int fd, const struct fd_parms *p) { int index; const struct fd_link *link = p->link; - char *pos = strrchr(link->name, '/'); + const char *pos = strrchr(link->name, '/'); if (!pos || pos == (link->name + link->len - 1)) { pr_err("Unexpected format on path %s\n", link->name + 1); -- 2.53.0