summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-cmd-parser.c
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2015-03-18 23:17:23 +0530
committerVijay Bellur <vbellur@redhat.com>2015-03-18 18:24:12 -0700
commit3e18f093974c85ac92a4c48f0cd13aa9ff9c5cac (patch)
tree6bbdd814492a3e7dcf6e9a06f49a373926f970dd /cli/src/cli-cmd-parser.c
parentfa50fcb6dddf4d7d0094c26cee802fd942f62727 (diff)
features/quota : Introducing inode quota
========================================================================== Inode quota ========================================================================== = Currently, the only way to retrieve the number of files/objects in a = = directory or volume is to do a crawl of the entire directory/volume. = = This is expensive and is not scalable. = = = = The proposed mechanism will provide an easier alternative to determine = = the count of files/objects in a directory or volume. = = = = The new mechanism proposes to store count of objects/files as part of = = an extended attribute of a directory. Each directory's extended = = attribute value will indicate the number of files/objects present = = in a tree with the directory being considered as the root of the tree. = = = = The count value can be accessed by performing a getxattr(). = = Cluster translators like afr, dht and stripe will perform aggregation = = of count values from various bricks when getxattr() happens on the key = = associated with file/object count. = A new interface is introduced: ------------------------------ limit-objects : limit the number of inodes at directory level list-objects : list the directories where the limit is set remove-objects : remove the limit from the directory ========================================================================== CLI COMMAND: gluster volume quota <volname> limit-objects <path> <number> [<percent>] * <number> is a hard-limit for number of objects limitation for path "<path>" If hard-limit is exceeded, creation of file/directory is no longer permitted. * <percent> is a soft-limit for number of objects creation for path "<path>" If soft-limit is exceeded, a warning is issued for each creation. CLI COMMAND: gluster volume quota <volname> remove-objects [path] ========================================================================== CLI COMMAND: gluster volume quota <volname> list-objects [path] ... Sample output: ------------------ Path Hard-limit Soft-limit Used Available Soft-limit exceeded? Hard-limit exceeded? ------------------------------------------------------------------------ -------------------------------------- /dir 10 80% 10 0 Yes Yes ========================================================================== [root@snapshot-28 dir]# ls a b file11 file12 file13 file14 file15 file16 file17 [root@snapshot-28 dir]# touch a1 touch: cannot touch `a1': Disk quota exceeded * Nine files are created in directory "dir" and directory is included in * the count too. Hence the limit "10" is reached and further file creation fails ========================================================================== Note: We have also done some re-factoring in cli for volume name validation. New function cli_validate_volname is created ========================================================================== Change-Id: I1823497de4f790a2a20ebb1770293472ea33ee2b BUG: 1190108 Signed-off-by: Sachin Pandit <spandit@redhat.com> Signed-off-by: vmallika <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/9769 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'cli/src/cli-cmd-parser.c')
-rw-r--r--cli/src/cli-cmd-parser.c218
1 files changed, 140 insertions, 78 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index c7fdafb32b6..83a9fbd7e7d 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -369,6 +369,55 @@ out:
}
int32_t
+cli_validate_volname (const char *volname)
+{
+ int32_t ret = -1;
+ int32_t i = -1;
+ static const char * const invalid_volnames[] = {
+ "volume", "type", "subvolumes", "option",
+ "end-volume", "all", "volume_not_in_ring",
+ "description", "force",
+ "snap-max-hard-limit",
+ "snap-max-soft-limit", "auto-delete",
+ "activate-on-create", NULL};
+
+ if (volname[0] == '-')
+ goto out;
+
+ for (i = 0; invalid_volnames[i]; i++) {
+ if (!strcmp (volname, invalid_volnames[i])) {
+ cli_err ("\"%s\" cannot be the name of a volume.",
+ volname);
+ goto out;
+ }
+ }
+
+ if (strchr (volname, '/'))
+ goto out;
+
+ if (strlen (volname) > GD_VOLUME_NAME_MAX) {
+ cli_err("Volume name exceeds %d characters.",
+ GD_VOLUME_NAME_MAX);
+ goto out;
+ }
+
+ for (i = 0; i < strlen (volname); i++) {
+ if (!isalnum (volname[i]) && (volname[i] != '_') &&
+ (volname[i] != '-')) {
+ cli_err ("Volume name should not contain \"%c\""
+ " character.\nVolume names can only"
+ "contain alphanumeric, '-' and '_' "
+ "characters.", volname[i]);
+ goto out;
+ }
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
int wordcount, dict_t **options)
{
@@ -379,7 +428,6 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
int count = 1;
int sub_count = 1;
int brick_index = 0;
- int i = 0;
char *trans_type = NULL;
int32_t index = 0;
char *bricks = NULL;
@@ -387,12 +435,6 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
char *opwords[] = { "replica", "stripe", "transport", "disperse",
"redundancy", "disperse-data", NULL };
- char *invalid_volnames[] = {"volume", "type", "subvolumes", "option",
- "end-volume", "all", "volume_not_in_ring",
- "description", "force",
- "snap-max-hard-limit",
- "snap-max-soft-limit", "auto-delete",
- "activate-on-create", NULL};
char *w = NULL;
char *ptr = NULL;
int op_count = 0;
@@ -420,37 +462,8 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
GF_ASSERT (volname);
/* Validate the volume name here itself */
- {
- if (volname[0] == '-')
- goto out;
-
- for (i = 0; invalid_volnames[i]; i++) {
- if (!strcmp (volname, invalid_volnames[i])) {
- cli_err ("\"%s\" cannot be the name of a volume.",
- volname);
- goto out;
- }
- }
-
- if (strchr (volname, '/'))
- goto out;
-
- if (strlen (volname) > GD_VOLUME_NAME_MAX) {
- cli_err("Volume name exceeds %d characters.",
- GD_VOLUME_NAME_MAX);
- goto out;
- }
-
- for (i = 0; i < strlen (volname); i++)
- if (!isalnum (volname[i]) && (volname[i] != '_') &&
- (volname[i] != '-')) {
- cli_err ("Volume name should not contain \"%c\""
- " character.\nVolume names can only"
- "contain alphanumeric, '-' and '_' "
- "characters.",volname[i]);
- goto out;
- }
- }
+ if (cli_validate_volname (volname) < 0)
+ goto out;
if (wordcount < 4) {
ret = -1;
@@ -853,24 +866,29 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
dict_t *dict = NULL;
char *volname = NULL;
int ret = -1;
- int i = 0;
+ int i = -1;
char key[20] = {0, };
uint64_t value = 0;
gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE;
char *opwords[] = { "enable", "disable", "limit-usage",
"remove", "list", "alert-time",
"soft-timeout", "hard-timeout",
- "default-soft-limit", NULL};
+ "default-soft-limit", "limit-objects",
+ "list-objects", "remove-objects", NULL};
char *w = NULL;
uint32_t time = 0;
double percent = 0;
+ char *end_ptr = NULL;
+ int64_t limit = 0;
GF_ASSERT (words);
GF_ASSERT (options);
dict = dict_new ();
- if (!dict)
+ if (!dict) {
+ gf_log ("cli", GF_LOG_ERROR, "dict_new failed");
goto out;
+ }
if (wordcount < 4)
goto out;
@@ -882,34 +900,8 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
}
/* Validate the volume name here itself */
- {
- if (volname[0] == '-')
- goto out;
-
- if (!strcmp (volname, "all")) {
- cli_err ("\"all\" cannot be the name of a volume.");
- goto out;
- }
-
- if (strchr (volname, '/'))
- goto out;
-
- if (strlen (volname) > GD_VOLUME_NAME_MAX) {
- cli_err("Volname can not exceed %d characters.",
- GD_VOLUME_NAME_MAX);
- goto out;
- }
-
- for (i = 0; i < strlen (volname); i++)
- if (!isalnum (volname[i]) && (volname[i] != '_') &&
- (volname[i] != '-')) {
- cli_err ("Volume name should not contain \"%c\""
- " character.\nVolume names can only"
- "contain alphanumeric, '-' and '_' "
- "characters.",volname[i]);
- goto out;
- }
- }
+ if (cli_validate_volname (volname) < 0)
+ goto out;
ret = dict_set_str (dict, "volname", volname);
if (ret < 0)
@@ -945,14 +937,19 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
}
if (strcmp (w, "limit-usage") == 0) {
+ type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE;
+ } else if (strcmp (w, "limit-objects") == 0) {
+ type = GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE ||
+ type == GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS) {
if (wordcount < 6 || wordcount > 7) {
ret = -1;
goto out;
}
- type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE;
-
if (words[4][0] != '/') {
cli_err ("Please enter absolute path");
ret = -1;
@@ -968,13 +965,26 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto out;
}
- ret = gf_string2bytesize_uint64 (words[5], &value);
- if (ret != 0) {
- if (errno == ERANGE)
- cli_err ("Value too large: %s", words[5]);
- else
- cli_err ("Please enter a correct value");
- goto out;
+ if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) {
+ ret = gf_string2bytesize_uint64 (words[5], &value);
+ if (ret != 0) {
+ if (errno == ERANGE)
+ cli_err ("Value too large: %s",
+ words[5]);
+ else
+ cli_err ("Please enter a correct "
+ "value");
+ goto out;
+ }
+ } else {
+ errno = 0;
+ limit = strtol (words[5], &end_ptr, 10);
+ if (errno == ERANGE || errno == EINVAL || limit <= 0) {
+ ret = -1;
+ cli_err ("Please enter an interger value in "
+ "the range 1 - %"PRId64, INT64_MAX);
+ goto out;
+ }
}
ret = dict_set_str (dict, "hard-limit", (char *) words[5]);
@@ -997,6 +1007,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto set_type;
}
+
if (strcmp (w, "remove") == 0) {
if (wordcount != 5) {
ret = -1;
@@ -1017,6 +1028,26 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto set_type;
}
+ if (strcmp (w, "remove-objects") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
+ }
+
+ type = GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS;
+
+ if (words[4][0] != '/') {
+ cli_err ("Please enter absolute path");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "path", (char *) words[4]);
+ if (ret < 0)
+ goto out;
+ goto set_type;
+ }
+
if (strcmp (w, "list") == 0) {
if (wordcount < 4) {
ret = -1;
@@ -1041,6 +1072,35 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto set_type;
}
+ if (strcmp (w, "list-objects") == 0) {
+ if (wordcount < 4) {
+ ret = -1;
+ goto out;
+ }
+
+ type = GF_QUOTA_OPTION_TYPE_LIST_OBJECTS;
+
+ i = 4;
+ while (i < wordcount) {
+ snprintf (key, 20, "path%d", i-4);
+
+ ret = dict_set_str (dict, key, (char *) words[i++]);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set "
+ "quota patch in request dictionary");
+ goto out;
+ }
+ }
+
+ ret = dict_set_int32 (dict, "count", i - 4);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set quota "
+ "limit count in request dictionary");
+ goto out;
+ }
+
+ goto set_type;
+ }
if (strcmp (w, "alert-time") == 0) {
if (wordcount != 5) {
@@ -1061,6 +1121,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto out;
goto set_type;
}
+
if (strcmp (w, "soft-timeout") == 0) {
if (wordcount != 5) {
ret = -1;
@@ -1080,6 +1141,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
goto out;
goto set_type;
}
+
if (strcmp (w, "hard-timeout") == 0) {
if(wordcount != 5) {
ret = -1;