[CRIU] [PATCH 19/28] dump: migrate shared files mappings with new files engine

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


From: Stanislav Kinsbursky <skinsbursky at openvz.org>

This patch also opens file when t's requested instead of wasting fd during
regular files restore.

Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
 cr-dump.c       |   52 +++++++++++++++++++++-------------------------------
 files.c         |   54 ++++++++++++++++++++++++++++++++++++++++++++++++------
 include/files.h |    1 +
 3 files changed, 70 insertions(+), 37 deletions(-)
-------------- next part --------------
diff --git a/cr-dump.c b/cr-dump.c
index f475f77..bdc0fe0 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -98,6 +98,8 @@ static int dump_one_reg_file(struct file_entry *p, pid_t pid,
 	int ret = -1;
 	struct fd_entry *fde = &e.fde;
 	struct stat fd_stat;
+	u8 new;
+	long id;
 
 	if (fstat(lfd, &fd_stat) < 0) {
 		pr_perror("Can't get stat on %d", lfd);
@@ -122,48 +124,36 @@ static int dump_one_reg_file(struct file_entry *p, pid_t pid,
 	fde->fd		= (u32)target_fd;
 	fde->id		= FD_ID_INVALID;
 
-	if (likely(!fd_is_special(fde))) {
-		u8 new;
-		long id;
+	p->id = MAKE_FD_GENID(fd_stat.st_dev, fd_stat.st_ino, p->pos);
+	id = file_collect(pid, target_fd, p, &new);
+	if (id < 0)
+		return id;
 
-		p->id = MAKE_FD_GENID(fd_stat.st_dev, fd_stat.st_ino, p->pos);
-		id = file_collect(pid, target_fd, p, &new);
-		if (id < 0)
-			return id;
+	/* Now it might have completely new ID here */
+	fde->id = id;
 
-		/* Now it might have completely new ID here */
-		fde->id = id;
+	if (new) {
+		p->len = len;
 
-		if (new) {
-			p->len = len;
+		pr_info("Dumping regular file: id %ld, pos %ld, "
+			"flags 0x%x, len %d",
+			p->id, p->pos, p->flags, p->len);
+		if (p->len)
+			pr_info(" --> %s", big_buffer);
+		pr_info("\n");
 
-			pr_info("Dumping regular file: id %ld, pos %ld, "
-				"flags 0x%x, len %d",
-				p->id, p->pos, p->flags, p->len);
-			if (p->len)
-				pr_info(" --> %s", big_buffer);
-			pr_info("\n");
-
-			if (write_img(cr_fdset->fds[CR_FD_REG_FILES], p))
-				return -1;
-			if (write_img_buf(cr_fdset->fds[CR_FD_REG_FILES], big_buffer, len))
-				return -1;
-		}
-	} else {
-		e.len   = len;
-		e.flags = p->flags;
-		e.pos   = p->pos;
-		e.addr  = target_fd;
+		if (write_img(cr_fdset->fds[CR_FD_REG_FILES], p))
+			return -1;
+		if (write_img_buf(cr_fdset->fds[CR_FD_REG_FILES], big_buffer, len))
+			return -1;
 	}
 
 	pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n",
 		p->type, len, p->flags, p->pos, target_fd);
 
+	e.addr = target_fd;
 	if (write_img(cr_fdset->fds[CR_FD_FDINFO], &e))
 		return -1;
-	if (unlikely(fd_is_special(fde)))
-		if (write_img_buf(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.len))
-			return -1;
 	return 0;
 }
 
diff --git a/files.c b/files.c
index a2e9e75..94ebdfe 100644
--- a/files.c
+++ b/files.c
@@ -395,6 +395,26 @@ static int open_fmap(int pid, struct fdinfo_entry *fe, int fd)
 	return 0;
 }
 
+static int collect_fmap(int pid, struct fdinfo_entry *fe, int fd)
+{
+	struct fmap_fd *new;
+
+	new = xmalloc(sizeof(*new));
+	if (!new)
+		return -1;
+
+	new->start	= fe->addr;
+	new->next	= fmap_fds;
+	new->pid	= pid;
+	new->id		= fe->fde.id;
+
+	fmap_fds	= new;
+
+	pr_info("%d: Added shared map %16lx\n", pid, new->start);
+
+	return 0;
+}
+
 static int open_fdinfo(int pid, struct fd_entry *fde, int *fdinfo_fd, int state)
 {
 	int ret;
@@ -488,8 +508,11 @@ int prepare_fds(int pid)
 				continue;
 
 			if (fd_is_special(&fe.fde)) {
-				if (open_special_fdinfo(pid, &fe, fdinfo_fd, state))
-					goto err;
+				if  (state == FD_STATE_RECV)
+					if (collect_fmap(pid, &fe, fdinfo_fd))
+						goto err;
+
+				lseek(fdinfo_fd, fe.len, SEEK_CUR);
 				continue;
 			}
 
@@ -531,8 +554,27 @@ static struct fmap_fd *pull_fmap_fd(int pid, unsigned long start)
 
 int get_filemap_fd(int pid, struct vma_entry *vma_entry)
 {
-	struct fmap_fd *fmap_fd;
-	
-	fmap_fd = pull_fmap_fd(pid, vma_entry->start);
-	return fmap_fd ? fmap_fd->fd : -1;
+	struct fmap_fd *fmap_fd = pull_fmap_fd(pid, vma_entry->start);
+
+	if (fmap_fd) {
+		struct file_info *fi;
+		const struct file_entry *rfe;
+		int fd;
+
+		fi = file_search(FDINFO_MAP, fmap_fd->id);
+		if (fi == NULL) {
+			pr_err("Failed to find map shared file: id %d\n\n", fmap_fd->id);
+			return -1;
+		}
+		rfe = fi->rfe;
+
+		fd = open((char *)rfe->name, rfe->flags);
+		if (fd < 0) {
+			pr_perror("Can't open file %s", rfe->name);
+			return -1;
+		}
+		lseek(fd, rfe->pos, SEEK_SET);
+		return fd;
+	}
+	return -1;
 }
diff --git a/include/files.h b/include/files.h
index 9d4e297..1bfa020 100644
--- a/include/files.h
+++ b/include/files.h
@@ -19,6 +19,7 @@ struct fmap_fd {
 	unsigned long		start;
 	int			pid;
 	int			fd;
+	int			id;
 };
 
 struct fdinfo_desc {


More information about the CRIU mailing list