[CRIU] [PATCH 15+1/3] restore: Mmap task_restore_args by hands

Pavel Emelyanov xemul at virtuozzo.com
Wed May 25 06:28:23 PDT 2016


The RM_PRIVATE memory can move every time we call rst_mem_alloc,
so it's impossible to have static pointer on it. Since task args
is used actyvely, it will be easier to handle it manually.

Reported-by: Andrey Vagin <avagin at virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/cr-restore.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 033119a..e747ec6 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -113,7 +113,7 @@
 static struct pstree_item *current;
 
 static int restore_task_with_children(void *);
-static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core);
+static int sigreturn_restore(pid_t pid, struct task_restore_args *ta, unsigned long alen, CoreEntry *core);
 static int prepare_restorer_blob(void);
 static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core);
 static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
@@ -483,7 +483,6 @@ static int prepare_mm(pid_t pid, struct task_restore_args *args);
 static int restore_one_alive_task(int pid, CoreEntry *core)
 {
 	unsigned args_len;
-	unsigned long ta_cp;
 	struct task_restore_args *ta;
 	pr_info("Restoring resources\n");
 
@@ -491,8 +490,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
 
 	args_len = round_up(sizeof(*ta) + sizeof(struct thread_restore_args) *
 			current->nr_threads, page_size());
-	ta_cp = rst_mem_align_cpos(RM_PRIVATE);
-	ta = rst_mem_alloc(args_len, RM_PRIVATE);
+	ta = mmap(NULL, args_len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
 	if (!ta)
 		return -1;
 
@@ -563,7 +561,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
 	if (setup_uffd(pid, ta))
 		return -1;
 
-	return sigreturn_restore(pid, ta_cp, core);
+	return sigreturn_restore(pid, ta, args_len, core);
 }
 
 static void zombie_prepare_signals(void)
@@ -2710,7 +2708,7 @@ static int rst_prep_creds(pid_t pid, CoreEntry *core, unsigned long *creds_pos)
 	return 0;
 }
 
-static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
+static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, unsigned long alen, CoreEntry *core)
 {
 	void *mem = MAP_FAILED;
 	void *restore_thread_exec_start;
@@ -2723,7 +2721,6 @@ static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 	long rst_mem_size;
 	long memzone_size;
 
-	struct task_restore_args *task_args;
 	struct thread_restore_args *thread_args;
 	struct restore_mem_zone *mz;
 
@@ -2764,7 +2761,7 @@ static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 
 	rst_mem_size = rst_mem_lock();
 	memzone_size = round_up(sizeof(struct restore_mem_zone) * current->nr_threads, page_size());
-	restore_bootstrap_len = restorer_len + memzone_size + rst_mem_size;
+	restore_bootstrap_len = restorer_len + memzone_size + alen + rst_mem_size;
 	BUG_ON(restore_bootstrap_len & (PAGE_SIZE - 1));
 	pr_info("%d threads require %ldK of memory\n",
 			current->nr_threads, KBYTES(restore_bootstrap_len));
@@ -2830,11 +2827,16 @@ static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 	mz = mem;
 	mem += memzone_size;
 
-	if (rst_mem_remap(mem))
+	task_args = mremap(task_args, alen, alen, MREMAP_MAYMOVE|MREMAP_FIXED, mem);
+	if (task_args != mem) {
+		pr_perror("Can't move task args");
 		goto err;
+	}
 
-	task_args	= rst_mem_remap_ptr(ta_cp, RM_PRIVATE);
-	thread_args	= (struct thread_restore_args *)(task_args + 1);
+	thread_args = (struct thread_restore_args *)(task_args + 1);
+	mem += alen;
+	if (rst_mem_remap(mem))
+		goto err;
 
 	/*
 	 * At this point we've found a gap in VM that fits in both -- current
@@ -2857,8 +2859,8 @@ static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 	task_args->breakpoint = &rsti(current)->breakpoint;
 	task_args->task_entries = rst_mem_remap_ptr(task_entries_pos, RM_SHREMAP);
 
-	task_args->rst_mem = mem;
-	task_args->rst_mem_size = rst_mem_size;
+	task_args->rst_mem = mem - alen;
+	task_args->rst_mem_size = rst_mem_size + alen;
 
 	task_args->bootstrap_start = (void *)exec_mem_hint;
 	task_args->bootstrap_len = restore_bootstrap_len;
-- 
2.5.0



More information about the CRIU mailing list