[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