[CRIU] [PATCH] page-xfer: receive information about presence of a parent from a page server

Andrey Vagin avagin at openvz.org
Thu Nov 6 14:18:26 PST 2014


We need to know this to insert holes. Currently xfer->parent isn't
initialized for remote sessions. In most cases it has a non-zero value,
so generate_iovs() is called with has_parent = true.

bash test/zdtm.sh -p -P -i 3 ns/transition/fork
(00.000106) Error (sysctl.c:194): Can't open sysctl net/ipv4/tcp_wmem: No such file or directory
(00.017048)    420: Error (image.c:231): Unable to open pagemap-420.img: No such file or directory
(00.017065)    420: Error (image.c:231): Unable to open pages-420.img: No such file or directory
(00.017090)    420: Error (page-read.c:73): No parent for snapshot pagemap
(00.017290)     86: Error (cr-restore.c:1185): 420 exited, status=1
(00.017317) Error (cr-restore.c:1831): Restoring FAILED.

Reported-by: Mr Jenkins
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 page-xfer.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/page-xfer.c b/page-xfer.c
index 86e26d8..c3af4a5 100644
--- a/page-xfer.c
+++ b/page-xfer.c
@@ -79,7 +79,8 @@ static void page_server_close(void)
 		cxfer.loc_xfer.close(&cxfer.loc_xfer);
 }
 
-static int page_server_open(struct page_server_iov *pi)
+static void close_page_xfer(struct page_xfer *xfer);
+static int page_server_open(int sk, struct page_server_iov *pi)
 {
 	int type;
 	long id;
@@ -94,6 +95,17 @@ static int page_server_open(struct page_server_iov *pi)
 		return -1;
 
 	cxfer.dst_id = pi->dst_id;
+
+	if (sk >= 0) {
+		char has_parent = !!cxfer.loc_xfer.parent;
+
+		if (write(sk, &has_parent, 1) != 1) {
+			pr_perror("Unable to send reponse");
+			close_page_xfer(&cxfer.loc_xfer);
+			return -1;
+		}
+	}
+
 	return 0;
 }
 
@@ -101,7 +113,7 @@ static int prep_loc_xfer(struct page_server_iov *pi)
 {
 	if (cxfer.dst_id != pi->dst_id) {
 		pr_warn("Deprecated IO w/o open\n");
-		return page_server_open(pi);
+		return page_server_open(-1, pi);
 	} else
 		return 0;
 }
@@ -192,7 +204,7 @@ static int page_server_serve(int sk)
 
 		switch (pi.cmd) {
 		case PS_IOV_OPEN:
-			ret = page_server_open(&pi);
+			ret = page_server_open(sk, &pi);
 			break;
 		case PS_IOV_ADD:
 			ret = page_server_add(sk, &pi);
@@ -482,6 +494,7 @@ static void close_server_xfer(struct page_xfer *xfer)
 static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
 {
 	struct page_server_iov pi;
+	char has_parent;
 
 	xfer->sk = page_server_sk;
 	xfer->write_pagemap = write_pagemap_to_server;
@@ -489,6 +502,7 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
 	xfer->write_hole = write_hole_to_server;
 	xfer->close = close_server_xfer;
 	xfer->dst_id = encode_pm_id(fd_type, id);
+	xfer->parent = NULL;
 
 	pi.cmd = PS_IOV_OPEN;
 	pi.dst_id = xfer->dst_id;
@@ -500,6 +514,14 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
 		return -1;
 	}
 
+	if (read(xfer->sk, &has_parent, 1) != 1) {
+		pr_perror("The page server doesn't answer");
+		return -1;
+	}
+
+	if (has_parent)
+		xfer->parent = (void *) 1; /* This is required for generate_iovs() */
+
 	return 0;
 }
 
-- 
1.9.3



More information about the CRIU mailing list