From ffbe47e0ec8411313b666a8705f31a67d3862763 Mon Sep 17 00:00:00 2001 From: vmallika Date: Wed, 15 Apr 2015 17:35:07 +0530 Subject: quota: support for inode quota in quota.conf Currently when quota limit is set, corresponding gfid is set in quota.conf. This patch supports storing inode-quota limits in quota.conf and also stores additional byte for each gfid to differentiate between usage quota limit and inode quota limit. Change-Id: I444d7399407594edd280e640681679a784d4c46a BUG: 1218170 Signed-off-by: vmallika Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/10069 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/10524 --- cli/src/cli-cmd-parser.c | 3 +- cli/src/cli-cmd-volume.c | 81 ++++++++++++++++++++++++++++-------------------- cli/src/cli-cmd.h | 2 +- cli/src/cli-rpc-ops.c | 22 +++++++------ 4 files changed, 62 insertions(+), 46 deletions(-) (limited to 'cli') diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 4fd205ed5fe..7d7eee5af6f 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1045,7 +1045,8 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) } else { errno = 0; limit = strtol (words[5], &end_ptr, 10); - if (errno == ERANGE || errno == EINVAL || limit <= 0) { + if (errno == ERANGE || errno == EINVAL || limit <= 0 + || strcmp (end_ptr, "") != 0) { ret = -1; cli_err ("Please enter an interger value in " "the range 1 - %"PRId64, INT64_MAX); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index c9c6b65f35f..72a789de56c 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1111,28 +1111,20 @@ out: 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)); -} - /* Checks if at least one limit has been set on the volume * * Returns true if at least one limit is set. Returns false otherwise. */ gf_boolean_t -_limits_set_on_volume (char *volname) { - gf_boolean_t limits_set = _gf_false; - int ret = -1; +_limits_set_on_volume (char *volname, int type) { + gf_boolean_t limits_set = _gf_false; + int ret = -1; char quota_conf_file[PATH_MAX] = {0,}; - int fd = -1; - char buf[16] = {0,}; + int fd = -1; + char buf[16] = {0,}; + float version = 0.0f; + char gfid_type_stored = 0; + char gfid_type = 0; /* TODO: fix hardcoding; Need to perform an RPC call to glusterd * to fetch working directory @@ -1144,17 +1136,31 @@ _limits_set_on_volume (char *volname) { if (fd == -1) goto out; - ret = cli_cmd_quota_conf_skip_header (fd); + ret = quota_conf_read_version (fd, &version); if (ret) goto out; - /* Try to read atleast one gfid */ - ret = read (fd, (void *)buf, 16); - if (ret == 16) - limits_set = _gf_true; + if (type == GF_QUOTA_OPTION_TYPE_LIST) + gfid_type = GF_QUOTA_CONF_TYPE_USAGE; + else + gfid_type = GF_QUOTA_CONF_TYPE_OBJECTS; + + /* Try to read atleast one gfid of type 'gfid_type' */ + while (1) { + ret = quota_conf_read_gfid (fd, buf, &gfid_type_stored, + version); + if (ret <= 0) + break; + + if (gfid_type_stored == gfid_type) { + limits_set = _gf_true; + break; + } + } out: if (fd != -1) close (fd); + return limits_set; } @@ -1213,6 +1219,8 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) gf_boolean_t xml_err_flag = _gf_false; char err_str[NAME_MAX] = {0,}; int32_t type = 0; + char gfid_type = 0; + float version = 0.0f; xdata = dict_new (); if (!xdata) { @@ -1248,9 +1256,11 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) /* Check if at least one limit is set on volume. No need to check for * quota enabled as cli_get_soft_limit() handles that */ - if (!_limits_set_on_volume (volname)) { - snprintf (err_str, sizeof (err_str), "No quota configured on " - "volume %s", volname); + if (!_limits_set_on_volume (volname, type)) { + snprintf (err_str, sizeof (err_str), "No%s quota configured on" + " volume %s", + (type == GF_QUOTA_OPTION_TYPE_LIST) ? "" : " inode", + volname); if (global_state->mode & GLUSTER_MODE_XML) { xml_err_flag = _gf_true; } else { @@ -1299,10 +1309,10 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) goto out; } - ret = cli_cmd_quota_conf_skip_header (fd); - if (ret) { + ret = quota_conf_read_version (fd, &version); + if (ret) goto out; - } + CLI_LOCAL_INIT (local, words, frame, xdata); proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; @@ -1324,18 +1334,21 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) goto out; } for (count = 0;; count++) { - ret = read (fd, (void*) buf, 16); - if (ret <= 0) { - //Finished reading all entries in the conf file + ret = quota_conf_read_gfid (fd, buf, &gfid_type, version); + if (ret == 0) { break; - } - if (ret < 16) { - //This should never happen. We must have a multiple of - //entry_sz bytes in our configuration file. + } else if (ret < 0) { gf_log (THIS->name, GF_LOG_CRITICAL, "Quota " "configuration store may be corrupt."); goto out; } + + if ((type == GF_QUOTA_OPTION_TYPE_LIST && + gfid_type == GF_QUOTA_CONF_TYPE_OBJECTS) || + (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS && + gfid_type == GF_QUOTA_CONF_TYPE_USAGE)) + continue; + uuid_utoa_r (buf, gfid_str); ret = dict_set_str (xdata, "gfid", gfid_str); if (ret) { diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h index d39c8b38f7f..94fa3e9c671 100644 --- a/cli/src/cli-cmd.h +++ b/cli/src/cli-cmd.h @@ -113,7 +113,7 @@ cli_cmd_get_confirmation (struct cli_state *state, const char *question); int cli_cmd_sent_status_get (int *status); gf_boolean_t -_limits_set_on_volume (char *volname); +_limits_set_on_volume (char *volname, int type); gf_boolean_t _quota_aux_mount_online (char *volname); diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 3c32e6d8a09..080c225e64d 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2587,7 +2587,7 @@ print_quota_list_object_output (cli_local_t *local, char *path, int64_t avail, goto out; } - cli_out ("%-40s %9"PRIu64" %9s %15"PRIu64" %10"PRIu64" %7"PRIu64 + cli_out ("%-40s %9"PRIu64" %9s %10"PRIu64" %10"PRIu64" %11"PRIu64 " %15s %20s", path, limits->hl, sl_str, used_space->file_count, used_space->dir_count, avail, sl ? "Yes" : "No", hl ? "Yes" : "No"); @@ -2759,12 +2759,20 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, if (!dict|| count <= 0) goto out; + ret = dict_get_int32 (dict, "type", &type); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get quota type"); + goto out; + } + /* Need to check if any quota limits are set on the volume before trying * to list them */ - if (!_limits_set_on_volume (volname)) { - snprintf (err_str, sizeof (err_str), "No quota configured on " - "volume %s", volname); + if (!_limits_set_on_volume (volname, type)) { + snprintf (err_str, sizeof (err_str), "No%s quota configured on " + "volume %s", + (type == GF_QUOTA_OPTION_TYPE_LIST) ? "" : " inode", + volname); if (global_state->mode & GLUSTER_MODE_XML) { xml_err_flag = _gf_true; } else { @@ -2780,12 +2788,6 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, goto out; } - ret = dict_get_int32 (dict, "type", &type); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to get quota type"); - goto out; - } - if (global_state->mode & GLUSTER_MODE_XML) { ret = cli_xml_output_vol_quota_limit_list_begin (local, op_ret, op_errno, op_errstr); -- cgit