diff options
author | Vishal Pandey <vpandey@redhat.com> | 2019-04-24 13:37:16 +0530 |
---|---|---|
committer | Vishal Pandey <vpandey-RH@review.gluster.org> | 2019-07-04 07:42:11 +0000 |
commit | 08c87ae4208b73f4f183f7b54ebcb373e8bc0ede (patch) | |
tree | 59d8e759a64913d7506dd98f6343fc0abe1fe801 /cli | |
parent | 96702cfea3ba55121c3bf203fcf2b86c803e1f04 (diff) |
glusterd/thin-arbiter: Thin-arbiter integration with GD1
gluster volume create <VOLNAME> replica 2 thin-arbiter 1 <host1>:<brick1> <host2>:<brick2>
<thin-arbiter-host>:<path-to-store-replica-id-file> [force]
The changes have been made in a way that the last brick in the bricks list
will be treated as the thin-arbiter.
GD1 will be manipulated to consider replica count to be as 2 and continue creating the
volume like any other replica 2 volume but since thin-arbiter volumes need ta-brick
client xlator entries for each subvolume in fuse volfile, volfile generation is
modified in a way to inject these entries seperately in the volfile for every subvolume.
Few more additions -
1- Save the volinfo with new fields ta_bricks list and thin_arbiter_count.
2- Introduce a new option client.ta-brick-port to add remote-port to ta-brick xlator entry
in fuse volfiles. The option can be set using the following CLI syntax -
gluster volume set <VOLNAME> client.ta-brick-port <PORTNO.>
3- Volume Info will contain a Thin-Arbiter-path entry to distinguish
from other replicate volumes.
Change-Id: Ib434e2313b29716f32476c6c211d282c4ef39406
Updates #687
Signed-off-by: Vishal Pandey <vpandey@redhat.com>
(cherry picked from commit 9b223b15ab69fce4076de036ee162f36a058bcd2)
Diffstat (limited to 'cli')
-rw-r--r-- | cli/src/cli-cmd-parser.c | 145 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 4 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 15 |
3 files changed, 158 insertions, 6 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index a6ce49035d9..decdd10cb50 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -80,6 +80,95 @@ str_getunamb(const char *tok, char **opwords) } int32_t +cli_cmd_ta_brick_parse(const char **words, int wordcount, char **ta_brick) +{ + char *host_name = NULL; + char *tmp_host = NULL; + char *delimiter = NULL; + cli_brick_t *brick = NULL; + int ret = 0; + + GF_ASSERT(words); + GF_ASSERT(wordcount); + + if (validate_brick_name((char *)words[wordcount - 1])) { + cli_err( + "Wrong brick type: %s, use <HOSTNAME>:" + "<export-dir-abs-path>", + words[wordcount - 1]); + ret = -1; + goto out; + } else { + delimiter = strrchr(words[wordcount - 1], ':'); + ret = gf_canonicalize_path(delimiter + 1); + if (ret) + goto out; + } + + tmp_host = gf_strdup((char *)words[wordcount - 1]); + if (!tmp_host) { + gf_log("cli", GF_LOG_ERROR, "Out of memory"); + ret = -1; + goto out; + } + get_host_name(tmp_host, &host_name); + if (!host_name) { + ret = -1; + gf_log("cli", GF_LOG_ERROR, + "Unable to retrieve " + "hostname"); + goto out; + } + + if (!(strcmp(host_name, "localhost") && strcmp(host_name, "127.0.0.1") && + strncmp(host_name, "0.", 2))) { + cli_err( + "Please provide a valid hostname/ip other " + "than localhost, 127.0.0.1 or loopback " + "address (0.0.0.0 to 0.255.255.255)."); + ret = -1; + goto out; + } + if (!valid_internet_address(host_name, _gf_false, _gf_false)) { + cli_err( + "internet address '%s' does not conform to " + "standards", + host_name); + } + + brick = GF_MALLOC(sizeof(cli_brick_t), gf_common_list_node); + if (brick == NULL) { + ret = -1; + gf_log("cli", GF_LOG_ERROR, "Out of memory"); + goto out; + } + + brick->name = words[wordcount - 1]; + brick->len = strlen(words[wordcount - 1]); + *ta_brick = GF_MALLOC(brick->len + 3, gf_common_mt_char); + if (*ta_brick == NULL) { + ret = -1; + gf_log("cli", GF_LOG_ERROR, "Out of memory"); + goto out; + } + + strcat(*ta_brick, " "); + strcat(*ta_brick, brick->name); + strcat(*ta_brick, " "); +out: + if (tmp_host) { + GF_FREE(tmp_host); + tmp_host = NULL; + } + if (brick) { + GF_FREE(brick); + brick = NULL; + } + + return ret; +} + +int32_t cli_cmd_bricks_parse(const char **words, int wordcount, int brick_index, char **bricks, int *brick_count) { @@ -476,14 +565,17 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, char *trans_type = NULL; int32_t index = 0; char *bricks = NULL; + char *ta_brick = NULL; int32_t brick_count = 0; - char *opwords[] = {"replica", "stripe", "transport", "disperse", - "redundancy", "disperse-data", "arbiter", NULL}; + char *opwords[] = {"replica", "stripe", "transport", + "disperse", "redundancy", "disperse-data", + "arbiter", "thin-arbiter", NULL}; char *w = NULL; int op_count = 0; int32_t replica_count = 1; int32_t arbiter_count = 0; + int32_t thin_arbiter_count = 0; int32_t stripe_count = 1; int32_t disperse_count = -1; int32_t redundancy_count = -1; @@ -581,6 +673,25 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, if (ret) goto out; index += 2; + } else if (!strcmp(words[index], "thin-arbiter")) { + ret = gf_string2int(words[index + 1], &thin_arbiter_count); + if ((ret == -1) || (thin_arbiter_count != 1)) { + cli_err( + "For thin-arbiter " + "configuration, " + "replica count must be" + " 2 and thin-arbiter count " + "must be 1. The 3rd " + "brick of the replica " + "will be the thin-arbiter brick"); + ret = -1; + goto out; + } + ret = dict_set_int32(dict, "thin-arbiter-count", + thin_arbiter_count); + if (ret) + goto out; + index += 2; } } @@ -589,7 +700,7 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, if ((arbiter_count == 1) && (replica_count == 2)) replica_count += arbiter_count; - if (replica_count == 2) { + if (replica_count == 2 && thin_arbiter_count == 0) { if (strcmp(words[wordcount - 1], "force")) { question = "Replica 2 volumes are prone" @@ -657,6 +768,12 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, "option."); ret = -1; goto out; + } else if ((strcmp(w, "thin-arbiter") == 0)) { + cli_err( + "thin-arbiter option must be preceded by replica " + "option."); + ret = -1; + goto out; } else { GF_ASSERT(!"opword mismatch"); ret = -1; @@ -680,7 +797,20 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, wc = wordcount - 1; } - ret = cli_cmd_bricks_parse(words, wc, brick_index, &bricks, &brick_count); + // Exclude the thin-arbiter-brick i.e. last brick in the bricks list + if (thin_arbiter_count == 1) { + ret = cli_cmd_bricks_parse(words, wc - 1, brick_index, &bricks, + &brick_count); + if (ret) + goto out; + + ret = cli_cmd_ta_brick_parse(words, wc, &ta_brick); + + } else { + ret = cli_cmd_bricks_parse(words, wc, brick_index, &bricks, + &brick_count); + } + if (ret) goto out; @@ -739,6 +869,12 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, if (ret) goto out; + if (thin_arbiter_count == 1) { + ret = dict_set_dynstr(dict, "ta-brick", ta_brick); + if (ret) + goto out; + } + ret = dict_set_int32(dict, "count", brick_count); if (ret) goto out; @@ -752,6 +888,7 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, out: if (ret) { GF_FREE(bricks); + GF_FREE(ta_brick); gf_log("cli", GF_LOG_ERROR, "Unable to parse create volume CLI"); if (dict) dict_unref(dict); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 713a047dd0b..f454b097aa7 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -2999,9 +2999,9 @@ struct cli_cmd volume_cmds[] = { "list information of all volumes"}, {"volume create <NEW-VOLNAME> [stripe <COUNT>] " - "[replica <COUNT> [arbiter <COUNT>]] " + "[[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] " "[disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] " - "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK>" + "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> <TA-BRICK>" "... [force]", cli_cmd_volume_create_cbk, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 16d5f73983f..35985ab44c6 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -723,10 +723,12 @@ gf_cli_get_volume_cbk(struct rpc_req *req, struct iovec *iov, int count, int32_t redundancy_count = 0; int32_t arbiter_count = 0; int32_t snap_count = 0; + int32_t thin_arbiter_count = 0; int32_t vol_type = 0; int32_t transport = 0; char *volume_id_str = NULL; char *volname = NULL; + char *ta_brick = NULL; dict_t *dict = NULL; cli_local_t *local = NULL; char key[1024] = {0}; @@ -903,6 +905,11 @@ xml_output: if (ret) goto out; + snprintf(key, 256, "volume%d.thin_arbiter_count", i); + ret = dict_get_int32(dict, key, &thin_arbiter_count); + if (ret) + goto out; + // Distributed (stripe/replicate/stripe-replica) setups vol_type = get_vol_type(type, dist_count, brick_count); @@ -929,6 +936,14 @@ xml_output: if (ret) goto out; + if (thin_arbiter_count) { + snprintf(key, 1024, "volume%d.thin_arbiter_brick", i); + ret = dict_get_str(dict, key, &ta_brick); + if (ret) + goto out; + cli_out("Thin-arbiter-path: %s", ta_brick); + } + snprintf(key, 256, "volume%d.opt_count", i); ret = dict_get_int32(dict, key, &opt_count); if (ret) |