diff options
author | Prasanna Kumar Kalever <prasanna.kalever@redhat.com> | 2018-02-05 15:07:26 +0530 |
---|---|---|
committer | Prasanna Kumar Kalever <prasanna.kalever@redhat.com> | 2018-02-07 16:49:21 +0530 |
commit | 540e81676b1011dcf85fbe5cd6739a4f2143b2ab (patch) | |
tree | 7eed76faf5483e03bbbe59bb23ede3675ae6ad97 /cli | |
parent | f217c0bf9cf464e21c01fa50643b778f236acedb (diff) |
replace: add replace feature
1. create conf in new node
2. delete conf from old node
3. replace portals from nodes hosting other paths (HA)
$ gluster-block create sample/block ha 3 192.168.124.57,192.168.124.26,192.168.124.30 1GiB --json-pretty
{
"IQN":"iqn.2016-12.org.gluster-block:d516bb5c-5f56-4d9c-96a7-385df19c2e2c",
"PORTAL(S)":[
"192.168.124.57:3260",
"192.168.124.26:3260",
"192.168.124.30:3260"
],
"RESULT":"SUCCESS"
}
$ gluster-block help
gluster-block (0.3)
usage:
gluster-block <command> <volname[/blockname]> [<args>] [--json*]
commands:
[...]
replace <volname/blockname> <old-node> <new-node> [force]
replace operations.
[...]
supported JSON formats:
--json|--json-plain|--json-spaced|--json-pretty
$ gluster-block replace sample/block 192.168.124.26 192.168.124.56 --json-pretty
{
"NAME":"block",
"CREATE SUCCESS":"192.168.124.56",
"DELETE SUCCESS":"192.168.124.26",
"REPLACE PORTAL SUCCESS ON":[
"192.168.124.57",
"192.168.124.30"
],
"RESULT":"SUCCESS"
}
Fixes: #4
Change-Id: I0411d15c407111db0d423052d9a6bc075174bf90
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
Diffstat (limited to 'cli')
-rw-r--r-- | cli/gluster-block.c | 149 |
1 files changed, 124 insertions, 25 deletions
diff --git a/cli/gluster-block.c b/cli/gluster-block.c index 53f72bc..98f5bba 100644 --- a/cli/gluster-block.c +++ b/cli/gluster-block.c @@ -14,14 +14,16 @@ # include "config.h" -# define GB_CREATE_HELP_STR "gluster-block create <volname/blockname> "\ - "[ha <count>] [auth <enable|disable>] "\ - "[prealloc <full|no>] <HOST1[,HOST2,...]> "\ +# define GB_CREATE_HELP_STR "gluster-block create <volname/blockname> " \ + "[ha <count>] [auth <enable|disable>] " \ + "[prealloc <full|no>] <HOST1[,HOST2,...]> " \ "<size> [--json*]" # define GB_DELETE_HELP_STR "gluster-block delete <volname/blockname> [force] [--json*]" -# define GB_MODIFY_HELP_STR "gluster-block modify <volname/blockname> "\ +# define GB_MODIFY_HELP_STR "gluster-block modify <volname/blockname> " \ "<auth enable|disable> [--json*]" +# define GB_REPLACE_HELP_STR "gluster-block replace <volname/blockname> " \ + "<old-node> <new-node> [force] [--json*]" # define GB_INFO_HELP_STR "gluster-block info <volname/blockname> [--json*]" # define GB_LIST_HELP_STR "gluster-block list <volname> [--json*]" @@ -43,7 +45,8 @@ typedef enum clioperations { LIST_CLI = 2, INFO_CLI = 3, DELETE_CLI = 4, - MODIFY_CLI = 5 + MODIFY_CLI = 5, + REPLACE_CLI = 6 } clioperations; @@ -59,6 +62,7 @@ glusterBlockCliRPC_1(void *cobj, clioperations opt) blockInfoCli *info_obj; blockListCli *list_obj; blockModifyCli *modify_obj; + blockReplaceCli *replace_obj; blockResponse reply = {0,}; char errMsg[2048] = {0}; @@ -145,6 +149,15 @@ glusterBlockCliRPC_1(void *cobj, clioperations opt) goto out; } break; + case REPLACE_CLI: + replace_obj = cobj; + if (block_replace_cli_1(replace_obj, &reply, clnt) != RPC_SUCCESS) { + LOG("cli", GB_LOG_ERROR, "%sblock %s replace on volume %s failed", + clnt_sperror(clnt, "block_replace_cli_1"), replace_obj->block_name, + replace_obj->volume); + goto out; + } + break; } out: @@ -204,6 +217,9 @@ glusterBlockHelp(void) " modify <volname/blockname> <auth enable|disable>\n" " modify block device.\n" "\n" + " replace <volname/blockname> <old-node> <new-node> [force]\n" + " replace operations.\n" + "\n" " help\n" " show this message and exit.\n" "\n" @@ -216,13 +232,26 @@ glusterBlockHelp(void) } static bool -glusterBlockIsNameAcceptable (char *name) +glusterBlockIsNameAcceptable(char *name) { int i = 0; - if (!name || strlen(name) == 0) + if (!name || strlen(name) == 0 || strlen(name) > 255) return FALSE; for (i = 0; i < strlen(name); i++) { - if (!isalnum (name[i]) && (name[i] != '_') && (name[i] != '-')) + if (!isalnum(name[i]) && (name[i] != '_') && (name[i] != '-')) + return FALSE; + } + return TRUE; +} + +static bool +glusterBlockIsAddrAcceptable(char *addr) +{ + int i = 0; + if (!addr || strlen(addr) == 0 || strlen(addr) > 255) + return FALSE; + for (i = 0; i < strlen(addr); i++) { + if (!isdigit(addr[i]) && (addr[i] != '.')) return FALSE; } return TRUE; @@ -235,9 +264,14 @@ glusterBlockParseVolumeBlock(char *volumeblock, char *volume, char *block, int ret = -1; size_t len = 0; char *sep = NULL; + char *tmp = NULL; + + if (GB_STRDUP(tmp, volumeblock) < 0) { + goto out; + } /* part before '/' is the volume name */ - sep = strchr(volumeblock, '/'); + sep = strchr(tmp, '/'); if (!sep) { MSG("argument '<volname/blockname>'(%s) is incorrect\n", volumeblock); @@ -245,29 +279,25 @@ glusterBlockParseVolumeBlock(char *volumeblock, char *volume, char *block, LOG("cli", GB_LOG_ERROR, "%s failed while parsing <volname/blockname>", op); goto out; } - len = sep - volumeblock; - if (len >= 255 || strlen(sep+1) >= 255) { - MSG("%s\n", "Both volname and blockname should be less than 255 " - "characters long"); - MSG("%s\n", helpstr); - LOG("cli", GB_LOG_ERROR, "%s failed while parsing <volname/blockname>", op); + *sep = '\0'; + + if (!glusterBlockIsNameAcceptable(tmp)) { + MSG("volume name(%s) should contain only aplhanumeric,'-', '_' characters " + "and should be less than 255 characters long\n", volume); goto out; } - strncpy(volume, volumeblock, len); /* part after / is blockname */ - strncpy(block, sep+1, strlen(sep+1)); - if (!glusterBlockIsNameAcceptable (volume)) { - MSG("volume name(%s) should contain only aplhanumeric,'-' " - "and '_' characters\n", volume); - goto out; - } - if (!glusterBlockIsNameAcceptable (block)) { - MSG("block name(%s) should contain only aplhanumeric,'-' " - "and '_' characters\n", block); + if (!glusterBlockIsNameAcceptable(sep+1)) { + MSG("block name(%s) should contain only aplhanumeric,'-', '_' characters " + "and should be less than 255 characters long\n", block); goto out; } + strncpy(volume, tmp, strlen(tmp)); + strncpy(block, sep+1, strlen(sep+1)); ret = 0; + out: + GB_FREE(tmp); return ret; } @@ -523,6 +553,68 @@ glusterBlockInfo(int argcount, char **options, int json) static int +glusterBlockReplace(int argcount, char **options, int json) +{ + blockReplaceCli robj = {0}; + int ret = -1; + bool singleBlock = false; + char helpMsg[256] = {0, }; + + + if (argcount < 5 || argcount > 6) { + MSG("Inadequate arguments for replace:\n%s\n", GB_REPLACE_HELP_STR); + return -1; + } + + if (glusterBlockParseVolumeBlock(options[2], robj.volume, robj.block_name, + helpMsg, "replace")) { + goto out; + } + + if (!glusterBlockIsAddrAcceptable(options[3])) { + MSG("host addr (%s) should be a valid ip address\n%s\n", + options[3], GB_REPLACE_HELP_STR); + goto out; + } + strcpy(robj.old_node, options[3]); + + if (!glusterBlockIsAddrAcceptable(options[4])) { + MSG("host addr (%s) should be a valid ip address\n%s\n", + options[4], GB_REPLACE_HELP_STR); + goto out; + } + strcpy(robj.new_node, options[4]); + + if (!strncmp(robj.old_node, robj.new_node, 255)) { + MSG("<old-node> (%s) and <new-node> (%s) cannot be same\n%s\n", + robj.old_node, robj.new_node, GB_REPLACE_HELP_STR); + goto out; + } + + robj.json_resp = json; + + if (argcount == 6) { + if (strcmp(options[5], "force")) { + MSG("unknown option '%s' for replace:\n%s\n", options[5], GB_REPLACE_HELP_STR); + return -1; + } else { + robj.force = true; + } + } + + ret = glusterBlockCliRPC_1(&robj, REPLACE_CLI); + if (ret) { + LOG("cli", GB_LOG_ERROR, "failed replace on volume %s", + robj.volume); + } + + out: + + return ret; +} + + +static int glusterBlockParseArgs(int count, char **options) { int ret = 0; @@ -577,6 +669,13 @@ glusterBlockParseArgs(int count, char **options) } goto out; + case GB_CLI_REPLACE: + ret = glusterBlockReplace(count, options, json); + if (ret) { + LOG("cli", GB_LOG_ERROR, "%s", FAILED_REPLACE); + } + goto out; + case GB_CLI_DELETE: ret = glusterBlockDelete(count, options, json); if (ret) { |