From 96be8be2d166c636c0dfcce3c2f435a2b50f6f30 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Thu, 5 Apr 2012 20:02:00 +0400 Subject: [PATCH] pipe: save all pipe data in a separate file 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 Signed-off-by: Pavel Emelyanov --- cr-dump.c | 27 ++++++++++++++++++++++++++- cr-show.c | 30 ++++++++++++++++++++++++++---- crtools.c | 7 +++++++ include/crtools.h | 3 +++ include/image.h | 13 +++++++++++++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/cr-dump.c b/cr-dump.c index be078b189..68b8a48a8 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 1ed3e5c6f..9ca4578bb 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 bb155a28a..3735d247e 100644 --- a/crtools.c +++ b/crtools.c @@ -81,6 +81,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 ef967d4da..2aac2ef87 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -49,6 +49,7 @@ enum { CR_FD_REG_FILES, CR_FD_INETSK, CR_FD_PIPES, + CR_FD_PIPES_DATA, _CR_FD_GLOB_TO, CR_FD_MAX @@ -84,6 +85,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); @@ -98,6 +100,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 1a0135cb5..73cd5f2e2 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,22 @@ 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 {