[CRIU] [PATCH 5/7] parasite: Split infecting routine into parts
Pavel Emelyanov
xemul at parallels.com
Mon Dec 17 15:30:58 EST 2012
The fist part prepares ctl to controll the seized task.
The 2nd one mmaps shareb buffer for data exchange.
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
include/parasite-syscall.h | 2 +
parasite-syscall.c | 57 ++++++++++++++++++++++++++++++-------------
2 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 4ef6ed9..c578792 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -52,6 +52,8 @@ extern int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *it
extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
struct pstree_item *item,
struct list_head *vma_area_list);
+extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_list);
+extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd);
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 7375afd..6c1492b 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -776,11 +776,10 @@ int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *item)
return ret;
}
-struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list)
+struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_list)
{
struct parasite_ctl *ctl = NULL;
struct vma_area *vma_area;
- int ret, fd;
/*
* Control block early setup.
@@ -822,26 +821,31 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
goto err;
}
- /*
- * Inject a parasite engine. Ie allocate memory inside alien
- * space and copy engine code there. Then re-map the engine
- * locally, so we will get an easy way to access engine memory
- * without using ptrace at all.
- */
+ return ctl;
+
+err:
+ xfree(ctl);
+ return NULL;
+}
+
+int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size)
+{
+ int fd;
+
ctl->remote_map = mmap_seized(ctl, NULL, (size_t)parasite_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", pid);
- goto err_restore;
+ pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->pid);
+ return -1;
}
ctl->map_length = round_up(parasite_size, PAGE_SIZE);
- fd = open_proc_rw(pid, "map_files/%p-%p",
+ fd = open_proc_rw(ctl->pid, "map_files/%p-%p",
ctl->remote_map, ctl->remote_map + ctl->map_length);
if (fd < 0)
- goto err_restore;
+ return -1;
ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FILE, fd, 0);
@@ -850,9 +854,32 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
if (ctl->local_map == MAP_FAILED) {
ctl->local_map = NULL;
pr_perror("Can't map remote parasite map");
- goto err_restore;
+ return -1;
}
+ return 0;
+}
+
+struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list)
+{
+ int ret;
+ struct parasite_ctl *ctl;
+
+ ctl = parasite_prep_ctl(pid, vma_area_list);
+ if (!ctl)
+ return NULL;
+
+ /*
+ * Inject a parasite engine. Ie allocate memory inside alien
+ * space and copy engine code there. Then re-map the engine
+ * locally, so we will get an easy way to access engine memory
+ * without using ptrace at all.
+ */
+
+ ret = parasite_map_exchange(ctl, parasite_size);
+ if (ret)
+ goto err_restore;
+
pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
memcpy(ctl->local_map, parasite_blob, sizeof(parasite_blob));
@@ -884,10 +911,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
err_restore:
parasite_cure_seized(ctl, item);
return NULL;
-
-err:
- xfree(ctl);
- return NULL;
}
#else /* CONFIG_X86_64 */
--
1.7.1
More information about the CRIU
mailing list