[CRIU] [RFC] splitting files.c

Cyrill Gorcunov gorcunov at openvz.org
Wed Jun 20 10:25:45 EDT 2012


Hi guys, while mocking up with fifos and paths handling I found that our
regular-files dumping code is a bit spread over files.c and cr-dump.c
files. So I thought it would be good to cope reg-files in one place,
that's how files-reg.c appeared.

What do you think, is it worth to?

	Cyrill
---
From: Cyrill Gorcunov <gorcunov at openvz.org>
Subject: [PATCH] files: Move regular files handling code to files-reg

Instead of spreading regular files handling code over
files.c and cr-dump.c move it to files-reg.c.

This allows to extend regular file handling code in
future without disturbing other source files and
make code logically coupled, where files.c is mostly
a place for general file handling code unrelated to
file type specifics.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 Makefile            |    1 +
 cr-dump.c           |  188 +----------------------
 files-reg.c         |  433 +++++++++++++++++++++++++++++++++++++++++++++++++++
 files.c             |  228 ---------------------------
 include/files-reg.h |   16 ++
 5 files changed, 451 insertions(+), 415 deletions(-)
 create mode 100644 files-reg.c
 create mode 100644 include/files-reg.h

diff --git a/Makefile b/Makefile
index 44b6854..3853028 100644
--- a/Makefile
+++ b/Makefile
@@ -44,6 +44,7 @@ OBJS		+= sk-tcp.o
 OBJS		+= sk-unix.o
 OBJS		+= sk-queue.o
 OBJS		+= files.o
+OBJS		+= files-reg.o
 OBJS		+= pipes.o
 OBJS		+= file-ids.o
 OBJS		+= namespaces.o
diff --git a/cr-dump.c b/cr-dump.c
index 9edc17c..2b2f99b 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -35,6 +35,7 @@
 #include "parasite.h"
 #include "parasite-syscall.h"
 #include "files.h"
+#include "files-reg.h"
 #include "pipes.h"
 #include "shmem.h"
 #include "sk-inet.h"
@@ -46,7 +47,6 @@
 # error No x86-32 support yet
 #endif
 
-static char big_buffer[PATH_MAX];
 static char loc_buf[PAGE_SIZE];
 
 static struct pstree_item *root_item = NULL;
@@ -140,180 +140,6 @@ static int collect_fds(pid_t pid, int *fd, int *nr_fd)
 	return 0;
 }
 
