[Sheepdog] [PATCH] sheep: retry read other copy in failure

Liu Yuan namei.unix at gmail.com
Wed Apr 18 04:43:52 CEST 2012


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

We have strong consistency for writing objects, so we can read
any copy for data. In recovery stage, read cluser might fail and
we should retry it.

- ask fix_object_consistency() to CREATE instead of WRITE in the case
of object not found.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 sheep/store.c |   48 ++++++++++++++++++++++++++++--------------------
 1 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/sheep/store.c b/sheep/store.c
index ab21bd8..d4546cd 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -306,7 +306,7 @@ static int do_local_io(struct request *req, uint32_t epoch);
 
 static int forward_read_obj_req(struct request *req)
 {
-	int i, n, nr, fd, ret;
+	int i, n, nr, fd, ret = SD_RES_SUCCESS;
 	unsigned wlen, rlen;
 	struct sd_obj_req hdr = *(struct sd_obj_req *)&req->rq;
 	struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
@@ -333,31 +333,39 @@ static int forward_read_obj_req(struct request *req)
 
 		if (is_myself(e[n].addr, e[n].port)) {
 			ret = do_local_io(req, hdr.epoch);
-			goto out;
+			if (ret != SD_RES_SUCCESS)
+				goto read_remote;
+			return ret;
 		}
 	}
 
-	n = obj_to_sheep(e, nr, oid, 0);
+read_remote:
+	for (i = 0; i < copies; i++) {
+		n = obj_to_sheep(e, nr, oid, i);
+		if (is_myself(e[n].addr, e[n].port))
+			continue;
 
-	fd = get_sheep_fd(e[n].addr, e[n].port, e[n].node_idx, hdr.epoch);
-	if (fd < 0) {
-		ret = SD_RES_NETWORK_ERROR;
-		goto out;
-	}
+		fd = get_sheep_fd(e[n].addr, e[n].port, e[n].node_idx, hdr.epoch);
+		if (fd < 0) {
+			ret = SD_RES_NETWORK_ERROR;
+			continue;
+		}
 
-	wlen = 0;
-	rlen = hdr.data_length;
+		wlen = 0;
+		rlen = hdr.data_length;
 
-	ret = exec_req(fd, (struct sd_req *)&hdr, req->data, &wlen, &rlen);
+		ret = exec_req(fd, (struct sd_req *)&hdr, req->data, &wlen, &rlen);
 
-	if (ret) { /* network errors */
-		del_sheep_fd(fd);
-		ret = SD_RES_NETWORK_ERROR;
-	} else {
-		memcpy(&req->rp, rsp, sizeof(*rsp));
-		ret = rsp->result;
+		if (ret) { /* network errors */
+			del_sheep_fd(fd);
+			ret = SD_RES_NETWORK_ERROR;
+			continue;
+		} else {
+			memcpy(&req->rp, rsp, sizeof(*rsp));
+			ret = rsp->result;
+			break;
+		}
 	}
-out:
 	return ret;
 }
 
@@ -822,10 +830,10 @@ static int fix_object_consistency(struct request *req)
 		goto out;
 	}
 
-	hdr->opcode = SD_OP_WRITE_OBJ;
+	hdr->opcode = SD_OP_CREATE_AND_WRITE_OBJ;
 	hdr->flags = SD_FLAG_CMD_WRITE;
 	hdr->oid = oid;
-	req->op = get_sd_op(SD_OP_WRITE_OBJ);
+	req->op = get_sd_op(hdr->opcode);
 	ret = forward_write_obj_req(req);
 	if (ret != SD_RES_SUCCESS) {
 		eprintf("failed to write object %d\n", ret);
-- 
1.7.8.2




More information about the sheepdog mailing list