[sheepdog] [PATCH 5/5] dog/vdi: rework 'vdi object location' and 'vdi track'
Robin Dong
robin.k.dong at gmail.com
Fri Feb 28 04:42:31 CET 2014
2014-02-27 13:48 GMT+08:00 Liu Yuan <namei.unix at gmail.com>:
> Add a SD_OP_EXIST to check if an object exists in the specific node.
>
> Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> ---
> dog/vdi.c | 275
> +++++++++++++----------------------------------
> include/internal_proto.h | 1 +
> sheep/ops.c | 20 ++++
> sheep/recovery.c | 17 +--
> sheep/sheep_priv.h | 1 +
> 5 files changed, 106 insertions(+), 208 deletions(-)
>
> diff --git a/dog/vdi.c b/dog/vdi.c
> index debed0a..8a8f089 100644
> --- a/dog/vdi.c
> +++ b/dog/vdi.c
> @@ -210,122 +210,23 @@ static void print_vdi_graph(uint32_t vid, const
> char *name, const char *tag,
>
> }
>
> -static void vdi_info_filler(uint32_t vid, const char *name, const char
> *tag,
> - uint32_t snapid, uint32_t flags,
> - const struct sd_inode *i, void *data)
> -{
> - struct get_vdi_info *info = data;
> -
> - if (info->name) {
> - if (info->tag && info->tag[0]) {
> - if (!strcmp(name, info->name) &&
> - !strcmp(tag, info->tag)) {
> - info->vid = vid;
> - info->nr_copies = i->nr_copies;
> - info->copy_policy = i->copy_policy;
> - }
> - } else if (info->snapid) {
> - if (!strcmp(name, info->name) &&
> - snapid == info->snapid) {
> - info->vid = vid;
> - info->nr_copies = i->nr_copies;
> - info->copy_policy = i->copy_policy;
> - }
> - } else {
> - if (!strcmp(name, info->name)) {
> - info->vid = vid;
> - info->nr_copies = i->nr_copies;
> - info->copy_policy = i->copy_policy;
> - }
> - }
> - }
> -}
> -
> -typedef int (*obj_parser_func_t)(const char *sheep, uint64_t oid,
> - struct sd_rsp *rsp, char *buf, void
> *data);
> -
> -static int do_print_obj(const char *sheep, uint64_t oid, struct sd_rsp
> *rsp,
> - char *buf, void *data)
> -{
> - switch (rsp->result) {
> - case SD_RES_SUCCESS:
> - printf("%s has the object\n", sheep);
> - break;
> - case SD_RES_NO_OBJ:
> - printf("%s doesn't have the object\n", sheep);
> - break;
> - case SD_RES_OLD_NODE_VER:
> - case SD_RES_NEW_NODE_VER:
> - sd_err("The node list has changed: please try again");
> - break;
> - default:
> - sd_err("%s: hit an unexpected error (%s)", sheep,
> - sd_strerror(rsp->result));
> - break;
> - }
> -
> - return 0;
> -}
> -
> -struct obj_info_filler_info {
> - bool success;
> - uint64_t data_oid;
> - unsigned idx;
> -};
> -
> -static int obj_info_filler(const char *sheep, uint64_t oid, struct sd_rsp
> *rsp,
> - char *buf, void *data)
> +static void for_each_node_print(uint64_t oid)
> {
> - struct obj_info_filler_info *info = data;
> - struct sd_inode *inode = (struct sd_inode *)buf;
> - uint32_t vdi_id;
> -
> - switch (rsp->result) {
> - case SD_RES_SUCCESS:
> - if (info->success)
> - break;
> - info->success = true;
> - vdi_id = sd_inode_get_vid(inode, info->idx);
> - if (vdi_id) {
> - info->data_oid = vid_to_data_oid(vdi_id,
> info->idx);
> - return 1;
> - }
> - break;
> - case SD_RES_NO_OBJ:
> - break;
> - case SD_RES_OLD_NODE_VER:
> - case SD_RES_NEW_NODE_VER:
> - sd_err("The node list has changed: please try again");
> - break;
> - default:
> - sd_err("%s: hit an unexpected error (%s)", sheep,
> - sd_strerror(rsp->result));
> - break;
> - }
> -
> - return 0;
> -}
> -
> -static void parse_objs(uint64_t oid, obj_parser_func_t func, void *data,
> - size_t size)
> -{
> - int ret, cb_ret;
> + int ret;
> struct sd_node *n;
> - char *buf;
> + const char *sheep;
>
> - buf = xzalloc(size);
> rb_for_each_entry(n, &sd_nroot, rb) {
> struct sd_req hdr;
> struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
>
> - sd_init_req(&hdr, SD_OP_READ_PEER);
> - hdr.data_length = size;
> + sd_init_req(&hdr, SD_OP_EXIST);
> + hdr.data_length = 0;
> hdr.flags = 0;
> hdr.epoch = sd_epoch;
> hdr.obj.oid = oid;
> - hdr.obj.ec_index = SD_MAX_COPIES + 1; /* Ignore index */
>
> - ret = dog_exec_req(&n->nid, &hdr, buf);
> + ret = dog_exec_req(&n->nid, &hdr, NULL);
> if (ret < 0)
> continue;
> switch (rsp->result) {
> @@ -333,16 +234,26 @@ static void parse_objs(uint64_t oid,
> obj_parser_func_t func, void *data,
> continue;
> }
>
> - cb_ret = func(addr_to_str(n->nid.addr, n->nid.port),
> - oid, rsp, buf, data);
> - if (cb_ret)
> + sheep = addr_to_str(n->nid.addr, n->nid.port);
> + switch (rsp->result) {
> + case SD_RES_SUCCESS:
> + printf("%s has the object\n", sheep);
> + break;
> + case SD_RES_NO_OBJ:
> + printf("%s doesn't have the object\n", sheep);
> break;
> + case SD_RES_OLD_NODE_VER:
> + case SD_RES_NEW_NODE_VER:
> + sd_err("The node list has changed: please try
> again");
> + break;
> + default:
> + sd_err("%s: hit an unexpected error (%s)", sheep,
> + sd_strerror(rsp->result));
> + break;
> + }
> }
> -
> - free(buf);
> }
>
> -
> static int vdi_list(int argc, char **argv)
> {
> const char *vdiname = argv[optind];
> @@ -901,67 +812,52 @@ static int vdi_object_map(int argc, char **argv)
> static int vdi_object_location(int argc, char **argv)
> {
> const char *vdiname = argv[optind];
> - uint64_t idx = vdi_cmd_data.index;
> - struct get_vdi_info info;
> - uint32_t vid;
> - size_t size;
> -
> - memset(&info, 0, sizeof(info));
> - info.name = vdiname;
> - info.tag = vdi_cmd_data.snapshot_tag;
> - info.vid = 0;
> - info.snapid = vdi_cmd_data.snapshot_id;
> -
> - if (parse_vdi(vdi_info_filler, SD_INODE_HEADER_SIZE, &info) < 0)
> - return EXIT_SYSFAIL;
> + uint64_t idx = vdi_cmd_data.index, oid;
> + struct sd_inode *inode = xmalloc(sizeof(*inode));
> + uint32_t vid, vdi_id;
> + int ret;
>
> - vid = info.vid;
> - if (vid == 0) {
> - sd_err("VDI not found");
> - return EXIT_MISSING;
> + ret = read_vdi_obj(vdiname, vdi_cmd_data.snapshot_id,
> + vdi_cmd_data.snapshot_tag, NULL, inode,
> + SD_INODE_SIZE);
> + if (ret != EXIT_SUCCESS) {
> + sd_err("FATAL: no inode objects");
> + return ret;
>
May be we should use 'goto out' which will free the memory of inode.
> }
> + vid = inode->vdi_id;
>
> if (idx == ~0) {
> - printf("Looking for the inode object 0x%" PRIx32 " with %d
> nodes\n\n",
> + printf("Looking for the inode object 0x%" PRIx32 " with %d"
> + " nodes\n\n",
> vid, sd_nodes_nr);
> - parse_objs(vid_to_vdi_oid(vid), do_print_obj, NULL,
> - SD_INODE_SIZE);
> - } else {
> - struct obj_info_filler_info oid_info = {0};
> + for_each_node_print(vid_to_vdi_oid(vid));
> + ret = EXIT_SUCCESS;
> + goto out;
> + }
>
> - oid_info.success = false;
> - oid_info.idx = idx;
> + if (idx >= MAX_DATA_OBJS) {
> + printf("The offset is too large!\n");
> + ret = EXIT_FAILURE;
> + goto out;
> + }
>
> - if (idx >= MAX_DATA_OBJS) {
> - printf("The offset is too large!\n");
> - exit(EXIT_FAILURE);
> - }
> + vdi_id = sd_inode_get_vid(inode, idx);
> + oid = vid_to_data_oid(vdi_id, idx);
> + if (vdi_id) {
> + printf("Looking for the object 0x%" PRIx64
> + " (vid 0x%" PRIx32 " idx %"PRIu64
> + ", %u copies) with %d nodes\n\n",
> + oid, vid, idx, inode->nr_copies, sd_nodes_nr);
>
> - size = get_store_objsize(info.copy_policy,
> - vid_to_data_oid(vid, 0));
> - parse_objs(vid_to_vdi_oid(vid), obj_info_filler, &oid_info,
> - size);
> -
> - if (oid_info.success) {
> - if (oid_info.data_oid) {
> - printf("Looking for the object 0x%" PRIx64
> - " (vid 0x%" PRIx32 " idx %"PRIu64
> - ", %u copies) with %d nodes\n\n",
> - oid_info.data_oid, vid, idx,
> - info.nr_copies, sd_nodes_nr);
> -
> - parse_objs(oid_info.data_oid, do_print_obj,
> - NULL, size);
> - } else
> - printf("The inode object 0x%" PRIx32 " idx"
> - " %"PRIu64" is not allocated\n",
> - vid, idx);
> - } else
> - sd_err("Failed to read the inode object 0x%"
> PRIx32,
> - vid);
> - }
> + for_each_node_print(oid);
> + } else
> + printf("The inode object 0x%" PRIx32 " idx"
> + " %"PRIu64" is not allocated\n",
> + vid, idx);
>
> - return EXIT_SUCCESS;
> +out:
> + free(inode);
> + return ret;
> }
>
> static int do_track_object(uint64_t oid, uint8_t nr_copies)
> @@ -1032,59 +928,37 @@ static int vdi_track(int argc, char **argv)
> {
> const char *vdiname = argv[optind];
> unsigned idx = vdi_cmd_data.index;
> - struct get_vdi_info info;
> - struct obj_info_filler_info oid_info = {0};
> - uint32_t vid;
> uint8_t nr_copies;
> uint64_t oid = vdi_cmd_data.oid;
> + struct sd_inode *inode = xmalloc(sizeof(*inode));
> + uint32_t vid, vdi_id;
> + int ret;
>
> - memset(&info, 0, sizeof(info));
> - info.name = vdiname;
> - info.tag = vdi_cmd_data.snapshot_tag;
> - info.vid = 0;
> - info.snapid = vdi_cmd_data.snapshot_id;
> -
> - if (parse_vdi(vdi_info_filler, SD_INODE_HEADER_SIZE, &info) < 0)
> - return EXIT_SYSFAIL;
> -
> - vid = info.vid;
> - nr_copies = info.nr_copies;
> - if (vid == 0) {
> - sd_err("VDI not found");
> - return EXIT_MISSING;
> + ret = read_vdi_obj(vdiname, vdi_cmd_data.snapshot_id,
> + vdi_cmd_data.snapshot_tag, NULL, inode,
> + SD_INODE_SIZE);
> + if (ret != EXIT_SUCCESS) {
> + sd_err("FATAL: no inode objects");
> + return ret;
>
ditto
> }
> + vid = inode->vdi_id;
> + nr_copies = inode->nr_copies;
>
> if (!oid) {
> if (idx == ~0) {
> printf("Tracking the inode object 0x%" PRIx32
> " with %d nodes\n", vid, sd_nodes_nr);
> + free(inode);
> return do_track_object(vid_to_vdi_oid(vid),
> nr_copies);
> }
>
> - oid_info.success = false;
> - oid_info.idx = idx;
> -
> if (idx >= MAX_DATA_OBJS) {
> printf("The offset is too large!\n");
> goto err;
> }
>
> - parse_objs(vid_to_vdi_oid(vid), obj_info_filler, &oid_info,
> - get_store_objsize(info.copy_policy,
> - vid_to_data_oid(vid, 0)));
> -
> - if (!oid_info.success) {
> - sd_err("Failed to read the inode object 0x%"
> PRIx32,
> - vid);
> - goto err;
> - }
> - if (!oid_info.data_oid) {
> - printf("The inode object 0x%"PRIx32
> - " idx %u is not allocated\n", vid, idx);
> - goto err;
> - }
> -
> - oid = oid_info.data_oid;
> + vdi_id = sd_inode_get_vid(inode, idx);
> + oid = vid_to_data_oid(vdi_id, idx);
>
> printf("Tracking the object 0x%" PRIx64
> " (the inode vid 0x%" PRIx32 " idx %u)"
> @@ -1094,9 +968,10 @@ static int vdi_track(int argc, char **argv)
> " (the inode vid 0x%" PRIx32 ")"
> " with %d nodes\n", oid, vid, sd_nodes_nr);
>
> + free(inode);
> return do_track_object(oid, nr_copies);
> -
> err:
> + free(inode);
> return EXIT_FAILURE;
> }
>
> diff --git a/include/internal_proto.h b/include/internal_proto.h
> index 460264c..ace4ac5 100644
> --- a/include/internal_proto.h
> +++ b/include/internal_proto.h
> @@ -99,6 +99,7 @@
> #define SD_OP_SET_LOGLEVEL 0xBA
> #define SD_OP_NFS_CREATE 0xBB
> #define SD_OP_NFS_DELETE 0xBC
> +#define SD_OP_EXIST 0xBD
>
> /* internal flags for hdr.flags, must be above 0x80 */
> #define SD_FLAG_CMD_RECOVERY 0x0080
> diff --git a/sheep/ops.c b/sheep/ops.c
> index 0e9bc82..ca00a18 100644
> --- a/sheep/ops.c
> +++ b/sheep/ops.c
> @@ -1015,6 +1015,19 @@ static int local_set_loglevel(struct request *req)
> return SD_RES_SUCCESS;
> }
>
> +static int local_oid_exist(struct request *req)
> +{
> + uint64_t oid = req->rq.obj.oid;
> + uint8_t ec_index = local_ec_index(req->vinfo, oid);
> +
> + if (is_erasure_oid(oid) && ec_index == SD_MAX_COPIES)
> + return SD_RES_NO_OBJ;
> +
> + if (sd_store->exist(oid, ec_index))
> + return SD_RES_SUCCESS;
> + return SD_RES_NO_OBJ;
> +}
> +
> #ifdef HAVE_NFS
>
> static int local_nfs_create(struct request *req)
> @@ -1336,6 +1349,13 @@ static struct sd_op_template sd_ops[] = {
> .process_work = local_set_loglevel,
> },
>
> + [SD_OP_EXIST] = {
> + .name = "EXIST",
> + .type = SD_OP_TYPE_LOCAL,
> + .force = true,
> + .process_work = local_oid_exist,
> + },
> +
> #ifdef HAVE_NFS
> [SD_OP_NFS_CREATE] = {
> .name = "NFS_CREATE",
> diff --git a/sheep/recovery.c b/sheep/recovery.c
> index 1e5f1af..859375d 100644
> --- a/sheep/recovery.c
> +++ b/sheep/recovery.c
> @@ -445,19 +445,20 @@ out:
> return lost;
> }
>
> -static uint8_t local_node_copy_index(struct vnode_info *vinfo, uint64_t
> oid)
> +uint8_t local_ec_index(struct vnode_info *vinfo, uint64_t oid)
> {
> - int idx;
> + int idx, m = min(get_vdi_copy_number(oid_to_vid(oid)),
> vinfo->nr_zones);
>
> if (!is_erasure_oid(oid))
> - return 0; /* no need to proceed */
> + return SD_MAX_COPIES;
>
> - for (idx = 0; idx < vinfo->nr_zones; idx++) {
> + for (idx = 0; idx < m; idx++) {
> const struct sd_node *n = oid_to_node(oid, &vinfo->vroot,
> idx);
> if (node_is_local(n))
> return idx;
> }
> - panic("can't get valid index for %"PRIx64, oid);
> + sd_debug("can't get valid index for %"PRIx64, oid);
> + return SD_MAX_COPIES;
> }
>
> /*
> @@ -486,7 +487,7 @@ static int recover_erasure_object(struct
> recovery_obj_work *row)
> uint8_t idx;
> int ret = -1;
>
> - idx = local_node_copy_index(cur, oid);
> + idx = local_ec_index(cur, oid);
> buf = read_erasure_object(oid, idx, row);
> if (!buf && !row->stop)
> buf = rebuild_erasure_object(oid, idx, row);
> @@ -530,7 +531,7 @@ static void recover_object_work(struct work *work)
> struct vnode_info *cur = rw->cur_vinfo;
> int ret, epoch;
>
> - if (sd_store->exist(oid, local_node_copy_index(cur, oid))) {
> + if (sd_store->exist(oid, local_ec_index(cur, oid))) {
> sd_debug("the object is already recovered");
> return;
> }
> @@ -585,7 +586,7 @@ main_fn bool oid_in_recovery(uint64_t oid)
> return false;
>
> cur = rinfo->cur_vinfo;
> - if (sd_store->exist(oid, local_node_copy_index(cur, oid))) {
> + if (sd_store->exist(oid, local_ec_index(cur, oid))) {
> sd_debug("the object %" PRIx64 " is already recoverd",
> oid);
> return false;
> }
> diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
> index f9c5062..3737f5a 100644
> --- a/sheep/sheep_priv.h
> +++ b/sheep/sheep_priv.h
> @@ -436,6 +436,7 @@ int gateway_write_obj(struct request *req);
> int gateway_create_and_write_obj(struct request *req);
> int gateway_remove_obj(struct request *req);
> bool is_erasure_oid(uint64_t oid);
> +uint8_t local_ec_index(struct vnode_info *vinfo, uint64_t oid);
>
> /* object_cache */
>
> --
> 1.8.1.2
>
> --
> sheepdog mailing list
> sheepdog at lists.wpkg.org
> http://lists.wpkg.org/mailman/listinfo/sheepdog
>
--
--
Best Regard
Robin Dong
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.wpkg.org/pipermail/sheepdog/attachments/20140228/1502db5f/attachment-0004.html>
More information about the sheepdog
mailing list