-/*
- * Ghost files are those not visible from the FS. Dumping them is
- * nasty and the only way we have -- just carry its contents with
- * us. Any brave soul to implement link unlinked file back?
- */
-struct ghost_file {
-	u32	dev;
-	u32	ino;
-	u32	id;
-	struct list_head list;
-};
-
-static u32 ghost_file_ids = 1;
-static LIST_HEAD(ghost_files);
-/*
- * This constant is selected without any calculations. Just do not
- * want to pick up too big files with us in the image.
- */
-#define MAX_GHOST_FILE_SIZE	(1 * 1024 * 1024)
-
-static int dump_ghost_file(int _fd, u32 id, const struct stat *st)
-{
-	int img, fd;
-	struct ghost_file_entry gfe;
-	char lpath[32];
-
-	pr_info("Dumping ghost file contents (id %#x)\n", id);
-
-	img = open_image(CR_FD_GHOST_FILE, O_DUMP, id);
-	if (img < 0)
-		return -1;
-
-	/*
-	 * Reopen file locally since it may have no read
-	 * permissions when drained
-	 */
-	snprintf(lpath, sizeof(lpath), "/proc/self/fd/%d", _fd);
-	fd = open(lpath, O_RDONLY);
-	if (fd < 0) {
-		pr_perror("Can't open ghost original file");
-		return -1;
-	}
-
-	gfe.uid = st->st_uid;
-	gfe.gid = st->st_gid;
-	gfe.mode = st->st_mode;
-
-	if (write_img(img, &gfe))
-		return -1;
-
-	if (copy_file(fd, img, st->st_size))
-		return -1;
-
-	close(fd);
-	close(img);
-	return 0;
-}
-
-static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
-{
-	struct ghost_file *gf;
-	struct remap_file_path_entry rpe;
-
-	pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id);
-
-	if (st->st_size > MAX_GHOST_FILE_SIZE) {
-		pr_err("Can't dump ghost file %s of %lu size\n",
-				path, st->st_size);
-		return -1;
-	}
-
-	list_for_each_entry(gf, &ghost_files, list)
-		if ((gf->dev == st->st_dev) && (gf->ino == st->st_ino))
-			goto dump_entry;
-
-	gf = xmalloc(sizeof(*gf));
-	if (gf == NULL)
-		return -1;
-
-	gf->dev = st->st_dev;
-	gf->ino = st->st_ino;
-	gf->id = ghost_file_ids++;
-	list_add_tail(&gf->list, &ghost_files);
-
-	if (dump_ghost_file(lfd, gf->id, st))
-		return -1;
-
-dump_entry:
-	rpe.orig_id = id;
-	rpe.remap_id = gf->id | REMAP_GHOST;
-
-	return write_img(fdset_fd(glob_fdset, CR_FD_REMAP_FPATH), &rpe);
-}
-
-static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id)
-{
-	int ret;
-	struct stat pst;
-
-	if (ost->st_nlink == 0)
-		/*
-		 * Unpleasant, but easy case. File is completely invisible
-		 * from the FS. Just dump its contents and that's it. But
-		 * be careful whether anybody still has any of its hardlinks
-		 * also open.
-		 */
-		return dump_ghost_remap(path, ost, lfd, id);
-
-	ret = stat(path, &pst);
-	if (ret < 0) {
-		/*
-		 * FIXME linked file, but path is not accessible (unless any
-		 * other error occurred). We can create a temporary link to it
-		 * uning linkat with AT_EMPTY_PATH flag and remap it to this
-		 * name.
-		 */
-		pr_perror("Can't stat path");
-		return -1;
-	}
-
-	if ((pst.st_ino != ost->st_ino) || (pst.st_dev != ost->st_dev)) {
-		/*
-		 * FIXME linked file, but the name we see it by is reused
-		 * by somebody else.
-		 */
-		pr_err("Unaccessible path opened %u:%u, need %u:%u\n",
-				(int)pst.st_dev, (int)pst.st_ino,
-				(int)ost->st_dev, (int)ost->st_ino);
-		return -1;
-	}
-
-	/*
-	 * File is linked and visible by the name it is opened by
-	 * this task. Go ahead and dump it.
-	 */
-	return 0;
-}
-
-static int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
-{
-	char fd_str[128];
-	int len, rfd;
-	struct reg_file_entry rfe;
-
-	snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
-	len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
-	if (len < 0) {
-		pr_perror("Can't readlink %s", fd_str);
-		return len;
-	}
-
-	big_buffer[len] = '\0';
-	pr_info("Dumping path for %d fd via self %d [%s]\n",
-			p->fd, lfd, big_buffer);
-
-	if (check_path_remap(big_buffer, &p->stat, lfd, id))
-		return -1;
-
-	rfe.len = len;
-	rfe.flags = p->flags;
-	rfe.pos = p->pos;
-	rfe.id = id;
-	rfe.fown = p->fown;
-
-	rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
-
-	if (write_img(rfd, &rfe))
-		return -1;
-	if (write_img_buf(rfd, big_buffer, len))
-		return -1;
-
-	return 0;
-}
-
 u32 make_gen_id(const struct fd_parms *p)
 {
 	return MAKE_FD_GENID(p->stat.st_dev, p->stat.st_ino, p->pos);
@@ -348,18 +174,6 @@ err:
 	return ret;
 }
 
