以下内容仅做记录,以备查看。
记录了sheepdog 最核心的算法和实现思路
//sheep分析记录 #define main_thread(type) struct { type __val; } 引用 ----------------------------------------------------------------------- md.c ======================================================================== struct disk { char path[PATH_MAX]; /*目录的路径名*/ uint16_t nr_vdisks; uint64_t space; }; struct vdisk { uint16_t idx; uint64_t id; }; #define MD_MAX_DISK 64 #define MD_DEFAULT_VDISKS 128 #define MD_MAX_VDISK (MD_MAX_DISK * MD_DEFAULT_VDISKS) static struct disk md_disks[MD_MAX_DISK]; static struct vdisk md_vds[MD_MAX_VDISK]; static int md_nr_disks; /* Protected by md_lock (当前添加的目录数)*/ static int md_nr_vds; /*虚拟出来的vdisk个数 /*重要函数 计算生成虚拟磁盘vdisk uint64_t md_init_space(void) { ... calculate_vdisks(md_disks, md_nr_disks, total); 计算一个目录下有几个vdisk md_nr_vds = disks_to_vdisks(md_disks, md_nr_disks, md_vds); ... } /*重要函数 计算填充vdisk的数据结构? static inline int disks_to_vdisks(struct disk *ds, int nmds, struct vdisk *vds) { struct disk *d_iter = ds; int i, j, nr_vdisks = 0; uint64_t hval; while (nmds--) { hval = FNV1A_64_INIT; for (i = 0; i < d_iter->nr_vdisks; i++) { hval = fnv_64a_buf(&nmds, sizeof(nmds), hval); for (j = strlen(d_iter->path) - 1; j >= 0; j--) hval = fnv_64a_buf(&d_iter->path[j], 1, hval); vds[nr_vdisks].id = hval; vds[nr_vdisks].idx = d_iter - ds; nr_vdisks++; } d_iter++; } xqsort(vds, nr_vdisks, vdisk_cmp); return nr_vdisks; } /*oid 找vdisk,从而找块文件是否存在 static inline struct vdisk *oid_to_vdisk(uint64_t oid) { return oid_to_vdisk_from(md_vds, md_nr_vds, oid); } /*重要函数,映射oid都对应虚拟磁盘vdisk (nr=md_nr_vds,vds=md_vds)*/ static struct vdisk *oid_to_vdisk_from(struct vdisk *vds, int nr, uint64_t oid) { uint64_t id = fnv_64a_buf(&oid, sizeof(oid), FNV1A_64_INIT); int start, end, pos; start = 0; end = nr - 1; if (id > vds[end].id || id < vds[start].id) return &vds[start]; for (;;) { pos = (end - start) / 2 + start; if (vds[pos].id < id) { if (vds[pos + 1].id >= id) return &vds[pos + 1]; start = pos; } else end = pos; } } ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- group.c ===================================================================================================== #define SD_DEFAULT_VNODES 64 #define SD_NODE_SIZE 56 /*节点数据结构 struct sd_node { struct node_id nid; uint16_t nr_vnodes; uint32_t zone; /* use last 4 bytes as zone id uint8_t *b = sys->this_node.nid.addr + 12; sys->this_node.zone = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 */ uint64_t space; }; /*虚拟节点数据结构 struct sd_vnode { struct node_id nid; uint16_t node_idx; uint32_t zone; uint64_t id; }; struct vnode_info { struct sd_vnode vnodes[SD_MAX_VNODES]; int nr_vnodes; struct sd_node nodes[SD_MAX_NODES]; int nr_nodes; int nr_zones; refcnt_t refcnt; }; /*重要,计算有好多个vnode,已经vnode对应的服务器地址 struct vnode_info *alloc_vnode_info(const struct sd_node *nodes, size_t nr_nodes) { ... recalculate_vnodes(vnode_info->nodes, nr_nodes); vnode_info->nr_vnodes = nodes_to_vnodes(vnode_info->nodes, nr_nodes, vnode_info->vnodes); vnode_info->nr_zones = get_zones_nr_from(nodes, nr_nodes); refcount_set(&vnode_info->refcnt, 1); return vnode_info; } /*特别重要 计算每个服务器对应的vnode个数,一般恒定64个(由recalculate_vnodes函数计算并由SD_DEFAULT_VNODES指定) static inline int nodes_to_vnodes(struct sd_node *nodes, int nr, struct sd_vnode *vnodes) { struct sd_node *n = nodes; int i, j, nr_vnodes = 0; uint64_t hval; while (nr--) { hval = FNV1A_64_INIT; for (i = 0; i < n->nr_vnodes; i++) { if (vnodes) { hval = fnv_64a_buf(&n->nid.port, sizeof(n->nid.port), hval); for (j = ARRAY_SIZE(n->nid.addr) - 1; j >= 0; j--) hval = fnv_64a_buf(&n->nid.addr[j], 1, hval); vnodes[nr_vnodes].id = hval; memcpy(vnodes[nr_vnodes].nid.addr, n->nid.addr, sizeof(n->nid.addr)); vnodes[nr_vnodes].nid.port = n->nid.port; vnodes[nr_vnodes].node_idx = n - nodes; vnodes[nr_vnodes].zone = n->zone; } nr_vnodes++; } n++; } if (vnodes) xqsort(vnodes, nr_vnodes, vnode_cmp); return nr_vnodes; }