[CRIU] [crtools-bot for Pavel Emelyanov ] restorer: Pass self-vmas via memory, not temp file

Cyrill Gorcunov gorcunov at openvz.org
Fri Mar 2 12:31:35 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit 85f18ef02f9ed5bf90251ddccebf6f8a6e658e9d
Author: Pavel Emelyanov <xemul at parallels.com>
Date:   Fri Mar 2 19:30:23 2012 +0400

    restorer: Pass self-vmas via memory, not temp file
    
    Reserve more mem for bootrstrap code and put all self vmas at its tail.
    
    Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-restore.c       |   65 ++++++++++++++++++++-------------------------------
 include/crtools.h  |    1 -
 include/restorer.h |    2 +-
 restorer.c         |   18 +++-----------
 4 files changed, 31 insertions(+), 55 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 4ef8c5e..e70c509 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1628,12 +1628,13 @@ static int prepare_creds(int pid, struct task_restore_core_args *args)
 static void sigreturn_restore(pid_t pid)
 {
 	long restore_code_len, restore_task_vma_len;
-	long restore_thread_vma_len;
+	long restore_thread_vma_len, self_vmas_len;
 
 	void *mem = MAP_FAILED;
 	void *restore_thread_exec_start;
 	void *restore_task_exec_start;
 	void *restore_code_start;
+	struct vma_entry *self_vma;
 
 	long new_sp, exec_mem_hint;
 	long ret;
@@ -1641,14 +1642,11 @@ static void sigreturn_restore(pid_t pid)
 	struct task_restore_core_args *task_args;
 	struct thread_restore_args *thread_args;
 
-	char self_vmas_path[PATH_MAX];
-
 	LIST_HEAD(self_vma_list);
 	struct vma_area *vma_area;
-	int fd_self_vmas = -1;
 	int fd_fdinfo = -1;
 	int fd_core = -1;
-	int num, i;
+	int i;
 
 	int *fd_core_threads;
 
@@ -1663,6 +1661,8 @@ static void sigreturn_restore(pid_t pid)
 	if (ret < 0)
 		goto err;
 
+	self_vmas_len = (ret + 1) * sizeof(*self_vma);
+
 	/* pr_info_vma_list(&self_vma_list); */
 
 	BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1);
@@ -1682,33 +1682,6 @@ static void sigreturn_restore(pid_t pid)
 		goto err;
 	}
 
-	if (get_image_path(self_vmas_path, sizeof(self_vmas_path),
-			   FMT_FNAME_VMAS, pid))
-		goto err;
-
-	fd_self_vmas = open(self_vmas_path, O_CREAT | O_RDWR | O_TRUNC, CR_FD_PERM);
-
-	/*
-	 * This is a temporary file used to pass vma info to
-	 * restorer code, thus unlink it early to make it disappear
-	 * as soon as we close it
-	 */
-	// unlink(self_vmas_path);
-
-	if (fd_self_vmas < 0) {
-		pr_perror("Can't open %s", self_vmas_path);
-		goto err;
-	}
-
-	num = 0;
-	list_for_each_entry(vma_area, &self_vma_list, list) {
-		ret = write(fd_self_vmas, &vma_area->vma, sizeof(vma_area->vma));
-		if (ret != sizeof(vma_area->vma)) {
-			pr_perror("\nUnable to write vma entry (%d written)", num);
-			goto err;
-		}
-		num++;
-	}
 
 	restore_code_len	= sizeof(restorer_blob);
 	restore_code_len	= round_up(restore_code_len, 16);
