[CRIU] [PATCH cr 10/11] pipe: save all pipe data in a separate file

Andrey Vagin avagin at openvz.org
Thu Apr 5 12:02:14 EDT 2012


A pipe buffer has 16 slots. A slot is page, offset and size.
When we use splice and data is not aligned, splice connects
a page from file cache and set offset. For this reason we loose
a part of buffer.

If a data size is more than 15 pages, data will be aligned in a image.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-dump.c         |   27 ++++++++++++++++++++++++++-
 cr-show.c         |   30 ++++++++++++++++++++++++++----
 crtools.c         |    7 +++++++
 include/crtools.h |    3 +++
 include/image.h   |   11 +++++++++++
 5 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index f1e9f6c..e78aaf8 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -215,13 +215,38 @@ static int dump_one_pipe(int lfd, u32 id, const struct fd_parms *p)
 dump:
 	pe.id = id;
 	pe.pipe_id = p->id;
-	pe.bytes = has_bytes;
 	pe.flags = p->flags;
 
 	if (write_img(fd_pipes, &pe))
 		goto err_close;
 
 	if (has_bytes) {
+		off_t off;
+		struct pipe_data_entry pde;
+
+		fd_pipes = fdset_fd(glob_fdset, CR_FD_PIPES_DATA);
+
+		pde.pipe_id = p->id;
+		pde.bytes = has_bytes;
+		pde.off = 0;
+
+		if (has_bytes > PIPE_NONALIG_DATA) {
+			off = lseek(fd_pipes, 0, SEEK_CUR);
+			off += sizeof(pde);
+			off &= PAGE_SIZE -1;
+			if (off)
+				pde.off = PAGE_SIZE - off;
+			pr_info("off %lx %x\n", off, pde.off);
+		}
+
+		if (write_img(fd_pipes, &pde))
+			goto err_close;
+
+		if (pde.off) {
+			off = lseek(fd_pipes, pde.off, SEEK_CUR);
+			pr_info("off %lx\n", off);
+		}
+
 		ret = splice(steal_pipe[0], NULL, fd_pipes,
 			     NULL, has_bytes, 0);
 		if (ret < 0) {
diff --git a/cr-show.c b/cr-show.c
index f7f8656..38cd3b5 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -126,6 +126,30 @@ out:
 	pr_img_tail(CR_FD_REG_FILES);
 }
 
+void show_pipes_data(int fd_pipes, struct cr_options *o)
+{
+	struct pipe_data_entry e;
+	int ret;
+
+	pr_img_head(CR_FD_PIPES_DATA);
+
+	while (1) {
+		int ret;
+		off_t off;
+
+		ret = read_img_eof(fd_pipes, &e);
+		if (ret <= 0)
+			goto out;
+		pr_msg("pipeid: %8x bytes: %8x off: %8x\n",
+		       e.pipe_id, e.bytes, e.off);
+
+		lseek(fd_pipes, e.off + e.bytes, SEEK_CUR);
+	}
+
+out:
+	pr_img_tail(CR_FD_PIPES);
+}
+
 void show_pipes(int fd_pipes, struct cr_options *o)
 {
 	struct pipe_entry e;
@@ -139,10 +163,8 @@ void show_pipes(int fd_pipes, struct cr_options *o)
 		ret = read_img_eof(fd_pipes, &e);
 		if (ret <= 0)
 			goto out;
-		pr_msg("id: %8x pipeid: %8x flags: %8x bytes: %8x\n",
-		       e.id, e.pipe_id, e.flags, e.bytes);
-		if (e.bytes)
-			lseek(fd_pipes, e.bytes, SEEK_CUR);
+		pr_msg("id: %8x pipeid: %8x flags: %8x\n",
+		       e.id, e.pipe_id, e.flags);
 	}
 
 out:
diff --git a/crtools.c b/crtools.c
index e3c27f6..e4142c8 100644
--- a/crtools.c
+++ b/crtools.c
@@ -82,6 +82,13 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
 		.show	= show_pipes,
 	},
 
+	/* info about pipes - fds, pipe id and pipe data */
+	[CR_FD_PIPES_DATA] = {
+		.fmt	= FMT_FNAME_PIPES_DATA,
+		.magic	= PIPES_DATA_MAGIC,
+		.show	= show_pipes_data,
+	},
+
 	 /* info about process linkage */
 	[CR_FD_PSTREE] = {
 		.fmt	= FMT_FNAME_PSTREE,
diff --git a/include/crtools.h b/include/crtools.h
index 8c494c2..6ab6975 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -50,6 +50,7 @@ enum {
 	CR_FD_REG_FILES,
 	CR_FD_INETSK,
 	CR_FD_PIPES,
+	CR_FD_PIPES_DATA,
 	_CR_FD_GLOB_TO,
 
 	CR_FD_MAX
@@ -85,6 +86,7 @@ void show_reg_files(int fd_reg_files, struct cr_options *o);
 void show_core(int fd_core, struct cr_options *o);
 void show_vmas(int fd_vma, struct cr_options *o);
 void show_pipes(int fd_pipes, struct cr_options *o);
+void show_pipes_data(int fd_pipes, struct cr_options *o);
 void show_pstree(int fd_pstree, struct cr_options *o);
 void show_sigacts(int fd_sigacts, struct cr_options *o);
 void show_itimers(int fd, struct cr_options *o);
@@ -99,6 +101,7 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
 #define FMT_FNAME_CORE		"core-%d.img"
 #define FMT_FNAME_VMAS		"vmas-%d.img"
 #define FMT_FNAME_PIPES		"pipes.img"
+#define FMT_FNAME_PIPES_DATA	"pipes-data.img"
 #define FMT_FNAME_PSTREE	"pstree.img"
 #define FMT_FNAME_SIGACTS	"sigacts-%d.img"
 #define FMT_FNAME_UNIXSK	"unixsk-%d.img"
diff --git a/include/image.h b/include/image.h
index ddd36f7..9dccb11 100644
--- a/include/image.h
+++ b/include/image.h
@@ -15,6 +15,7 @@
 #define CORE_MAGIC	0x55053847 /* Kolomna */
 #define VMAS_MAGIC	0x54123737 /* Tula */
 #define PIPES_MAGIC	0x56513555 /* Tver */
+#define PIPES_DATA_MAGIC 0x56453709 /* Dubna */
 #define SIGACT_MAGIC	0x55344201 /* Murom */
 #define UNIXSK_MAGIC	0x54373943 /* Ryazan */
 #define INETSK_MAGIC	0x56443851 /* Pereslavl */
@@ -75,10 +76,20 @@ struct pipe_entry {
 	u32	id;
 	u32	pipe_id;
 	u32	flags;
+} __packed;
+
+struct pipe_data_entry {
+	u32	pipe_id;
 	u32	bytes;
+	u32	off;
 	u8	data[0];
 } __packed;
 
+/* splice() connect cache pages to pipe buffer, so
+ * some part of pages may be loosed if data are not
+ * aligned in a file. */
+#define PIPE_NONALIG_DATA (15 * PAGE_SIZE)
+
 #define USK_INFLIGHT		1
 
 struct unix_sk_entry {
-- 
1.7.1



More information about the CRIU mailing list