[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