214 lines
6.4 KiB
Diff
214 lines
6.4 KiB
Diff
From 2911f505eefcfaea582d457c1fa18df34d151954 Mon Sep 17 00:00:00 2001
|
|
From: Jingxian He <hejingxian@huawei.com>
|
|
Date: Wed, 19 May 2021 21:33:22 +0800
|
|
Subject: [PATCH 21/72] pid: add pid recover method for criu
|
|
|
|
The default pid recover method cannot recover the task
|
|
pid at every time.
|
|
We add a new pid recover method by setting the fork_pid of
|
|
the parent task struct, add the kernel will alloc pid by
|
|
the fork_pid.
|
|
The new pid recover method can also avoid other tasks using
|
|
the dumping task pids.
|
|
|
|
Signed-off-by: Jingxian He <hejingxian@huawei.com>
|
|
---
|
|
criu/config.c | 1 +
|
|
criu/cr-restore.c | 27 ++++++++++++++++++++++++++-
|
|
criu/crtools.c | 1 +
|
|
criu/include/cr_options.h | 1 +
|
|
criu/include/pin-mem.h | 4 ++++
|
|
criu/include/restorer.h | 1 +
|
|
criu/pie/restorer.c | 25 ++++++++++++++++++++++++-
|
|
7 files changed, 58 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/criu/config.c b/criu/config.c
|
|
index 53a5cfd..6dfbb01 100644
|
|
--- a/criu/config.c
|
|
+++ b/criu/config.c
|
|
@@ -699,6 +699,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
|
|
BOOL_OPT("pin-memory", &opts.pin_memory),
|
|
{ "lsm-mount-context", required_argument, 0, 1099 },
|
|
{ "network-lock", required_argument, 0, 1100 },
|
|
+ BOOL_OPT("use-fork-pid", &opts.use_fork_pid),
|
|
{},
|
|
};
|
|
|
|
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
|
|
index 5514c29..497dd14 100644
|
|
--- a/criu/cr-restore.c
|
|
+++ b/criu/cr-restore.c
|
|
@@ -80,6 +80,7 @@
|
|
#include "timens.h"
|
|
#include "bpfmap.h"
|
|
#include "apparmor.h"
|
|
+#include "pin-mem.h"
|
|
|
|
#include "parasite-syscall.h"
|
|
#include "files-reg.h"
|
|
@@ -1340,6 +1341,23 @@ static int set_next_pid(void *arg)
|
|
return 0;
|
|
}
|
|
|
|
+static int write_fork_pid(int pid)
|
|
+{
|
|
+ int fd, ret;
|
|
+
|
|
+ fd = open(PIN_MEM_FILE, O_RDWR);
|
|
+ if (fd < 0) {
|
|
+ pr_warn("error open file: %s\n", PIN_MEM_FILE);
|
|
+ return -1;
|
|
+ }
|
|
+ ret = ioctl(fd, SET_FORK_PID, &pid);
|
|
+ if (ret < 0) {
|
|
+ pr_warn("write fork pid fail, errno: %s\n", strerror(errno));
|
|
+ }
|
|
+ close(fd);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static inline int fork_with_pid(struct pstree_item *item)
|
|
{
|
|
struct cr_clone_arg ca;
|
|
@@ -1424,7 +1442,7 @@ static inline int fork_with_pid(struct pstree_item *item)
|
|
if (!(ca.clone_flags & CLONE_NEWPID)) {
|
|
lock_last_pid();
|
|
|
|
- if (!kdat.has_clone3_set_tid) {
|
|
+ if (!kdat.has_clone3_set_tid && !opts.use_fork_pid) {
|
|
if (external_pidns) {
|
|
/*
|
|
* Restoring into another namespace requires a helper
|
|
@@ -1434,6 +1452,12 @@ static inline int fork_with_pid(struct pstree_item *item)
|
|
*/
|
|
ret = call_in_child_process(set_next_pid, (void *)&pid);
|
|
} else {
|
|
+ if (opts.use_fork_pid) {
|
|
+ ret = write_fork_pid(pid);
|
|
+ if (ret < 0)
|
|
+ goto err_unlock;
|
|
+ }
|
|
+
|
|
ret = set_next_pid((void *)&pid);
|
|
}
|
|
if (ret != 0) {
|
|
@@ -3886,6 +3910,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
|
|
task_args->thread_args);
|
|
|
|
task_args->pin_memory = opts.pin_memory;
|
|
+ task_args->use_fork_pid = opts.use_fork_pid;
|
|
|
|
/*
|
|
* An indirect call to task_restore, note it never returns
|
|
diff --git a/criu/crtools.c b/criu/crtools.c
|
|
index 1b90481..502acdf 100644
|
|
--- a/criu/crtools.c
|
|
+++ b/criu/crtools.c
|
|
@@ -448,6 +448,7 @@ usage:
|
|
" --with-cpu-affinity Allow to restore cpu affinity. Only for hosts with\n"
|
|
" same cpu quantity.\n"
|
|
" --pin-memory Use pin memory method for checkpoint and restore.\n"
|
|
+ " --use-fork-pid Allow to restore task pid by setting fork pid of task struct.\n"
|
|
"\n"
|
|
"Check options:\n"
|
|
" Without options, \"criu check\" checks availability of absolutely required\n"
|
|
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
|
|
index 61898fd..923cc5f 100644
|
|
--- a/criu/include/cr_options.h
|
|
+++ b/criu/include/cr_options.h
|
|
@@ -191,6 +191,7 @@ struct cr_options {
|
|
/* restore cpu affinity */
|
|
int with_cpu_affinity;
|
|
int pin_memory;
|
|
+ int use_fork_pid;
|
|
};
|
|
|
|
extern struct cr_options opts;
|
|
diff --git a/criu/include/pin-mem.h b/criu/include/pin-mem.h
|
|
index 7e53b12..2b54996 100644
|
|
--- a/criu/include/pin-mem.h
|
|
+++ b/criu/include/pin-mem.h
|
|
@@ -6,6 +6,7 @@
|
|
#include "vma.pb-c.h"
|
|
|
|
#if __has_include("linux/pin_memory.h")
|
|
+# define CONFIG_PID_RESERVE
|
|
# include <linux/pin_memory.h>
|
|
#else
|
|
|
|
@@ -35,6 +36,9 @@ struct pin_mem_area_set {
|
|
struct _pin_mem_area mem_area[MAX_PIN_MEM_AREA_NUM];
|
|
};
|
|
|
|
+#define _SET_FORK_PID 8
|
|
+#define SET_FORK_PID _IOW(PIN_MEM_MAGIC, _SET_FORK_PID, int)
|
|
+
|
|
#endif /* __has_include("linux/pin_memory.h") */
|
|
|
|
#define PIN_MEM_FILE "/dev/pinmem"
|
|
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
|
|
index e0bdc04..93f87f4 100644
|
|
--- a/criu/include/restorer.h
|
|
+++ b/criu/include/restorer.h
|
|
@@ -233,6 +233,7 @@ struct task_restore_args {
|
|
int child_subreaper;
|
|
bool has_clone3_set_tid;
|
|
bool pin_memory;
|
|
+ bool use_fork_pid;
|
|
} __aligned(64);
|
|
|
|
/*
|
|
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
|
|
index db01ba5..1317582 100644
|
|
--- a/criu/pie/restorer.c
|
|
+++ b/criu/pie/restorer.c
|
|
@@ -1426,6 +1426,22 @@ int remap_vmas(int pid)
|
|
return ret;
|
|
}
|
|
|
|
+int write_fork_pid(int pid)
|
|
+{
|
|
+ int fd, ret;
|
|
+
|
|
+ fd = sys_open(PIN_MEM_FILE, O_RDWR, 0);
|
|
+ if (fd < 0) {
|
|
+ pr_warn("error open file: %s\n", PIN_MEM_FILE);
|
|
+ return -1;
|
|
+ }
|
|
+ ret = sys_ioctl(fd, SET_FORK_PID, (unsigned long) &pid);
|
|
+ if (ret < 0) {
|
|
+ pr_warn("write fork pid fail fail: %d\n", pid);
|
|
+ }
|
|
+ sys_close(fd);
|
|
+ return ret;
|
|
+}
|
|
|
|
/*
|
|
* The main routine to restore task via sigreturn.
|
|
@@ -1815,7 +1831,7 @@ long __export_restore_task(struct task_restore_args *args)
|
|
long parent_tid;
|
|
int i, fd = -1;
|
|
|
|
- if (!args->has_clone3_set_tid) {
|
|
+ if (!args->has_clone3_set_tid && !args->use_fork_pid) {
|
|
/* One level pid ns hierarhy */
|
|
fd = sys_openat(args->proc_fd, LAST_PID_PATH, O_RDWR, 0);
|
|
if (fd < 0) {
|
|
@@ -1847,6 +1863,13 @@ long __export_restore_task(struct task_restore_args *args)
|
|
pr_debug("Using clone3 to restore the process\n");
|
|
RUN_CLONE3_RESTORE_FN(ret, c_args, sizeof(c_args), &thread_args[i],
|
|
args->clone_restore_fn);
|
|
+ } else if (args->use_fork_pid) {
|
|
+ if (write_fork_pid(thread_args[i].pid) < 0) {
|
|
+ pr_err("Clone fail with fork pid\n");
|
|
+ mutex_unlock(&task_entries_local->last_pid_mutex);
|
|
+ goto core_restore_end;
|
|
+ }
|
|
+ RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, thread_args, args->clone_restore_fn);
|
|
} else {
|
|
last_pid_len =
|
|
std_vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid - 1, &s);
|
|
--
|
|
2.34.1
|
|
|