From 51e56ed2d4d4e9a98a5f23cfa857403100db433a Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Wed, 16 Jan 2019 02:22:13 -0500
Subject: [PATCH 040/131] add timeout(200ms) for cmds send to [lxc monitor]

Signed-off-by: LiFeng <lifeng68@huawei.com>
---
 src/lxc/af_unix.c  | 25 +++++++++++++++++++++++--
 src/lxc/af_unix.h  |  2 ++
 src/lxc/commands.c |  7 +++++--
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c
index 02f32c45..24500a8f 100644
--- a/src/lxc/af_unix.c
+++ b/src/lxc/af_unix.c
@@ -194,8 +194,9 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
 	return ret;
 }
 
-int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
-			       void *data, size_t size)
+/* isulad: add wait timeout Microseconds*/
+int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds,
+			       void *data, size_t size, unsigned int timeout)
 {
 	int ret;
 	struct msghdr msg;
@@ -204,6 +205,7 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
 	char buf[1] = {0};
 	char *cmsgbuf;
 	size_t cmsgbufsize = CMSG_SPACE(num_recvfds * sizeof(int));
+	struct timeval out;
 
 	memset(&msg, 0, sizeof(msg));
 	memset(&iov, 0, sizeof(iov));
@@ -222,6 +224,19 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 
+	if (timeout > 0) {
+		memset(&out, 0, sizeof(out));
+		out.tv_sec = timeout / 1000000;
+		out.tv_usec = timeout % 1000000;
+		ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
+		        (const void *)&out, sizeof(out));
+		if (ret < 0) {
+			ERROR("Failed to set %u timeout on containter "
+			     "state socket", timeout);
+			goto out;
+		}
+	}
+
 	ret = recvmsg(fd, &msg, 0);
 	if (ret <= 0)
 		goto out;
@@ -238,6 +253,12 @@ out:
 	return ret;
 }
 
+int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
+			       void *data, size_t size)
+{
+	return lxc_abstract_unix_recv_fds_timeout(fd, recvfds, num_recvfds, data, size, 0);
+}
+
 int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
 {
 	struct msghdr msg = {0};
diff --git a/src/lxc/af_unix.h b/src/lxc/af_unix.h
index f2c2fdcc..74fd77ff 100644
--- a/src/lxc/af_unix.h
+++ b/src/lxc/af_unix.h
@@ -37,5 +37,7 @@ extern int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
 				      void *data, size_t size);
 extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size);
 extern int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size);
+extern int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds,
+			       void *data, size_t size, unsigned int timeout);
 
 #endif /* __LXC_AF_UNIX_H */
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index 133384d7..47a824a9 100644
--- a/src/lxc/commands.c
+++ b/src/lxc/commands.c
@@ -126,13 +126,16 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
 	int ret, rspfd;
 	struct lxc_cmd_rsp *rsp = &cmd->rsp;
 
-	ret = lxc_abstract_unix_recv_fds(sock, &rspfd, 1, rsp, sizeof(*rsp));
+	/*isulad: add timeout 200ms to avoid long block due to [lxc monitor] error*/
+	ret = lxc_abstract_unix_recv_fds_timeout(sock, &rspfd, 1, rsp, sizeof(*rsp), 200 * 1000);
 	if (ret < 0) {
 		SYSWARN("Failed to receive response for command \"%s\"",
 		        lxc_cmd_str(cmd->req.cmd));
 
-		if (errno == ECONNRESET)
+		if (errno == ECONNRESET || errno == EAGAIN || errno == EWOULDBLOCK) {
+			errno = ECONNRESET; /*isulad set errno ECONNRESET when timeout */
 			return -1;
+		}
 
 		return -1;
 	}
-- 
2.23.0

