[CRIU] [PATCH 18/28] rst: exe migration update

Kinsbursky Stanislav skinsbursky at openvz.org
Thu Mar 22 13:59:32 EDT 2012


From: Stanislav Kinsbursky <skinsbursky at openvz.org>

This patch does two things:
1) pass opened exe fd  to restorer instead of reading and openning it inside.
2) uses new shared files migration engine

Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
 cr-dump.c          |    2 +-
 cr-restore.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++++-----
 files.c            |   20 ++++++-----------
 include/image.h    |    4 +--
 include/restorer.h |    2 +-
 restorer.c         |   63 +++-------------------------------------------------
 6 files changed, 70 insertions(+), 83 deletions(-)
-------------- next part --------------
diff --git a/cr-dump.c b/cr-dump.c
index 179f49a..f475f77 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -194,7 +194,7 @@ static int dump_task_special_files(pid_t pid, const struct cr_fdset *cr_fdset)
 	fd = open_proc(pid, "exe");
 	if (fd < 0)
 		return -1;
-	ret = dump_one_reg_file(&fe, FD_PID_INVALID, fd, 0, cr_fdset, 1);
+	ret = dump_one_reg_file(&fe, pid, fd, 0, cr_fdset, 1);
 
 	return ret;
 }
diff --git a/cr-restore.c b/cr-restore.c
index 95ca897..1d16e57 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -38,6 +38,7 @@
 #include "restorer-blob.h"
 #include "crtools.h"
 #include "namespaces.h"
+#include "file-ids.h"
 
 /*
  * real_pid member formerly served cases when
@@ -1505,6 +1506,48 @@ static int prepare_creds(int pid, struct task_restore_core_args *args)
 	return ret > 0 ? 0 : -1;
 }
 
+static char *restorer_get_exe_path(int pid)
+{
+	struct fdinfo_entry fe;
+	struct file_info *sfi;
+	char *path = NULL;
+	int fdinfo_fd;
+
+	fdinfo_fd = open_image_ro(CR_FD_FDINFO, pid);
+	if (fdinfo_fd < 0) {
+		pr_perror("Can't open fdinfo-%d", pid);
+		goto err;
+	}
+
+	while (1) {
+		int ret;
+
+		ret = read(fdinfo_fd, &fe, sizeof(fe));
+		if (ret == 0) {
+			pr_err("%d: failed to find exe fd entry\n", pid);
+			goto err;
+		}
+
+		if (ret != sizeof(fe)) {
+			pr_perror("%d: Bad fdinfo entry", pid);
+			goto err;
+		}
+		if (fe.fde.type == FDINFO_EXE)
+			break;
+	}
+
+	sfi = file_search(FDINFO_EXE, fe.fde.id);
+	if (sfi == NULL) {
+		pr_err("Failed to find exe with id %ld\n", fe.fde.id);
+		goto err;
+	}
+
+	path = (char *)sfi->rfe->name;
+err:
+	close_safe(&fdinfo_fd);
+	return path;
+}
+
 static int sigreturn_restore(pid_t pid)
 {
 	long restore_code_len, restore_task_vma_len;
@@ -1524,7 +1567,8 @@ static int sigreturn_restore(pid_t pid)
 
 	LIST_HEAD(self_vma_list);
 	struct vma_area *vma_area;
-	int fd_fdinfo = -1;
+	int fd_exe = -1;
+	char *path;
 	int fd_core = -1;
 	int fd_pages = -1;
 	int fd_vmas = -1;
@@ -1558,9 +1602,15 @@ static int sigreturn_restore(pid_t pid)
 		goto err;
 	}
 
-	fd_fdinfo = open_image_ro(CR_FD_FDINFO, pid);
-	if (fd_fdinfo < 0) {
-		pr_perror("Can't open fdinfo-%d", pid);
+	path = restorer_get_exe_path(pid);
+	if (path == NULL) {
+		pr_err("%d: failed to find exe path\n", pid);
+		goto err;
+	}
+
+	fd_exe = open(path, O_RDWR, 0744);
+	if (fd_exe < 0) {
+		pr_perror("Can't open exe-%d", pid);
 		goto err;
 	}
 
@@ -1696,7 +1746,7 @@ static int sigreturn_restore(pid_t pid)
 	task_args->fd_vmas	= fd_vmas;
 	task_args->logfd	= log_get_fd();
 	task_args->sigchld_act	= sigchld_act;
-	task_args->fd_fdinfo	= fd_fdinfo;
+	task_args->fd_exe	= fd_exe;
 	task_args->fd_pages	= fd_pages;
 
 	ret = prepare_itimers(pid, task_args);
@@ -1773,7 +1823,7 @@ static int sigreturn_restore(pid_t pid)
 err:
 	free_mappings(&self_vma_list);
 	close_safe(&fd_core);
-	close_safe(&fd_fdinfo);
+	close_safe(&fd_exe);
 
 	/* Just to be sure */
 	exit(1);
diff --git a/files.c b/files.c
index b4cc0c3..a2e9e75 100644
--- a/files.c
+++ b/files.c
@@ -219,17 +219,6 @@ static int restore_cwd(int id)
 	return 0;
 }
 