-static const struct fdtype_ops regfile_ops = {
-	.type		= FDINFO_REG,
-	.make_gen_id	= make_gen_id,
-	.dump		= dump_one_reg_file,
-};
-
-static int dump_reg_file(struct fd_parms *p, int lfd,
-			     const struct cr_fdset *cr_fdset)
-{
-	return do_dump_gen_file(p, lfd, &regfile_ops, cr_fdset);
-}
-
 static int dump_task_exe_link(pid_t pid, struct mm_entry *mm)
 {
 	struct fd_parms params = { };
diff --git a/files-reg.c b/files-reg.c
new file mode 100644
index 0000000..3407bee
--- /dev/null
+++ b/files-reg.c
@@ -0,0 +1,433 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "crtools.h"
+
+#include "files.h"
+#include "image.h"
+#include "list.h"
+#include "util.h"
+
+#include "files-reg.h"
+
+struct reg_file_info {
+	struct file_desc	d;
+
+	struct reg_file_entry	rfe;
+	char			*remap_path;
+	char			*path;
+};
+
+struct ghost_file {
+	struct list_head	list;
+	u32			id;
+	char			*path;
+};
+
+/*
+ * Ghost files are those not visible from the FS. Dumping them is
+ * nasty and the only way we have -- just carry its contents with
+ * us. Any brave soul to implement link unlinked file back?
+ */
+struct ghost_file_dumpee {
+	struct list_head	list;
+	u32			id;
+	u32			dev;
+	u32			ino;
+};
+
+static u32 ghost_file_ids = 1;
+static LIST_HEAD(ghost_files);
+
+/*
+ * This constant is selected without any calculations. Just do not
+ * want to pick up too big files with us in the image.
+ */
+#define MAX_GHOST_FILE_SIZE	(1 * 1024 * 1024)
+
+void clear_ghost_files(void)
+{
+	struct ghost_file *gf;
+
+	pr_info("Unlinking ghosts\n");
+	list_for_each_entry(gf, &ghost_files, list) {
+		pr_info("\t`- %s\n", gf->path);
+		unlink(gf->path);
+	}
+}
+
+static int open_remap_ghost(struct reg_file_info *rfi, struct remap_file_path_entry *rfe)
+{
+	struct ghost_file_entry gfe;
+	struct ghost_file *gf;
+	int gfd, ifd;
+
+	list_for_each_entry(gf, &ghost_files, list) {
+		if (gf->id == rfe->remap_id)
+			goto gf_found;
+	}
+
+	/*
+	 * Ghost not found. We will create one in the same dir
+	 * as the very first client of it thus resolving any
+	 * issues with cross-device links.
+	 */
+	pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);
+
+	gf = xmalloc(sizeof(*gf));
+	if (!gf)
+		return -1;
+	gf->path = xmalloc(PATH_MAX);
+	if (!gf->path)
+		goto err;
+
+	ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id);
+	if (ifd < 0)
+		goto err;
+
+	if (read_img(ifd, &gfe) < 0)
+		goto err;
+
+	snprintf(gf->path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id);
+	gfd = open(gf->path, O_WRONLY | O_CREAT | O_EXCL, gfe.mode);
+	if (gfd < 0) {
+		pr_perror("Can't open ghost file");
+		goto err;
+	}
+
+	if (fchown(gfd, gfe.uid, gfe.gid) < 0) {
+		pr_perror("Can't reset user/group on ghost %#x\n", rfe->remap_id);
+		goto err;
+	}
+
+	if (copy_file(ifd, gfd, 0) < 0)
+		goto err;
+
+	close(ifd);
+	close(gfd);
+
+	gf->id = rfe->remap_id;
+	list_add_tail(&gf->list, &ghost_files);
+
+gf_found:
+	rfi->remap_path = gf->path;
+	return 0;
+
+err:
+	xfree(gf->path);
+	xfree(gf);
+	return -1;
+}
+
+static int collect_remaps(void)
+{
+	int fd, ret = 0;
+
+	fd = open_image_ro(CR_FD_REMAP_FPATH);
+	if (fd < 0)
+		return -1;
+
+	while (1) {
+		struct remap_file_path_entry rfe;
+		struct reg_file_info *rfi;
+		struct file_desc *fdesc;
+
+		ret = read_img_eof(fd, &rfe);
+		if (ret <= 0)
+			break;
+
+		ret = -1;
+		if (!(rfe.remap_id & REMAP_GHOST)) {
+			pr_err("Non ghost remap not supported @%#x\n", rfe.orig_id);
+			break;
+		}
+
+		fdesc = find_file_desc_raw(FDINFO_REG, rfe.orig_id);
+		if (fdesc == NULL) {
+			pr_err("Remap for non existing file %#x\n",
+					rfe.orig_id);
+			break;
+		}
+
+		rfe.remap_id &= ~REMAP_GHOST;
+		rfi = container_of(fdesc, struct reg_file_info, d);
+		pr_info("Configuring remap %#x -> %#x\n", rfi->rfe.id, rfe.remap_id);
+		ret = open_remap_ghost(rfi, &rfe);
+		if (ret < 0)
+			break;
+	}
+
+	close(fd);
+	return ret;
+}
+
+static int dump_ghost_file(int _fd, u32 id, const struct stat *st)
+{
+	struct ghost_file_entry gfe;
+	char lpath[32];
+	int img, fd;
+
+	pr_info("Dumping ghost file contents (id %#x)\n", id);
+
+	img = open_image(CR_FD_GHOST_FILE, O_DUMP, id);
+	if (img < 0)
+		return -1;
+
+	/*
+	 * Reopen file locally since it may have no read
+	 * permissions when drained
+	 */
+	snprintf(lpath, sizeof(lpath), "/proc/self/fd/%d", _fd);
+	fd = open(lpath, O_RDONLY);
+	if (fd < 0) {
+		pr_perror("Can't open ghost original file");
+		return -1;
+	}
+
+	gfe.uid	= st->st_uid;
+	gfe.gid	= st->st_gid;
+	gfe.mode= st->st_mode;
+
+	if (write_img(img, &gfe))
+		return -1;
+
+	if (copy_file(fd, img, st->st_size))
+		return -1;
+
+	close(fd);
+	close(img);
+	return 0;
+}
+
+static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
+{
+	struct remap_file_path_entry rpe;
+	struct ghost_file_dumpee *gf;
+
+	pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id);
+
+	if (st->st_size > MAX_GHOST_FILE_SIZE) {
+		pr_err("Can't dump ghost file %s of %lu size\n",
+		       path, st->st_size);
+		return -1;
+	}
+
+	list_for_each_entry(gf, &ghost_files, list) {
+		if ((gf->dev == st->st_dev) && (gf->ino == st->st_ino))
+			goto dump_entry;
+	}
+
+	gf = xmalloc(sizeof(*gf));
+	if (gf == NULL)
+		return -1;
+
+	gf->dev	= st->st_dev;
+	gf->ino	= st->st_ino;
+	gf->id	= ghost_file_ids++;
+
+	list_add_tail(&gf->list, &ghost_files);
+
+	if (dump_ghost_file(lfd, gf->id, st))
+		return -1;
+
+dump_entry:
+	rpe.orig_id	= id;
+	rpe.remap_id	= gf->id | REMAP_GHOST;
+
+	return write_img(fdset_fd(glob_fdset, CR_FD_REMAP_FPATH), &rpe);
+}
+
+static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id)
+{
+	int ret;
+	struct stat pst;
+
+	if (ost->st_nlink == 0) {
+		/*
+		 * Unpleasant, but easy case. File is completely invisible
+		 * from the FS. Just dump its contents and that's it. But
+		 * be careful whether anybody still has any of its hardlinks
+		 * also open.
+		 */
+		return dump_ghost_remap(path, ost, lfd, id);
+	}
+
+	ret = stat(path, &pst);
+	if (ret < 0) {
+		/*
+		 * FIXME linked file, but path is not accessible (unless any
+		 * other error occurred). We can create a temporary link to it
+		 * uning linkat with AT_EMPTY_PATH flag and remap it to this
+		 * name.
+		 */
+		pr_perror("Can't stat path");
+		return -1;
+	}
+
+	if ((pst.st_ino != ost->st_ino) || (pst.st_dev != ost->st_dev)) {
+		/*
+		 * FIXME linked file, but the name we see it by is reused
+		 * by somebody else.
+		 */
+		pr_err("Unaccessible path opened %u:%u, need %u:%u\n",
+		       (int)pst.st_dev, (int)pst.st_ino,
+		       (int)ost->st_dev, (int)ost->st_ino);
+		return -1;
+	}
+
+	/*
+	 * File is linked and visible by the name it is opened by
+	 * this task. Go ahead and dump it.
+	 */
+	return 0;
+}
+
+int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
+{
+	struct reg_file_entry rfe;
+	char path[PATH_MAX];
+	char fd_str[128];
+	int len, rfd;
+
+	snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
+	len = readlink(fd_str, path, sizeof(path) - 1);
+	if (len < 0) {
+		pr_perror("Can't readlink %s", fd_str);
+		return len;
+	}
+
+	path[len] = '\0';
+	pr_info("Dumping path for %d fd via self %d [%s]\n",
+		p->fd, lfd, path);
+
+	if (check_path_remap(path, &p->stat, lfd, id))
+		return -1;
+
+	rfe.id		= id;
+	rfe.flags	= p->flags;
+	rfe.len		= len;
+	rfe.pos		= p->pos;
+	rfe.fown	= p->fown;
+
+	rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
+
+	if (write_img(rfd, &rfe))
+		return -1;
+	if (write_img_buf(rfd, path, len))
+		return -1;
+
+	return 0;
+}
+
+static const struct fdtype_ops regfile_ops = {
+	.type		= FDINFO_REG,
+	.make_gen_id	= make_gen_id,
+	.dump		= dump_one_reg_file,
+};
+
+int dump_reg_file(struct fd_parms *p, int lfd, const struct cr_fdset *set)
+{
+	return do_dump_gen_file(p, lfd, &regfile_ops, set);
+}
+
+static int open_fe_fd(struct file_desc *d)
+{
+	struct reg_file_info *rfi;
+	int tmp;
+
+	rfi = container_of(d, struct reg_file_info, d);
+	if (rfi->remap_path) {
+		if (link(rfi->remap_path, rfi->path) < 0) {
+			pr_perror("Can't link %s -> %s\n",
+				  rfi->remap_path, rfi->path);
+			return -1;
+		}
+	}
+
+	tmp = open(rfi->path, rfi->rfe.flags);
+	if (tmp < 0) {
+		pr_perror("Can't open file %s", rfi->path);
+		return -1;
+	}
+
+	if (rfi->remap_path)
+		unlink(rfi->path);
+
+	lseek(tmp, rfi->rfe.pos, SEEK_SET);
+
+	if (restore_fown(tmp, &rfi->rfe.fown))
+		return -1;
+
+	return tmp;
+}
+
+int open_reg_by_id(u32 id)
+{
+	struct file_desc *d;
+
+	d = find_file_desc_raw(FDINFO_REG, id);
+	if (!d) {
+		pr_perror("Can't find regfile for %#x\n", id);
+		return -1;
+	}
+
+	return open_fe_fd(d);
+}
+
+static struct file_desc_ops reg_desc_ops = {
+	.type = FDINFO_REG,
+	.open = open_fe_fd,
+};
+
+int collect_reg_files(void)
+{
+	struct reg_file_info *rfi = NULL;
+	int fd, ret = -1;
+
+	fd = open_image_ro(CR_FD_REG_FILES);
+	if (fd < 0)
+		return -1;
+
+	while (1) {
+		int len;
+
+		rfi = xmalloc(sizeof(*rfi));
+		ret = -1;
+		if (rfi == NULL)
+			break;
+
+		rfi->path = NULL;
+		ret = read_img_eof(fd, &rfi->rfe);
+		if (ret <= 0)
+			break;
+
+		len = rfi->rfe.len;
+		rfi->path = xmalloc(len + 1);
+		ret = -1;
+		if (rfi->path == NULL)
+			break;
+
+		ret = read_img_buf(fd, rfi->path, len);
+		if (ret < 0)
+			break;
+
+		rfi->remap_path = NULL;
+		rfi->path[len] = '\0';
+
+		pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe.id);
+		file_desc_add(&rfi->d, rfi->rfe.id, &reg_desc_ops);
+	}
+
+	if (rfi) {
+		xfree(rfi->path);
+		xfree(rfi);
+	}
+
+	close(fd);
+
+	return collect_remaps();
+}
diff --git a/files.c b/files.c
index 82b9fad..e504d2e 100644
--- a/files.c
+++ b/files.c
@@ -81,13 +81,6 @@ struct fdinfo_list_entry *file_master(struct file_desc *d)
 			struct fdinfo_list_entry, desc_list);
 }
 
