diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 157 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 59 | 
3 files changed, 203 insertions, 15 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 69e7fbdbe16..5278a3ebfcb 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -2482,12 +2482,103 @@ out:         return ret;  } +static int +extract_hostname_path_from_token (const char *tmp_words, char **hostname, +                                  char **path) +{ +        int ret = 0; +        char *delimiter = NULL; +        char *tmp_host = NULL; +        char *host_name = NULL; +        char *words = NULL; + +        *hostname = NULL; +        *path = NULL; + +        words = GF_CALLOC (1, strlen (tmp_words) + 1, gf_common_mt_char); +        if (!words){ +                ret = -1; +                goto out; +        } + +        strncpy (words, tmp_words, strlen (tmp_words) + 1); + +        if (validate_brick_name (words)) { +                cli_err ("Wrong brick type: %s, use <HOSTNAME>:" +                        "<export-dir-abs-path>", words); +                ret = -1; +                goto out; +        } else { +                delimiter = strrchr (words, ':'); +                ret = gf_canonicalize_path (delimiter + 1); +                if (ret) { +                        goto out; +                } else { +                        *path = GF_CALLOC (1, strlen (delimiter+1) +1, +                                           gf_common_mt_char); +                        if (!*path) { +                           ret = -1; +                                goto out; + +                        } +                        strncpy (*path, delimiter +1, +                                 strlen(delimiter + 1) + 1); +                } +        } + +        tmp_host = gf_strdup (words); +        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 allocate " +                        "memory"); +                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)) { +                cli_err ("internet address '%s' does not conform to " +                          "standards", host_name); +                ret = -1; +                goto out; +        } + +        *hostname = GF_CALLOC (1, strlen (host_name) + 1, +                                       gf_common_mt_char); +        if (!*hostname) { +                ret = -1; +                goto out; +        } +        strncpy (*hostname, host_name, strlen (host_name) + 1); +        ret = 0; + +out: +        GF_FREE (words); +        GF_FREE (tmp_host); +        return ret; +} + +  int  cli_cmd_volume_heal_options_parse (const char **words, int wordcount,                                     dict_t **options)  {          int     ret = 0;          dict_t  *dict = NULL; +        char    *hostname = NULL; +        char    *path = NULL;          dict = dict_new ();          if (!dict) @@ -2524,28 +2615,66 @@ cli_cmd_volume_heal_options_parse (const char **words, int wordcount,                  }          }          if (wordcount == 5) { -                if (strcmp (words[3], "info")) { +                if (strcmp (words[3], "info") && +                    strcmp (words[3], "statistics")) {                          ret = -1;                          goto out;                  } -                if (!strcmp (words[4], "healed")) { -                        ret = dict_set_int32 (dict, "heal-op", -                                              GF_AFR_OP_HEALED_FILES); -                        goto done; -                } -                if (!strcmp (words[4], "heal-failed")) { -                        ret = dict_set_int32 (dict, "heal-op", -                                              GF_AFR_OP_HEAL_FAILED_FILES); -                        goto done; + +                if (!strcmp (words[3], "info")) { +                        if (!strcmp (words[4], "healed")) { +                                ret = dict_set_int32 (dict, "heal-op", +                                                      GF_AFR_OP_HEALED_FILES); +                                goto done; +                        } +                        if (!strcmp (words[4], "heal-failed")) { +                                ret = dict_set_int32 (dict, "heal-op", +                                                   GF_AFR_OP_HEAL_FAILED_FILES); +                                goto done; +                        } +                        if (!strcmp (words[4], "split-brain")) { +                                ret = dict_set_int32 (dict, "heal-op", +                                                   GF_AFR_OP_SPLIT_BRAIN_FILES); +                                goto done; +                        }                  } -                if (!strcmp (words[4], "split-brain")) { -                        ret = dict_set_int32 (dict, "heal-op", -                                              GF_AFR_OP_SPLIT_BRAIN_FILES); -                        goto done; + +                if (!strcmp (words[3], "statistics")) { +                        if (!strcmp (words[4], "heal-count")) { +                                ret = dict_set_int32 (dict, "heal-op", +                                               GF_AFR_OP_STATISTICS_HEAL_COUNT); +                                goto done; +                        }                  }                  ret = -1;                  goto out;          } +        if (wordcount == 7) { +                if (!strcmp (words[3], "statistics") +                    && !strcmp (words[4], "heal-count") +                    && !strcmp (words[5], "replica")) { + +                        ret = dict_set_int32 (dict, "heal-op", +                                   GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA); +                        if (ret) +                                goto out; +                        ret = extract_hostname_path_from_token (words[6], +                                                              &hostname, &path); +                        if (ret) +                                goto out; +                        ret = dict_set_dynstr (dict, "per-replica-cmd-hostname", +                                               hostname); +                        if (ret) +                                goto out; +                        ret = dict_set_dynstr (dict, "per-replica-cmd-path", +                                               path); +                        if (ret) +                                goto out; +                        else +                                goto done; + +                } +        }          ret = -1;          goto out;  done: diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 1c6baa5e8e1..f8988f1d768 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1918,7 +1918,7 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_volume_status_cbk,            "display status of all or specified volume(s)/brick"}, -        { "volume heal <VOLNAME> [{full | statistics |info {healed | heal-failed | split-brain}}]", +        { "volume heal <VOLNAME> [{full | statistics {heal-count {replica <hostname:brickname>}} |info {healed | heal-failed | split-brain}}]",            cli_cmd_volume_heal_cbk,            "self-heal commands on volume specified by <VOLNAME>"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 459dfa18823..b1d9e65622e 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -7109,6 +7109,53 @@ out:          return;  } + +void +cmd_heal_volume_statistics_heal_count_out (dict_t *dict, int brick) +{ +        uint64_t        num_entries = 0; +        int             ret = 0; +        char            key[256] = {0}; +        char           *hostname = NULL; +        char           *path = NULL; +        char           *status = NULL; +        char            *shd_status = NULL; + +        snprintf (key, sizeof key, "%d-hostname", brick); +        ret = dict_get_str (dict, key, &hostname); +        if (ret) +                goto out; +        snprintf (key, sizeof key, "%d-path", brick); +        ret = dict_get_str (dict, key, &path); +        if (ret) +                goto out; +        cli_out ("\nBrick %s:%s", hostname, path); + +        snprintf (key, sizeof key, "%d-status", brick); +        ret = dict_get_str (dict, key, &status); +        if (status && strlen (status)) +                cli_out ("Status: %s", status); + +        snprintf (key, sizeof key, "%d-shd-status",brick); +        ret = dict_get_str (dict, key, &shd_status); + +        if(!shd_status) +        { +                snprintf (key, sizeof key, "%d-hardlinks", brick); +                ret = dict_get_uint64 (dict, key, &num_entries); +                if (ret) +                        cli_out ("No gathered input for this brick"); +                else +                        cli_out ("Number of entries: %"PRIu64, num_entries); + + +        } + +out: +        return; +} + +  int  gf_cli_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,                               int count, void *myframe) @@ -7190,6 +7237,12 @@ gf_cli_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,                  case    GF_AFR_OP_STATISTICS:                          heal_op_str =  "crawl statistics";                          break; +                case    GF_AFR_OP_STATISTICS_HEAL_COUNT: +                        heal_op_str = "count of entries to be healed"; +                        break; +                case    GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: +                        heal_op_str = "count of entries to be healed per replica"; +                        break;                  case    GF_AFR_OP_INVALID:                          heal_op_str = "invalid heal op";                          break; @@ -7255,6 +7308,12 @@ gf_cli_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,                          for (i = 0; i < brick_count; i++)                                  cmd_heal_volume_statistics_out (dict, i);                          break; +                case GF_AFR_OP_STATISTICS_HEAL_COUNT: +                case GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: +                        for (i = 0; i < brick_count; i++) +                                cmd_heal_volume_statistics_heal_count_out (dict, +                                                                           i); +                        break;                  case GF_AFR_OP_INDEX_SUMMARY:                  case GF_AFR_OP_HEALED_FILES:                  case GF_AFR_OP_HEAL_FAILED_FILES:  | 
