[CRIU] [PATCH 13/15] parasite: unmap itself (v2)

Andrey Vagin avagin at openvz.org
Mon Sep 23 06:33:36 EDT 2013


This patch adds a new parasite command, which unmaps the parasite blob.
This command never returns and the criu process traps the target process
on the exit from the munmap syscall.

v2: rename the function for unmaping a parasite blob to not intersects
with criu's functions.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 include/parasite.h |  6 ++++++
 parasite-syscall.c | 19 ++++++++-----------
 pie/parasite.c     | 16 ++++++++++++++++
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/include/parasite.h b/include/parasite.h
index e9672ac..4e26967 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -25,6 +25,7 @@ enum {
 
 	PARASITE_CMD_INIT_DAEMON,
 	PARASITE_CMD_DUMP_THREAD,
+	PARASITE_CMD_UNMAP,
 
 	/*
 	 * These two must be greater than INITs.
@@ -70,6 +71,11 @@ struct parasite_init_args {
 	struct rt_sigframe	*sigframe;
 };
 
+struct parasite_unmap_args {
+	void			*parasite_start;
+	unsigned long		parasite_len;
+};
+
 struct parasite_vma_entry
 {
 	unsigned long	start;
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 48d0785..40a9167 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -307,14 +307,6 @@ int parasite_execute_daemon(unsigned int cmd, struct parasite_ctl *ctl)
 	return ret;
 }
 
-static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
-{
-	unsigned long x;
-
-	return syscall_seized(ctl, __NR_munmap, &x,
-			(unsigned long)addr, length, 0, 0, 0, 0);
-}
-
 static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
 {
 	int sun_len;
@@ -850,10 +842,15 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
 	close_safe(&ctl->tsock);
 
 	if (ctl->remote_map) {
-		if (munmap_seized(ctl, (void *)ctl->remote_map, ctl->map_length)) {
-			pr_err("munmap_seized failed (pid: %d)\n", ctl->pid.real);
+		struct parasite_unmap_args *args;
+
+		*ctl->addr_cmd = PARASITE_CMD_UNMAP;
+
+		args = parasite_args(ctl, struct parasite_unmap_args);
+		args->parasite_start = ctl->remote_map;
+		args->parasite_len = ctl->map_length;
+		if (parasite_unmap(ctl, ctl->parasite_ip))
 			ret = -1;
-		}
 	}
 
 	return ret;
diff --git a/pie/parasite.c b/pie/parasite.c
index 50435d0..927cc83 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -478,6 +478,20 @@ out:
 	return 0;
 }
 
+static noinline int unmap_itself(void *data)
+{
+	struct parasite_unmap_args *args = data;
+
+	sys_munmap(args->parasite_start, args->parasite_len);
+	/*
+	 * sys_munmap never return back. The controll process must
+	 * trap us on the exit from munmap
+	 */
+
+	BUG();
+	return -1;
+}
+
 static noinline __used int parasite_init_daemon(void *data)
 {
 	struct parasite_init_args *args = data;
@@ -523,6 +537,8 @@ int __used parasite_service(unsigned int cmd, void *args)
 		return dump_thread(args);
 	case PARASITE_CMD_INIT_DAEMON:
 		return parasite_init_daemon(args);
+	case PARASITE_CMD_UNMAP:
+		return unmap_itself(args);
 	}
 
 	pr_err("Unknown command to parasite: %d\n", cmd);
-- 
1.8.3.1



More information about the CRIU mailing list