diff options
| author | Vishal Pandey <vpandey@redhat.com> | 2019-04-24 13:37:16 +0530 | 
|---|---|---|
| committer | Atin Mukherjee <amukherj@redhat.com> | 2019-06-28 17:30:53 +0000 | 
| commit | 9b223b15ab69fce4076de036ee162f36a058bcd2 (patch) | |
| tree | e29e9119fd8a24d5fb681d3468e9828bb20bd713 /cli | |
| parent | 29ad22aa9482a69f3fcf04eea762e76602bbe9a0 (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>
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 f2948a3cbdb..c6f08985b12 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)  | 
