[CRIU] [PATCH] sockets: don't double buffer size for sockets

Andrey Vagin avagin at openvz.org
Tue Sep 17 11:03:24 EDT 2013


SO_SNDBUF and SO_RCVBUF sets a double input value, because
"Linux reserves half of te socket buffer for metadata."

So if a process is suspended/restored many times, a socket buffer
size is doubled on each iteration and in a one moment it is overflowed.
Very likely the program hangs in such situation, because the socket with
negative buffer size is unusable.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 sockets.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/sockets.c b/sockets.c
index 68b8bf3..c25ca69 100644
--- a/sockets.c
+++ b/sockets.c
@@ -315,8 +315,13 @@ int restore_socket_opts(int sk, SkOptsEntry *soe)
 	struct timeval tv;
 
 	pr_info("%d restore sndbuf %d rcv buf %d\n", sk, soe->so_sndbuf, soe->so_rcvbuf);
-	ret |= restore_opt(sk, SOL_SOCKET, SO_SNDBUFFORCE, &soe->so_sndbuf);
-	ret |= restore_opt(sk, SOL_SOCKET, SO_RCVBUFFORCE, &soe->so_rcvbuf);
+
+	/* setsockopt() multiplies the input values by 2 */
+	val = soe->so_sndbuf / 2;
+	ret |= restore_opt(sk, SOL_SOCKET, SO_SNDBUFFORCE, &val);
+	val = soe->so_rcvbuf / 2;
+	ret |= restore_opt(sk, SOL_SOCKET, SO_RCVBUFFORCE, &val);
+
 	if (soe->has_so_priority) {
 		pr_debug("\trestore priority %d for socket\n", soe->so_priority);
 		ret |= restore_opt(sk, SOL_SOCKET, SO_PRIORITY, &soe->so_priority);
-- 
1.8.3.1



More information about the CRIU mailing list