[CRIU] [PATCH 7/8] restorer: unmap itself

Andrey Vagin avagin at openvz.org
Fri Sep 13 05:53:44 EDT 2013


This patch adds a function for removing the restorer blob. This function
never returns and the process must be trapped on the exit from the
munmap syscall.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c       | 25 ++++++++++++++++++++-----
 include/crtools.h  |  2 ++
 include/restorer.h |  3 +++
 pie/restorer.c     | 10 ++++++++++
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index ddfb9f9..80a8c79 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1365,6 +1365,7 @@ static void finalize_restore(int status)
 
 	for_each_pstree_item(item) {
 		pid_t pid = item->pid.real;
+		struct parasite_ctl *ctl;
 
 		if (item->state == TASK_DEAD)
 			continue;
@@ -1375,7 +1376,13 @@ static void finalize_restore(int status)
 		if (status  < 0)
 			goto detach;
 
-		/* TODO Unmap the restorer blob and restore the process state */
+		/* Unmap the restorer blob */
+		ctl = __parasite_prep_ctl(pid);
+		if (ctl == NULL)
+			goto detach;
+		parasite_unmap(ctl, (unsigned long) item->rst->munmap_restorer);
+
+		/* TODO restore the process state */
 detach:
 		if (ptrace(PTRACE_DETACH, pid, NULL, 0))
 			pr_perror("Unable to execute %d", pid);
@@ -2212,6 +2219,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 
 	long new_sp, exec_mem_hint;
 	long ret;
+
+	void *bootstrap_start;
 	long restore_bootstrap_len;
 
 	struct task_restore_core_args *task_args;
@@ -2320,6 +2329,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 		vdso_rt_size = vdso_rt_vma_size + vdso_rt_delta;
 	}
 
+	restore_bootstrap_len += vdso_rt_size;
+
 	/*
 	 * Restorer is a blob (code + args) that will get mapped in some
 	 * place, that should _not_ intersect with both -- current mappings
@@ -2332,16 +2343,16 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	 */
 
 	exec_mem_hint = restorer_get_vma_hint(pid, &rst_vmas.h, &self_vmas.h,
-					      restore_bootstrap_len +
-					      vdso_rt_size);
+					      restore_bootstrap_len);
+	bootstrap_start = (void *) exec_mem_hint;
 	if (exec_mem_hint == -1) {
 		pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
-		       restore_bootstrap_len + vdso_rt_size);
+		       restore_bootstrap_len);
 		goto err;
 	}
 
 	pr_info("Found bootstrap VMA hint at: 0x%lx (needs ~%ldK)\n", exec_mem_hint,
-			KBYTES(restore_bootstrap_len + vdso_rt_size));
+			KBYTES(restore_bootstrap_len));
 
 	ret = remap_restorer_blob((void *)exec_mem_hint);
 	if (ret < 0)
@@ -2353,6 +2364,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	 */
 	restore_thread_exec_start	= restorer_sym(exec_mem_hint, __export_restore_thread);
 	restore_task_exec_start		= restorer_sym(exec_mem_hint, __export_restore_task);
+	current->rst->munmap_restorer	= restorer_sym(exec_mem_hint, __export_unmap);
 
 	exec_mem_hint += restorer_len;
 
@@ -2370,6 +2382,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	task_args	= mem;
 	thread_args	= mem + restore_task_vma_len;
 
+	task_args->bootstrap_start = bootstrap_start;
+	task_args->bootstrap_len = restore_bootstrap_len;
+
 	/*
 	 * Get a reference to shared memory area which is
 	 * used to signal if shmem restoration complete
diff --git a/include/crtools.h b/include/crtools.h
index a574b46..02c6bd3 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -177,6 +177,8 @@ struct rst_info {
 	unsigned long		premmapped_len;
 	unsigned long		clone_flags;
 
+	void			*munmap_restorer;
+
 	int			nr_zombies;
 
 	int service_fd_id;
diff --git a/include/restorer.h b/include/restorer.h
index 1ed1d81..ae762d7 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -126,6 +126,9 @@ struct task_restore_core_args {
 	unsigned long			premmapped_len;
 	rt_sigaction_t			sigchld_act;
 
+	void				*bootstrap_start;
+	unsigned long			bootstrap_len;
+
 	struct itimerval		itimers[3];
 
 	int 				timer_n;
diff --git a/pie/restorer.c b/pie/restorer.c
index b29ce11..8c2ddd9 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -510,6 +510,13 @@ static void restore_posix_timers(struct task_restore_core_args *args)
 		sys_timer_settime((timer_t)rt->spt.it_id, 0, &rt->val, NULL);
 	}
 }
+static void *bootstrap_start;
+static unsigned int bootstrap_len;
+
+void __export_unmap(void)
+{
+	sys_munmap(bootstrap_start, bootstrap_len);
+}
 
 /*
  * The main routine to restore task via sigreturn.
@@ -530,6 +537,9 @@ long __export_restore_task(struct task_restore_core_args *args)
 	pid_t my_pid = sys_getpid();
 	rt_sigaction_t act;
 
+	bootstrap_start = args->bootstrap_start;
+	bootstrap_len	= args->bootstrap_len;
+
 	task_entries = args->task_entries;
 
 	ksigfillset(&act.rt_sa_mask);
-- 
1.8.3.1



More information about the CRIU mailing list