@@ -1738,6 +1711,7 @@ static void sigreturn_restore(pid_t pid)
 	exec_mem_hint = restorer_get_vma_hint(pid, &self_vma_list,
 					      restore_task_vma_len +
 					      restore_thread_vma_len +
+					      self_vmas_len +
 					      SHMEMS_SIZE + TASK_ENTRIES_SIZE);
 	if (exec_mem_hint == -1) {
 		pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
@@ -1748,8 +1722,6 @@ static void sigreturn_restore(pid_t pid)
 	pr_info("Found bootstrap VMA hint at: %lx (needs ~%ldK)\n", exec_mem_hint,
 			KBYTES(restore_task_vma_len + restore_thread_vma_len));
 
-	free_mappings(&self_vma_list);
-
 	/* VMA we need to run task_restore code */
 	mem = mmap((void *)exec_mem_hint,
 			restore_task_vma_len + restore_thread_vma_len,
@@ -1806,12 +1778,28 @@ static void sigreturn_restore(pid_t pid)
 		goto err;
 	task_args->task_entries = mem;
 
+	mem += TASK_ENTRIES_SIZE;
+	self_vma = mmap(mem, self_vmas_len, PROT_READ | PROT_WRITE,
+			MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
+	if (self_vma != mem) {
+		pr_perror("Can't map self vmas");
+		goto err;
+	}
+	task_args->self_vmas = self_vma;
+
+	list_for_each_entry(vma_area, &self_vma_list, list) {
+		*self_vma = vma_area->vma;
+		self_vma++;
+	}
+
+	self_vma->start = 0;
+	free_mappings(&self_vma_list);
+
 	/*
 	 * Arguments for task restoration.
 	 */
 	task_args->pid		= pid;
 	task_args->fd_core	= fd_core;
-	task_args->fd_self_vmas	= fd_self_vmas;
 	task_args->logfd	= log_get_fd();
 	task_args->sigchld_act	= sigchld_act;
 	task_args->fd_fdinfo	= fd_fdinfo;
@@ -1860,13 +1848,13 @@ static void sigreturn_restore(pid_t pid)
 	pr_info("task_args: %p\n"
 		"task_args->pid: %d\n"
 		"task_args->fd_core: %d\n"
-		"task_args->fd_self_vmas: %d\n"
 		"task_args->nr_threads: %d\n"
 		"task_args->clone_restore_fn: %p\n"
 		"task_args->thread_args: %p\n",
 		task_args, task_args->pid,
-		task_args->fd_core, task_args->fd_self_vmas,
-		task_args->nr_threads, task_args->clone_restore_fn,
+		task_args->fd_core,
+		task_args->nr_threads,
+		task_args->clone_restore_fn,
 		task_args->thread_args);
 
 	/*
@@ -1889,7 +1877,6 @@ err:
 	free_mappings(&self_vma_list);
 	close_safe(&fd_core);
 	close_safe(&fd_fdinfo);
-	close_safe(&fd_self_vmas);
 
 	/* Just to be sure */
 	exit(1);
diff --git a/include/crtools.h b/include/crtools.h
index ac4f03a..795626f 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -72,7 +72,6 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
 #define FMT_FNAME_PIPES		"pipes-%d.img"
 #define FMT_FNAME_PSTREE	"pstree-%d.img"
 #define FMT_FNAME_SHMEM		"shmem-%d.img"
-#define FMT_FNAME_VMAS		"vmas-%d.img"
 #define FMT_FNAME_SIGACTS	"sigacts-%d.img"
 #define FMT_FNAME_UNIXSK	"unixsk-%d.img"
 #define FMT_FNAME_INETSK	"inetsk-%d.img"
diff --git a/include/restorer.h b/include/restorer.h
index e0ecf6b..a84147b 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -66,7 +66,6 @@ struct task_restore_core_args {
 	int				pid;			/* task pid */
 	int				fd_core;		/* opened core file */
 	int				fd_fdinfo;		/* opened files dump file */
-	int				fd_self_vmas;		/* opened file with running VMAs to unmap */
 	int				logfd;
 	bool				restore_threads;	/* if to restore threads */
 	u32				rst_lock;
@@ -77,6 +76,7 @@ struct task_restore_core_args {
 	struct thread_restore_args	*thread_args;		/* array of thread arguments */
 	struct shmems			*shmems;
 	struct task_entries		*task_entries;
+	struct vma_entry		*self_vmas;
 	rt_sigaction_t			sigchld_act;
 
 	struct itimerval		itimers[3];
diff --git a/restorer.c b/restorer.c
index ecffd7e..ecd423a 100644
--- a/restorer.c
+++ b/restorer.c
@@ -355,7 +355,6 @@ long restore_task(struct task_restore_core_args *args)
 	restorer_set_logfd(args->logfd);
 
 	core_entry	= first_on_heap(core_entry, args->mem_zone.heap);
-	vma_entry	= next_on_heap(vma_entry, core_entry);
 
 #if 0
 	write_hex_n((long)args);
@@ -371,18 +370,7 @@ long restore_task(struct task_restore_core_args *args)
 		goto core_restore_end;
 	}
 
-	/* Note no magic constant on fd_self_vmas */
-	ret = sys_lseek(args->fd_self_vmas, 0, SEEK_SET);
-	while (1) {
-		ret = sys_read(args->fd_self_vmas, vma_entry, sizeof(*vma_entry));
-		if (!ret)
-			break;
-		if (ret != sizeof(*vma_entry)) {
-			write_num_n(__LINE__);
-			write_num_n(ret);
-			goto core_restore_end;
-		}
-
+	for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) {
 		if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
 			continue;
 
@@ -392,11 +380,13 @@ long restore_task(struct task_restore_core_args *args)
 		}
 	}
 
-	sys_close(args->fd_self_vmas);
+	sys_munmap(args->self_vmas,
+			((void *)(vma_entry + 1) - ((void *)args->self_vmas)));
 
 	/*
 	 * OK, lets try to map new one.
 	 */
+	vma_entry = next_on_heap(vma_entry, core_entry);
 	sys_lseek(args->fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET);
 	while (1) {
 		ret = sys_read(args->fd_core, vma_entry, sizeof(*vma_entry));


More information about the CRIU mailing list