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, ...@@ -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, extern int __parasite_execute_syscall(struct parasite_ctl *ctl,
user_regs_struct_t *regs, const char *code_syscall); user_regs_struct_t *regs, const char *code_syscall);
extern bool arch_can_dump_task(struct parasite_ctl *ctl); 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 * The PTRACE_SYSCALL will trap task twice -- on
......
...@@ -304,6 +304,8 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, ...@@ -304,6 +304,8 @@ static int __parasite_dump_pages_seized(struct pstree_item *item,
* use, i.e. on non-lazy non-predump. * use, i.e. on non-lazy non-predump.
*/ */
cpp_flags |= PP_CHUNK_MODE; cpp_flags |= PP_CHUNK_MODE;
if (!seized_native(ctl))
cpp_flags |= PP_COMPAT;
pp = create_page_pipe(vma_area_list->priv_size, pp = create_page_pipe(vma_area_list->priv_size,
pargs_iovs(args), cpp_flags); pargs_iovs(args), cpp_flags);
if (!pp) if (!pp)
......
...@@ -81,6 +81,18 @@ static int ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size) ...@@ -81,6 +81,18 @@ static int ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size)
return 0; 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) static int page_pipe_grow(struct page_pipe *pp)
{ {
struct page_pipe_buf *ppb; 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 ...@@ -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", pr_debug("Add iov to page pipe (%u iovs, %u/%u total)\n",
ppb->nr_segs, pp->free_iov, pp->nr_iovs); ppb->nr_segs, pp->free_iov, pp->nr_iovs);
iov_init(&ppb->iov[ppb->nr_segs++], addr); 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++; pp->free_iov++;
BUG_ON(pp->free_iov > pp->nr_iovs); BUG_ON(pp->free_iov > pp->nr_iovs);
out: out:
...@@ -256,7 +274,13 @@ int page_pipe_add_hole(struct page_pipe *pp, unsigned long addr) ...@@ -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)) iov_grow_page(&pp->holes[pp->free_hole - 1], addr))
goto out; goto out;
iov_init(&pp->holes[pp->free_hole++], addr); 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: out:
return 0; return 0;
} }
...@@ -266,6 +290,7 @@ void debug_show_page_pipe(struct page_pipe *pp) ...@@ -266,6 +290,7 @@ void debug_show_page_pipe(struct page_pipe *pp)
struct page_pipe_buf *ppb; struct page_pipe_buf *ppb;
int i; int i;
struct iovec *iov; struct iovec *iov;
struct iovec_compat *iov_c;
if (pr_quelled(LOG_DEBUG)) if (pr_quelled(LOG_DEBUG))
return; return;
...@@ -277,14 +302,28 @@ void debug_show_page_pipe(struct page_pipe *pp) ...@@ -277,14 +302,28 @@ void debug_show_page_pipe(struct page_pipe *pp)
pr_debug("\tbuf %u pages, %u iovs:\n", pr_debug("\tbuf %u pages, %u iovs:\n",
ppb->pages_in, ppb->nr_segs); ppb->pages_in, ppb->nr_segs);
for (i = 0; i < ppb->nr_segs; i++) { for (i = 0; i < ppb->nr_segs; i++) {
iov = &ppb->iov[i]; if (pp->flags & PP_COMPAT) {
pr_debug("\t\t%p %lu\n", iov->iov_base, iov->iov_len / PAGE_SIZE); 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("* %u holes:\n", pp->free_hole); pr_debug("* %u holes:\n", pp->free_hole);
for (i = 0; i < pp->free_hole; i++) { for (i = 0; i < pp->free_hole; i++) {
iov = &pp->holes[i]; if (pp->flags & PP_COMPAT) {
pr_debug("\t%p %lu\n", iov->iov_base, iov->iov_len / PAGE_SIZE); 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);
}
} }
} }
...@@ -120,7 +120,7 @@ static int restore_thread_ctx(int pid, struct thread_ctx *ctx) ...@@ -120,7 +120,7 @@ static int restore_thread_ctx(int pid, struct thread_ctx *ctx)
return ret; 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); 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