summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--glfs-operations.c26
-rw-r--r--glfs-operations.h19
-rw-r--r--gluster-block.c10
-rw-r--r--gluster-blockd.c168
-rw-r--r--rpc/block.h1
-rw-r--r--rpc/block.x1
-rw-r--r--rpc/block_xdr.c2
-rw-r--r--utils.c37
-rw-r--r--utils.h44
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;
diff --git a/utils.c b/utils.c
index 9e71a73..aa2e3b8 100644
--- a/utils.c
+++ b/utils.c
@@ -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,
diff --git a/utils.h b/utils.h
index d4801ae..6a98e67 100644
--- a/utils.h
+++ b/utils.h
@@ -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);