[CRIU] [RFC 5/5] dump: Check for restorer blob on dump and skip it

Cyrill Gorcunov gorcunov at openvz.org
Sun May 26 17:12:42 EDT 2013


We already skip auto-generated vdso area on subsequent
dumps, lets do the same for restorer blob.

Need to use more unified (unioned) way to represent
marks instead of opencoded solution.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c                  |  4 ++--
 include/parasite-syscall.h |  4 ++--
 include/parasite.h         | 12 +++++++++---
 parasite-syscall.c         | 46 ++++++++++++++++++++++++++++------------------
 pie/parasite.c             | 15 +++++++++------
 5 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 6ea17a7..dd5ac7b 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1418,9 +1418,9 @@ static int dump_one_task(struct pstree_item *item)
 		}
 	}
 
-	ret = parasite_fixup_vdso(parasite_ctl, pid, &vmas);
+	ret = parasite_fixup_marked(parasite_ctl, pid, &vmas);
 	if (ret) {
-		pr_err("Can't fixup vdso VMAs (pid: %d)\n", pid);
+		pr_err("Can't fixup marked VMAs (pid: %d)\n", pid);
 		goto err_cure_fdset;
 	}
 
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 3babeb8..fccfe38 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -109,7 +109,7 @@ extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
 					bool signals_blocked);
 extern bool arch_can_dump_task(pid_t pid);
 
-extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
-			       struct vm_area_list *vma_area_list);
+extern int parasite_fixup_marked(struct parasite_ctl *ctl, pid_t pid,
+				 struct vm_area_list *vma_area_list);
 
 #endif /* __CR_PARASITE_SYSCALL_H__ */
diff --git a/include/parasite.h b/include/parasite.h
index d26b130..12dd5fe 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -45,7 +45,7 @@ enum {
 	PARASITE_CMD_DRAIN_FDS,
 	PARASITE_CMD_GET_PROC_FD,
 	PARASITE_CMD_DUMP_TTY,
-	PARASITE_CMD_CHECK_VDSO_MARK,
+	PARASITE_CMD_CHECK_MARK,
 
 	PARASITE_CMD_MAX,
 };
@@ -90,11 +90,17 @@ struct parasite_vma_entry
 	int		prot;
 };
 
