diff options
-rw-r--r-- | glfs-operations.c | 26 | ||||
-rw-r--r-- | glfs-operations.h | 19 | ||||
-rw-r--r-- | gluster-block.c | 10 | ||||
-rw-r--r-- | gluster-blockd.c | 168 | ||||
-rw-r--r-- | rpc/block.h | 1 | ||||
-rw-r--r-- | rpc/block.x | 1 | ||||
-rw-r--r-- | rpc/block_xdr.c | 2 | ||||
-rw-r--r-- | utils.c | 37 | ||||
-rw-r--r-- | utils.h | 44 |
9 files changed, 229 insertions, 79 deletions
diff --git a/glfs-operations.c b/glfs-operations.c index d567605..d530096 100644 --- a/glfs-operations.c +++ b/glfs-operations.c @@ -145,24 +145,6 @@ glusterBlockCreateMetaLockFile(struct glfs *glfs) } -static int -blockEnumParse(const char *opt) -{ - int i; - - if (!opt) { - return METAKEY__MAX; - } - - for (i = 0; i < METAKEY__MAX; i++) { - if (!strcmp(opt, MetakeyLookup[i])) { - return i; - } - } - - return i; -} - void blockFreeMetaInfo(MetaInfo *info) { @@ -175,6 +157,7 @@ blockFreeMetaInfo(MetaInfo *info) GB_FREE(info); } + static void blockStuffMetaInfo(MetaInfo *info, char *line) { @@ -183,7 +166,7 @@ blockStuffMetaInfo(MetaInfo *info, char *line) int Flag = 0; size_t i; - switch (blockEnumParse(opt)) { + switch (blockMetaKeyEnumParse(opt)) { case GBID: strcpy(info->gbid, strchr(line, ' ')+1); break; @@ -228,7 +211,7 @@ blockStuffMetaInfo(MetaInfo *info, char *line) GB_FREE(tmp); } -void +int blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info) { size_t count = 0; @@ -239,6 +222,7 @@ blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info) tgfd = glfs_open(glfs, metafile, O_RDWR); if (!tgfd) { ERROR("%s", "glfs_open failed"); + return -1; } while (glfs_read (tgfd, line, 48, 0) > 0) { @@ -249,4 +233,6 @@ blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info) } glfs_close(tgfd); + + return 0; } diff --git a/glfs-operations.h b/glfs-operations.h index c2bf076..abfcb27 100644 --- a/glfs-operations.h +++ b/glfs-operations.h @@ -22,15 +22,6 @@ # include "rpc/block.h" -typedef enum Metakey { - GBID = 0, - SIZE = 1, - HA = 2, - ENTRYCREATE = 3, - - METAKEY__MAX = 4 /* Updata this when add new Key */ -} Metakey; - typedef struct NodeInfo { char addr[255]; @@ -47,14 +38,6 @@ typedef struct MetaInfo { NodeInfo **list; } MetaInfo; -static const char *const MetakeyLookup[] = { - [GBID] = "GBID", - [SIZE] = "SIZE", - [HA] = "HA", - [ENTRYCREATE] = "ENTRYCREATE", - [METAKEY__MAX] = NULL, -}; - struct glfs * glusterBlockVolumeInit(char *volume, char *volfileserver); @@ -68,7 +51,7 @@ glusterBlockDeleteEntry(char *volume, char *gbid); struct glfs_fd * glusterBlockCreateMetaLockFile(struct glfs *glfs); -void +int blockGetMetaInfo(struct glfs *glfs, char *metafile, MetaInfo *info); void diff --git a/gluster-block.c b/gluster-block.c index b8e64b9..af131a1 100644 --- a/gluster-block.c +++ b/gluster-block.c @@ -115,6 +115,7 @@ glusterBlockHelp(void) " -c, --create <name> Create the gluster block\n" " -h, --host <gluster-node> node addr from gluster pool\n" " -s, --size <size> block storage size in KiB|MiB|GiB|TiB..\n" + " -m, --multipath <count> multi path requirement for high availablity\n" "\n" " -l, --list List available gluster blocks\n" "\n" @@ -151,6 +152,7 @@ glusterBlockCreate(int count, char **options, char *name) {"volume", required_argument, 0, 'v'}, {"host", required_argument, 0, 'h'}, {"size", required_argument, 0, 's'}, + {"multipath", required_argument, 0, 'm'}, {"block-host", required_argument, 0, 'b'}, {0, 0, 0, 0} }; @@ -165,9 +167,15 @@ glusterBlockCreate(int count, char **options, char *name) break; switch (c) { + case 'm': + sscanf(optarg, "%u", &cobj.mpath); + ret++; + break; + case 'b': if (GB_STRDUP(cobj.block_hosts, optarg) < 0) return -1; + ret++; break; case 'v': @@ -211,7 +219,7 @@ glusterBlockCreate(int count, char **options, char *name) goto out; } - if (ret != 3) { + if (ret != 5) { ERROR("%s", "Insufficient arguments supplied for" "'gluster-block create'\n"); ret = -1; diff --git a/gluster-blockd.c b/gluster-blockd.c index 27602fa..3e0ab91 100644 --- a/gluster-blockd.c +++ b/gluster-blockd.c @@ -173,15 +173,108 @@ fail: return NULL; } +static int +block_create_remote(struct glfs_fd *tgfd, blockCreate *cobj, char *addr, char **reply) +{ + char *write = NULL; + char *out = NULL; + char *tmp = NULL; + int ret; + + METAUPDATE(tgfd, write, "%s: CONFIGINPROGRESS\n", addr); + + ret = gluster_block_1(addr, cobj, CREATE_SRV, &out); + if (ret) { + METAUPDATE(tgfd, write, "%s: CONFIGFAIL\n", addr); + ERROR("%s on host: %s", FAILED_CREATE, addr); + + *reply = out; + goto out; + } + + METAUPDATE(tgfd, write, "%s: CONFIGSUCCESS\n", addr); + + asprintf(reply, "%s%s\n", (tmp==NULL?"":tmp), out); + if (tmp) + GB_FREE(tmp); + tmp = *reply; + GB_FREE(out); + + out: + return ret; +} + +static int +block_cross_check_request(struct glfs *glfs, + struct glfs_fd *tgfd, + blockCreateCli *blk, + blockCreate *cobj, + blockServerDefPtr list, + char **reply) +{ + MetaInfo *info; + size_t success_count = 0; + size_t fail_count = 0; + size_t spent; + size_t spare; + size_t morereq; + size_t i; + int ret; + + if (GB_ALLOC(info) < 0) + goto out; + + ret = blockGetMetaInfo(glfs, blk->block_name, info); + if(ret) + goto out; + + for (i = 0; i < info->nhosts; i++) { + switch (blockMetaStatusEnumParse(info->list[i]->status)) { + case CONFIGSUCCESS: + success_count++; + break; + case CONFIGINPROGRESS: + case CONFIGFAIL: + fail_count++; + } + } + + /* check if mpath is satisfied */ + if(blk->mpath == success_count) { + return 0; + } else { + spent = success_count + fail_count; /* total spent */ + spare = list->nhosts - spent; /* spare after spent */ + morereq = blk->mpath - success_count; /* needed nodes to complete req */ + if (spare == 0) { + ERROR("%s", "No Spare nodes: rewining the creation of target"); + return -1; + } else if (spare < morereq) { + ERROR("%s", "Not enough Spare nodes: rewining the creation of target"); + return -1; + } else { + /* create on spare */ + MSG("%s", "trying to serve the mpath from spare machines"); + for(i = spent; i < list->nhosts; i++) { + block_create_remote(tgfd, cobj, list->hosts[i], reply); + } + } + } + + blockFreeMetaInfo(info); + ret = block_cross_check_request(glfs, tgfd, blk, cobj, list, reply); + + out: + return ret; +} + blockResponse * block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) { int ret = -1; size_t i = 0; - char *out = NULL; char *savereply = NULL; - char *tmp = NULL; uuid_t uuid; static blockCreate *cobj; static blockResponse *reply = NULL; @@ -210,9 +303,6 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) uuid_generate(uuid); uuid_unparse(uuid, gbid); - if(GB_ALLOC(reply) < 0) - goto out; - if (!glfs_access(glfs, blk->block_name, F_OK)) { GB_STRDUP(reply->out, "BLOCK Already EXIST"); @@ -227,8 +317,8 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) } METAUPDATE(tgfd, write, - "GBID: %s\nSIZE: %zu\nHA: %d\nENTRYCREATE: INPROGRESS\n", - gbid, blk->size, 1); + "GBID: %s\nSIZE: %zu\nHA: %d\nENTRYCREATE: CONFIGINPROGRESS\n", + gbid, blk->size, blk->mpath); ret = glusterBlockCreateEntry(blk, gbid); if (ret) { @@ -237,7 +327,7 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) goto out; } - METAUPDATE(tgfd, write, "ENTRYCREATE: SUCCESS\n"); + METAUPDATE(tgfd, write, "ENTRYCREATE: CONFIGSUCCESS\n"); if(GB_ALLOC(cobj) < 0) goto out; @@ -250,29 +340,22 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) list = blockServerParse(blk->block_hosts); - for (i = 0; i < list->nhosts; i++) { - METAUPDATE(tgfd, write, "%s: INPROGRESS\n", list->hosts[i]); + /* TODO: Fail if mpath > list->nhosts */ - ret = gluster_block_1(list->hosts[i], cobj, CREATE_SRV, &out); - if (ret) { - METAUPDATE(tgfd, write, "%s: FAIL\n", list->hosts[i]); - ERROR("%s on host: %s", - FAILED_CREATE, list->hosts[i]); - } + for (i = 0; i < blk->mpath; i++) { + block_create_remote(tgfd, cobj, list->hosts[i], &savereply); + } - METAUPDATE(tgfd, write, "%s: SUCCESS\n", list->hosts[i]); + /* Check Point */ + ret = block_cross_check_request(glfs, tgfd, blk, cobj, list, &savereply); - asprintf(&savereply, "%s%s\n", (tmp==NULL?"":tmp), out); - if (tmp) - GB_FREE(tmp); - tmp = savereply; - GB_FREE(out); - } +out: + if(GB_ALLOC(reply) < 0) + goto out; reply->out = savereply; reply->exit = ret; -out: if (glfs_close(tgfd) != 0) ERROR("%s", "glfs_close: failed"); @@ -395,7 +478,9 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp) if (GB_ALLOC(info) < 0) goto out; - blockGetMetaInfo(glfs, blk->block_name, info); + ret = blockGetMetaInfo(glfs, blk->block_name, info); + if(ret) + goto out; if(GB_ALLOC(cobj) < 0) goto out; @@ -428,13 +513,13 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp) FAILED_DELETING_FILE, blk->volume, "localhost"); } + out: if (GB_ALLOC(reply) < 0) goto out; reply->out = savereply; reply->exit = ret; -out: if (glfs_close(tgfd) != 0) ERROR("%s", "glfs_close: failed"); @@ -547,13 +632,14 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp) } } - if (GB_ALLOC(reply) < 0) - goto out; - - reply->out = filelist; ret = 0; out: + if (GB_ALLOC(reply) < 0) + goto out; + + reply->out = filelist? filelist:strdup("*Nil*"); + reply->exit = ret; glfs_closedir (tgfd); @@ -564,8 +650,6 @@ out: glfs_fini(glfs); - reply->exit = ret; - return reply; } @@ -574,6 +658,7 @@ blockResponse * block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp) { blockResponse *reply = NULL; + char *out = NULL; struct glfs *glfs; struct glfs_fd *lkfd; struct flock lock = {0, }; @@ -597,17 +682,24 @@ block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp) if (GB_ALLOC(info) < 0) goto out; - blockGetMetaInfo(glfs, blk->block_name, info); - - if (GB_ALLOC(reply) < 0) + ret = blockGetMetaInfo(glfs, blk->block_name, info); + if(ret) goto out; - asprintf(&reply->out, "NAME: %s\nVOLUME: %s\nGBID: %s\nSIZE: %zu\nMULTIPATH: %zu", + asprintf(&out, "NAME: %s\nVOLUME: %s\nGBID: %s\nSIZE: %zu\nMULTIPATH: %zu\n", blk->block_name, blk->volume, info->gbid, info->size, info->mpath); - ret = 0; out: + if (GB_ALLOC(reply) < 0) + goto out; + + if(!out) + asprintf(&out, "No Block with name %s", blk->block_name); + + reply->out = out; + reply->exit = ret; + METAUNLOCK(lock, lkfd); if (glfs_close(lkfd) != 0) @@ -617,7 +709,5 @@ block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp) blockFreeMetaInfo(info); - reply->exit = ret; - return reply; } diff --git a/rpc/block.h b/rpc/block.h index 98ec806..9c3ee9e 100644 --- a/rpc/block.h +++ b/rpc/block.h @@ -28,6 +28,7 @@ struct blockCreateCli { char volume[255]; char volfileserver[255]; u_quad_t size; + u_int mpath; char block_name[255]; char *block_hosts; }; diff --git a/rpc/block.x b/rpc/block.x index 21c30aa..a5dce19 100644 --- a/rpc/block.x +++ b/rpc/block.x @@ -10,6 +10,7 @@ struct blockCreateCli { char volume[255]; char volfileserver[255]; u_quad_t size; + u_int mpath; /* HA request count */ char block_name[255]; string block_hosts<>; }; diff --git a/rpc/block_xdr.c b/rpc/block_xdr.c index 3bc0afc..8d05f3a 100644 --- a/rpc/block_xdr.c +++ b/rpc/block_xdr.c @@ -36,6 +36,8 @@ xdr_blockCreateCli (XDR *xdrs, blockCreateCli *objp) return FALSE; if (!xdr_u_quad_t (xdrs, &objp->size)) return FALSE; + if (!xdr_u_int (xdrs, &objp->mpath)) + return FALSE; if (!xdr_vector (xdrs, (char *)objp->block_name, 255, sizeof (char), (xdrproc_t) xdr_char)) return FALSE; @@ -12,6 +12,43 @@ # include "utils.h" +int +blockMetaKeyEnumParse(const char *opt) +{ + int i; + + if (!opt) { + return METAKEY__MAX; + } + + for (i = 0; i < METAKEY__MAX; i++) { + if (!strcmp(opt, MetakeyLookup[i])) { + return i; + } + } + + return i; +} + + +int +blockMetaStatusEnumParse(const char *opt) +{ + int i; + + if (!opt) { + return METASTATUS__MAX; + } + + for (i = 0; i < METASTATUS__MAX; i++) { + if (!strcmp(opt, MetaStatusLookup[i])) { + return i; + } + } + + return i; +} + int gbAlloc(void *ptrptr, size_t size, @@ -91,7 +91,49 @@ # define GB_FREE(ptr) gbFree(1 ? (void *) &(ptr) : (ptr)) - +typedef enum Metakey { + GBID = 0, + SIZE = 1, + HA = 2, + ENTRYCREATE = 3, + + METAKEY__MAX = 4 /* Updata this when add new Key */ +} Metakey; + +static const char *const MetakeyLookup[] = { + [GBID] = "GBID", + [SIZE] = "SIZE", + [HA] = "HA", + [ENTRYCREATE] = "ENTRYCREATE", + [METAKEY__MAX] = NULL, +}; + +typedef enum MetaStatus { + CONFIGSUCCESS = 0, + CONFIGFAIL = 1, + CONFIGINPROGRESS = 2, + CLEANUPSUCCESS = 3, + CLEANUPFAIL = 4, + CLEANUPINPROGRES = 5, + + METASTATUS__MAX = 6 /* Updata this when add new Status type */ +} MetaStatus; + +static const char *const MetaStatusLookup[] = { + [CONFIGINPROGRESS] = "CONFIGINPROGRESS", + [CONFIGSUCCESS] = "CONFIGSUCCESS", + [CONFIGFAIL] = "CONFIGFAIL", + [CLEANUPINPROGRES] = "CLEANUPINPROGRESS", + [CLEANUPSUCCESS] = "CLEANUPSUCCESS", + [CLEANUPFAIL] = "CLEANUPFAIL", + + [METASTATUS__MAX] = NULL, +}; + + +int blockMetaKeyEnumParse(const char *opt); + +int blockMetaStatusEnumParse(const char *opt); int gbAlloc(void *ptrptr, size_t size, const char *filename, const char *funcname, size_t linenr); |