[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