[CRIU] [PATCH] page-xfer: Don't expect that page server cmd is read in one call

Pavel Emelyanov xemul at parallels.com
Fri Feb 28 09:19:08 PST 2014


Under memory pressure 24-bytes command for page server can be
splitted in chunks when returned by kernel. Keep that in mind
and continue reading the command by parts.

Are there better ways for doing this?

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>

---

diff --git a/page-xfer.c b/page-xfer.c
index f13b0ac..43112d8 100644
--- a/page-xfer.c
+++ b/page-xfer.c
@@ -165,29 +165,35 @@ static int page_server_serve(int sk)
 	pr_debug("Created xfer pipe size %u\n", cxfer.pipe_size);
 
 	while (1) {
-		struct page_server_iov pi;
-
-		ret = read(sk, &pi, sizeof(pi));
-		if (!ret)
-			break;
+		struct page_server_iov *pi;
+		char pi_buf[sizeof(*pi)];
+		int filled = 0;
+
+		do {
+			ret = read(sk, pi_buf + filled, sizeof(*pi) - filled);
+			if (!ret)
+				break;
+			if (ret < 0) {
+				pr_perror("Can't read pagemap from socket");
+				ret = -1;
+				break;
+			}
 
-		if (ret != sizeof(pi)) {
-			pr_perror("Can't read pagemap from socket");
-			ret = -1;
-			break;
-		}
+			filled += ret;
+		} while (filled < sizeof(*pi));
 
+		pi = (struct page_server_iov *)pi_buf;
 		flushed = false;
 
-		switch (pi.cmd) {
+		switch (pi->cmd) {
 		case PS_IOV_OPEN:
-			ret = page_server_open(&pi);
+			ret = page_server_open(pi);
 			break;
 		case PS_IOV_ADD:
-			ret = page_server_add(sk, &pi);
+			ret = page_server_add(sk, pi);
 			break;
 		case PS_IOV_HOLE:
-			ret = page_server_hole(sk, &pi);
+			ret = page_server_hole(sk, pi);
 			break;
 		case PS_IOV_FLUSH:
 		{
@@ -207,7 +213,7 @@ static int page_server_serve(int sk)
 			break;
 		}
 		default:
-			pr_err("Unknown command %u\n", pi.cmd);
+			pr_err("Unknown command %u\n", pi->cmd);
 			ret = -1;
 			break;
 		}


More information about the CRIU mailing list