[sheepdog] [PATCH 1/2] net: pass a function pointer to check if need retry

Liu Yuan namei.unix at gmail.com
Thu Jan 31 07:38:54 CET 2013


From: Liu Yuan <tailai.ly at taobao.com>

This is a prepare patch for 'retry write'.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 collie/common.c      |    4 +++-
 include/net.h        |    7 ++++---
 lib/net.c            |   29 ++++++++++++++---------------
 sheep/gateway.c      |    2 +-
 sheep/sockfd_cache.c |    2 +-
 sheepfs/volume.c     |    6 +++---
 6 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/collie/common.c b/collie/common.c
index 29f7dae..90501c7 100644
--- a/collie/common.c
+++ b/collie/common.c
@@ -239,7 +239,9 @@ int send_light_req(struct sd_req *hdr, const char *host, int port)
 	return 0;
 }
 
+
 int collie_exec_req(int sockfd, struct sd_req *hdr, void *data)
 {
-	return net_exec_req(sockfd, hdr, data, true);
+	/* Retry hard for collie because we can't get the newest epoch */
+	return exec_req(sockfd, hdr, data, NULL, 0);
 }
diff --git a/include/net.h b/include/net.h
index 97e93d0..ad90994 100644
--- a/include/net.h
+++ b/include/net.h
@@ -46,13 +46,14 @@ int conn_tx_on(struct connection *conn);
 int conn_rx_off(struct connection *conn);
 int conn_rx_on(struct connection *conn);
 bool is_conn_dead(const struct connection *conn);
-int do_read(int sockfd, void *buf, int len);
+int do_read(int sockfd, void *buf, int len,
+	    bool (*need_retry)(uint32_t), uint32_t);
 int rx(struct connection *conn, enum conn_state next_state);
 int tx(struct connection *conn, enum conn_state next_state);
 int connect_to(const char *name, int port);
 int send_req(int sockfd, struct sd_req *hdr, void *data, unsigned int wlen);
-int exec_req(int sockfd, struct sd_req *hdr, void *data);
-int net_exec_req(int sockfd, struct sd_req *hdr, void *data, bool retry_eagain);
+int exec_req(int sockfd, struct sd_req *hdr, void *,
+	     bool (*need_retry)(uint32_t), uint32_t);
 int create_listen_ports(const char *bindaddr, int port,
 			int (*callback)(int fd, void *), void *data);
 int create_unix_domain_socket(const char *unix_path,
diff --git a/lib/net.c b/lib/net.c
index 596f9a9..6504cd8 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -267,7 +267,8 @@ success:
 	return fd;
 }
 
