diff options
| author | Venkatesh Somyajulu <vsomyaju@redhat.com> | 2013-10-07 13:47:47 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-10-14 14:41:54 -0700 | 
| commit | 75caba63714c7f7f9ab810937dae69a1a28ece53 (patch) | |
| tree | 36e810729072177e9ec69ab8e7a65aca3221e7cd /cli | |
| parent | 047882750e0e97f5eed21ebe3445cdb216b15a9d (diff) | |
cluster/afr: [Feature] Command implementation to get heal-count
Currently to know the number of files to be healed, either user
has to go to backend and check the number of entries present in
indices/xattrop directory. But if a volume consists of large
number of bricks, going to each backend and counting the number
of entries is a time-taking task. Otherwise user can give
gluster volume heal vol-name info command but with this
approach if no. of entries are very hugh in the indices/
xattrop directory, it will comsume time.
So as a feature, new command is implemented.
Command 1: gluster volume heal vn statistics heal-count
This command will get the number of entries present in
every brick of a volume. The output displays only entries
count.
Command 2: gluster volume heal vn statistics heal-count
           replica 192.168.122.1:/home/user/brickname
           Here if we are concerned with just one replica.
So providing any one of the brick of a replica will get
the number of entries to be healed for that replica only.
Example:
Replicate volume with replica count 2.
Backend status:
--------------
[root@dhcp-0-17 xattrop]# ls -lia | wc -l
1918
NOTE: Out of 1918, 2 entries are <xattrop-gfid> dummy
entries so actual no. of entries to be healed are
1916.
[root@dhcp-0-17 xattrop]# pwd
/home/user/2ty/.glusterfs/indices/xattrop
Command output:
--------------
Gathering count of entries to be healed on volume volume3 has been successful
Brick 192.168.122.1:/home/user/22iu
Status: Brick is Not connected
Entries count is not available
Brick 192.168.122.1:/home/user/2ty
Number of entries: 1916
Change-Id: I72452f3de50502dc898076ec74d434d9e77fd290
BUG: 1015990
Signed-off-by: Venkatesh Somyajulu <vsomyaju@redhat.com>
Reviewed-on: http://review.gluster.org/6044
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
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:  | 
