From bbcbaf494ad406ceea4f0175b91cf67966d32a27 Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Kalever Date: Fri, 3 Feb 2017 18:34:07 +0530 Subject: cli: deprecated getopts_long usage deprecated getopts as to eliminate use of '--' with command line options The new usage looks like: gluster-block (Version 0.1) create Create the gluster block volserver [gluster-node] node addr from gluster pool(def: localhost) size block storage size in KiB|MiB|GiB|TiB.. mpath multi path requirement for high availablity servers [] block servers, clubbed with any option list List available gluster blocks info Details about gluster block modify Modify the metadata delete Delete the gluster block volume gluster volume name Signed-off-by: Prasanna Kumar Kalever --- gluster-block.c | 339 ++++++++++++++++++++++++++++--------------------------- gluster-blockd.c | 13 ++- utils.c | 59 ++++++++++ utils.h | 82 ++++++++++++-- 4 files changed, 314 insertions(+), 179 deletions(-) diff --git a/gluster-block.c b/gluster-block.c index 4acf498..b9d21c2 100644 --- a/gluster-block.c +++ b/gluster-block.c @@ -106,13 +106,12 @@ glusterBlockCliRPC_1(void *cobj, operations opt, char **out) ret = reply->exit; out: - if (!clnt_freeres(clnt, (xdrproc_t)xdr_blockResponse, (char *)reply)) - LOG("cli", GB_LOG_ERROR, "%s", clnt_sperror(clnt, "clnt_freeres failed")); + if (clnt) { + if (!reply || !clnt_freeres(clnt, (xdrproc_t)xdr_blockResponse, (char *)reply)) + LOG("cli", GB_LOG_ERROR, "%s", clnt_sperror(clnt, "clnt_freeres failed")); - if (clnt) clnt_destroy (clnt); - - close(sockfd); + } return ret; } @@ -123,87 +122,87 @@ glusterBlockHelp(void) { MSG("%s", "gluster-block (Version 0.1) \n" - " -c, --create Create the gluster block\n" - " -h, --host node addr from gluster pool\n" - " -s, --size block storage size in KiB|MiB|GiB|TiB..\n" - " -m, --multipath multi path requirement for high availablity\n" + " create Create the gluster block\n" + " volserver [gluster-node] node addr from gluster pool(default: localhost)\n" + " size block storage size in KiB|MiB|GiB|TiB..\n" + " mpath multi path requirement for high availablity\n" + " servers block servers, clubbed with any option\n" "\n" - " -l, --list List available gluster blocks\n" + " list List available gluster blocks\n" "\n" - " -i, --info Details about gluster block\n" + " info Details about gluster block\n" "\n" - " -m, --modify Modify the metadata\n" + " modify Modify the metadata\n" "\n" - " -d, --delete Delete the gluster block\n" + " delete Delete the gluster block\n" "\n" - " -v, --volume gluster volume name\n" - " [-b, --block-host ] block servers, clubbed with any option\n"); + " volume gluster volume name\n" + ); } static int -glusterBlockCreate(int count, char **options, char *name) +glusterBlockCreate(int argcount, char **options) { + size_t opt; + size_t optind = 2; int ret = 0; - int optchar; - int option_index = 0; char *out = NULL; + bool volserver = FALSE; static blockCreateCli cobj = {0, }; - if (!name) { - LOG("cli", GB_LOG_ERROR, "%s", "Insufficient arguments supplied for" - "'gluster-block create'"); - ret = -1; - goto out; + if(argcount <= optind) { + MSG("%s\n", "Insufficient options for create"); + return -1; } - strcpy(cobj.block_name, name); + /* name of block */ + strcpy(cobj.block_name, options[optind++]); while (1) { - static const struct option long_options[] = { - {"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} - }; - - optchar = getopt_long(count, options, "b:v:h:s:", - long_options, &option_index); - - if (optchar == -1) + if(argcount <= optind) { break; + } - switch (optchar) { - case 'm': - sscanf(optarg, "%u", &cobj.mpath); + opt = glusterBlockCLICreateOptEnumParse(options[optind++]); + if (opt == GB_CLI_CREATE_OPT_MAX) { + MSG("unrecognized option '%s'\n", options[optind-1]); + return -1; + } else if (opt && !options[optind]) { + MSG("%s: require argument\n", options[optind-1]); + return -1; + } + + + switch (opt) { + case GB_CLI_CREATE_VOLUME: + strcpy(cobj.volume, options[optind++]); ret++; break; - case 'b': - if (GB_STRDUP(cobj.block_hosts, optarg) < 0) { - LOG("cli", GB_LOG_ERROR, "%s", "failed while parsing size"); - ret = -1; - goto out; - } - ret++; + case GB_CLI_CREATE_VOLSERVER: + strcpy(cobj.volfileserver, options[optind++]); + volserver = TRUE; break; - case 'v': - strcpy(cobj.volume, optarg); + case GB_CLI_CREATE_MULTIPATH: + sscanf(options[optind++], "%u", &cobj.mpath); ret++; break; - case 'h': - strcpy(cobj.volfileserver, optarg); + case GB_CLI_CREATE_SIZE: + cobj.size = glusterBlockCreateParseSize(options[optind++]); + if (cobj.size < 0) { + LOG("cli", GB_LOG_ERROR, "%s", "failed while parsing size"); + ret = -1; + goto out; + } ret++; break; - case 's': - cobj.size = glusterBlockCreateParseSize(optarg); - if (cobj.size < 0) { + case GB_CLI_CREATE_BACKEND_SERVESRS: + if (GB_STRDUP(cobj.block_hosts, options[optind++]) < 0) { LOG("cli", GB_LOG_ERROR, "%s", "failed while parsing size"); ret = -1; goto out; @@ -211,37 +210,28 @@ glusterBlockCreate(int count, char **options, char *name) ret++; break; - case '?': + default: MSG("unrecognized option '%s'\n", options[optind-1]); - MSG("%s", "Hint: gluster-block --help\n"); + MSG("%s", "Hint: gluster-block help\n"); goto out; - - default: - break; } } - /* Print any remaining command line arguments (not options). */ - if (optind < count) { - LOG("cli", GB_LOG_ERROR, "%s", "non-option ARGV-elements: "); - while (optind < count) - MSG("provided options: %s", options[optind++]); - putchar('\n'); - MSG("Hint: %s --help\n", options[0]); + /* check all options required by create command are specified */ + if(ret < 4) { + MSG("%s\n", "Insufficient options for create"); ret = -1; goto out; } - if (ret != 5) { - LOG("cli", GB_LOG_ERROR, "%s", "Insufficient arguments supplied for" - "'gluster-block create'\n"); - ret = -1; - goto out; + if(!volserver) { + strcpy(cobj.volfileserver, "localhost"); } ret = glusterBlockCliRPC_1(&cobj, CREATE_CLI, &out); - MSG("%s", out); + if(out) + MSG("%s", out); out: GB_FREE(cobj.block_hosts); @@ -252,59 +242,122 @@ glusterBlockCreate(int count, char **options, char *name) static int -glusterBlockList(char *volume) +glusterBlockList(int argcount, char **options) { + size_t opt; + size_t optind = 2; static blockListCli cobj; char *out = NULL; int ret = -1; - strcpy(cobj.volume, volume); + if(argcount <= optind) { + MSG("%s\n", "Insufficient options for list"); + return -1; + } - ret = glusterBlockCliRPC_1(&cobj, LIST_CLI, &out); + opt = glusterBlockCLICommonOptEnumParse(options[optind++]); + if (opt == GB_CLI_COMMON_OPT_MAX) { + MSG("unrecognized option '%s'\n", options[optind-1]); + MSG("%s\n", "List needs 'volume' option"); + return -1; + } else if (!options[optind]) { + MSG("%s: require argument\n", options[optind-1]); + return -1; + } - MSG("%s", out); - GB_FREE(out); + if ((opt == GB_CLI_COMMON_VOLUME)) { + strcpy(cobj.volume, options[optind]); + + ret = glusterBlockCliRPC_1(&cobj, LIST_CLI, &out); + + if(out) + MSG("%s", out); + + GB_FREE(out); + } return ret; } static int -glusterBlockDelete(char* name, char* volume) +glusterBlockDelete(int argcount, char **options) { + size_t opt; + size_t optind = 2; static blockDeleteCli cobj; char *out = NULL; int ret = -1; + if(argcount <= optind) { + MSG("%s\n", "Insufficient options for delete"); + return -1; + } - strcpy(cobj.block_name, name); - strcpy(cobj.volume, volume); + /* name of block */ + strcpy(cobj.block_name, options[optind++]); + + opt = glusterBlockCLICommonOptEnumParse(options[optind++]); + if (opt == GB_CLI_COMMON_OPT_MAX) { + MSG("unrecognized option '%s'\n", options[optind-1]); + MSG("%s\n", "Delete needs 'volume' option"); + return -1; + } else if (!options[optind]) { + MSG("%s: require argument\n", options[optind-1]); + return -1; + } - ret = glusterBlockCliRPC_1(&cobj, DELETE_CLI, &out); + if ((opt == GB_CLI_COMMON_VOLUME)) { + strcpy(cobj.volume, options[optind]); + ret = glusterBlockCliRPC_1(&cobj, DELETE_CLI, &out); - MSG("%s", out); - GB_FREE(out); + if(out) + MSG("%s", out); + + GB_FREE(out); + } return ret; } static int -glusterBlockInfo(char* name, char* volume) +glusterBlockInfo(int argcount, char **options) { + size_t opt; + size_t optind = 2; static blockInfoCli cobj; char *out = NULL; int ret = -1; + if(argcount <= optind) { + MSG("%s\n", "Insufficient options for info"); + return -1; + } + + /* name of block */ + strcpy(cobj.block_name, options[optind++]); + + opt = glusterBlockCLICommonOptEnumParse(options[optind++]); + if (opt == GB_CLI_COMMON_OPT_MAX) { + MSG("unrecognized option '%s'\n", options[optind-1]); + MSG("%s\n", "Info needs 'volume' option"); + return -1; + } else if (!options[optind]) { + MSG("%s: require argument\n", options[optind-1]); + return -1; + } - strcpy(cobj.block_name, name); - strcpy(cobj.volume, volume); + if ((opt == GB_CLI_COMMON_VOLUME)) { + strcpy(cobj.volume, options[optind]); + ret = glusterBlockCliRPC_1(&cobj, INFO_CLI, &out); - ret = glusterBlockCliRPC_1(&cobj, INFO_CLI, &out); + if(out) + MSG("%s", out); - MSG("%s", out); - GB_FREE(out); + GB_FREE(out); + } return ret; } @@ -313,98 +366,52 @@ glusterBlockInfo(char* name, char* volume) static int glusterBlockParseArgs(int count, char **options) { - int optchar; int ret = 0; - int optFlag = 0; - char *blockname = NULL; - char *volume = NULL; + size_t opt = 0; + opt = glusterBlockCLIOptEnumParse(options[1]); + if (!opt || opt >= GB_CLI_OPT_MAX) { + MSG("unknow option: %s\n", options[1]); + return -1; + } while (1) { - static const struct option long_options[] = { - {HELP, no_argument, 0, 'h'}, - {CREATE, required_argument, 0, 'c'}, - {DELETE, required_argument, 0, 'd'}, - {LIST, no_argument, 0, 'l'}, - {INFO, required_argument, 0, 'i'}, - {MODIFY, required_argument, 0, 'm'}, - {VOLUME, required_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - - /* getopt_long stores the option index here. */ - int option_index = 0; - - optchar = getopt_long(count, options, "hc:b:d:lim:", - long_options, &option_index); - - /* Detect the end of the options. */ - if (optchar == -1) - break; - - switch (optchar) { - case 'v': - volume = optarg; - break; - - case 'c': - ret = glusterBlockCreate(count, options, optarg); + switch (opt) { + case GB_CLI_CREATE: + ret = glusterBlockCreate(count, options); if (ret && ret != EEXIST) { LOG("cli", GB_LOG_ERROR, "%s", FAILED_CREATE); - goto out; } - break; + goto out; - case 'l': - case 'd': - case 'i': - if (optFlag) /* more than one main operations ? */ - goto out; - optFlag = optchar; - blockname = optarg; - break; + case GB_CLI_LIST: + ret = glusterBlockList(count, options); + if (ret) { + LOG("cli", GB_LOG_ERROR, "%s", FAILED_LIST); + } + goto out; - case 'm': - MSG("option --modify yet TODO '%s'\n", optarg); - break; + case GB_CLI_INFO: + ret = glusterBlockInfo(count, options); + if (ret) { + LOG("cli", GB_LOG_ERROR, "%s", FAILED_INFO); + } + goto out; - case 'h': - glusterBlockHelp(); - break; + case GB_CLI_DELETE: + ret = glusterBlockDelete(count, options); + if (ret) { + LOG("cli", GB_LOG_ERROR, "%s", FAILED_DELETE); + } + goto out; - case '?': - /* getopt_long already printed an error message. */ - break; + case GB_CLI_HELP: + glusterBlockHelp(); + goto out; } } - switch (optFlag) { - case 'l': - ret = glusterBlockList(volume); - if (ret) - LOG("cli", GB_LOG_ERROR, "%s", FAILED_LIST); - break; - case 'i': - ret = glusterBlockInfo(blockname, volume); - if (ret) - LOG("cli", GB_LOG_ERROR, "%s", FAILED_INFO); - break; - case 'd': - ret = glusterBlockDelete(blockname, volume); - if (ret) - LOG("cli", GB_LOG_ERROR, "%s", FAILED_DELETE); - break; - } - out: - if (ret == 0 && optind < count) { - LOG("cli", GB_LOG_ERROR, "%s", "Unable to parse elements: "); - while (optind < count) - MSG("provided options: %s", options[optind++]); - putchar('\n'); - MSG("Hint: %s --help\n", options[0]); - } - return ret; } diff --git a/gluster-blockd.c b/gluster-blockd.c index ef27dbd..9d1ace8 100644 --- a/gluster-blockd.c +++ b/gluster-blockd.c @@ -118,13 +118,14 @@ glusterBlockCallRPC_1(char *host, void *cobj, ret = reply->exit; out: - if (!clnt_freeres(clnt, (xdrproc_t)xdr_blockResponse, (char *)reply)) { - LOG("mgmt", GB_LOG_ERROR, "%s", - clnt_sperror(clnt, "clnt_freeres failed")); - } - if (clnt) { - clnt_destroy (clnt); + if (!reply || + !clnt_freeres(clnt, (xdrproc_t)xdr_blockResponse, (char *)reply)) { + LOG("mgmt", GB_LOG_ERROR, "%s", + clnt_sperror(clnt, "clnt_freeres failed")); + + clnt_destroy (clnt); + } } close(sockfd); diff --git a/utils.c b/utils.c index ee3515f..059fb6b 100644 --- a/utils.c +++ b/utils.c @@ -13,6 +13,65 @@ +int +glusterBlockCLIOptEnumParse(const char *opt) +{ + int i; + + + if (!opt) { + return GB_CLI_OPT_MAX; + } + + for (i = 0; i < GB_CLI_OPT_MAX; i++) { + if (!strcmp(opt, gbCmdlineOptLookup[i])) { + return i; + } + } + + return i; +} + +int +glusterBlockCLICreateOptEnumParse(const char *opt) +{ + int i; + + + if (!opt) { + return GB_CLI_CREATE_OPT_MAX; + } + + /* i = 11, enum start look gbCmdlineCreateOption */ + for (i = 11; i < GB_CLI_CREATE_OPT_MAX; i++) { + if (!strcmp(opt, gbCmdlineCreateOptLookup[i])) { + return i; + } + } + + return i; +} + +int +glusterBlockCLICommonOptEnumParse(const char *opt) +{ + int i; + + + if (!opt) { + return GB_CLI_COMMON_OPT_MAX; + } + + /* i = 21, enum start look gbCmdlineCreateOption */ + for (i = 21; i < GB_CLI_COMMON_OPT_MAX; i++) { + if (!strcmp(opt, gbCmdlineCommonOptLookup[i])) { + return i; + } + } + + return i; +} + int blockMetaKeyEnumParse(const char *opt) { diff --git a/utils.h b/utils.h index fc088ce..4cc1347 100644 --- a/utils.h +++ b/utils.h @@ -136,6 +136,70 @@ gbFree(1 ? (void *) &(ptr) : (ptr)) +typedef enum gbCmdlineCreateOption { + /* needed by create option */ + GB_CLI_CREATE_VOLUME = 11, + GB_CLI_CREATE_VOLSERVER = 12, /* optional (default: localhost)*/ + GB_CLI_CREATE_SIZE = 13, + GB_CLI_CREATE_MULTIPATH = 14, + GB_CLI_CREATE_BACKEND_SERVESRS = 15, + + GB_CLI_CREATE_OPT_MAX +} gbCmdlineCreateOption; + + +typedef enum gbCmdlineCommonOption { + /* common to all the cli options */ + GB_CLI_COMMON_VOLUME = 21, + + GB_CLI_COMMON_OPT_MAX +} gbCmdlineCommonOption; + + +typedef enum gbCmdlineOption { + GB_CLI_UNKNOWN = 0, + + GB_CLI_CREATE = 1, + GB_CLI_LIST = 2, + GB_CLI_INFO = 3, + GB_CLI_DELETE = 4, + GB_CLI_MODIFY = 5, + GB_CLI_HELP = 6, + + GB_CLI_OPT_MAX +} gbCmdlineOption; + + +static const char *const gbCmdlineOptLookup[] = { + [GB_CLI_UNKNOWN] = "NONE", + + [GB_CLI_CREATE] = "create", + [GB_CLI_LIST] = "list", + [GB_CLI_INFO] = "info", + [GB_CLI_DELETE] = "delete", + [GB_CLI_MODIFY] = "modify", + [GB_CLI_HELP] = "help", + + [GB_CLI_OPT_MAX] = NULL, +}; + +static const char *const gbCmdlineCreateOptLookup[] = { + [GB_CLI_CREATE_VOLUME] = "volume", + [GB_CLI_CREATE_VOLSERVER] = "volserver", + [GB_CLI_CREATE_SIZE] = "size", + [GB_CLI_CREATE_MULTIPATH] = "mpath", + [GB_CLI_CREATE_BACKEND_SERVESRS] = "backend-servers", + + + [GB_CLI_CREATE_OPT_MAX] = NULL +}; + +static const char *const gbCmdlineCommonOptLookup[] = { + [GB_CLI_COMMON_VOLUME] = "volume", + + [GB_CLI_COMMON_OPT_MAX] = NULL +}; + typedef enum LogLevel { GB_LOG_NONE = 0, GB_LOG_EMERGENCY = 1, @@ -167,18 +231,16 @@ static const char *const LogLevelLookup[] = { }; typedef enum Metakey { - GB_META_INVALID = 0, - GB_META_VOLUME = 1, - GB_META_GBID = 2, - GB_META_SIZE = 3, - GB_META_HA = 4, - GB_META_ENTRYCREATE = 5, + GB_META_VOLUME = 0, + GB_META_GBID = 1, + GB_META_SIZE = 2, + GB_META_HA = 3, + GB_META_ENTRYCREATE = 4, GB_METAKEY_MAX } Metakey; static const char *const MetakeyLookup[] = { - [GB_META_INVALID] = NULL, [GB_META_VOLUME] = "VOLUME", [GB_META_GBID] = "GBID", [GB_META_SIZE] = "SIZE", @@ -211,6 +273,12 @@ static const char *const MetaStatusLookup[] = { }; +int glusterBlockCLIOptEnumParse(const char *opt); + +int glusterBlockCLICreateOptEnumParse(const char *opt); + +int glusterBlockCLICommonOptEnumParse(const char *opt); + int blockMetaKeyEnumParse(const char *opt); int blockMetaStatusEnumParse(const char *opt); -- cgit