diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 72 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 25 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 110 | ||||
| -rw-r--r-- | cli/src/cli.h | 4 | 
4 files changed, 180 insertions, 31 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 703a06e84a3..00c2f3618e6 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -2108,3 +2108,75 @@ out:         return ret;  } + +int +cli_cmd_volume_heal_options_parse (const char **words, int wordcount, +                                   dict_t **options) +{ +        int     ret = 0; +        dict_t  *dict = NULL; + +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_set_str (dict, "volname", (char *) words[2]); +        if (ret) { +                gf_log (THIS->name, GF_LOG_ERROR, "failed to set volname"); +                goto out; +        } + +        if (wordcount == 3) { +                ret = dict_set_int32 (dict, "heal-op", GF_AFR_OP_HEAL_INDEX); +                goto done; +        } + +        if (wordcount == 4) { +                if (!strcmp (words[3], "full")) { +                        ret = dict_set_int32 (dict, "heal-op", +                                              GF_AFR_OP_HEAL_FULL); +                        goto done; +                } else if (!strcmp (words[3], "info")) { +                        ret = dict_set_int32 (dict, "heal-op", +                                              GF_AFR_OP_INDEX_SUMMARY); +                        goto done; +                } else { +                        ret = -1; +                        goto out; +                } +        } +        if (wordcount == 5) { +                if (strcmp (words[3], "info")) { +                        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[4], "split-brain")) { +                        ret = dict_set_int32 (dict, "heal-op", +                                              GF_AFR_OP_SPLIT_BRAIN_FILES); +                        goto done; +                } +                ret = -1; +                goto out; +        } +        ret = -1; +        goto out; +done: +        *options = dict; +out: +        if (ret && dict) { +                dict_unref (dict); +                *options = NULL; +        } + +        return ret; +} diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 37b41c81e80..0906f3387ce 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1560,32 +1560,29 @@ cli_cmd_volume_heal_cbk (struct cli_state *state, struct cli_cmd_word *word,          call_frame_t            *frame = NULL;          int                     sent = 0;          int                     parse_error = 0; -        dict_t                  *dict = NULL; +        dict_t                  *options = NULL;          frame = create_frame (THIS, THIS->ctx->pool);          if (!frame)                  goto out; -        if (wordcount != 3) { +        if (wordcount < 3) {                 cli_usage_out (word->pattern); -                parse_error = 1; +               parse_error = 1;                 goto out;          } -        dict = dict_new (); -        if (!dict) -                goto out; - -        ret = dict_set_str (dict, "volname", (char *) words[2]); +        ret = cli_cmd_volume_heal_options_parse (words, wordcount, &options);          if (ret) { -                gf_log (THIS->name, GF_LOG_ERROR, "failed to set volname"); +                cli_usage_out (word->pattern); +                parse_error = 1;                  goto out;          }          proc = &cli_rpc_prog->proctable[GLUSTER_CLI_HEAL_VOLUME];          if (proc->fn) { -                ret = proc->fn (frame, THIS, dict); +                ret = proc->fn (frame, THIS, options);          }  out: @@ -1595,8 +1592,8 @@ out:                          cli_out ("Volume heal failed");          } -        if (dict) -                dict_unref (dict); +        if (options) +                dict_unref (options);          return ret;  } @@ -1826,9 +1823,9 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_volume_status_cbk,            "display status of all or specified volume(s)/brick"}, -        { "volume heal <VOLNAME>", +        { "volume heal <VOLNAME> [{full | info {healed | heal-failed | split-brain}}]",            cli_cmd_volume_heal_cbk, -          "Start healing of volume specified by <VOLNAME>"}, +          "self-heal commands on volume specified by <VOLNAME>"},          {"volume statedump <VOLNAME> [nfs] [all|mem|iobuf|callpool|priv|fd|"           "inode|history]...", diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index d1888415cef..9537c977d12 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -5320,6 +5320,38 @@ gf_cli3_1_umount (call_frame_t *frame, xlator_t *this, void *data)          return ret;  } +void +cmd_heal_volume_brick_out (dict_t *dict, int brick) +{ +        uint64_t        num_entries = 0; +        int             ret = 0; +        char            key[256] = {0}; +        char            *hostname = NULL; +        char            *path = NULL; +        uint64_t        i = 0; + +        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; +        snprintf (key, sizeof (key), "%d-count", brick); +        ret = dict_get_uint64 (dict, key, &num_entries); +        cli_out ("\nEntries on %s:%s %"PRIu64, hostname, path, num_entries); +        for (i = 0; i < num_entries; i++) { +                snprintf (key, sizeof (key), "%d-%"PRIu64, brick, i); +                ret = dict_get_str (dict, key, &path); +                if (ret) +                        continue; +                cli_out (path); +        } +out: +        return; +} +  int  gf_cli3_1_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,                               int count, void *myframe) @@ -5329,7 +5361,11 @@ gf_cli3_1_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,          cli_local_t             *local = NULL;          char                    *volname = NULL;          call_frame_t            *frame = NULL; +        dict_t                  *input_dict = NULL;          dict_t                  *dict = NULL; +        int                     brick_count = 0; +        int                     i = 0; +        gf_xl_afr_op_t          heal_op = GF_AFR_OP_INVALID;          if (-1 == req->rpc_status) {                  goto out; @@ -5348,21 +5384,24 @@ gf_cli3_1_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,                  frame->local = NULL;          } -        if (local) -                dict = local->dict; - -#if (HAVE_LIB_XML) -        if (global_state->mode & GLUSTER_MODE_XML) { -                ret = cli_xml_output_dict ("volHeal", dict, rsp.op_ret, -                                           rsp.op_errno, rsp.op_errstr); -                if (ret) -                        gf_log ("cli", GF_LOG_ERROR, -                                "Error outputting to xml"); -                goto out; -        } -#endif - -        ret = dict_get_str (dict, "volname", &volname); +        if (local) { +                input_dict = local->dict; +                ret = dict_get_int32 (input_dict, "heal-op", +                                      (int32_t*)&heal_op); +        } + +//#if (HAVE_LIB_XML) +//        if (global_state->mode & GLUSTER_MODE_XML) { +//                ret = cli_xml_output_dict ("volHeal", dict, rsp.op_ret, +//                                           rsp.op_errno, rsp.op_errstr); +//                if (ret) +//                        gf_log ("cli", GF_LOG_ERROR, +//                                "Error outputting to xml"); +//                goto out; +//        } +//#endif + +        ret = dict_get_str (input_dict, "volname", &volname);          if (ret) {                  gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");                  goto out; @@ -5376,14 +5415,51 @@ gf_cli3_1_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,                  cli_out ("Starting heal on volume %s has been %s", volname,                          (rsp.op_ret) ? "unsuccessful": "successful"); +        if (rsp.op_ret) { +                ret = rsp.op_ret; +                goto out; +        } + +        if ((heal_op == GF_AFR_OP_HEAL_FULL) || +            (heal_op == GF_AFR_OP_HEAL_INDEX)) { +                ret = 0; +                goto out; +        } +        dict = dict_new (); + +        if (!dict) { +                ret = -1; +                goto out; +        } + +        ret = dict_unserialize (rsp.dict.dict_val, +                                rsp.dict.dict_len, +                                &dict); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, +                                "Unable to allocate memory"); +                goto out; +        } else { +                dict->extra_stdfree = rsp.dict.dict_val; +        } +        ret = dict_get_int32 (dict, "count", &brick_count); +        if (ret) +                goto out; + +        if (!brick_count) { +                cli_out ("All bricks of volume %s are down.", volname); +                goto out; +        } + +        for (i = 0; i < brick_count; i++) +                cmd_heal_volume_brick_out (dict, i);          ret = rsp.op_ret;  out:          cli_cmd_broadcast_response (ret);          if (local)                  cli_local_wipe (local); -        if (rsp.dict.dict_val) -                free (rsp.dict.dict_val);          if (rsp.op_errstr)                  free (rsp.op_errstr);          if (dict) diff --git a/cli/src/cli.h b/cli/src/cli.h index 74e1423f5db..1f78da1fba0 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -259,6 +259,10 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,                               dict_t **options);  int +cli_cmd_volume_heal_options_parse (const char **words, int wordcount, +                                   dict_t **options); + +int  cli_print_brick_status (cli_volume_status_t *status);  void  | 