-static int net_do_read(int sockfd, void *buf, int len, bool retry_eagain)
+int do_read(int sockfd, void *buf, int len, bool (*need_retry)(uint32_t epoch),
+	    uint32_t epoch)
 {
 	int ret;
 reread:
@@ -275,7 +276,14 @@ reread:
 	if (ret < 0 || !ret) {
 		if (errno == EINTR)
 			goto reread;
-		if (retry_eagain && errno == EAGAIN)
+		/*
+		 * Since we set timeout for read, we'll get EAGAIN even for
+		 * blocking sockfd.
+		 *
+		 * Always retry if need_retry is NULL
+		 */
+		if (errno == EAGAIN &&
+		    (need_retry == NULL || need_retry(epoch)))
 			goto reread;
 
 		sd_eprintf("failed to read from socket: %d, %d(%m)\n",
@@ -291,11 +299,6 @@ reread:
 	return 0;
 }
 
-int do_read(int sockfd, void *buf, int len)
-{
-	return net_do_read(sockfd, buf, len, false);
-}
-
 static void forward_iov(struct msghdr *msg, int len)
 {
 	while (msg->msg_iov->iov_len <= len) {
@@ -360,7 +363,8 @@ int send_req(int sockfd, struct sd_req *hdr, void *data, unsigned int wlen)
 	return ret;
 }
 
-int net_exec_req(int sockfd, struct sd_req *hdr, void *data, bool retry_eagain)
+int exec_req(int sockfd, struct sd_req *hdr, void *data,
+	     bool (*need_retry)(uint32_t epoch), uint32_t epoch)
 {
 	int ret;
 	struct sd_rsp *rsp = (struct sd_rsp *)hdr;
@@ -377,7 +381,7 @@ int net_exec_req(int sockfd, struct sd_req *hdr, void *data, bool retry_eagain)
 	if (send_req(sockfd, hdr, data, wlen))
 		return 1;
 
-	ret = net_do_read(sockfd, rsp, sizeof(*rsp), retry_eagain);
+	ret = do_read(sockfd, rsp, sizeof(*rsp), need_retry, epoch);
 	if (ret) {
 		sd_eprintf("failed to read a response\n");
 		return 1;
@@ -387,7 +391,7 @@ int net_exec_req(int sockfd, struct sd_req *hdr, void *data, bool retry_eagain)
 		rlen = rsp->data_length;
 
 	if (rlen) {
-		ret = net_do_read(sockfd, data, rlen, retry_eagain);
+		ret = do_read(sockfd, data, rlen, need_retry, epoch);
 		if (ret) {
 			sd_eprintf("failed to read the response data\n");
 			return 1;
@@ -397,11 +401,6 @@ int net_exec_req(int sockfd, struct sd_req *hdr, void *data, bool retry_eagain)
 	return 0;
 }
 
-int exec_req(int sockfd, struct sd_req *hdr, void *data)
-{
-	return net_exec_req(sockfd, hdr, data, false);
-}
-
 char *addr_to_str(char *str, int size, const uint8_t *addr, uint16_t port)
 {
 	int  af = AF_INET6;
diff --git a/sheep/gateway.c b/sheep/gateway.c
index d62347c..b54154d 100644
--- a/sheep/gateway.c
+++ b/sheep/gateway.c
@@ -193,7 +193,7 @@ again:
 			finish_one_write_err(wi, i);
 			goto finish_write;
 		}
-		if (do_read(pi.pfds[i].fd, rsp, sizeof(*rsp))) {
+		if (do_read(pi.pfds[i].fd, rsp, sizeof(*rsp), NULL, 0)) {
 			sd_eprintf("remote node might have gone away\n");
 			err_ret = SD_RES_NETWORK_ERROR;
 			finish_one_write_err(wi, i);
diff --git a/sheep/sockfd_cache.c b/sheep/sockfd_cache.c
index d39ff6e..8aadd7c 100644
--- a/sheep/sockfd_cache.c
+++ b/sheep/sockfd_cache.c
@@ -521,7 +521,7 @@ int sheep_exec_req(const struct node_id *nid, struct sd_req *hdr, void *buf)
 	if (!sfd)
 		return SD_RES_NETWORK_ERROR;
 
-	ret = exec_req(sfd->fd, hdr, buf);
+	ret = exec_req(sfd->fd, hdr, buf, NULL, 0);
 	if (ret) {
 		sd_dprintf("remote node might have gone away\n");
 		sheep_del_sockfd(nid, sfd);
diff --git a/sheepfs/volume.c b/sheepfs/volume.c
index 1742eb2..87086a4 100644
--- a/sheepfs/volume.c
+++ b/sheepfs/volume.c
@@ -197,7 +197,7 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
 		hdr.flags |= SD_FLAG_CMD_CACHE;
 
 	fd = get_socket_fd(vdi, &sock_idx);
-	ret = exec_req(fd, &hdr, buf);
+	ret = exec_req(fd, &hdr, buf, NULL, 0);
 	put_socket_fd(vdi, sock_idx);
 
 	if (ret || rsp->result != SD_RES_SUCCESS) {
@@ -303,7 +303,7 @@ static int volume_do_sync(uint32_t vid)
 	hdr.obj.oid = vid_to_vdi_oid(vid);
 
 	fd = get_socket_fd(vdi, &idx);
-	ret = exec_req(fd, &hdr, NULL);
+	ret = exec_req(fd, &hdr, NULL, NULL, 0);
 	put_socket_fd(vdi, idx);
 
 	if (ret || rsp->result != SD_RES_SUCCESS) {
@@ -490,7 +490,7 @@ static int volume_sync_and_delete(uint32_t vid)
 	hdr.obj.oid = vid_to_vdi_oid(vid);
 
 	fd = get_socket_fd(vdi, &idx);
-	ret = exec_req(fd, &hdr, NULL);
+	ret = exec_req(fd, &hdr, NULL, NULL, 0);
 	put_socket_fd(vdi, idx);
 
 	if (ret || rsp->result != SD_RES_SUCCESS) {
-- 
1.7.9.5




More information about the sheepdog mailing list