Commit aefed47f authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

page-pipe: add compatible iovec

struct iovec may have different size for dumpee.
But that reason, pages dump will fail (with added debug to pie):
(00.011440) page-pipe: Page pipe:
(00.011441) page-pipe: * 1 pipes 8/523 iovs:
(00.011442) page-pipe: 	buf 16 pages, 8 iovs:
(00.011444) page-pipe: 		0x8048000 3
(00.011446) page-pipe: 		0xf7512000 1
(00.011447) page-pipe: 		0xf76ca000 4
(00.011449) page-pipe: 		0xf76cf000 1
(00.011450) page-pipe: 		0xf76dc000 2
(00.011452) page-pipe: 		0xf76e1000 1
(00.011454) page-pipe: 		0xf7702000 2
(00.011455) page-pipe: 		0xffdad000 2
(00.011470) page-pipe: * 0 holes:
(00.011471) PPB: 16 pages 8 segs 16 pipe 0 off
(00.011476) Sent msg to daemon 8 0 0
pie: __fetched msg: 8 0 0
(00.011479) Wait for ack 8 on daemon socket
pie: sys_vmsplice for 16 pages 8 segs 0 off
pie:  buf 16 pages, 8 iovs:
pie: 	0x8048000 0
pie: 	0x3000 0
pie: 	0xf7512000 0
pie: 	0x1000 0
pie: 	0xf76ca000 0
pie: 	0x4000 0
pie: 	0xf76cf000 0
pie: 	0x1000 0
pie: Error (pie/parasite.c:93): Can't splice pages to pipe (0/16)
pie: __sent ack msg: 8 8 -1

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 8e329bde
......@@ -119,6 +119,7 @@ extern int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
extern int __parasite_execute_syscall(struct parasite_ctl *ctl,
user_regs_struct_t *regs, const char *code_syscall);
extern bool arch_can_dump_task(struct parasite_ctl *ctl);
extern bool seized_native(struct parasite_ctl *ctl);
/*
* The PTRACE_SYSCALL will trap task twice -- on
......
......@@ -304,6 +304,8 @@ static int __parasite_dump_pages_seized(struct pstree_item *item,
* use, i.e. on non-lazy non-predump.
*/
cpp_flags |= PP_CHUNK_MODE;
if (!seized_native(ctl))
cpp_flags |= PP_COMPAT;
pp = create_page_pipe(vma_area_list->priv_size,
pargs_iovs(args), cpp_flags);
if (!pp)
......
......@@ -81,6 +81,18 @@ static int ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size)
return 0;
}
/* XXX: move to arch-depended file, when non-x86 add support for compat mode */
struct iovec_compat {
u32 iov_base;
u32 iov_len;
};
static inline void iov_init_compat(struct iovec_compat *iov, unsigned long addr)
{
iov->iov_base = (u32)addr;
iov->iov_len = PAGE_SIZE;
}
static int page_pipe_grow(struct page_pipe *pp)
{
struct page_pipe_buf *ppb;
......@@ -208,7 +220,13 @@ static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *pp
pr_debug("Add iov to page pipe (%u iovs, %u/%u total)\n",
ppb->nr_segs, pp->free_iov, pp->nr_iovs);
if (pp->flags & PP_COMPAT) {
struct iovec_compat *iovs = (void *)ppb->iov;
iov_init_compat(&iovs[ppb->nr_segs++], addr);
} else {
iov_init(&ppb->iov[ppb->nr_segs++], addr);
}
pp->free_iov++;
BUG_ON(pp->free_iov > pp->nr_iovs);
out:
......@@ -256,7 +274,13 @@ int page_pipe_add_hole(struct page_pipe *pp, unsigned long addr)
iov_grow_page(&pp->holes[pp->free_hole - 1], addr))
goto out;
if (pp->flags & PP_COMPAT) {
struct iovec_compat *iovs = (void *)pp->holes;
iov_init_compat(&iovs[pp->free_hole++], addr);
} else {
iov_init(&pp->holes[pp->free_hole++], addr);
}
out:
return 0;
}
......@@ -266,6 +290,7 @@ void debug_show_page_pipe(struct page_pipe *pp)
struct page_pipe_buf *ppb;
int i;
struct iovec *iov;
struct iovec_compat *iov_c;
if (pr_quelled(LOG_DEBUG))
return;
......@@ -277,14 +302,28 @@ void debug_show_page_pipe(struct page_pipe *pp)
pr_debug("\tbuf %u pages, %u iovs:\n",
ppb->pages_in, ppb->nr_segs);
for (i = 0; i < ppb->nr_segs; i++) {
if (pp->flags & PP_COMPAT) {
iov_c = (void *)ppb->iov;
pr_debug("\t\t%x %lu\n", iov_c[i].iov_base,
iov_c[i].iov_len / PAGE_SIZE);
} else {
iov = &ppb->iov[i];
pr_debug("\t\t%p %lu\n", iov->iov_base, iov->iov_len / PAGE_SIZE);
pr_debug("\t\t%p %lu\n", iov->iov_base,
iov->iov_len / PAGE_SIZE);
}
}
}
pr_debug("* %u holes:\n", pp->free_hole);
for (i = 0; i < pp->free_hole; i++) {
if (pp->flags & PP_COMPAT) {
iov_c = (void *)pp->holes;
pr_debug("\t%x %lu\n", iov_c[i].iov_base,
iov_c[i].iov_len / PAGE_SIZE);
} else {
iov = &pp->holes[i];
pr_debug("\t%p %lu\n", iov->iov_base, iov->iov_len / PAGE_SIZE);
pr_debug("\t%p %lu\n", iov->iov_base,
iov->iov_len / PAGE_SIZE);
}
}
}
......@@ -120,7 +120,7 @@ static int restore_thread_ctx(int pid, struct thread_ctx *ctx)
return ret;
}
static inline bool seized_native(struct parasite_ctl *ctl)
bool seized_native(struct parasite_ctl *ctl)
{
return user_regs_native(&ctl->orig.regs);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment