[CRIU] [PATCH 1/2] page-server: Fix incompatibility of page server protocol

Pavel Emelyanov xemul at virtuozzo.com
Fri Jul 14 18:30:57 MSK 2017


It turned out (surprise surprise) that page server exchanges CR_FD_PAGEMAP
and CR_FD_SHMEM_PAGEMAP values in ps_iov_msg. The problem is that these
constants sit in enum and change their values from version to version %)

So here's the fixed version of the protocol including the backward compat
checks on all the values that could be met from older CRIUs (we're lucky
and they didn't intersect).

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/page-xfer.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index d949c06..56d1853 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -54,14 +54,61 @@ static void psi2iovec(struct page_server_iov *ps, struct iovec *iov)
 #define PS_TYPE_BITS	8
 #define PS_TYPE_MASK	((1 << PS_TYPE_BITS) - 1)
 
+#define PS_TYPE_PID	(1)
+#define PS_TYPE_SHMEM	(2)
+/*
+ * XXX: When adding new types here check decode_pm_type for legacy
+ * numbers that can be met from older CRIUs
+ */
+
 static inline u64 encode_pm_id(int type, long id)
 {
+	if (type == CR_FD_PAGEMAP)
+		type = PS_TYPE_PID;
+	else if (type == CR_FD_SHMEM_PAGEMAP)
+		type = PS_TYPE_SHMEM;
+	else {
+		BUG();
+		return 0;
+	}
+
 	return ((u64)id) << PS_TYPE_BITS | type;
 }
 
 static int decode_pm_type(u64 dst_id)
 {
-	return dst_id & PS_TYPE_MASK;
+	int type;
+
+	/*
+	 * Magic numbers below came from the older CRIU versions that
+	 * errorneously used the changing CR_FD_* constants. The
+	 * changes were made when we merged images together and moved
+	 * the CR_FD_-s at the tail of the enum
+	 */
+	type = dst_id & PS_TYPE_MASK;
+	switch (type) {
+	case 10: /* 3.1 3.2 */
+	case 11: /* 1.3 1.4 1.5 1.6 1.7 1.8 2.* 3.0 */
+	case 16: /* 1.2 */
+	case 17: /* 1.0 1.1 */
+	case PS_TYPE_PID:
+		type = CR_FD_PAGEMAP;
+		break;
+	case 27: /* 1.3 */
+	case 28: /* 1.4 1.5 */
+	case 29: /* 1.6 1.7 */
+	case 32: /* 1.2 1.8 */
+	case 33: /* 1.0 1.1 3.1 3.2 */
+	case 34: /* 2.* 3.0 */
+	case PS_TYPE_SHMEM:
+		type = CR_FD_SHMEM_PAGEMAP;
+		break;
+	default:
+		type = -1;
+		break;
+	}
+
+	return type;
 }
 
 static long decode_pm_id(u64 dst_id)
@@ -497,6 +544,11 @@ static int page_server_check_parent(int sk, struct page_server_iov *pi)
 	type = decode_pm_type(pi->dst_id);
 	id = decode_pm_id(pi->dst_id);
 
+	if (type == -1) {
+		pr_err("Unknown pagemap type received\n");
+		return -1;
+	}
+
 	ret = check_parent_local_xfer(type, id);
 	if (ret < 0)
 		return -1;
@@ -571,6 +623,11 @@ static int page_server_open(int sk, struct page_server_iov *pi)
 
 	type = decode_pm_type(pi->dst_id);
 	id = decode_pm_id(pi->dst_id);
+	if (type == -1) {
+		pr_err("Unknown pagemap type received\n");
+		return -1;
+	}
+
 	pr_info("Opening %d/%ld\n", type, id);
 
 	page_server_close();
-- 
2.1.4


More information about the CRIU mailing list