-struct reg_file_info {
-	struct reg_file_entry rfe;
-	char *remap_path;
-	char *path;
-	struct file_desc d;
-};
-
 void show_saved_files(void)
 {
 	int i;
@@ -157,184 +150,6 @@ int rst_file_params(int fd, fown_t *fown, int flags)
 	return 0;
 }
 
-static int open_fe_fd(struct file_desc *d);
-
-static struct file_desc_ops reg_desc_ops = {
-	.type = FDINFO_REG,
-	.open = open_fe_fd,
-};
-
-struct ghost_file {
-	u32 id;
-	char *path;
-	struct list_head list;
-};
-
-static LIST_HEAD(ghost_files);
-
-void clear_ghost_files(void)
-{
-	struct ghost_file *gf;
-
-	pr_info("Unlinking ghosts\n");
-
-	list_for_each_entry(gf, &ghost_files, list) {
-		pr_info("\t`- %s\n", gf->path);
-		unlink(gf->path);
-	}
-}
-
-static int open_remap_ghost(struct reg_file_info *rfi,
-		struct remap_file_path_entry *rfe)
-{
-	struct ghost_file *gf;
-	struct ghost_file_entry gfe;
-	int gfd, ifd;
-
-	list_for_each_entry(gf, &ghost_files, list)
-		if (gf->id == rfe->remap_id)
-			goto gf_found;
-
-	/*
-	 * Ghost not found. We will create one in the same dir
-	 * as the very first client of it thus resolving any
-	 * issues with cross-device links.
-	 */
-
-	pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);
-
-	gf = xmalloc(sizeof(*gf));
-	if (!gf)
-		return -1;
-	gf->path = xmalloc(PATH_MAX);
-	if (!gf->path)
-		return -1;
-
-	ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id);
-	if (ifd < 0)
-		return -1;
-
-	if (read_img(ifd, &gfe) < 0)
-		return -1;
-
-	snprintf(gf->path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id);
-	gfd = open(gf->path, O_WRONLY | O_CREAT | O_EXCL, gfe.mode);
-	if (gfd < 0) {
-		pr_perror("Can't open ghost file");
-		return -1;
-	}
-
-	if (fchown(gfd, gfe.uid, gfe.gid) < 0) {
-		pr_perror("Can't reset user/group on ghost %#x\n", rfe->remap_id);
-		return -1;
-	}
-
-	if (copy_file(ifd, gfd, 0) < 0)
-		return -1;
-
-	close(ifd);
-	close(gfd);
-
-	gf->id = rfe->remap_id;
-	list_add_tail(&gf->list, &ghost_files);
-gf_found:
-	rfi->remap_path = gf->path;
-	return 0;
-}
-
-static int collect_remaps(void)
-{
-	int fd, ret = 0;
-
-	fd = open_image_ro(CR_FD_REMAP_FPATH);
-	if (fd < 0)
-		return -1;
-
-	while (1) {
-		struct remap_file_path_entry rfe;
-		struct file_desc *fdesc;
-		struct reg_file_info *rfi;
-
-		ret = read_img_eof(fd, &rfe);
-		if (ret <= 0)
-			break;
-
-		ret = -1;
-
-		if (!(rfe.remap_id & REMAP_GHOST)) {
-			pr_err("Non ghost remap not supported @%#x\n",
-					rfe.orig_id);
-			break;
-		}
-
-		fdesc = find_file_desc_raw(FDINFO_REG, rfe.orig_id);
-		if (fdesc == NULL) {
-			pr_err("Remap for non existing file %#x\n",
-					rfe.orig_id);
-			break;
-		}
-
-		rfe.remap_id &= ~REMAP_GHOST;
-		rfi = container_of(fdesc, struct reg_file_info, d);
-		pr_info("Configuring remap %#x -> %#x\n", rfi->rfe.id, rfe.remap_id);
-		ret = open_remap_ghost(rfi, &rfe);
-		if (ret < 0)
-			break;
-	}
-
-	close(fd);
-	return ret;
-}
-
-int collect_reg_files(void)
-{
-	struct reg_file_info *rfi = NULL;
-	int fd, ret = -1;
-
-	fd = open_image_ro(CR_FD_REG_FILES);
-	if (fd < 0)
-		return -1;
-
-	while (1) {
-		int len;
-
-		rfi = xmalloc(sizeof(*rfi));
-		ret = -1;
-		if (rfi == NULL)
-			break;
-
-		rfi->path = NULL;
-		ret = read_img_eof(fd, &rfi->rfe);
-		if (ret <= 0)
-			break;
-
-		len = rfi->rfe.len;
-		rfi->path = xmalloc(len + 1);
-		ret = -1;
-		if (rfi->path == NULL)
-			break;
-
-		ret = read_img_buf(fd, rfi->path, len);
-		if (ret < 0)
-			break;
-
-		rfi->remap_path = NULL;
-		rfi->path[len] = '\0';
-
-		pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe.id);
-		file_desc_add(&rfi->d, rfi->rfe.id, &reg_desc_ops);
-	}
-
-	if (rfi) {
-		xfree(rfi->path);
-		xfree(rfi);
-	}
-
-	close(fd);
-
-	return collect_remaps();
-}
-
 static int collect_fd(int pid, struct fdinfo_entry *e, struct rst_info *rst_info)
 {
 	struct fdinfo_list_entry *l, *le = &fdinfo_list[nr_fdinfo_list];
@@ -403,49 +218,6 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info)
 	return ret;
 }
 
