[CRIU] crtools error: "can't splice to pipe"
Cyrill Gorcunov
gorcunov at gmail.com
Tue Apr 29 07:05:46 PDT 2014
On Tue, Apr 29, 2014 at 10:01:08AM -0400, J F wrote:
> Here is an update one. Btw, you can fetch the latest criu repo by
>
> A A A A git clone --depth 1 https://github.com/xemul/criu.git
> A A A A git checkout -f
> A A A A git apply patch
> A A A A make
>
> I did the above and got an error applying patch, doesn't occur with your
> other patch file.
Weird. Mind to try apply this one?
-------------- next part --------------
diff --git a/pie/parasite.c b/pie/parasite.c
index 152186271361..fe1e8750e6a4 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -60,7 +60,7 @@ static int mprotect_vmas(struct parasite_dump_pages_args *args)
static int dump_pages(struct parasite_dump_pages_args *args)
{
- int p, ret;
+ int p, ret, summary;
struct iovec *iovs;
p = recv_fd(tsock);
@@ -70,7 +70,48 @@ static int dump_pages(struct parasite_dump_pages_args *args)
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) {
+ pr_debug("\tSplicing %u segments (iovs %p off %u iov %p): ret %i\n",
+ args->nr_segs, iovs, args->off, &iovs[args->off], ret);
+
+ summary = args->nr_pages * PAGE_SIZE;
+ while (ret > 0 && ret != summary) {
+ int left_pages = summary - (ret / PAGE_SIZE);
+ struct iovec *iov = &iovs[args->nr_segs - 1];
+ unsigned int nr_segs = 0;
+
+ summary = left_pages * PAGE_SIZE;
+ while (left_pages) {
+ left_pages -= iov->iov_len / PAGE_SIZE;
+ nr_segs++;
+ iov--;
+
+ if (left_pages < 0) {
+ int d = (-left_pages) * PAGE_SIZE;
+
+ /*
+ * We're in a middle of IOV, need
+ * to adjust base address.
+ */
+ iov[1].iov_base += d;
+ iov[1].iov_len -= d;
+
+ if (iov[1].iov_len < d) {
+ pr_err("Wrong len: %i\n", d);
+ sys_close(p);
+ return -1;
+ }
+
+ left_pages = 0;
+ }
+ }
+
+ ret = sys_vmsplice(p, &iov[1], nr_segs,
+ SPLICE_F_GIFT | SPLICE_F_NONBLOCK);
+ pr_debug("\t\tContinue splicing %u segments (iov %p): ret %i\n",
+ nr_segs, &iov[1], ret);
+ }
+
+ if (ret < 0) {
sys_close(p);
pr_err("Can't splice pages to pipe (%d/%d)\n", ret, args->nr_pages);
return -1;
More information about the CRIU
mailing list