From 8b1856d5c72c6870c04a87158718d2df62591a6c Mon Sep 17 00:00:00 2001
From: Jingxian He <hejingxian@huawei.com>
Date: Wed, 11 Aug 2021 15:01:27 +0800
Subject: [PATCH 46/72] sk: fix share sockets repair problem

Repair off the share sockets after reusing them
to recover the share socket state.

Signed-off-by: Jingxian He <hejingxian@huawei.com>
Signed-off-by: fu.lin <fulin10@huawei.com>
---
 criu/files.c      | 33 ++++++++++++++++++++++++++++++++-
 criu/sk-inet.c    |  7 +++++--
 criu/sk-netlink.c |  5 +++--
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/criu/files.c b/criu/files.c
index e79052e..24ed219 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -51,6 +51,7 @@
 #include "bpfmap.h"
 #include "files-chr.h"
 #include "orphan-inode.h"
+#include "sk-inet.h"
 
 #include "protobuf.h"
 #include "util.h"
@@ -1215,7 +1216,7 @@ int setup_and_serve_out(struct fdinfo_list_entry *fle, int new_fd)
 	if (reopen_fd_as(fle->fe->fd, new_fd))
 		return -1;
 
-	pr_info("*******flags: %d",fle->fe->flags);
+	pr_info("*******flags: %d\n",fle->fe->flags);
 	if (fcntl(fle->fe->fd, F_SETFD, fle->fe->flags) == -1) {
 		pr_perror("Unable to set file descriptor flags");
 		return -1;
@@ -1229,6 +1230,30 @@ int setup_and_serve_out(struct fdinfo_list_entry *fle, int new_fd)
 	return 0;
 }
 
+#define MAX_SHARE_SOCKETS_NUM 25000
+int repair_share_sockets[MAX_SHARE_SOCKETS_NUM];
+int repair_share_num;
+
+int add_repair_share_socket(int fd)
+{
+	if (repair_share_num >= MAX_SHARE_SOCKETS_NUM)
+		return -1;
+	repair_share_sockets[repair_share_num] = fd;
+	repair_share_num++;
+	return 0;
+}
+
+void repair_off_share_sockets(void)
+{
+	int i;
+
+	for (i = 0; i < repair_share_num; i++) {
+		tcp_repair_off(repair_share_sockets[i]);
+		pr_info("repair off socket:%d\n", repair_share_sockets[i]);
+	}
+	repair_share_num = 0;
+}
+
 static int open_fd(struct fdinfo_list_entry *fle)
 {
 	struct file_desc *d = fle->desc;
@@ -1248,6 +1273,7 @@ static int open_fd(struct fdinfo_list_entry *fle)
 
 	if (d->ops->type == FD_TYPES__INETSK) {
 		if (check_need_repair(d)) {
+			pr_info("start repair for:%d\n", d->id);
 			ret = repair_share_socket(d->id);
 			if (!ret) {
 				new_fd = get_share_socket();
@@ -1255,6 +1281,10 @@ static int open_fd(struct fdinfo_list_entry *fle)
 				if (new_fd <= 0 || setup_and_serve_out(fle, new_fd) < 0)
 					return -1;
 				fle->stage = FLE_RESTORED;
+				if (add_repair_share_socket(fle->fe->fd)) {
+					pr_perror("add repair share socket fail\n");
+					return -1;
+				}
 				return 0;
 			}
 		}
@@ -1379,6 +1409,7 @@ static int open_fdinfos(struct pstree_item *me)
 			wait_fds_event();
 	} while (again || progress);
 
+	repair_off_share_sockets();
 	BUG_ON(!list_empty(list));
 	/*
 	 * Fake fles may be used for restore other
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index c7de793..c0251db 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -635,8 +635,11 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
 	BUG_ON(sk->sd.already_dumped);
 
 	if (check_share_dst_port(sk->dst_port) || check_share_src_port(sk->src_port)) {
-		pr_info("Start add share prot:%d src %d\n", sk->dst_port, sk->src_port);
-		add_share_socket(id, lfd, dst_pid, sk->src_port);
+		pr_info("Start add share prot:%d-%d dst_pid %d id %d\n",
+			sk->dst_port, sk->src_port, dst_pid, id);
+		ret = add_share_socket(id, lfd, dst_pid, sk->src_port);
+		if (ret)
+			pr_warn("add share socket ret %d\n", ret);
 	}
 
 	ie.id = id;
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index d4b3b7b..2832060 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -115,9 +115,10 @@ static bool can_dump_netlink_sk(int lfd)
 
 	ret = fd_has_data(lfd);
 	if (ret == 1)
-		pr_err("The socket has data to read\n");
+		pr_warn("The socket has data to read\n");
 
-	return ret == 0;
+	/* ignore netlink socket data */
+	return true;
 }
 
 static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p)
-- 
2.34.1

