diff options
Diffstat (limited to 'cli/src/cli-cmd-volume.c')
-rw-r--r-- | cli/src/cli-cmd-volume.c | 270 |
1 files changed, 206 insertions, 64 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 17663091..adad8442 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1096,16 +1096,193 @@ print_quota_list_header (void) } int -cli_get_soft_limit (call_frame_t *frame, cli_local_t *local, dict_t *options, - const char **words) +cli_get_soft_limit (dict_t *options, const char **words, dict_t *xdata) { - rpc_clnt_procedure_t *proc = NULL; - int ret = -1; + call_frame_t *frame = NULL; + cli_local_t *local = NULL; + rpc_clnt_procedure_t *proc = NULL; + char *default_sl = NULL; + char *default_sl_dup = NULL; + int ret = -1; + frame = create_frame (THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + + //We need a ref on @options to prevent CLI_STACK_DESTROY + //from destroying it prematurely. + dict_ref (options); CLI_LOCAL_INIT (local, words, frame, options); proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA]; ret = proc->fn (frame, THIS, options); + ret = dict_get_str (options, "default-soft-limit", &default_sl); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get default soft limit"); + goto out; + } + + default_sl_dup = gf_strdup (default_sl); + if (!default_sl_dup) { + ret = -1; + goto out; + } + + ret = dict_set_dynstr (xdata, "default-soft-limit", default_sl_dup); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to set default soft limit"); + GF_FREE (default_sl_dup); + goto out; + } + +out: + CLI_STACK_DESTROY (frame); + return ret; +} + +#define QUOTA_CONF_HEADER \ + "GlusterFS Quota conf | version: v%d.%d\n" +int +cli_cmd_quota_conf_skip_header (int fd) +{ + char buf[PATH_MAX] = {0,}; + + snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1); + return gf_skip_header_section (fd, strlen (buf)); +} + +int +cli_cmd_quota_handle_list_all (const char **words, dict_t *options) +{ + int all_failed = 1; + int count = 0; + int ret = -1; + rpc_clnt_procedure_t *proc = NULL; + cli_local_t *local = NULL; + call_frame_t *frame = NULL; + dict_t *xdata = NULL; + char *gfid_str = NULL; + char *volname = NULL; + char *volname_dup = NULL; + unsigned char buf[16] = {0}; + int fd = -1; + char quota_conf_file[PATH_MAX] = {0}; + + xdata = dict_new (); + if (!xdata) { + ret = -1; + goto out; + } + + ret = dict_get_str (options, "volname", &volname); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get volume name"); + goto out; + } + + ret = cli_get_soft_limit (options, words, xdata); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to fetch default " + "soft-limit"); + 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; + goto out; + } + + ret = dict_set_dynstr (xdata, "volume-uuid", volname_dup); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to set volume-uuid"); + GF_FREE (volname_dup); + goto out; + } + + //TODO: fix hardcoding; Need to perform an RPC call to glusterd + //to fetch working directory + sprintf (quota_conf_file, "/var/lib/glusterd/vols/%s/quota.conf", + volname); + fd = open (quota_conf_file, O_RDONLY); + if (fd == -1) { + //This may because no limits were yet set on the volume + gf_log ("cli", GF_LOG_TRACE, "Unable to open " + "quota.conf"); + ret = 0; + goto out; + } + + ret = cli_cmd_quota_conf_skip_header (fd); + if (ret) { + goto out; + } + CLI_LOCAL_INIT (local, words, frame, xdata); + proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; + + print_quota_list_header (); + gfid_str = GF_CALLOC (1, gf_common_mt_char, 64); + if (!gfid_str) { + ret = -1; + goto out; + } + for (count = 0;; count++) { + ret = read (fd, (void*) buf, 16); + if (ret <= 0) { + //Finished reading all entries in the conf file + break; + } + if (ret < 16) { + //This should never happen. We must have a multiple of + //entry_sz bytes in our configuration file. + gf_log (THIS->name, GF_LOG_CRITICAL, "Quota " + "configuration store may be corrupt."); + goto out; + } + uuid_utoa_r (buf, gfid_str); + ret = dict_set_str (xdata, "gfid", gfid_str); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to set gfid"); + goto out; + } + + ret = proc->fn (frame, THIS, xdata); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get quota " + "limits for %s", uuid_utoa ((unsigned char*)buf)); + } + + dict_del (xdata, "gfid"); + all_failed = all_failed && ret; + } + + if (count > 0) { + ret = all_failed? 0: -1; + } else { + ret = 0; + } +out: + if (count == 0) { + cli_out ("quota: No quota configured on volume %s", volname); + } + if (fd != -1) { + close (fd); + } + + GF_FREE (gfid_str); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Couldn't fetch quota limits " + "for even one of the directories configured"); + } + CLI_STACK_DESTROY (frame); return ret; } @@ -1124,26 +1301,11 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, cli_local_t *local = NULL; int sent = 0; char *volname = NULL; - dict_t *xdata = NULL; - char buf[256] = {0}; - FILE *fp = NULL; const char *question = "Disabling quota will delete all the quota " "configuration. Do you want to continue?"; - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA]; - if (proc == NULL) { - ret = -1; - goto out; - } - - frame = create_frame (THIS, THIS->ctx->pool); - if (!frame) { - ret = -1; - goto out; - } - + //parse **words into options dictionary ret = cli_cmd_quota_parse (words, wordcount, &options); - if (ret < 0) { cli_usage_out (word->pattern); parse_err = 1; @@ -1155,10 +1317,21 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, gf_log ("cli", GF_LOG_ERROR, "Failed to get opcode"); goto out; } - if (type == GF_QUOTA_OPTION_TYPE_DISABLE) { + + //handle quota-disable and quota-list-all different from others + switch (type) { + case GF_QUOTA_OPTION_TYPE_DISABLE: answer = cli_cmd_get_confirmation (state, question); if (answer == GF_ANSWER_NO) goto out; + break; + case GF_QUOTA_OPTION_TYPE_LIST: + if (wordcount != 4) + break; + ret = cli_cmd_quota_handle_list_all (words, options); + goto out; + default: + break; } ret = dict_get_str (options, "volname", &volname); @@ -1166,59 +1339,29 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, gf_log ("cli", GF_LOG_ERROR, "Failed to get volume name"); goto out; } - if (type == GF_QUOTA_OPTION_TYPE_LIST && wordcount == 4) { - ret = cli_get_soft_limit (frame, local, options, words); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to fetch default " - "soft-limit"); - goto out; - } - proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; - xdata = dict_new (); - if (!xdata) { - ret = -1; - goto out; - } - ret = dict_set_str (xdata, "volume-uuid", volname); - if (ret) - goto out; - - char quota_conf_file[PATH_MAX] = {0}; - //TODO: fix hardcoding - sprintf (quota_conf_file, "/var/lib/glusterd/vols/%s/quota.conf", - volname); - fp = fopen (quota_conf_file, "r"); - if (!fp) { - gf_log ("cli", GF_LOG_ERROR, "Failed to open quota.conf"); - goto out; - } - - print_quota_list_header (); - while (fscanf (fp, "%s", buf) != EOF) { - - ret = dict_set_str (xdata, "gfid", buf); - if (ret) - goto out; - //Given the path, get the gfi - ret = proc->fn (frame, THIS, xdata); - dict_del (xdata, "gfid"); - - } - goto out; - } + //create auxillary mount need for quota commands that operate on path ret = cli_stage_quota_op (volname, type); if (ret) goto out; + frame = create_frame (THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; + goto out; + } + CLI_LOCAL_INIT (local, words, frame, options); + proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA]; + if (proc == NULL) { + ret = -1; + goto out; + } if (proc->fn) ret = proc->fn (frame, THIS, options); out: - if (fp) - fclose (fp); if (ret) { cli_cmd_sent_status_get (&sent); if (sent == 0 && parse_err == 0) @@ -1227,7 +1370,6 @@ out: } CLI_STACK_DESTROY (frame); - return ret; } |