From: Liu Yuan <tailai.ly at taobao.com> Current recovery logic needs to query underlying object store of object list in the specified epoch, in order to calculate object relocation. We need to abstract it out to adopt sheepdog to more stores. Signed-off-by: Liu Yuan <tailai.ly at taobao.com> --- sheep/sheep_priv.h | 1 + sheep/simple_store.c | 40 +++++++++++++++++++++++++++++++++++++++- sheep/store.c | 46 ++++++++++------------------------------------ 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index 618267e..7c61032 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -172,6 +172,7 @@ struct store_driver { int (*write)(uint64_t oid, struct siocb *); int (*read)(uint64_t oid, struct siocb *); int (*close)(uint64_t oid, struct siocb *); + int (*get_objlist)(struct siocb *); }; extern void register_store_driver(struct store_driver *); diff --git a/sheep/simple_store.c b/sheep/simple_store.c index 424589f..441bc3f 100644 --- a/sheep/simple_store.c +++ b/sheep/simple_store.c @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <dirent.h> #include "sheep_priv.h" #include "strbuf.h" @@ -141,13 +142,50 @@ static int simple_store_close(uint64_t oid, struct siocb *iocb) return SD_RES_SUCCESS; } +static int simple_store_get_objlist(struct siocb *siocb) +{ + struct strbuf buf = STRBUF_INIT; + int epoch = siocb->epoch; + uint64_t *objlist = (uint64_t *)siocb->buf; + DIR *dir; + struct dirent *d; + int ret = SD_RES_SUCCESS; + + strbuf_addf(&buf,"%s%08u/", obj_path, epoch); + + dprintf("%s\n", buf.buf); + + dir = opendir(buf.buf); + if (!dir) { + ret = SD_RES_EIO; + goto out; + } + + while ((d = readdir(dir))) { + uint64_t oid; + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + oid = strtoull(d->d_name, NULL, 16); + if (oid == 0) + continue; + + objlist[siocb->length++] = oid; + } + closedir(dir); +out: + strbuf_release(&buf); + return ret; +} + struct store_driver store = { .driver_name = "simple", .init = simple_store_init, .open = simple_store_open, .write = simple_store_write, .read = simple_store_read, - .close = simple_store_close + .close = simple_store_close, + .get_objlist = simple_store_get_objlist }; void register_store_driver(struct store_driver *driver) diff --git a/sheep/store.c b/sheep/store.c index de952d4..9f687da 100644 --- a/sheep/store.c +++ b/sheep/store.c @@ -102,15 +102,8 @@ static int merge_objlist(uint64_t *list1, int nr_list1, int get_obj_list(const struct sd_list_req *hdr, struct sd_list_rsp *rsp, void *data) { - DIR *dir; - struct dirent *d; - uint64_t oid; - uint32_t epoch; - char path[1024]; - uint64_t *p = (uint64_t *)data; - int nr = 0; - uint64_t *objlist = NULL; - int obj_nr, i; + uint64_t *list = (uint64_t *)data; + int i, nr = 0; int res = SD_RES_SUCCESS; int buf_len; char *buf; @@ -124,39 +117,20 @@ int get_obj_list(const struct sd_list_req *hdr, struct sd_list_rsp *rsp, void *d goto out; } - objlist = (uint64_t *)buf; - for (epoch = 1; epoch <= hdr->tgt_epoch; epoch++) { - snprintf(path, sizeof(path), "%s%08u/", obj_path, epoch); - - dprintf("%"PRIu32", %s\n", sys->this_node.port, path); - - dir = opendir(path); - if (!dir) { - eprintf("%s\n", path); - continue; - } - - obj_nr = 0; - while ((d = readdir(dir))) { - if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) - continue; - - oid = strtoull(d->d_name, NULL, 16); - if (oid == 0) - continue; - - objlist[obj_nr++] = oid; - } + for (i = 1; i <= hdr->tgt_epoch; i++) { + struct siocb iocb = { 0 }; - closedir(dir); - - nr = merge_objlist(p, nr, objlist, obj_nr); + iocb.buf = buf; + iocb.length = 0; + iocb.epoch = i; + store.get_objlist(&iocb); + nr = merge_objlist(list, nr, (uint64_t *)iocb.buf, iocb.length); } out: free(buf); rsp->data_length = nr * sizeof(uint64_t); for (i = 0; i < nr; i++) { - dprintf("oid %"PRIx64"\n", p[i]); + dprintf("oid %"PRIx64"\n", list[i]); } return res; } -- 1.7.8.rc3 |