-static int open_fe_fd(struct file_desc *d)
-{
-	struct reg_file_info *rfi;
-	int tmp;
-
-	rfi = container_of(d, struct reg_file_info, d);
-
-	if (rfi->remap_path)
-		if (link(rfi->remap_path, rfi->path) < 0) {
-			pr_perror("Can't link %s -> %s\n",
-					rfi->remap_path, rfi->path);
-			return -1;
-		}
-
-	tmp = open(rfi->path, rfi->rfe.flags);
-	if (tmp < 0) {
-		pr_perror("Can't open file %s", rfi->path);
-		return -1;
-	}
-
-	if (rfi->remap_path)
-		unlink(rfi->path);
-
-	lseek(tmp, rfi->rfe.pos, SEEK_SET);
-
-	if (restore_fown(tmp, &rfi->rfe.fown))
-		return -1;
-
-	return tmp;
-}
-int open_reg_by_id(u32 id)
-{
-	struct file_desc *fd;
-
-	fd = find_file_desc_raw(FDINFO_REG, id);
-	if (fd == NULL) {
-		pr_perror("Can't find regfile for %#x\n", id);
-		return -1;
-	}
-
-	return open_fe_fd(fd);
-}
-
 #define SETFL_MASK (O_APPEND | O_ASYNC | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
 int set_fd_flags(int fd, int flags)
 {
diff --git a/include/files-reg.h b/include/files-reg.h
new file mode 100644
index 0000000..04b2862
--- /dev/null
+++ b/include/files-reg.h
@@ -0,0 +1,16 @@
+#ifndef FILES_REG_H__
+#define FILES_REG_H__
+
+#include "types.h"
+
+struct cr_fdset;
+struct fd_parms;
+
+extern int open_reg_by_id(u32 id);
+extern void clear_ghost_files(void);
+extern int collect_reg_files(void);
+
+extern int dump_reg_file(struct fd_parms *p, int lfd, const struct cr_fdset *set);
+extern int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p);
+
+#endif /* FILES_REG_H__ */
-- 
1.7.7.6



More information about the CRIU mailing list