summaryrefslogtreecommitdiffstats
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/src/cli-cmd-parser.c218
-rw-r--r--cli/src/cli-cmd-volume.c65
-rw-r--r--cli/src/cli-rpc-ops.c445
-rw-r--r--cli/src/cli-xml-output.c67
-rw-r--r--cli/src/cli.c32
-rw-r--r--cli/src/cli.h13
6 files changed, 509 insertions, 331 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;
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index dc223990741..5632a9798bb 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -900,40 +900,30 @@ cli_stage_quota_op (char *volname, int op_code)
int ret = -1;
switch (op_code) {
- case GF_QUOTA_OPTION_TYPE_ENABLE:
- case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
- case GF_QUOTA_OPTION_TYPE_REMOVE:
- case GF_QUOTA_OPTION_TYPE_LIST:
- ret = gf_cli_create_auxiliary_mount (volname);
- if (ret) {
- cli_err ("quota: Could not start quota "
- "auxiliary mount");
- goto out;
- }
- ret = 0;
- break;
+ case GF_QUOTA_OPTION_TYPE_ENABLE:
+ case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
+ case GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS:
+ case GF_QUOTA_OPTION_TYPE_REMOVE:
+ case GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS:
+ case GF_QUOTA_OPTION_TYPE_LIST:
+ ret = gf_cli_create_auxiliary_mount (volname);
+ if (ret) {
+ cli_err ("quota: Could not start quota "
+ "auxiliary mount");
+ goto out;
+ }
+ ret = 0;
+ break;
- default:
- ret = 0;
- break;
+ default:
+ ret = 0;
+ break;
}
out:
return ret;
}
-static void
-print_quota_list_header (void)
-{
- //Header
- cli_out (" Path Hard-limit "
- "Soft-limit Used Available Soft-limit exceeded?"
- " Hard-limit exceeded?");
- cli_out ("-----------------------------------------------------"
- "-----------------------------------------------------"
- "-----------------");
-}
-
int
cli_get_soft_limit (dict_t *options, const char **words, dict_t *xdata)
{
@@ -1082,6 +1072,7 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
char quota_conf_file[PATH_MAX] = {0};
gf_boolean_t xml_err_flag = _gf_false;
char err_str[NAME_MAX] = {0,};
+ int32_t type = 0;
xdata = dict_new ();
if (!xdata) {
@@ -1095,6 +1086,18 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
goto out;
}
+ ret = dict_get_int32 (options, "type", &type);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to get quota option type");
+ goto out;
+ }
+
+ ret = dict_set_int32 (xdata, "type", type);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set type in xdata");
+ goto out;
+ }
+
ret = cli_get_soft_limit (options, words, xdata);
if (ret) {
gf_log ("cli", GF_LOG_ERROR, "Failed to fetch default "
@@ -1164,7 +1167,7 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT];
if (!(global_state->mode & GLUSTER_MODE_XML)) {
- print_quota_list_header ();
+ print_quota_list_header (type);
} else {
ret = cli_xml_output_vol_quota_limit_list_begin
(local, 0, 0, NULL);
@@ -1336,6 +1339,7 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,
goto out;
break;
case GF_QUOTA_OPTION_TYPE_LIST:
+ case GF_QUOTA_OPTION_TYPE_LIST_OBJECTS:
if (wordcount != 4)
break;
ret = cli_cmd_quota_handle_list_all (words, options);
@@ -2437,8 +2441,11 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_profile_cbk,
"volume profile operations"},
- { "volume quota <VOLNAME> {enable|disable|list [<path> ...]|remove <path>| default-soft-limit <percent>} |\n"
+ { "volume quota <VOLNAME> {enable|disable|list [<path> ...]| "
+ "list-objects [<path> ...] | remove <path>| remove-objects <path> | "
+ "default-soft-limit <percent>} |\n"
"volume quota <VOLNAME> {limit-usage <path> <size> [<percent>]} |\n"
+ "volume quota <VOLNAME> {limit-objects <path> <number> [<percent>]} |\n"
"volume quota <VOLNAME> {alert-time|soft-timeout|hard-timeout} {<time>}",
cli_cmd_quota_cbk,
"quota translator specific operations"},
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 00ea6633bb6..928df1e7082 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -43,6 +43,7 @@
#include "cli-quotad-client.h"
#include "run.h"
+#include "quota-common-utils.h"
enum gf_task_types {
GF_TASK_TYPE_REBALANCE,
@@ -2465,39 +2466,167 @@ out:
}
static int
-print_quota_list_output (cli_local_t *local, char *mountdir,
- char *default_sl, char *path)
+print_quota_list_usage_output (cli_local_t *local, char *path, int64_t avail,
+ char *sl_str, quota_limits_t *limits,
+ quota_meta_t *used_space, gf_boolean_t sl,
+ gf_boolean_t hl)
+{
+ int32_t ret = -1;
+ char *used_str = NULL;
+ char *avail_str = NULL;
+ char *hl_str = NULL;
+
+ hl_str = gf_uint64_2human_readable (limits->hl);
+ used_str = gf_uint64_2human_readable (used_space->size);
+ avail_str = gf_uint64_2human_readable (avail);
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_quota_xml_output (local, path, hl_str,
+ sl_str, used_str,
+ avail_str, sl ? "Yes" : "No",
+ hl ? "Yes" : "No");
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to "
+ "output in xml format for quota "
+ "list command");
+ }
+ goto out;
+ }
+
+ if (!used_str) {
+ cli_out ("%-40s %7s %9s %11"PRIu64 "%9"PRIu64" %15s %18s",
+ path, hl_str, sl_str, used_space->size, avail,
+ sl ? "Yes" : "No", hl ? "Yes" : "No");
+ } else {
+ cli_out ("%-40s %7s %9s %11s %7s %15s %20s", path, hl_str,
+ sl_str, used_str, avail_str, sl ? "Yes" : "No",
+ hl ? "Yes" : "No");
+ }
+
+ ret = 0;
+out:
+ GF_FREE (hl_str);
+ GF_FREE (used_str);
+ GF_FREE (avail_str);
+
+ return ret;
+}
+
+static int
+print_quota_list_object_output (cli_local_t *local, char *path, int64_t avail,
+ char *sl_str, quota_limits_t *limits,
+ quota_meta_t *used_space, gf_boolean_t sl,
+ gf_boolean_t hl)
+{
+ int32_t ret = -1;
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_quota_object_xml_output (local, path, sl_str, limits,
+ used_space, avail,
+ sl ? "Yes" : "No",
+ hl ? "Yes" : "No");
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to "
+ "output in xml format for quota "
+ "list command");
+ }
+ goto out;
+ }
+
+ cli_out ("%-40s %9"PRIu64" %9s %15"PRIu64" %10"PRIu64" %7"PRIu64
+ " %15s %20s", path, limits->hl, sl_str,
+ used_space->file_count, used_space->dir_count,
+ avail, sl ? "Yes" : "No", hl ? "Yes" : "No");
+
+ ret = 0;
+
+out:
+
+ return ret;
+}
+
+static int
+print_quota_list_output (cli_local_t *local, char *path, char *default_sl,
+ quota_limits_t *limits, quota_meta_t *used_space,
+ int type)
{
int64_t avail = 0;
- char *used_str = NULL;
- char *avail_str = NULL;
- int ret = -1;
+ char percent_str[20] = {0};
char *sl_final = NULL;
- char *hl_str = NULL;
+ int ret = -1;
double sl_num = 0;
gf_boolean_t sl = _gf_false;
gf_boolean_t hl = _gf_false;
- char percent_str[20] = {0};
+ int64_t used_size = 0;
+
+ GF_ASSERT (local);
+ GF_ASSERT (path);
+
+ if (limits->sl < 0) {
+ ret = gf_string2percent (default_sl, &sl_num);
+ sl_num = (sl_num * limits->hl) / 100;
+ sl_final = default_sl;
+ } else {
+ sl_num = (limits->sl * limits->hl) / 100;
+ snprintf (percent_str, sizeof (percent_str), "%"PRIu64"%%",
+ limits->sl);
+ sl_final = percent_str;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ used_size = used_space->size;
+ else
+ used_size = used_space->file_count + used_space->dir_count;
+
+ if (limits->hl > used_size) {
+ avail = limits->hl - used_size;
+ hl = _gf_false;
+ if (used_size > sl_num)
+ sl = _gf_true;
+ else
+ sl = _gf_false;
+ } else {
+ avail = 0;
+ hl = sl = _gf_true;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ ret = print_quota_list_usage_output (local, path, avail,
+ sl_final, limits,
+ used_space, sl, hl);
+ else
+ ret = print_quota_list_object_output (local, path, avail,
+ sl_final, limits,
+ used_space, sl, hl);
+
+ return ret;
+}
+
+static int
+print_quota_list_from_mountdir (cli_local_t *local, char *mountdir,
+ char *default_sl, char *path, int type)
+{
+ int ret = -1;
ssize_t xattr_size = 0;
+ quota_limits_t limits = {0,};
+ quota_meta_t used_space = {0,};
+ char *key = NULL;
- struct quota_limit {
- int64_t hl;
- int64_t sl;
- } __attribute__ ((__packed__)) existing_limits;
+ GF_ASSERT (local);
+ GF_ASSERT (mountdir);
+ GF_ASSERT (path);
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ key = "trusted.glusterfs.quota.limit-set";
+ else
+ key = "trusted.glusterfs.quota.limit-objects";
- struct quota_meta {
- int64_t size;
- int64_t file_count;
- int64_t dir_count;
- } __attribute__ ((__packed__)) used_space;
- ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.limit-set",
- (void *)&existing_limits,
- sizeof (existing_limits));
+ ret = sys_lgetxattr (mountdir, key, (void *)&limits, sizeof (limits));
if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get the xattr "
- "trusted.glusterfs.quota.limit-set on %s. Reason : %s",
- mountdir, strerror (errno));
+ gf_log ("cli", GF_LOG_ERROR, "Failed to get the xattr %s "
+ "on %s. Reason : %s", key, mountdir, strerror (errno));
+
switch (errno) {
#if defined(ENODATA)
case ENODATA:
@@ -2505,56 +2634,22 @@ print_quota_list_output (cli_local_t *local, char *mountdir,
#if defined(ENOATTR) && (ENOATTR != ENODATA)
case ENOATTR:
#endif
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_list_xml_error
- (local, path, "Limit not set");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed "
- "to print xml output");
- goto out;
- }
- } else {
- cli_err ("%-40s %s", path, strerror (errno));
- }
+ cli_err ("%-40s %s", path, "Limit not set");
break;
default:
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_list_xml_error
- (local, path, strerror (errno));
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed "
- "to print xml output");
- goto out;
- }
- } else {
- cli_err ("%-40s %s", path, strerror (errno));
- }
+ cli_err ("%-40s %s", path, strerror (errno));
break;
}
goto out;
}
- existing_limits.hl = ntoh64 (existing_limits.hl);
- existing_limits.sl = ntoh64 (existing_limits.sl);
-
- hl_str = gf_uint64_2human_readable (existing_limits.hl);
+ limits.hl = ntoh64 (limits.hl);
+ limits.sl = ntoh64 (limits.sl);
- if (existing_limits.sl < 0) {
- ret = gf_string2percent (default_sl, &sl_num);
- sl_num = (sl_num * existing_limits.hl) / 100;
- sl_final = default_sl;
- } else {
- sl_num = (existing_limits.sl * existing_limits.hl) / 100;
- snprintf (percent_str, sizeof (percent_str), "%"PRIu64"%%",
- existing_limits.sl);
- sl_final = percent_str;
- }
-
- used_space.size = used_space.file_count = used_space.dir_count = 0;
xattr_size = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size",
NULL, 0);
- if (xattr_size > sizeof (int64_t)) {
+ if (xattr_size > (sizeof (int64_t) * 2)) {
ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size",
&used_space, sizeof (used_space));
} else if (xattr_size > 0) {
@@ -2563,6 +2658,8 @@ print_quota_list_output (cli_local_t *local, char *mountdir,
*/
ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size",
&(used_space.size), sizeof (used_space.size));
+ used_space.file_count = 0;
+ used_space.dir_count = 0;
} else {
ret = -1;
}
@@ -2570,73 +2667,17 @@ print_quota_list_output (cli_local_t *local, char *mountdir,
if (ret < 0) {
gf_log ("cli", GF_LOG_ERROR, "Failed to get quota size "
"on path %s: %s", mountdir, strerror (errno));
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_xml_output (local, path, hl_str,
- sl_final, "N/A",
- "N/A", "N/A", "N/A");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to "
- "output in xml format for quota "
- "list command");
- }
- goto out;
- } else {
- cli_out ("%-40s %7s %9s %11s %7s %15s %20s",
- path, hl_str, sl_final,
- "N/A", "N/A", "N/A", "N/A");
- }
- } else {
- used_space.size = ntoh64 (used_space.size);
- used_space.file_count = ntoh64 (used_space.file_count);
- used_space.dir_count = ntoh64 (used_space.dir_count);
-
- used_str = gf_uint64_2human_readable (used_space.size);
-
- if (existing_limits.hl > used_space.size) {
- avail = existing_limits.hl - used_space.size;
- hl = _gf_false;
- if (used_space.size > sl_num)
- sl = _gf_true;
- else
- sl = _gf_false;
- } else {
- avail = 0;
- hl = sl = _gf_true;
- }
-
- avail_str = gf_uint64_2human_readable (avail);
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_xml_output (local, path, hl_str,
- sl_final, used_str,
- avail_str, sl ? "Yes" : "No",
- hl ? "Yes" : "No");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to "
- "output in xml format for quota "
- "list command");
- }
- goto out;
- }
-
- if (used_str == NULL) {
- cli_out ("%-40s %7s %9s %11"PRIu64
- "%9"PRIu64" %15s %18s", path, hl_str,
- sl_final, used_space.size, avail,
- sl ? "Yes" : "No",
- hl ? "Yes" : "No");
- } else {
- cli_out ("%-40s %7s %9s %11s %7s %15s %20s", path, hl_str,
- sl_final, used_str, avail_str, sl? "Yes" : "No",
- hl? "Yes" : "No");
- }
+ print_quota_list_empty (path, type);
+ goto out;
}
+ used_space.size = ntoh64 (used_space.size);
+ used_space.file_count = ntoh64 (used_space.file_count);
+ used_space.dir_count = ntoh64 (used_space.dir_count);
+
+ ret = print_quota_list_output (local, path, default_sl, &limits,
+ &used_space, type);
out:
- GF_FREE (used_str);
- GF_FREE (avail_str);
- GF_FREE (hl_str);
return ret;
}
@@ -2652,6 +2693,7 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname,
char *path = NULL;
gf_boolean_t xml_err_flag = _gf_false;
char err_str[NAME_MAX] = {0,};
+ int type = -1;
if (!dict|| count <= 0)
goto out;
@@ -2677,6 +2719,12 @@ 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);
@@ -2686,12 +2734,7 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname,
goto out;
}
} else {
- cli_out (" Path Hard-limit "
- "Soft-limit Used Available Soft-limit exceeded?"
- " Hard-limit exceeded?");
- cli_out ("-----------------------------------------------------"
- "-----------------------------------------------------"
- "-----------------");
+ print_quota_list_header (type);
}
while (count--) {
@@ -2708,8 +2751,8 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname,
if (ret)
goto out;
GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, path);
- ret = print_quota_list_output (local, mountdir, default_sl,
- path);
+ ret = print_quota_list_from_mountdir (local, mountdir,
+ default_sl, path, type);
}
out:
@@ -2726,42 +2769,31 @@ out:
int
print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict)
{
- int64_t used_space = 0;
- int64_t avail = 0;
- int64_t *limit = NULL;
- char *used_str = NULL;
- char *avail_str = NULL;
- char *hl_str = NULL;
- char *sl_final = NULL;
- char *path = NULL;
- char *default_sl = NULL;
- int ret = -1;
- cli_local_t *local = NULL;
- dict_t *gd_rsp_dict = NULL;
- double sl_num = 0;
- gf_boolean_t sl = _gf_false;
- gf_boolean_t hl = _gf_false;
- char percent_str[20] = {0,};
+ char *path = NULL;
+ char *default_sl = NULL;
+ int ret = -1;
+ cli_local_t *local = NULL;
+ dict_t *gd_rsp_dict = NULL;
+ quota_meta_t used_space = {0, };
+ quota_limits_t limits = {0, };
+ quota_limits_t *size_limits = NULL;
+ int32_t type = 0;
local = frame->local;
gd_rsp_dict = local->dict;
- struct quota_limit {
- int64_t hl;
- int64_t sl;
- } __attribute__ ((__packed__)) *existing_limits = NULL;
+ GF_ASSERT (frame);
- ret = dict_get_str (rsp_dict, GET_ANCESTRY_PATH_KEY, &path);
+ ret = dict_get_int32 (rsp_dict, "type", &type);
if (ret) {
- gf_log ("cli", GF_LOG_WARNING, "path key is not present "
- "in dict");
+ gf_log ("cli", GF_LOG_ERROR, "Failed to get type");
goto out;
}
- ret = dict_get_bin (rsp_dict, QUOTA_LIMIT_KEY, (void**)&limit);
+ ret = dict_get_str (rsp_dict, GET_ANCESTRY_PATH_KEY, &path);
if (ret) {
- gf_log ("cli", GF_LOG_WARNING,
- "limit key not present in dict");
+ gf_log ("cli", GF_LOG_WARNING, "path key is not present "
+ "in dict");
goto out;
}
@@ -2771,76 +2803,41 @@ print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict)
"get default soft limit");
goto out;
}
- existing_limits = (struct quota_limit *)limit;
- existing_limits->hl = ntoh64 (existing_limits->hl);
- existing_limits->sl = ntoh64 (existing_limits->sl);
-
- hl_str = gf_uint64_2human_readable (existing_limits->hl);
- if (existing_limits->sl < 0) {
- ret = gf_string2percent (default_sl, &sl_num);
- sl_num = (sl_num * existing_limits->hl) / 100;
- sl_final = default_sl;
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ ret = dict_get_bin (rsp_dict, QUOTA_LIMIT_KEY,
+ (void **)&size_limits);
+ if (ret) {
+ gf_log ("cli", GF_LOG_WARNING,
+ "limit key not present in dict on %s",
+ path);
+ goto out;
+ }
} else {
- sl_num = (existing_limits->sl * existing_limits->hl) / 100;
- snprintf (percent_str, sizeof (percent_str), "%"PRIu64"%%",
- existing_limits->sl);
- sl_final = percent_str;
+ ret = dict_get_bin (rsp_dict, QUOTA_LIMIT_OBJECTS_KEY,
+ (void **)&size_limits);
+ if (ret) {
+ gf_log ("cli", GF_LOG_WARNING,
+ "object limit key not present in dict on %s",
+ path);
+ goto out;
+ }
}
- ret = dict_get_bin (rsp_dict, QUOTA_SIZE_KEY, (void**)&limit);
+ limits.hl = ntoh64 (size_limits->hl);
+ limits.sl = ntoh64 (size_limits->sl);
+
+ ret = quota_dict_get_meta (rsp_dict, QUOTA_SIZE_KEY, &used_space);
if (ret < 0) {
gf_log ("cli", GF_LOG_WARNING,
"size key not present in dict");
- cli_out ("%-40s %7s %9s %11s %7s %15s %20s", path, hl_str,
- sl_final, "N/A", "N/A", "N/A", "N/A");
- } else {
- used_space = *limit;
- used_space = ntoh64 (used_space);
- used_str = gf_uint64_2human_readable (used_space);
-
- if (existing_limits->hl > used_space) {
- avail = existing_limits->hl - used_space;
- hl = _gf_false;
- if (used_space > sl_num)
- sl = _gf_true;
- else
- sl = _gf_false;
- } else {
- avail = 0;
- hl = sl = _gf_true;
- }
- avail_str = gf_uint64_2human_readable (avail);
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_xml_output (local, path, hl_str,
- sl_final, used_str,
- avail_str, sl ? "Yes" : "No",
- hl ? "Yes" : "No");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed in "
- "printing xml output for quota list "
- "command");
- }
- goto out;
- }
-
- if (used_str == NULL)
- cli_out ("%-40s %7s %9s %11"PRIu64
- "%9"PRIu64" %15s %20s", path, hl_str,
- sl_final, used_space, avail, sl? "Yes" : "No",
- hl? "Yes" : "No");
- else
- cli_out ("%-40s %7s %9s %11s %7s %15s %20s", path,
- hl_str, sl_final, used_str, avail_str,
- sl? "Yes" : "No", hl? "Yes" : "No");
+ print_quota_list_empty (path, type);
+ goto out;
}
- ret = 0;
+ ret = print_quota_list_output (local, path, default_sl, &limits,
+ &used_space, type);
out:
- GF_FREE (used_str);
- GF_FREE (avail_str);
- GF_FREE (hl_str);
return ret;
}
@@ -2848,7 +2845,7 @@ int
cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- //TODO: we need to gather the path, hard-limit, soft-limit and used space
+ /*TODO: we need to gather the path, hard-limit, soft-limit and used space*/
gf_cli_rsp rsp = {0,};
int ret = -1;
dict_t *dict = NULL;
@@ -2931,8 +2928,6 @@ cli_quotad_getlimit (call_frame_t *frame, xlator_t *this, void *data)
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
-
-
}
void
@@ -3050,7 +3045,8 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov,
if (ret)
gf_log (frame->this->name, GF_LOG_TRACE, "failed to get count");
- if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ if ((type == GF_QUOTA_OPTION_TYPE_LIST)
+ || (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) {
gf_cli_quota_list (local, volname, dict, default_sl,
entry_count, rsp.op_ret,
rsp.op_errno, rsp.op_errstr);
@@ -3076,7 +3072,8 @@ xml_output:
goto out;
}
- if (!rsp.op_ret && type != GF_QUOTA_OPTION_TYPE_LIST)
+ if (!rsp.op_ret && type != GF_QUOTA_OPTION_TYPE_LIST
+ && type != GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)
cli_out ("volume quota : success");
ret = rsp.op_ret;
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
index b6ae793131a..e5afe1b427d 100644
--- a/cli/src/cli-xml-output.c
+++ b/cli/src/cli-xml-output.c
@@ -5828,3 +5828,70 @@ out:
return 0;
#endif /* HAVE_LIB_XML */
}
+
+int
+cli_quota_object_xml_output (cli_local_t *local, char *path, char *sl_str,
+ quota_limits_t *limits, quota_meta_t *used_space,
+ int64_t avail, char *sl, char *hl)
+{
+#if (HAVE_LIB_XML)
+ int ret = -1;
+
+ ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"limit");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"path",
+ "%s", path);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"hard_limit",
+ "%"PRIu64, limits->hl);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"soft_limit",
+ "%s", sl_str);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"file_count",
+ "%"PRIu64,
+ used_space->file_count);
+
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"dir_count", "%"PRIu64,
+ used_space->dir_count);
+
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"available", "%"PRIu64,
+ avail);
+
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"sl_exceeded",
+ "%s", sl);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"hl_exceeded",
+ "%s", hl);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ return ret;
+#else
+ return 0;
+#endif /* HAVE_LIB_XML */
+}
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 54236344569..66aa5858cf6 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -744,3 +744,35 @@ cli_print_line (int len)
printf ("\n");
}
+
+void
+print_quota_list_header (int type)
+{
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ cli_out (" Path Hard-limit "
+ "Soft-limit Used Available Soft-limit exceeded?"
+ " Hard-limit exceeded?");
+ cli_out ("-----------------------------------------------------"
+ "-----------------------------------------------------"
+ "-----------------");
+ } else {
+ cli_out (" Path Hard-limit "
+ "Soft-limit Files Dirs Available "
+ "Soft-limit exceeded? Hard-limit exceeded?");
+ cli_out ("-----------------------------------------------------"
+ "-----------------------------------------------------"
+ "-----------------------------------");
+ }
+}
+
+void
+print_quota_list_empty (char *path, int type)
+{
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ cli_out ("%-40s %7s %9s %10s %7s %15s %20s", path,
+ "N/A", "N/A", "N/A", "N/A", "N/A", "N/A");
+ else
+ cli_out ("%-40s %9s %9s %12s %10s %10s %15s %20s", path,
+ "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A");
+}
+
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 6951555d479..ad286ef5f85 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -19,6 +19,7 @@
#include "glusterfs.h"
#include "protocol-common.h"
#include "logging.h"
+#include "quota-common-utils.h"
#include "cli1-xdr.h"
@@ -375,6 +376,11 @@ cli_quota_xml_output (cli_local_t *local, char *path, char *hl_str,
char *sl, char *hl);
int
+cli_quota_object_xml_output (cli_local_t *local, char *path, char *sl_str,
+ quota_limits_t *limits, quota_meta_t *used_space,
+ int64_t avail, char *sl, char *hl);
+
+int
cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
char *op_errstr);
@@ -425,4 +431,11 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
int
cli_xml_output_vol_getopts (dict_t *dict, int op_ret, int op_errno,
char *op_errstr);
+
+void
+print_quota_list_header (int type);
+
+void
+print_quota_list_empty (char *path, int type);
+
#endif /* __CLI_H__ */