-struct parasite_vdso_vma_entry {
+enum {
+	MTYPE_INVALID,
+	MTYPE_RESTORER,
+	MTYPE_VDSO,
+};
+
+struct parasite_marked_vma_entry {
 	unsigned long	start;
 	unsigned long	len;
+	int		mtype;
 	unsigned long	proxy_addr;
-	int		is_marked;
 };
 
 struct parasite_dump_pages_args {
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 37a9c4f..bfda314 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -652,22 +652,20 @@ err:
 	return ret;
 }
 
-/*
- * Find out proxy vdso vma and drop it from the list. Also
- * fix vdso status on vmas if wrong status found.
- */
-int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
-			struct vm_area_list *vma_area_list)
+/* Find out marked vmas and drop them from the list */
+int parasite_fixup_marked(struct parasite_ctl *ctl, pid_t pid,
+			  struct vm_area_list *vma_area_list)
 {
 	unsigned long proxy_addr = VDSO_BAD_ADDR;
-	struct parasite_vdso_vma_entry *args;
-	struct vma_area *marked = NULL;
+	struct parasite_marked_vma_entry *args;
+	struct vma_area *restorer = NULL;
+	struct vma_area *vdso = NULL;
 	struct vma_area *vma;
 	int fd, ret = -1;
 	off_t off;
 	u64 pfn;
 
-	args = parasite_args(ctl, struct parasite_vdso_vma_entry);
+	args = parasite_args(ctl, struct parasite_marked_vma_entry);
 	fd = open_proc(pid, "pagemap");
 	if (fd < 0)
 		return -1;
@@ -687,19 +685,24 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		args->start = vma->vma.start;
 		args->len = vma_area_len(vma);
 
-		if (parasite_execute_daemon(PARASITE_CMD_CHECK_VDSO_MARK, ctl)) {
+		if (parasite_execute_daemon(PARASITE_CMD_CHECK_MARK, ctl)) {
 			pr_err("vdso: Parasite failed to poke for mark\n");
 			ret = -1;
 			goto err;
 		}
 
 		/*
-		 * Defer handling marked vdso.
+		 * Defer handling marked areas.
 		 */
-		if (unlikely(args->is_marked)) {
+		switch (args->mtype) {
+		case MTYPE_RESTORER:
+			BUG_ON(restorer);
+			restorer = vma;
+			continue;
+		case MTYPE_VDSO:
 			BUG_ON(args->proxy_addr == VDSO_BAD_ADDR);
-			BUG_ON(marked);
-			marked = vma;
+			BUG_ON(vdso);
+			vdso = vma;
 			proxy_addr = args->proxy_addr;
 			continue;
 		}
@@ -743,9 +746,9 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 	 * There is marked vdso, it means such vdso is autogenerated
 	 * and must be dropped from vma list.
 	 */
-	if (marked) {
+	if (vdso) {
 		pr_debug("vdso: Found marked at %lx (proxy at %lx)\n",
-			 (long)marked->vma.start, (long)proxy_addr);
+			 (long)vdso->vma.start, (long)proxy_addr);
 
 		/*
 		 * Don't forget to restore the proxy vdso status, since
@@ -762,8 +765,15 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 
 		pr_debug("vdso: Droppping marked vdso at %lx\n",
 			 (long)vma->vma.start);
-		list_del(&marked->list);
-		xfree(marked);
+		list_del(&vdso->list);
+		xfree(vdso);
+	}
+
+	if (restorer) {
+		pr_debug("rstr: Found marked at %lx, dropping it\n",
+			 (long)restorer->vma.start);
+		list_del(&restorer->list);
+		xfree(restorer);
 	}
 	ret = 0;
 err:
diff --git a/pie/parasite.c b/pie/parasite.c
index 3e01cc7..e384450 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -6,6 +6,7 @@
 #include <stdarg.h>
 #include <sys/ioctl.h>
 
+#include "signatures.h"
 #include "syscall.h"
 #include "parasite.h"
 #include "lock.h"
@@ -410,16 +411,18 @@ static int parasite_cfg_log(struct parasite_log_args *args)
 	return ret;
 }
 
-static int parasite_check_vdso_mark(struct parasite_vdso_vma_entry *args)
+static int parasite_check_mark(struct parasite_marked_vma_entry *args)
 {
 	struct vdso_mark *m = (void *)args->start;
 
+	args->mtype = MTYPE_INVALID;
+
 	if (is_vdso_mark(m)) {
-		args->is_marked = 1;
+		args->mtype = MTYPE_VDSO;
 		args->proxy_addr = m->proxy_addr;
 	} else {
-		args->is_marked = 0;
-		args->proxy_addr = VDSO_BAD_ADDR;
+		if (*(u64 *)(void *)args->start == CRIU_SIG_RESTORER)
+			args->mtype = MTYPE_VDSO;
 	}
 
 	return 0;
@@ -605,8 +608,8 @@ __parasite_daemon_thread_leader(void *args, struct tid_state_s *s)
 		case PARASITE_CMD_DUMP_TTY:
 			ret = parasite_dump_tty(args);
 			break;
-		case PARASITE_CMD_CHECK_VDSO_MARK:
-			ret = parasite_check_vdso_mark(args);
+		case PARASITE_CMD_CHECK_MARK:
+			ret = parasite_check_mark(args);
 			break;
 		default:
 			pr_err("Unknown command in parasite daemon thread leader: %d\n", m.cmd);
-- 
1.8.1.4



More information about the CRIU mailing list