[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