[CRIU] [PATCH 3/4] restorer: unmap itself (v2)

Andrey Vagin avagin at openvz.org
Fri Sep 13 09:08:21 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.

v2: * release parasite_ctl sturcture and use the new interface of
      parasite_prep_ctl

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

diff --git a/cr-restore.c b/cr-restore.c
index 13d3e0a..08ceafa 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1373,6 +1373,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;
@@ -1383,7 +1384,16 @@ 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, NULL);
+		if (ctl == NULL)
+			goto detach;
+
+		parasite_unmap(ctl, (unsigned long) item->rst->munmap_restorer);
+
+		xfree(ctl);
+
+		/* TODO restore the process state */
 detach:
 		if (ptrace(PTRACE_DETACH, pid, NULL, 0))
 			pr_perror("Unable to execute %d", pid);
@@ -2220,6 +2230,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;
@@ -2328,6 +2340,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
@@ -2340,16 +2354,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)
@@ -2361,6 +2375,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;
 
@@ -2378,6 +2393,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..3c88484 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -510,6 +510,17 @@ 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);
+	/*
+	 * sys_munmap must not return here. The controll process must
+	 * trap us on the exit from sys_munmap.
+	 */
+}
 
 /*
  * The main routine to restore task via sigreturn.
@@ -530,6 +541,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