[CRIU] [PATCH] [RFC] tcp: split packets if it can't be restored with the ENOMEM error

Andrey Vagin avagin at openvz.org
Thu Nov 20 13:40:06 PST 2014


Currently CRIU restore fails if a packet can't be restored.
(00.000164) Error (sysctl.c:194): Can't open sysctl net/ipv4/tcp_wmem: No such file or directory
(00.019311)     95: Error (sk-tcp.c:477): Can't restore 1 queue data (-1), want (1534662:1534662): Cannot allocate memory
(00.019969) Error (cr-restore.c:1838): Restoring FAILED.

This patch splits packets and tries to restore them again.

Reported-by: Mr Jenkins
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 sk-tcp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/sk-tcp.c b/sk-tcp.c
index eb6dd15..f2b03c2 100644
--- a/sk-tcp.c
+++ b/sk-tcp.c
@@ -472,6 +472,21 @@ static int __send_tcp_queue(int sk, int queue, u32 len, struct cr_img *img)
 		int chunk = (len > max ? max : len);
 
 		ret = send(sk, buf + off, chunk, 0);
+		if (ret == -1 && errno == ENOMEM && max > 0) {
+			/*
+			 * The maximum value is set for per-socket limits,
+			 * send() fails due to global limits, so we can fixup
+			 * maximum size of packet for all socket.
+			 */
+			if (queue == TCP_SEND_QUEUE) {
+				kdat.tcp_max_wshare >>= 1;
+				max = kdat.tcp_max_wshare;
+			} else {
+				kdat.tcp_max_rshare >>= 1;
+				max = kdat.tcp_max_rshare;
+			}
+			continue;
+		}
 		if (ret != chunk) {
 			pr_perror("Can't restore %d queue data (%d), want (%d:%d)",
 				  queue, ret, chunk, len);
-- 
1.9.3



More information about the CRIU mailing list