[CRIU] [PATCH 28/78] infect: Move parasite_map_exchange() into infect.c
Cyrill Gorcunov
gorcunov at openvz.org
Mon Nov 7 08:36:13 PST 2016
From: Pavel Emelyanov <xemul at virtuozzo.com>
Note -- this will go away from compel API with cr-exec.c
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/cr-exec.c | 2 +-
criu/include/infect-priv.h | 5 ++
criu/include/parasite-syscall.h | 1 -
criu/infect.c | 128 ++++++++++++++++++++++++++++++++++++++--
criu/parasite-syscall.c | 126 ---------------------------------------
5 files changed, 130 insertions(+), 132 deletions(-)
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index bec423d53a5c..742e5f35be70 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -59,7 +59,7 @@ static int execute_syscall(struct parasite_ctl *ctl,
int len;
if (!r_mem) {
- err = parasite_map_exchange(ctl, PAGE_SIZE);
+ err = compel_map_exchange(ctl, PAGE_SIZE);
if (err)
return err;
diff --git a/criu/include/infect-priv.h b/criu/include/infect-priv.h
index a461ffa2ce9f..fe8e22d111b9 100644
--- a/criu/include/infect-priv.h
+++ b/criu/include/infect-priv.h
@@ -32,4 +32,9 @@ struct parasite_ctl {
int tsock; /* transport socket for transferring fds */
};
+#define MEMFD_FNAME "CRIUMFD"
+#define MEMFD_FNAME_SZ sizeof(MEMFD_FNAME)
+
+/* XXX -- remove with cr-exec.c */
+extern int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size);
#endif
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index d21d0862a96c..f05bb74098cf 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -85,7 +85,6 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
struct vm_area_list *vma_area_list);
extern void parasite_ensure_args_size(unsigned long sz);
extern unsigned long get_exec_start(struct vm_area_list *);
-extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
extern int parasite_dump_cgroup(struct parasite_ctl *ctl, struct parasite_dump_cgroup_args *cgroup);
diff --git a/criu/infect.c b/criu/infect.c
index b16453a835af..0237fd8a93f7 100644
--- a/criu/infect.c
+++ b/criu/infect.c
@@ -20,9 +20,6 @@
#include "infect.h"
#include "infect-priv.h"
-#define MEMFD_FNAME "CRIUMFD"
-#define MEMFD_FNAME_SZ sizeof(MEMFD_FNAME)
-
/* XXX will be removed soon */
extern int parasite_wait_ack(int sockfd, unsigned int cmd, struct ctl_msg *m);
@@ -569,6 +566,129 @@ static int parasite_start_daemon(struct parasite_ctl *ctl)
return 0;
}
+static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
+{
+ int fd;
+
+ ctl->remote_map = mmap_seized(ctl, NULL, size,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+ if (!ctl->remote_map) {
+ pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->rpid);
+ return -1;
+ }
+
+ ctl->map_length = round_up(size, page_size());
+
+ fd = open_proc_rw(ctl->rpid, "map_files/%p-%p",
+ ctl->remote_map, ctl->remote_map + ctl->map_length);
+ if (fd < 0)
+ return -1;
+
+ ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_FILE, fd, 0);
+ close(fd);
+
+ if (ctl->local_map == MAP_FAILED) {
+ ctl->local_map = NULL;
+ pr_perror("Can't map remote parasite map");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
+{
+ void *where = (void *)ctl->ictx.syscall_ip + BUILTIN_SYSCALL_SIZE;
+ u8 orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
+ pid_t pid = ctl->rpid;
+ unsigned long sret = -ENOSYS;
+ int ret, fd, lfd;
+ bool __maybe_unused compat_task = !seized_native(ctl);
+
+ if (ctl->ictx.flags & INFECT_NO_MEMFD)
+ return 1;
+
+ BUILD_BUG_ON(sizeof(orig_code) < sizeof(long));
+
+ if (ptrace_swap_area(pid, where, (void *)orig_code, sizeof(orig_code))) {
+ pr_err("Can't inject memfd args (pid: %d)\n", pid);
+ return -1;
+ }
+
+ ret = syscall_seized(ctl, __NR(memfd_create, compat_task), &sret,
+ (unsigned long)where, 0, 0, 0, 0, 0);
+
+ if (ptrace_poke_area(pid, orig_code, where, sizeof(orig_code))) {
+ fd = (int)(long)sret;
+ if (fd >= 0)
+ syscall_seized(ctl, __NR(close, compat_task), &sret,
+ fd, 0, 0, 0, 0, 0);
+ pr_err("Can't restore memfd args (pid: %d)\n", pid);
+ return -1;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ fd = (int)(long)sret;
+ if (fd == -ENOSYS)
+ return 1;
+ if (fd < 0)
+ return fd;
+
+ ctl->map_length = round_up(size, page_size());
+ lfd = open_proc_rw(ctl->rpid, "fd/%d", fd);
+ if (lfd < 0)
+ goto err_cure;
+
+ if (ftruncate(lfd, ctl->map_length) < 0) {
+ pr_perror("Fail to truncate memfd for parasite");
+ goto err_cure;
+ }
+
+ ctl->remote_map = mmap_seized(ctl, NULL, size,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FILE | MAP_SHARED, fd, 0);
+ if (!ctl->remote_map) {
+ pr_err("Can't rmap memfd for parasite blob\n");
+ goto err_curef;
+ }
+
+ ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_FILE, lfd, 0);
+ if (ctl->local_map == MAP_FAILED) {
+ ctl->local_map = NULL;
+ pr_perror("Can't lmap memfd for parasite blob");
+ goto err_curef;
+ }
+
+ syscall_seized(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
+ close(lfd);
+
+ pr_info("Set up parasite blob using memfd\n");
+ return 0;
+
+err_curef:
+ close(lfd);
+err_cure:
+ syscall_seized(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
+ return -1;
+}
+
+int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size)
+{
+ int ret;
+
+ ret = parasite_memfd_exchange(ctl, size);
+ if (ret == 1) {
+ pr_info("MemFD parasite doesn't work, goto legacy mmap\n");
+ ret = parasite_mmap_exchange(ctl, size);
+ }
+ return ret;
+}
+
#define init_parasite_ctl(ctl, blob_type) \
do { \
memcpy(ctl->local_map, parasite_##blob_type##_blob, \
@@ -614,7 +734,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
if (nr_threads > 1)
map_exchange_size += PARASITE_STACK_SIZE;
- ret = parasite_map_exchange(ctl, map_exchange_size);
+ ret = compel_map_exchange(ctl, map_exchange_size);
if (ret)
goto err;
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index b961e09f6503..c40e60abd045 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -44,9 +44,6 @@
#include "infect.h"
#include "infect-priv.h"
-#define MEMFD_FNAME "CRIUMFD"
-#define MEMFD_FNAME_SZ sizeof(MEMFD_FNAME)
-
unsigned long get_exec_start(struct vm_area_list *vmas)
{
struct vma_area *vma_area;
@@ -726,129 +723,6 @@ goon:
return 0;
}
-static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
-{
- int fd;
-
- ctl->remote_map = mmap_seized(ctl, NULL, size,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_ANONYMOUS | MAP_SHARED, -1, 0);
- if (!ctl->remote_map) {
- pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->rpid);
- return -1;
- }
-
- ctl->map_length = round_up(size, page_size());
-
- fd = open_proc_rw(ctl->rpid, "map_files/%p-%p",
- ctl->remote_map, ctl->remote_map + ctl->map_length);
- if (fd < 0)
- return -1;
-
- ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_FILE, fd, 0);
- close(fd);
-
- if (ctl->local_map == MAP_FAILED) {
- ctl->local_map = NULL;
- pr_perror("Can't map remote parasite map");
- return -1;
- }
-
- return 0;
-}
-
-static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
-{
- void *where = (void *)ctl->ictx.syscall_ip + BUILTIN_SYSCALL_SIZE;
- u8 orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
- pid_t pid = ctl->rpid;
- unsigned long sret = -ENOSYS;
- int ret, fd, lfd;
- bool __maybe_unused compat_task = !seized_native(ctl);
-
- if (ctl->ictx.flags & INFECT_NO_MEMFD)
- return 1;
-
- BUILD_BUG_ON(sizeof(orig_code) < sizeof(long));
-
- if (ptrace_swap_area(pid, where, (void *)orig_code, sizeof(orig_code))) {
- pr_err("Can't inject memfd args (pid: %d)\n", pid);
- return -1;
- }
-
- ret = syscall_seized(ctl, __NR(memfd_create, compat_task), &sret,
- (unsigned long)where, 0, 0, 0, 0, 0);
-
- if (ptrace_poke_area(pid, orig_code, where, sizeof(orig_code))) {
- fd = (int)(long)sret;
- if (fd >= 0)
- syscall_seized(ctl, __NR(close, compat_task), &sret,
- fd, 0, 0, 0, 0, 0);
- pr_err("Can't restore memfd args (pid: %d)\n", pid);
- return -1;
- }
-
- if (ret < 0)
- return ret;
-
- fd = (int)(long)sret;
- if (fd == -ENOSYS)
- return 1;
- if (fd < 0)
- return fd;
-
- ctl->map_length = round_up(size, page_size());
- lfd = open_proc_rw(ctl->rpid, "fd/%d", fd);
- if (lfd < 0)
- goto err_cure;
-
- if (ftruncate(lfd, ctl->map_length) < 0) {
- pr_perror("Fail to truncate memfd for parasite");
- goto err_cure;
- }
-
- ctl->remote_map = mmap_seized(ctl, NULL, size,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FILE | MAP_SHARED, fd, 0);
- if (!ctl->remote_map) {
- pr_err("Can't rmap memfd for parasite blob\n");
- goto err_curef;
- }
-
- ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_FILE, lfd, 0);
- if (ctl->local_map == MAP_FAILED) {
- ctl->local_map = NULL;
- pr_perror("Can't lmap memfd for parasite blob");
- goto err_curef;
- }
-
- syscall_seized(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
- close(lfd);
-
- pr_info("Set up parasite blob using memfd\n");
- return 0;
-
-err_curef:
- close(lfd);
-err_cure:
- syscall_seized(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
- return -1;
-}
-
-int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size)
-{
- int ret;
-
- ret = parasite_memfd_exchange(ctl, size);
- if (ret == 1) {
- pr_info("MemFD parasite doesn't work, goto legacy mmap\n");
- ret = parasite_mmap_exchange(ctl, size);
- }
- return ret;
-}
-
int parasite_dump_cgroup(struct parasite_ctl *ctl, struct parasite_dump_cgroup_args *cgroup)
{
int ret;
--
2.7.4
More information about the CRIU
mailing list