[CRIU] [PATCH 2/4] parasite: remove restriction to a number of iovec-s
Andrei Vagin
avagin at openvz.org
Tue Nov 7 03:02:35 MSK 2017
From: Andrei Vagin <avagin at virtuozzo.com>
vmsplice can't splice more than UIO_MAXIOV, but we can
call it a few times from a parasite.
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
criu/page-pipe.c | 8 +-------
criu/pie/parasite.c | 25 +++++++++++++++++++++----
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index 7da8bebc3..4eabb5ed5 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -207,15 +207,9 @@ static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *pp
return 1; /* need to add another buf */
}
- if (ppb->nr_segs) {
- if (iov_grow_page(&ppb->iov[ppb->nr_segs - 1], addr))
+ if (ppb->nr_segs && iov_grow_page(&ppb->iov[ppb->nr_segs - 1], addr))
goto out;
- if (ppb->nr_segs == UIO_MAXIOV)
- /* XXX -- shrink pipe back? */
- return 1;
- }
-
pr_debug("Add iov to page pipe (%u iovs, %u/%u total)\n",
ppb->nr_segs, pp->free_iov, pp->nr_iovs);
iov_init(&ppb->iov[ppb->nr_segs++], addr);
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index db2a75f59..6ab3f78f6 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -66,6 +66,7 @@ static int dump_pages(struct parasite_dump_pages_args *args)
{
int p, ret, tsock;
struct iovec *iovs;
+ int off = 0, nr = args->nr_segs, nr_pages;
tsock = parasite_get_rpc_sock();
p = recv_fd(tsock);
@@ -73,11 +74,27 @@ static int dump_pages(struct parasite_dump_pages_args *args)
return -1;
iovs = pargs_iovs(args);
- ret = sys_vmsplice(p, &iovs[args->off], args->nr_segs,
- SPLICE_F_GIFT | SPLICE_F_NONBLOCK);
- if (ret != PAGE_SIZE * args->nr_pages) {
+ nr_pages = 0;
+ if (nr > UIO_MAXIOV)
+ nr = UIO_MAXIOV;
+ while (1) {
+ ret = sys_vmsplice(p, &iovs[args->off + off], nr,
+ SPLICE_F_GIFT | SPLICE_F_NONBLOCK);
+ if (ret < 0) {
+ sys_close(p);
+ pr_err("Can't splice pages to pipe (%d/%d/%d)\n", ret, nr, off);
+ return -1;
+ }
+ nr_pages += ret;
+ off += nr;
+ if (off == args->nr_segs)
+ break;
+ if (off + nr > args->nr_segs)
+ nr = args->nr_segs - off;
+ }
+ if (nr_pages != args->nr_pages * PAGE_SIZE) {
sys_close(p);
- pr_err("Can't splice pages to pipe (%d/%d)\n", ret, args->nr_pages);
+ pr_err("Can't splice pages to pipe (%d/%d)\n", nr_pages, args->nr_pages);
return -1;
}
--
2.13.6
More information about the CRIU
mailing list