diff options
Diffstat (limited to 'cli/src/cli-cmd-volume.c')
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 865 |
1 files changed, 272 insertions, 593 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 55917e8217c..f238851586e 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -23,17 +23,16 @@ #include "cli-cmd.h" #include "cli-mem-types.h" #include "cli1-xdr.h" -#include "run.h" -#include "syscall.h" -#include "common-utils.h" -#include "events.h" +#include <glusterfs/run.h> +#include <glusterfs/syscall.h> +#include <glusterfs/common-utils.h> +#include <glusterfs/events.h> -extern struct rpc_clnt *global_rpc; -extern struct rpc_clnt *global_quotad_rpc; - -extern rpc_clnt_prog_t *cli_rpc_prog; extern rpc_clnt_prog_t cli_quotad_clnt; +static int +gf_asprintf_append(char **string_ptr, const char *format, ...); + int cli_cmd_volume_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, const char **words, int wordcount); @@ -47,10 +46,6 @@ cli_cmd_quota_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, const char **words, int wordcount); int -cli_cmd_tier_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, - const char **words, int wordcount); - -int cli_cmd_volume_info_cbk(struct cli_state *state, struct cli_cmd_word *word, const char **words, int wordcount) { @@ -66,10 +61,6 @@ cli_cmd_volume_info_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOLUME]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - if ((wordcount == 2) || (wordcount == 3 && !strcmp(words[2], "all"))) { ctx.flags = GF_CLI_GET_NEXT_VOLUME; proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_NEXT_VOLUME]; @@ -92,6 +83,10 @@ cli_cmd_volume_info_cbk(struct cli_state *state, struct cli_cmd_word *word, if (!local) goto out; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) + goto out; + local->get_vol.flags = ctx.flags; if (ctx.volname) local->get_vol.volname = gf_strdup(ctx.volname); @@ -217,10 +212,6 @@ cli_cmd_volume_create_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CREATE_VOLUME]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_create_parse(state, words, wordcount, &options, &bricks); @@ -246,6 +237,12 @@ cli_cmd_volume_create_cbk(struct cli_state *state, struct cli_cmd_word *word, } } + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -288,14 +285,6 @@ cli_cmd_volume_delete_cbk(struct cli_state *state, struct cli_cmd_word *word, "Do you want to continue?"; proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DELETE_VOLUME]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - - dict = dict_new(); - if (!dict) - goto out; - if (wordcount != 3) { cli_usage_out(word->pattern); parse_error = 1; @@ -304,6 +293,10 @@ cli_cmd_volume_delete_cbk(struct cli_state *state, struct cli_cmd_word *word, volname = (char *)words[2]; + dict = dict_new(); + if (!dict) + goto out; + ret = dict_set_str(dict, "volname", volname); if (ret) { gf_log(THIS->name, GF_LOG_WARNING, "dict set failed"); @@ -325,6 +318,12 @@ cli_cmd_volume_delete_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, dict); if (proc->fn) { @@ -360,30 +359,15 @@ cli_cmd_volume_start_cbk(struct cli_state *state, struct cli_cmd_word *word, int flags = 0; cli_local_t *local = NULL; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - if (wordcount < 3 || wordcount > 4) { cli_usage_out(word->pattern); parse_error = 1; goto out; } - dict = dict_new(); - if (!dict) { - goto out; - } - if (!words[2]) goto out; - ret = dict_set_str(dict, "volname", (char *)words[2]); - if (ret) { - gf_log(THIS->name, GF_LOG_ERROR, "dict set failed"); - goto out; - } - if (wordcount == 4) { if (!strcmp("force", words[3])) { flags |= GF_CLI_FLAG_OP_FORCE; @@ -394,6 +378,18 @@ cli_cmd_volume_start_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } } + + 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, "dict set failed"); + goto out; + } + ret = dict_set_int32(dict, "flags", flags); if (ret) { gf_log(THIS->name, GF_LOG_ERROR, "dict set failed"); @@ -402,6 +398,12 @@ cli_cmd_volume_start_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_START_VOLUME]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, dict); if (proc->fn) { @@ -488,10 +490,6 @@ cli_cmd_volume_stop_cbk(struct cli_state *state, struct cli_cmd_word *word, "Stopping volume will make its data inaccessible. " "Do you want to continue?"; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - if (wordcount < 3 || wordcount > 4) { cli_usage_out(word->pattern); parse_error = 1; @@ -542,6 +540,12 @@ cli_cmd_volume_stop_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STOP_VOLUME]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, dict); if (proc->fn) { @@ -556,6 +560,8 @@ out: } CLI_STACK_DESTROY(frame); + if (dict) + dict_unref(dict); if (ret == 0 && GF_ANSWER_YES == answer) { gf_event(EVENT_VOLUME_STOP, "name=%s;force=%d", (char *)words[2], @@ -576,20 +582,16 @@ cli_cmd_volume_rename_cbk(struct cli_state *state, struct cli_cmd_word *word, int sent = 0; int parse_error = 0; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - - dict = dict_new(); - if (!dict) - goto out; - if (wordcount != 4) { cli_usage_out(word->pattern); parse_error = 1; goto out; } + dict = dict_new(); + if (!dict) + goto out; + ret = dict_set_str(dict, "old-volname", (char *)words[2]); if (ret) @@ -603,6 +605,11 @@ cli_cmd_volume_rename_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RENAME_VOLUME]; if (proc->fn) { + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } ret = proc->fn(frame, THIS, dict); } @@ -641,10 +648,6 @@ cli_cmd_volume_defrag_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; #endif - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_defrag_parse(words, wordcount, &dict); if (ret) { @@ -654,6 +657,12 @@ cli_cmd_volume_defrag_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEFRAG_VOLUME]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, dict); if (proc->fn) { @@ -702,10 +711,6 @@ cli_cmd_volume_reset_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_VOLUME]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_reset_parse(words, wordcount, &options); if (ret) { cli_usage_out(word->pattern); @@ -713,6 +718,12 @@ cli_cmd_volume_reset_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -817,10 +828,6 @@ cli_cmd_volume_set_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SET_VOLUME]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_set_parse(state, words, wordcount, &options, &op_errstr); if (ret) { @@ -834,6 +841,12 @@ cli_cmd_volume_set_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -850,13 +863,21 @@ out: #if (USE_EVENTS) if (ret == 0 && strcmp(words[2], "help") != 0) { ret1 = dict_get_int32(options, "count", &num_options); - if (ret1) + if (ret1) { num_options = 0; - else + goto end; + } else { num_options = num_options / 2; + } + char *free_list_key[num_options]; + char *free_list_val[num_options]; + for (i = 0; i < num_options; i++) { + free_list_key[i] = NULL; + free_list_val[i] = NULL; + } /* Initialize opts_str */ - opts_str = gf_strdup(""); + opts_str = ""; /* Prepare String in format options=KEY1,VALUE1,KEY2,VALUE2 */ for (i = 1; i <= num_options; i++) { @@ -866,6 +887,7 @@ out: tmp_opt = ""; gf_asprintf(&opts_str, "%s,%s", opts_str, tmp_opt); + free_list_key[i - 1] = opts_str; sprintf(dict_key, "value%d", i); ret1 = dict_get_str(options, dict_key, &tmp_opt); @@ -873,16 +895,21 @@ out: tmp_opt = ""; gf_asprintf(&opts_str, "%s,%s", opts_str, tmp_opt); + free_list_val[i - 1] = opts_str; } gf_event(EVENT_VOLUME_SET, "name=%s;options=%s", (char *)words[2], opts_str); /* Allocated by gf_strdup and gf_asprintf */ - GF_FREE(opts_str); + for (i = 0; i < num_options; i++) { + GF_FREE(free_list_key[i]); + GF_FREE(free_list_val[i]); + } } #endif +end: CLI_STACK_DESTROY(frame); return ret; @@ -1027,10 +1054,6 @@ cli_cmd_volume_add_brick_cbk(struct cli_state *state, struct cli_cmd_word *word, "filesystem operations on the volume after the change. Do you " "really want to continue with 'stripe' count option ? "; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_add_brick_parse(state, words, wordcount, &options, 0); if (ret) { cli_usage_out(word->pattern); @@ -1075,6 +1098,12 @@ cli_cmd_volume_add_brick_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ADD_BRICK]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -1100,335 +1129,6 @@ out: } int -cli_tier_validate_replica_type(dict_t *dict, int type) -{ - int brick_count = -1; - int replica_count = 1; - int ret = -1; - - ret = dict_get_int32(dict, "count", &brick_count); - if (ret) { - gf_log("cli", GF_LOG_ERROR, "Failed to get brick count"); - goto out; - } - - ret = dict_get_int32(dict, "replica-count", &replica_count); - if (ret) { - gf_log("cli", GF_LOG_DEBUG, - "Failed to get replica count. " - "Defaulting to one"); - replica_count = 1; - } - - /* - * Change the calculation of sub_count once attach-tier support - * disperse volume. - * sub_count = disperse_count for disperse volume - * */ - - if (brick_count % replica_count) { - if (type == GF_CLUSTER_TYPE_REPLICATE) - cli_err( - "number of bricks is not a multiple of " - "replica count"); - else if (type == GF_CLUSTER_TYPE_DISPERSE) - cli_err( - "number of bricks is not a multiple of " - "disperse count"); - else - cli_err( - "number of bricks given doesn't match " - "required count"); - - ret = -1; - goto out; - } - ret = 0; -out: - return ret; -} - -int -do_cli_cmd_volume_attach_tier(struct cli_state *state, - struct cli_cmd_word *word, const char **words, - int wordcount) -{ - int ret = -1; - rpc_clnt_procedure_t *proc = NULL; - call_frame_t *frame = NULL; - dict_t *options = NULL; - int sent = 0; - int parse_error = 0; - cli_local_t *local = NULL; - int type = 0; - - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - - ret = cli_cmd_volume_add_brick_parse(state, words, wordcount, &options, - &type); - if (ret) { - cli_usage_out(word->pattern); - parse_error = 1; - goto out; - } - - /* - * Merge this check when attach-tier has it's own cli parse function. - */ - ret = cli_tier_validate_replica_type(options, type); - if (ret) { - cli_usage_out(word->pattern); - parse_error = 1; - goto out; - } - - if (state->mode & GLUSTER_MODE_WIGNORE) { - ret = dict_set_int32(options, "force", _gf_true); - if (ret) { - gf_log("cli", GF_LOG_ERROR, - "Failed to set force " - "option"); - goto out; - } - } - - ret = dict_set_int32(options, "attach-tier", 1); - if (ret) - goto out; - - ret = dict_set_int32(options, "hot-type", type); - if (ret) - goto out; - - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ADD_TIER_BRICK]; - - CLI_LOCAL_INIT(local, words, frame, options); - - if (proc->fn) { - ret = proc->fn(frame, THIS, options); - } - -out: - if (ret) { - cli_cmd_sent_status_get(&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out("attach-tier failed"); - } - - CLI_STACK_DESTROY(frame); - - return ret; -} - -int -do_cli_cmd_volume_detach_tier(struct cli_state *state, - struct cli_cmd_word *word, const char **words, - int wordcount, gf_boolean_t *aborted) -{ - int ret = -1; - rpc_clnt_procedure_t *proc = NULL; - call_frame_t *frame = NULL; - dict_t *options = NULL; - int sent = 0; - int parse_error = 0; - gf_answer_t answer = GF_ANSWER_NO; - cli_local_t *local = NULL; - int need_question = 0; - - const char *question = - "Removing tier can result in data loss. " - "Do you want to Continue?"; - - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - - ret = cli_cmd_volume_detach_tier_parse(words, wordcount, &options, - &need_question); - if (ret) { - cli_usage_out(word->pattern); - parse_error = 1; - goto out; - } - - ret = dict_set_int32(options, "force", 1); - if (ret) - goto out; - - ret = dict_set_int32(options, "count", 0); - if (ret) - goto out; - - *aborted = _gf_false; - - if (!(state->mode & GLUSTER_MODE_SCRIPT) && need_question) { - /* we need to ask question only in case of 'commit or force' */ - answer = cli_cmd_get_confirmation(state, question); - if (GF_ANSWER_NO == answer) { - ret = 0; - *aborted = _gf_true; - goto out; - } - } - - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REMOVE_TIER_BRICK]; - - CLI_LOCAL_INIT(local, words, frame, options); - - if (proc->fn) { - ret = proc->fn(frame, THIS, options); - } - -out: - if (ret) { - cli_cmd_sent_status_get(&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out("Volume detach tier failed"); - } - - CLI_STACK_DESTROY(frame); - - return ret; -} - -int -cli_cmd_volume_tier_cbk(struct cli_state *state, struct cli_cmd_word *word, - const char **words, int wordcount) -{ - int ret = -1; - call_frame_t *frame = NULL; - dict_t *options = NULL; - rpc_clnt_procedure_t *proc = NULL; - cli_local_t *local = NULL; - int i = 0; - eventtypes_t event = EVENT_LAST; - gf_boolean_t aborted = _gf_false; - gf_answer_t answer = GF_ANSWER_NO; - - const char *detach_question = - "gluster volume detach-tier <VOLNAME> " - "<start|stop|status|commit|force> is " - "deprecated. Use the new command \'" - "gluster volume tier <VOLNAME> detach <start|" - "stop|status|commit|force>\'\n" - "Do you want to Continue?"; - - const char *attach_question = - "gluster volume attach-tier <VOLNAME> " - "[<replica COUNT>] <NEW-BRICK>... is " - "deprecated. Use the new command \'" - "gluster volume tier <VOLNAME> attach [<replica" - " COUNT>] <NEW-BRICK>... [force]\'\n" - "Do you want to Continue?"; - - if (wordcount < 4) { - if (wordcount == 3 && !strcmp(words[2], "help")) { - cli_cmd_tier_help_cbk(state, word, words, wordcount); - ret = 0; - } else { - cli_usage_out(word->pattern); - } - goto out; - } - - if (!strcmp(words[1], "detach-tier")) { - /* we need to ask question when older command is used */ - answer = cli_cmd_get_confirmation(state, detach_question); - if (GF_ANSWER_NO == answer) { - ret = 0; - goto out; - } - ret = do_cli_cmd_volume_detach_tier(state, word, words, wordcount, - &aborted); - goto out; - } else if (!strcmp(words[3], "detach")) { - for (i = 3; i < wordcount; i++) - words[i] = words[i + 1]; - - ret = do_cli_cmd_volume_detach_tier(state, word, words, wordcount - 1, - &aborted); - if (!aborted) { - if (!strcmp(words[wordcount - 2], "commit")) { - event = EVENT_TIER_DETACH_COMMIT; - } else if (!strcmp(words[wordcount - 2], "start")) { - event = EVENT_TIER_DETACH_START; - } else if (!strcmp(words[wordcount - 2], "stop")) { - event = EVENT_TIER_DETACH_STOP; - } else if (!strcmp(words[wordcount - 2], "force")) { - event = EVENT_TIER_DETACH_FORCE; - } - } - goto out; - - } else if (!strcmp(words[1], "attach-tier")) { - /* we need to ask question when the older command is used */ - answer = cli_cmd_get_confirmation(state, attach_question); - if (GF_ANSWER_NO == answer) { - ret = 0; - goto out; - } - ret = do_cli_cmd_volume_attach_tier(state, word, words, wordcount); - goto out; - } else if (!strcmp(words[3], "attach")) { - for (i = 3; i < wordcount; i++) - words[i] = words[i + 1]; - - ret = do_cli_cmd_volume_attach_tier(state, word, words, wordcount - 1); - if (!strcmp(words[wordcount - 2], "force")) { - event = EVENT_TIER_ATTACH_FORCE; - } else { - event = EVENT_TIER_ATTACH; - } - goto out; - } - - ret = cli_cmd_volume_tier_parse(words, wordcount, &options); - if (ret) { - cli_usage_out(word->pattern); - goto out; - } - - if (!strcmp(words[wordcount - 1], "start")) { - event = EVENT_TIER_START; - } else { - if (!strcmp(words[wordcount - 2], "start") && - !strcmp(words[wordcount - 1], "force")) { - event = EVENT_TIER_START_FORCE; - } - } - - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_TIER]; - - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) { - gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame"); - ret = -1; - goto out; - } - - CLI_LOCAL_INIT(local, words, frame, options); - - if (proc->fn) { - ret = proc->fn(frame, THIS, options); - } - -out: - if (ret) { - cli_out("Tier command failed"); - } else { - if (event != EVENT_LAST) { - gf_event(event, "vol=%s", words[2]); - } - } - if (options) - dict_unref(options); - - return ret; -} - -int cli_get_soft_limit(dict_t *options, const char **words, dict_t *xdata) { call_frame_t *frame = NULL; @@ -1541,7 +1241,7 @@ cli_cmd_quota_handle_list_all(const char **words, dict_t *options) cli_local_t *local = NULL; call_frame_t *frame = NULL; dict_t *xdata = NULL; - char *gfid_str = NULL; + char gfid_str[UUID_CANONICAL_FORM_LEN + 1]; char *volname = NULL; char *volname_dup = NULL; unsigned char buf[16] = {0}; @@ -1605,12 +1305,6 @@ cli_cmd_quota_handle_list_all(const char **words, dict_t *options) goto out; } - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) { - ret = -1; - goto out; - } - volname_dup = gf_strdup(volname); if (!volname_dup) { ret = -1; @@ -1642,15 +1336,15 @@ cli_cmd_quota_handle_list_all(const char **words, dict_t *options) if (ret) goto out; - CLI_LOCAL_INIT(local, words, frame, xdata); - proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; - - gfid_str = GF_CALLOC(1, gf_common_mt_char, 64); - if (!gfid_str) { + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { ret = -1; goto out; } + CLI_LOCAL_INIT(local, words, frame, xdata); + proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; + for (count = 0;; count++) { ret = quota_conf_read_gfid(fd, buf, &gfid_type, version); if (ret == 0) { @@ -1749,12 +1443,13 @@ out: "xml format"); } } + if (xdata) + dict_unref(xdata); if (fd != -1) { sys_close(fd); } - GF_FREE(gfid_str); if (ret) { gf_log("cli", GF_LOG_ERROR, "Could not fetch and display quota" @@ -1781,6 +1476,7 @@ cli_cmd_bitrot_cbk(struct cli_state *state, struct cli_cmd_word *word, int event_type = -1; char *tmp = NULL; char *events_str = NULL; + char *volname = NULL; #endif ret = cli_cmd_bitrot_parse(words, wordcount, &options); @@ -1826,10 +1522,9 @@ out: if (ret1) cmd_type = -1; else { - ret1 = dict_get_str(options, "volname", &tmp); + ret1 = dict_get_str(options, "volname", &volname); if (ret1) - tmp = ""; - gf_asprintf(&events_str, "name=%s", tmp); + volname = ""; } switch (cmd_type) { @@ -1847,21 +1542,21 @@ out: ret1 = dict_get_str(options, "scrub-throttle-value", &tmp); if (ret1) tmp = ""; - gf_asprintf(&events_str, "%s;value=%s", events_str, tmp); + gf_asprintf(&events_str, "name=%s;value=%s", volname, tmp); break; case GF_BITROT_OPTION_TYPE_SCRUB_FREQ: event_type = EVENT_BITROT_SCRUB_FREQ; ret1 = dict_get_str(options, "scrub-frequency-value", &tmp); if (ret1) tmp = ""; - gf_asprintf(&events_str, "%s;value=%s", events_str, tmp); + gf_asprintf(&events_str, "name=%s;value=%s", volname, tmp); break; case GF_BITROT_OPTION_TYPE_SCRUB: event_type = EVENT_BITROT_SCRUB_OPTION; ret1 = dict_get_str(options, "scrub-value", &tmp); if (ret1) tmp = ""; - gf_asprintf(&events_str, "%s;value=%s", events_str, tmp); + gf_asprintf(&events_str, "name=%s;value=%s", volname, tmp); break; default: break; @@ -1970,6 +1665,8 @@ out: "Quota command failed. Please check the cli " "logs for more details"); } + if (options) + dict_unref(options); /* Events for Quota */ if (ret == 0) { @@ -2057,10 +1754,6 @@ cli_cmd_volume_remove_brick_cbk(struct cli_state *state, int32_t command = GF_OP_CMD_NONE; char *question = NULL; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_remove_brick_parse(state, words, wordcount, &options, &need_question, &brick_count, &command); @@ -2077,14 +1770,15 @@ cli_cmd_volume_remove_brick_cbk(struct cli_state *state, " on the volume.\nDo you want to continue?"; } else if (command == GF_OP_CMD_START) { question = - "Running remove-brick with cluster.force-migration" - " enabled can result in data corruption. It is safer" - " to disable this option so that files that receive " - "writes during migration are not migrated.\nFiles " - "that are not migrated can then be manually copied " - "after the remove-brick commit operation.\nDo you " - "want to continue with your current " - "cluster.force-migration settings?"; + "It is recommended that remove-brick be run with" + " cluster.force-migration option disabled to prevent" + " possible data corruption. Doing so will ensure that" + " files that receive writes during migration will not" + " be migrated and will need to be manually copied" + " after the remove-brick commit operation. Please" + " check the value of the option and update accordingly." + " \nDo you want to continue with your current" + " cluster.force-migration settings?"; } if (!brick_count) { @@ -2125,6 +1819,12 @@ cli_cmd_volume_remove_brick_cbk(struct cli_state *state, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REMOVE_BRICK]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -2146,6 +1846,8 @@ out: #endif CLI_STACK_DESTROY(frame); + if (options) + dict_unref(options); return ret; } @@ -2169,10 +1871,6 @@ cli_cmd_volume_reset_brick_cbk(struct cli_state *state, #endif proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_BRICK]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_reset_brick_parse(words, wordcount, &options); if (ret) { @@ -2191,6 +1889,12 @@ cli_cmd_volume_reset_brick_cbk(struct cli_state *state, } } + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -2237,10 +1941,6 @@ cli_cmd_volume_replace_brick_cbk(struct cli_state *state, #endif proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REPLACE_BRICK]; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - ret = cli_cmd_volume_replace_brick_parse(words, wordcount, &options); if (ret) { @@ -2249,6 +1949,12 @@ cli_cmd_volume_replace_brick_cbk(struct cli_state *state, goto out; } + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -2344,8 +2050,7 @@ cli_cmd_log_rotate_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } - if (!((strcmp("rotate", words[2]) == 0) || - (strcmp("rotate", words[3]) == 0))) { + if (!(strcmp("rotate", words[3]) == 0)) { cli_usage_out(word->pattern); parse_error = 1; goto out; @@ -2353,6 +2058,10 @@ cli_cmd_log_rotate_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LOG_ROTATE]; + ret = cli_cmd_log_rotate_parse(words, wordcount, &options); + if (ret) + goto out; + frame = create_frame(THIS, THIS->ctx->pool); if (!frame) { gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame"); @@ -2360,10 +2069,6 @@ cli_cmd_log_rotate_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } - ret = cli_cmd_log_rotate_parse(words, wordcount, &options); - if (ret) - goto out; - CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -2453,6 +2158,7 @@ cli_cmd_volume_gsync_set_cbk(struct cli_state *state, struct cli_cmd_word *word, rpc_clnt_procedure_t *proc = NULL; call_frame_t *frame = NULL; cli_local_t *local = NULL; + char *errstr = NULL; #if (USE_EVENTS) int ret1 = -1; int cmd_type = -1; @@ -2464,16 +2170,21 @@ cli_cmd_volume_gsync_set_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GSYNC_SET]; - frame = create_frame(THIS, THIS->ctx->pool); - if (frame == NULL) { - ret = -1; + ret = cli_cmd_gsync_set_parse(state, words, wordcount, &options, &errstr); + if (ret) { + if (errstr) { + cli_err("%s", errstr); + GF_FREE(errstr); + } else { + cli_usage_out(word->pattern); + } + parse_err = 1; goto out; } - ret = cli_cmd_gsync_set_parse(words, wordcount, &options); - if (ret) { - cli_usage_out(word->pattern); - parse_err = 1; + frame = create_frame(THIS, THIS->ctx->pool); + if (frame == NULL) { + ret = -1; goto out; } @@ -2529,13 +2240,15 @@ out: if (ret1) tmp = ""; - gf_asprintf(&events_str, "%soption=%s;", events_str, tmp); + gf_asprintf_append(&events_str, "%soption=%s;", events_str, + tmp); ret1 = dict_get_str(options, "op_value", &tmp); if (ret1) tmp = ""; - gf_asprintf(&events_str, "%svalue=%s;", events_str, tmp); + gf_asprintf_append(&events_str, "%svalue=%s;", events_str, + tmp); } else if (strcmp(tmp, "del") == 0) { event_type = EVENT_GEOREP_CONFIG_RESET; @@ -2543,7 +2256,8 @@ out: if (ret1) tmp = ""; - gf_asprintf(&events_str, "%soption=%s;", events_str, tmp); + gf_asprintf_append(&events_str, "%soption=%s;", events_str, + tmp); } break; default: @@ -2553,42 +2267,49 @@ out: if (event_type > -1) { /* Capture all optional arguments used */ ret1 = dict_get_int32(options, "force", &tmpi); - if (ret1 == 0) - gf_asprintf(&events_str, "%sforce=%d;", events_str, tmpi); - + if (ret1 == 0) { + gf_asprintf_append(&events_str, "%sforce=%d;", events_str, + tmpi); + } ret1 = dict_get_int32(options, "push_pem", &tmpi); - if (ret1 == 0) - gf_asprintf(&events_str, "%spush_pem=%d;", events_str, tmpi); - + if (ret1 == 0) { + gf_asprintf_append(&events_str, "%spush_pem=%d;", events_str, + tmpi); + } ret1 = dict_get_int32(options, "no_verify", &tmpi); - if (ret1 == 0) - gf_asprintf(&events_str, "%sno_verify=%d;", events_str, tmpi); + if (ret1 == 0) { + gf_asprintf_append(&events_str, "%sno_verify=%d;", events_str, + tmpi); + } ret1 = dict_get_int32(options, "ssh_port", &tmpi); - if (ret1 == 0) - gf_asprintf(&events_str, "%sssh_port=%d;", events_str, tmpi); + if (ret1 == 0) { + gf_asprintf_append(&events_str, "%sssh_port=%d;", events_str, + tmpi); + } ret1 = dict_get_int32(options, "reset-sync-time", &tmpi); - if (ret1 == 0) - gf_asprintf(&events_str, "%sreset_sync_time=%d;", events_str, - tmpi); - + if (ret1 == 0) { + gf_asprintf_append(&events_str, "%sreset_sync_time=%d;", + events_str, tmpi); + } /* Capture Master and Slave Info */ ret1 = dict_get_str(options, "master", &tmp); if (ret1) tmp = ""; - gf_asprintf(&events_str, "%smaster=%s;", events_str, tmp); + gf_asprintf_append(&events_str, "%smaster=%s;", events_str, tmp); ret1 = dict_get_str(options, "slave", &tmp); if (ret1) tmp = ""; - gf_asprintf(&events_str, "%sslave=%s", events_str, tmp); + gf_asprintf_append(&events_str, "%sslave=%s", events_str, tmp); gf_event(event_type, "%s", events_str); } /* Allocated by gf_strdup and gf_asprintf */ - GF_FREE(events_str); + if (events_str) + GF_FREE(events_str); } #endif @@ -2838,7 +2559,7 @@ cli_launch_glfs_heal(int heal_op, dict_t *options) runinit(&runner); ret = dict_get_str(options, "volname", &volname); - runner_add_args(&runner, SBIN_DIR "/glfsheal", volname, NULL); + runner_add_args(&runner, GLFSHEAL_PREFIX "/glfsheal", volname, NULL); runner_redir(&runner, STDOUT_FILENO, RUN_PIPE); switch (heal_op) { @@ -2913,9 +2634,6 @@ cli_cmd_volume_heal_cbk(struct cli_state *state, struct cli_cmd_word *word, int heal_op = 0; this = THIS; - frame = create_frame(this, this->ctx->pool); - if (!frame) - goto out; if (wordcount < 3) { cli_usage_out(word->pattern); @@ -2942,6 +2660,12 @@ cli_cmd_volume_heal_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_HEAL_VOLUME]; + frame = create_frame(this, this->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -2976,10 +2700,6 @@ cli_cmd_volume_statedump_cbk(struct cli_state *state, struct cli_cmd_word *word, int parse_error = 0; cli_local_t *local = NULL; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - if (wordcount < 3) { cli_usage_out(word->pattern); parse_error = 1; @@ -3005,6 +2725,12 @@ cli_cmd_volume_statedump_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATEDUMP_VOLUME]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -3032,12 +2758,11 @@ cli_cmd_volume_list_cbk(struct cli_state *state, struct cli_cmd_word *word, rpc_clnt_procedure_t *proc = NULL; int sent = 0; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_VOLUME]; if (proc->fn) { + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) + goto out; ret = proc->fn(frame, THIS, NULL); } @@ -3066,10 +2791,6 @@ cli_cmd_volume_clearlocks_cbk(struct cli_state *state, int parse_error = 0; cli_local_t *local = NULL; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - if (wordcount < 7 || wordcount > 8) { cli_usage_out(word->pattern); parse_error = 1; @@ -3096,6 +2817,12 @@ cli_cmd_volume_clearlocks_cbk(struct cli_state *state, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CLRLOCKS_VOLUME]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) { @@ -3126,10 +2853,6 @@ cli_cmd_volume_barrier_cbk(struct cli_state *state, struct cli_cmd_word *word, int parse_error = 0; cli_local_t *local = NULL; - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - if (wordcount != 4) { cli_usage_out(word->pattern); parse_error = 1; @@ -3151,6 +2874,12 @@ cli_cmd_volume_barrier_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BARRIER_VOLUME]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) @@ -3185,10 +2914,6 @@ cli_cmd_volume_getopt_cbk(struct cli_state *state, struct cli_cmd_word *word, goto out; } - frame = create_frame(THIS, THIS->ctx->pool); - if (!frame) - goto out; - options = dict_new(); if (!options) goto out; @@ -3203,6 +2928,12 @@ cli_cmd_volume_getopt_cbk(struct cli_state *state, struct cli_cmd_word *word, proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOL_OPT]; + frame = create_frame(THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT(local, words, frame, options); if (proc->fn) @@ -3232,6 +2963,16 @@ struct cli_cmd bitrot_cmds[] = { {"volume bitrot <VOLNAME> {enable|disable}", NULL, /*cli_cmd_bitrot_cbk,*/ "Enable/disable bitrot for volume <VOLNAME>"}, + {"volume bitrot <VOLNAME> signing-time <time-in-secs>", + NULL, /*cli_cmd_bitrot_cbk,*/ + "Waiting time for an object after last fd is closed to start signing " + "process"}, + + {"volume bitrot <VOLNAME> signer-threads <count>", + NULL, /*cli_cmd_bitrot_cbk,*/ + "Number of signing process threads. Usually set to number of available " + "cores"}, + {"volume bitrot <VOLNAME> scrub-throttle {lazy|normal|aggressive}", NULL, /*cli_cmd_bitrot_cbk,*/ "Set the speed of the scrubber for volume <VOLNAME>"}, @@ -3247,6 +2988,8 @@ struct cli_cmd bitrot_cmds[] = { "the scrubber. ondemand starts the scrubber immediately."}, {"volume bitrot <VOLNAME> {enable|disable}\n" + "volume bitrot <VOLNAME> signing-time <time-in-secs>\n" + "volume bitrot <VOLNAME> signer-threads <count>\n" "volume bitrot <volname> scrub-throttle {lazy|normal|aggressive}\n" "volume bitrot <volname> scrub-frequency {hourly|daily|weekly|biweekly" "|monthly}\n" @@ -3289,50 +3032,6 @@ struct cli_cmd quota_cmds[] = { {NULL, NULL, NULL}}; -struct cli_cmd tier_cmds[] = { - - {"volume tier help", cli_cmd_tier_help_cbk, - "display help for volume tier commands"}, - - {"volume tier <VOLNAME> status", cli_cmd_volume_tier_cbk, - "Display tier status for <VOLNAME>"}, - - {"volume tier <VOLNAME> start [force]", cli_cmd_volume_tier_cbk, - "Start the tier service for <VOLNAME>"}, - - {"volume tier <VOLNAME> stop [force]", cli_cmd_volume_tier_cbk, - "Stop the tier service for <VOLNAME>"}, - - {"volume tier <VOLNAME> attach [<replica COUNT>] <NEW-BRICK>... [force]", - cli_cmd_volume_tier_cbk, "Attach a hot tier to <VOLNAME>"}, - - {"volume tier <VOLNAME> detach <start|stop|status|commit|[force]>", - cli_cmd_volume_tier_cbk, "Detach the hot tier from <VOLNAME>"}, - - {"volume attach-tier <VOLNAME> [<replica COUNT>] <NEW-BRICK>...", - cli_cmd_volume_tier_cbk, - "NOTE: this is old syntax, will be deprecated in next release. " - "Please use gluster volume tier <vol> attach " - "[<replica COUNT>] <NEW-BRICK>..."}, - - {"volume detach-tier <VOLNAME> " - "<start|stop|status|commit|force>", - cli_cmd_volume_tier_cbk, - "NOTE: this is old syntax, will be deprecated in next release. " - "Please use gluster volume tier <vol> detach " - "{start|stop|commit} [force]"}, - - {"volume tier <VOLNAME> status\n" - "volume tier <VOLNAME> start [force]\n" - "volume tier <VOLNAME> stop\n" - "volume tier <VOLNAME> attach [<replica COUNT>] <NEW-BRICK>... [force]\n" - "volume tier <VOLNAME> detach <start|stop|status|commit|[force]>\n", - cli_cmd_volume_tier_cbk, NULL}, - - {NULL, NULL, NULL} - -}; - struct cli_cmd volume_cmds[] = { {"volume help", cli_cmd_volume_help_cbk, "display help for volume commands"}, @@ -3341,12 +3040,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>" -#ifdef HAVE_BD_XLATOR - "?<vg_name>" -#endif + "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> <TA-BRICK>" "... [force]", cli_cmd_volume_create_cbk, @@ -3388,13 +3084,14 @@ struct cli_cmd volume_cmds[] = { {"volume set <VOLNAME> <KEY> <VALUE>", cli_cmd_volume_set_cbk, "set options for volume <VOLNAME>"}, + {"volume set <VOLNAME> group <GROUP>", cli_cmd_volume_set_cbk, + "This option can be used for setting multiple pre-defined volume options " + "where group_name is a file under /var/lib/glusterd/groups containing one " + "key value pair per line"}, + {"volume log <VOLNAME> rotate [BRICK]", cli_cmd_log_rotate_cbk, "rotate the log file for corresponding volume/brick"}, - {"volume log rotate <VOLNAME> [BRICK]", cli_cmd_log_rotate_cbk, - "rotate the log file for corresponding volume/brick" - " NOTE: This is an old syntax, will be deprecated from next release."}, - {"volume sync <HOSTNAME> [all|<VOLNAME>]", cli_cmd_sync_volume_cbk, "sync the volume information from a peer"}, @@ -3402,8 +3099,8 @@ struct cli_cmd volume_cmds[] = { "reset all the reconfigured options"}, #if (SYNCDAEMON_COMPILE) - {"volume " GEOREP " [<VOLNAME>] [<SLAVE-URL>] {\\\n create [[ssh-port n] " - "[[no-verify] | [push-pem]]] [force] \\\n" + {"volume " GEOREP " [<MASTER-VOLNAME>] [<SLAVE-IP>]::[<SLAVE-VOLNAME>] {" + "\\\n create [[ssh-port n] [[no-verify] \\\n | [push-pem]]] [force] \\\n" " | start [force] \\\n | stop [force] \\\n | pause [force] \\\n | resume " "[force] \\\n" " | config [[[\\!]<option>] [<value>]] \\\n | status " @@ -3417,12 +3114,12 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_profile_cbk, "volume profile operations"}, {"volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick " - "<brick>] [list-cnt <value>] |\n" - "volume top <VOLNAME> {read-perf|write-perf} [bs <size> count <count>] " + "<brick>] [list-cnt <value>] | " + "{read-perf|write-perf} [bs <size> count <count>] " "[brick <brick>] [list-cnt <value>]", cli_cmd_volume_top_cbk, "volume top operations"}, - {"volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad|tierd]]" + {"volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad]]" " [detail|clients|mem|inode|fd|callpool|tasks|client-list]", cli_cmd_volume_status_cbk, "display status of all or specified volume(s)/brick"}, @@ -3511,32 +3208,6 @@ cli_cmd_bitrot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, } int -cli_cmd_tier_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, - const char **words, int wordcount) -{ - struct cli_cmd *cmd = NULL; - struct cli_cmd *tier_cmd = NULL; - int count = 0; - - cmd = GF_MALLOC(sizeof(tier_cmds), cli_mt_cli_cmd); - memcpy(cmd, tier_cmds, sizeof(tier_cmds)); - count = (sizeof(tier_cmds) / sizeof(struct cli_cmd)); - cli_cmd_sort(cmd, count); - - cli_out("\ngluster tier commands"); - cli_out("======================\n"); - - for (tier_cmd = cmd; tier_cmd->pattern; tier_cmd++) { - if ((_gf_false == tier_cmd->disable) && tier_cmd->desc) { - cli_out("%s - %s", tier_cmd->pattern, tier_cmd->desc); - } - } - cli_out("\n"); - GF_FREE(cmd); - return 0; -} - -int cli_cmd_volume_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, const char **words, int wordcount) { @@ -3585,15 +3256,23 @@ cli_cmd_volume_register(struct cli_state *state) goto out; } -#if !defined(__NetBSD__) - for (cmd = tier_cmds; cmd->pattern; cmd++) { - ret = cli_cmd_register(&state->tree, cmd); - if (ret) - goto out; - } - -#endif - out: return ret; } + +static int +gf_asprintf_append(char **string_ptr, const char *format, ...) +{ + va_list arg; + int rv = 0; + char *tmp = *string_ptr; + + va_start(arg, format); + rv = gf_vasprintf(string_ptr, format, arg); + va_end(arg); + + if (tmp) + GF_FREE(tmp); + + return rv; +} |
