[sheepdog] [PATCH v1 2/5] sheep: add disk information into sd_node
Liu Yuan
namei.unix at gmail.com
Mon May 5 05:03:45 CEST 2014
On Tue, Apr 29, 2014 at 10:53:42AM +0800, Robin Dong wrote:
> From: Robin Dong <sanbai at taobao.com>
>
> Add disk information into sd_node therefore it will be sended
> to cluster shared region (corosync/zookeeper, etc.) and be
> aware of by all nodes in this cluster.
>
> The new size of sd_node is 592 bytes and the max size of zookeeper
> is 983080, so the SD_MAX_NODES is 983080/(592 * 2) = 830.
>
> Signed-off-by: Robin Dong <sanbai at taobao.com>
> ---
> include/internal_proto.h | 21 ++++++++++++++--
> sheep/group.c | 9 ++++++-
> sheep/md.c | 64 +++++++++++++++++++++++++++++++-----------------
> sheep/sheep_priv.h | 24 ++++++++++++++++++
> 4 files changed, 92 insertions(+), 26 deletions(-)
>
> diff --git a/include/internal_proto.h b/include/internal_proto.h
> index 7db3769..3a47b85 100644
> --- a/include/internal_proto.h
> +++ b/include/internal_proto.h
> @@ -42,7 +42,11 @@
> * Currently, only zookeeper driver support SD_MAX_NODES nodes because
> * its message buffer size is large enough to hold nodes[SD_MAX_NODES].
> */
> -#define SD_MAX_NODES 6144
> +#ifdef HAVE_DISKVNODES
> + #define SD_MAX_NODES 830
> +#else
> + #define SD_MAX_NODES 6144
> +#endif
> #define SD_DEFAULT_VNODES 128
>
> /*
> @@ -148,7 +152,17 @@ struct node_id {
> uint8_t pad[4];
> };
>
> -#define SD_NODE_SIZE 80
> +struct disk_info {
> + uint64_t disk_id;
> + uint64_t disk_space;
> +};
> +
> +#ifdef HAVE_DISKVNODES
> + #define DISK_MAX 32
> + #define SD_NODE_SIZE (80 + sizeof(struct disk_info) * DISK_MAX)
> +#else
> + #define SD_NODE_SIZE 80
> +#endif
>
> struct sd_node {
> struct rb_node rb;
> @@ -156,6 +170,9 @@ struct sd_node {
> uint16_t nr_vnodes;
> uint32_t zone;
> uint64_t space;
> +#ifdef HAVE_DISKVNODES
> + struct disk_info disks[DISK_MAX];
> +#endif
> };
>
> /*
> diff --git a/sheep/group.c b/sheep/group.c
> index 4114dfb..b5cc484 100644
> --- a/sheep/group.c
> +++ b/sheep/group.c
> @@ -965,7 +965,12 @@ static void update_node_size(struct sd_node *node)
> if (unlikely(!n))
> panic("can't find %s", node_to_str(node));
> n->space = node->space;
> -
> +#ifdef HAVE_DISKVNODES
> + memset(n->disks, 0, sizeof(struct disk_info) * DISK_MAX);
> + for (int i = 0; i < DISK_MAX; i++)
> + if (node->disks[i].disk_id)
> + n->disks[i] = node->disks[i];
> +#endif
> put_vnode_info(cur_vinfo);
> }
>
> @@ -1026,6 +1031,8 @@ int create_cluster(int port, int64_t zone, int nr_vnodes,
>
> sys->this_node.space = sys->disk_space;
>
> + update_node_disks();
> +
> sys->cinfo.epoch = get_latest_epoch();
> if (sys->cinfo.epoch) {
> sys->cinfo.nr_nodes = epoch_log_read(sys->cinfo.epoch,
> diff --git a/sheep/md.c b/sheep/md.c
> index 8154ee6..bec8853 100644
> --- a/sheep/md.c
> +++ b/sheep/md.c
> @@ -17,27 +17,7 @@
>
> #define NONE_EXIST_PATH "/all/disks/are/broken/,ps/əʌo7/!"
>
> -struct disk {
> - struct rb_node rb;
> - char path[PATH_MAX];
> - uint64_t space;
> -};
> -
> -struct vdisk {
> - struct rb_node rb;
> - struct disk *disk;
> - uint64_t hash;
> -};
> -
> -struct md {
> - struct rb_root vroot;
> - struct rb_root root;
> - struct sd_rw_lock lock;
> - uint64_t space;
> - uint32_t nr_disks;
> -};
> -
> -static struct md md = {
> +struct md md = {
> .vroot = RB_ROOT,
> .root = RB_ROOT,
> .lock = SD_RW_LOCK_INITIALIZER,
> @@ -87,7 +67,7 @@ static struct vdisk *oid_to_vdisk(uint64_t oid)
> return hval_to_vdisk(sd_hash_oid(oid));
> }
>
> -static void create_vdisks(struct disk *disk)
> +static void create_vdisks(const struct disk *disk)
> {
> uint64_t hval = sd_hash(disk->path, strlen(disk->path));
> int nr = vdisk_number(disk);
> @@ -751,6 +731,42 @@ static inline void md_del_disk(const char *path)
> md_remove_disk(disk);
> }
>
> +#ifdef HAVE_DISKVNODES
> +void update_node_disks(void)
> +{
> + const struct disk *disk;
> + int i = 0;
> + bool rb_empty = false;
this is not necessary. RB_EMPTY_ROOT is good enough.
> +
> + if (!sys)
> + return;
> +
> + memset(sys->this_node.disks, 0, sizeof(struct disk_info) * DISK_MAX);
> + sd_read_lock(&md.lock);
> + rb_for_each_entry(disk, &md.root, rb) {
> + sys->this_node.disks[i].disk_id =
> + sd_hash(disk->path, strlen(disk->path));
> + sys->this_node.disks[i].disk_space = disk->space;
> + i++;
> + }
> + sd_rw_unlock(&md.lock);
> +
> + if (md.vroot.rb_node == NULL)
> + rb_empty = true;
> + sd_write_lock(&md.lock);
> + rb_for_each_entry(disk, &md.root, rb) {
> + if (!rb_empty)
use RB_EMPTY_ROOT macro directly for if condition.
Thanks,
Yuan
More information about the sheepdog
mailing list