From: "fu.lin" fu.lin10@huawei.com
In original criu design, SysVIPC memory segment, which belongs to host ipcns, shouldn't be dumped because criu requires the whole ipcns to be dumped. During the restoring ipcns, the new shared memory will be created, and fill the original page data in it.
This patch makes the shared-memory in host ipcns restore possible. Idea: The SysVIPC memory won't disappear after the task exit. The basic information can be got from `/proc/sysvipc/shm` as long as the system doesn't reboot. Compared with restoring the whole ipcns, the processes of the shared memory creating and page data filling are ignored.
Reference: - https://www.criu.org/What_cannot_be_checkpointed
Conflict:NA Reference:https://gitee.com/src-openeuler/criu/pulls/21 Signed-off-by: fu.lin fu.lin10@huawei.com --- criu/cr-dump.c | 9 ++++----- criu/cr-restore.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/criu/cr-dump.c b/criu/cr-dump.c index 2bbcef3..e76fe5a 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -444,12 +444,11 @@ static int dump_filemap(struct vma_area *vma_area, int fd)
static int check_sysvipc_map_dump(pid_t pid, VmaEntry *vma) { - if (root_ns_mask & CLONE_NEWIPC) - return 0; + if (!(root_ns_mask & CLONE_NEWIPC)) + pr_info("Task %d with SysVIPC shmem map @%"PRIx64" lives in host IPC ns\n", + pid, vma->start);
- pr_err("Task %d with SysVIPC shmem map @%"PRIx64" doesn't live in IPC ns\n", - pid, vma->start); - return -1; + return 0; }
static int get_task_auxv(pid_t pid, MmEntry *mm) diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 2ed61d0..ed82524 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -1840,6 +1840,49 @@ static int create_children_and_session(void) return 0; }
+static int prepare_rootns_sysv_shm(unsigned long clone_flags) +{ + int retval = 0; + char *line = NULL; + size_t len = 0; + FILE *fp; + key_t key; + int shmid; + mode_t mode; + size_t size; + + /* This is completed by `prepare_namespace()` */ + if (!!(clone_flags & CLONE_NEWIPC)) + return 0; + + pr_info("Restoring SYSV shm in host namespace\n"); + + fp = fopen("/proc/sysvipc/shm", "r"); + if (fp == NULL) { + pr_err("Can't open '/proc/sysvipc/shm', errno(%d): %s\n", errno, strerror(errno)); + return -1; + } + +#if BITS_PER_LONG <= 32 +# define SIZE_SPEC "%10lu" +#else +# define SIZE_SPEC "%21lu" +#endif + + while (getline(&line, &len, fp) != -1) { + if (sscanf(line, "%10d %10d %4o" SIZE_SPEC, &key, &shmid, &mode, &size) != 4) + continue; + + retval = collect_sysv_shmem(shmid, size); + if (retval != 0) + goto out; + } + +out: + fclose(fp); + return retval; +} + static int restore_task_with_children(void *_arg) { struct cr_clone_arg *ca = _arg; @@ -1947,6 +1990,9 @@ static int restore_task_with_children(void *_arg) if (prepare_namespace(current, ca->clone_flags)) goto err;
+ if (prepare_rootns_sysv_shm(ca->clone_flags)) + goto err; + if (restore_finish_ns_stage(CR_STATE_PREPARE_NAMESPACES, CR_STATE_FORKING) < 0) goto err;