-static int restore_exe_early(struct fdinfo_entry *fe, int fd)
-{
-	/*
-	 * We restore the EXE symlink at very late stage
-	 * because of restrictions applied from kernel side,
-	 * so simply skip it for a while.
-	 */
-	lseek(fd, fe->len, SEEK_CUR);
-	return 0;
-}
-
 static int receive_shared_fd(int pid, struct file_info *fi, struct fd_entry *fde)
 {
 	int real_fd;
@@ -451,8 +440,6 @@ static int open_special_fdinfo(int pid, struct fdinfo_entry *fe,
 
 	if (fe->fde.type == FDINFO_MAP)
 		return open_fmap(pid, fe, fdinfo_fd);
-	if (fe->fde.type == FDINFO_EXE)
-		return restore_exe_early(fe, fdinfo_fd);
 
 	pr_info("%d: fe->type: %d\n", pid,  fe->fde.type);
 	BUG_ON(1);
@@ -492,6 +479,13 @@ int prepare_fds(int pid)
 				cwd_id = fe.fde.id;
 				continue;
 			}
+			if (fe.fde.type == FDINFO_EXE)
+				/*
+				 * We restore the EXE symlink at very late stage
+				 * because of restrictions applied from kernel side,
+				 * so simply skip it for a while.
+				 */
+				continue;
 
 			if (fd_is_special(&fe.fde)) {
 				if (open_special_fdinfo(pid, &fe, fdinfo_fd, state))
diff --git a/include/image.h b/include/image.h
index 685fe06..abc7fd0 100644
--- a/include/image.h
+++ b/include/image.h
@@ -69,9 +69,7 @@ struct fdinfo_entry {
 	u8	name[0];
 } __packed;
 
-#define fd_is_special(fde)		\
-	(((fde)->type == FDINFO_MAP) ||	\
-	 ((fde)->type == FDINFO_EXE))
+#define fd_is_special(fde)	((fde)->type == FDINFO_MAP)
 
 struct pstree_entry {
 	u32	pid;
diff --git a/include/restorer.h b/include/restorer.h
index 1ce7ad2..389028e 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -66,7 +66,7 @@ struct task_restore_core_args {
 	int				pid;			/* task pid */
 	int				fd_core;		/* opened core file */
 	int				fd_vmas;		/* opened vmas file */
-	int				fd_fdinfo;		/* opened files dump file */
+	int                             fd_exe;			/* opened exe path */
 	int				fd_pages;		/* opened pages dump file */
 	int				logfd;
 	bool				restore_threads;	/* if to restore threads */
diff --git a/restorer.c b/restorer.c
index 043da1a..c6557e7 100644
--- a/restorer.c
+++ b/restorer.c
@@ -235,66 +235,12 @@ core_restore_end:
 
 static long restore_self_exe_late(struct task_restore_core_args *args)
 {
-	struct fdinfo_entry fe;
-	long ret = -1;
-	char *path;
-	int fd;
-
-	/*
-	 * Path to exe file and its len is in image.
-	 */
-	for (;;) {
-		if (sys_read(args->fd_fdinfo, &fe, sizeof(fe)) != sizeof(fe)) {
-			write_string("sys_read lookup failed\n");
-			goto err;
-		}
+	int ret;
 
-		if (fe.fde.type == FDINFO_EXE)
-			break;
+	write_string("Restoring EXE\n");
 
-		if (fe.len)
-			sys_lseek(args->fd_fdinfo, fe.len, SEEK_CUR);
-	}
-
-	path = (char *)sys_mmap(NULL, fe.len + 1,
-				PROT_READ | PROT_WRITE,
-				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	if ((long)path < 0) {
-		write_string("sys_mmap failed\n");
-		write_num_n(fe.len);
-		goto err;
-	}
-
-	if (sys_read(args->fd_fdinfo, path, fe.len) != fe.len) {
-		sys_munmap(path, fe.len);
-		write_string("sys_read for exe-path failed\n");
-		goto err;
-	}
-	path[fe.len] = '\0';
-
-	write_string("Restoring EXE (");
-	write_string(path);
-	write_string(")\n");
-
-	fd = sys_open(path, fe.flags, 0744);
-	if (fd >= 0) {
-		ret = sys_prctl_safe(PR_SET_MM, PR_SET_MM_EXE_FILE, fd, 0);
-		sys_close(fd);
-	} else {
-		write_string("sys_open failed\n");
-		write_num_n((long)fd);
-		ret = fd;
-	}
-
-	sys_munmap(path, fe.len + 1);
-
-	/* FIXME Once kernel side stabilized -- drop next line */
-	ret = 0;
-	return ret;
-
-err:
-	write_num_n(__LINE__);
-	write_num_n(sys_getpid());
+	ret = sys_prctl_safe(PR_SET_MM, PR_SET_MM_EXE_FILE, args->fd_exe, 0);
+	sys_close(args->fd_exe);
 	return ret;
 }
 
@@ -526,7 +472,6 @@ long restore_task(struct task_restore_core_args *args)
 	 * new ones from image file.
 	 */
 	ret = restore_self_exe_late(args);
-	sys_close(args->fd_fdinfo);
 	if (ret)
 		goto core_restore_end;
 


More information about the CRIU mailing list