mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
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 <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
7b10ef0761
commit
96be8be2d1
27
cr-dump.c
27
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) {
|
||||
|
30
cr-show.c
30
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:
|
||||
|
@@ -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,
|
||||
|
@@ -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"
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user