[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