[Sheepdog] [PATCH 4/5] sheep: access local objects directly
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Thu Jan 27 13:47:41 CET 2011
This patch fixes a dead lock which happens when sending vdi
creation/deletion requests continuously.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
sheep/sdnet.c | 39 +++++++++++++++++++++++++++++++++++++++
sheep/sheep_priv.h | 4 ++++
sheep/store.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 0 deletions(-)
diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index 4cfa6df..0040945 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -591,6 +591,19 @@ int write_object(struct sheepdog_node_list_entry *e,
n = obj_to_sheep(e, nodes, oid, i);
+ if (memcmp(e[n].addr, sys->this_node.addr, sizeof(e[n].addr)) == 0 &&
+ e[n].port == sys->this_node.port) {
+ ret = write_object_local(oid, data, datalen, offset, nr,
+ node_version, create);
+
+ if (ret != 0)
+ eprintf("fail %"PRIx64" %"PRIx32"\n", oid, ret);
+ else
+ success++;
+
+ continue;
+ }
+
addr_to_str(name, sizeof(name), e[n].addr, 0);
fd = connect_to(name, e[n].port);
@@ -637,6 +650,32 @@ int read_object(struct sheepdog_node_list_entry *e,
if (nr > nodes)
nr = nodes;
+ /* search a local object first */
+ for (i = 0; i < nr; i++) {
+ n = obj_to_sheep(e, nodes, oid, i);
+
+ if (memcmp(e[n].addr, sys->this_node.addr, sizeof(e[n].addr)) == 0 &&
+ e[n].port == sys->this_node.port) {
+ ret = read_object_local(oid, data, datalen, offset, nr,
+ node_version);
+
+ if (ret < 0) {
+ eprintf("fail %"PRIx64" %"PRId32"\n", oid, ret);
+ return ret;
+ }
+
+ /* fix replication consistency */
+ if (nr > 1) {
+ if (write_object(e, nodes, node_version, oid,
+ data, datalen, offset, nr, 0))
+ eprintf("failed to fix obj consistency\n");
+ }
+
+ return ret;
+ }
+
+ }
+
for (i = 0; i < nr; i++) {
unsigned wlen = 0, rlen = datalen;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index d91e572..9b21e0f 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -162,6 +162,10 @@ int create_cluster(int port);
void start_cpg_event_work(void);
void store_queue_request(struct work *work, int idx);
+int write_object_local(uint64_t oid, char *data, unsigned int datalen,
+ uint64_t offset, int copies, uint32_t epoch, int create);
+int read_object_local(uint64_t oid, char *data, unsigned int datalen,
+ uint64_t offset, int copies, uint32_t epoch);
int read_epoch(uint32_t *epoch, uint64_t *ctime,
struct sheepdog_node_list_entry *entries, int *nr_entries);
diff --git a/sheep/store.c b/sheep/store.c
index 4b685f2..8fa4d9e 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -568,6 +568,54 @@ int update_epoch_store(uint32_t epoch)
return 0;
}
+int write_object_local(uint64_t oid, char *data, unsigned int datalen,
+ uint64_t offset, int copies, uint32_t epoch, int create)
+{
+ struct request req;
+ struct sd_obj_req *hdr = (struct sd_obj_req *)&req.rq;
+
+ memset(&req, 0, sizeof(req));
+
+ hdr->oid = oid;
+ if (create)
+ hdr->opcode = SD_OP_CREATE_AND_WRITE_OBJ;
+ else
+ hdr->opcode = SD_OP_WRITE_OBJ;
+ hdr->copies = copies;
+ hdr->flags = SD_FLAG_CMD_WRITE;
+ hdr->offset = offset;
+ hdr->data_length = datalen;
+ req.data = data;
+
+ return store_queue_request_local(&req, epoch);
+}
+
+int read_object_local(uint64_t oid, char *data, unsigned int datalen,
+ uint64_t offset, int copies, uint32_t epoch)
+{
+ int ret;
+ struct request req;
+ struct sd_obj_req *hdr = (struct sd_obj_req *)&req.rq;
+ struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req.rp;
+
+ memset(&req, 0, sizeof(req));
+
+ hdr->oid = oid;
+ hdr->opcode = SD_OP_READ_OBJ;
+ hdr->copies = copies;
+ hdr->flags = 0;
+ hdr->offset = offset;
+ hdr->data_length = datalen;
+ req.data = data;
+
+ ret = store_queue_request_local(&req, epoch);
+
+ if (ret != 0 || rsp->data_length != datalen)
+ return -rsp->result;
+
+ return rsp->data_length;
+}
+
static int store_queue_request_local(struct request *req, uint32_t epoch)
{
int fd = -1, copies;
--
1.5.6.5
More information about the sheepdog
mailing list