summaryrefslogtreecommitdiffstats
path: root/cli
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2013-11-25 15:16:23 +0530
committerVijay Bellur <vbellur@redhat.com>2013-11-30 10:15:05 -0800
commit182bad8bfd099da5e742da28c4820936eb1f3867 (patch)
tree50cbf409e303d5bef128c5da08809aef75dc62b4 /cli
parent72f733a64abeffee23fb87a3cb397baea1dc22a4 (diff)
cli, glusterd: More quota fixes ...
... which may be grouped under the following categories: 1. Fix incorrect cli exit status for 'quota list' cmd 2. Print appropriate error message on quota parse errors in cli Authored by: Anuradha Talur <atalur@redhat.com> 3. glusterd: Improve quota validation during stage-op 4. Fix peer probe issues resulting from quota conf checksum mismatches 5. Enhancements to CLI output in the event of quota command failures Authored by: Kaushal Madappa <kmadappa@redhat.com> 7. Move aux mount location from /tmp to /var/run/gluster Authored by: Krishnan Parthasarathi <kparthas@redhat.com> 8. Fix performance issues in quota limit-usage Authored by: Krutika Dhananjay <kdhananj@redhat.com> Note: Some functions that were used in earlier version of quota, that aren't called anymore have been removed. Change-Id: I9d874f839ae5fdcfbe6d4f2d727eac091f27ac57 BUG: 969461 Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-on: http://review.gluster.org/6366 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'cli')
-rw-r--r--cli/src/cli-cmd-parser.c6
-rw-r--r--cli/src/cli-cmd-volume.c103
-rw-r--r--cli/src/cli-cmd.h6
-rw-r--r--cli/src/cli-rpc-ops.c64
-rw-r--r--cli/src/cli.h4
5 files changed, 156 insertions, 27 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index dd7b11b..88fbf96 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -535,6 +535,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
w = str_getunamb (words[3], opwords);
if (!w) {
+ cli_out ("Invalid quota option : %s", words[3]);
ret = - 1;
goto out;
}
@@ -587,7 +588,10 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
ret = gf_string2bytesize (words[5], &value);
if (ret != 0) {
- cli_err ("Please enter a correct value");
+ if (errno == ERANGE)
+ cli_err ("Value too large: %s", words[5]);
+ else
+ cli_err ("Please enter a correct value");
goto out;
}
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 9bc11d2..22bf66b 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -28,6 +28,7 @@
#include "cli-mem-types.h"
#include "cli1-xdr.h"
#include "run.h"
+#include "syscall.h"
extern struct rpc_clnt *global_rpc;
extern struct rpc_clnt *global_quotad_rpc;
@@ -1026,7 +1027,7 @@ gf_cli_create_auxiliary_mount (char *volname)
goto out;
}
- snprintf (mountdir, sizeof (mountdir)-1, "/tmp/%s", volname);
+ GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/");
ret = mkdir (mountdir, 0777);
if (ret && errno != EEXIST) {
gf_log ("cli", GF_LOG_ERROR, "Failed to create auxiliary mount "
@@ -1071,8 +1072,11 @@ cli_stage_quota_op (char *volname, int op_code)
case GF_QUOTA_OPTION_TYPE_REMOVE:
case GF_QUOTA_OPTION_TYPE_LIST:
ret = gf_cli_create_auxiliary_mount (volname);
- if (ret)
+ if (ret) {
+ cli_err ("quota: Could not start quota "
+ "auxiliary mount");
goto out;
+ }
ret = 0;
break;
@@ -1153,6 +1157,77 @@ cli_cmd_quota_conf_skip_header (int fd)
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;
+ char quota_conf_file[PATH_MAX] = {0,};
+ int fd = -1;
+ char buf[16] = {0,};
+
+ /* 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)
+ goto out;
+
+ ret = cli_cmd_quota_conf_skip_header (fd);
+ if (ret)
+ goto out;
+
+ /* Try to read atleast one gfid */
+ ret = read (fd, (void *)buf, 16);
+ if (ret == 16)
+ limits_set = _gf_true;
+out:
+ if (fd != -1)
+ close (fd);
+ return limits_set;
+}
+
+/* Checks if the mount is connected to the bricks
+ *
+ * Returns true if connected and false if not
+ */
+gf_boolean_t
+_quota_aux_mount_online (char *volname)
+{
+ int ret = 0;
+ char mount_path[PATH_MAX + 1] = {0,};
+ struct stat buf = {0,};
+
+ GF_ASSERT (volname);
+
+ /* Try to create the aux mount before checking if bricks are online */
+ ret = gf_cli_create_auxiliary_mount (volname);
+ if (ret) {
+ cli_err ("quota: Could not start quota auxiliary mount");
+ return _gf_false;
+ }
+
+ GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mount_path, volname, "/");
+
+ ret = sys_stat (mount_path, &buf);
+ if (ret) {
+ if (ENOTCONN == errno) {
+ cli_err ("quota: Cannot connect to bricks. Check if "
+ "bricks are online.");
+ } else {
+ cli_err ("quota: Error on quota auxiliary mount (%s).",
+ strerror (errno));
+ }
+ return _gf_false;
+ }
+ return _gf_true;
+}
+
int
cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
{
@@ -1189,6 +1264,21 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
goto out;
}
+ /* 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)) {
+ cli_out ("quota: No quota configured on volume %s", volname);
+ ret = 0;
+ goto out;
+ }
+
+ /* Check if the mount is online before doing any listing */
+ if (!_quota_aux_mount_online (volname)) {
+ ret = -1;
+ goto out;
+ }
+
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame) {
ret = -1;
@@ -1265,22 +1355,19 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
}
if (count > 0) {
- ret = all_failed? 0: -1;
+ ret = all_failed? -1: 0;
} 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");
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch and display quota"
+ " limits");
}
CLI_STACK_DESTROY (frame);
return ret;
diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h
index 52396bb..541b4ff 100644
--- a/cli/src/cli-cmd.h
+++ b/cli/src/cli-cmd.h
@@ -119,4 +119,10 @@ gf_answer_t
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);
+
+gf_boolean_t
+_quota_aux_mount_online (char *volname);
+
#endif /* __CLI_CMD_H__ */
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 07c081a..d125a92 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -2288,8 +2288,8 @@ out:
static int
print_quota_list_output (char *mountdir, char *default_sl, char *path)
{
- uint64_t used_space = 0;
- uint64_t avail = 0;
+ int64_t used_space = 0;
+ int64_t avail = 0;
char *used_str = NULL;
char *avail_str = NULL;
int ret = -1;
@@ -2309,6 +2309,20 @@ print_quota_list_output (char *mountdir, char *default_sl, char *path)
gf_log ("cli", GF_LOG_ERROR, "Failed to get the xattr "
"trusted.glusterfs.quota.limit-set on %s. Reason : %s",
mountdir, strerror (errno));
+ switch (errno) {
+#if defined(ENODATA)
+ case ENODATA:
+#endif
+#if defined(ENOATTR) && (ENOATTR != ENODATA)
+ case ENOATTR:
+#endif
+ cli_err ("%-40s %s", path, "Limit not set");
+ break;
+ default:
+ cli_err ("%-40s %s", path, strerror (errno));
+ break;
+ }
+
goto out;
}
@@ -2371,10 +2385,20 @@ gf_cli_print_limit_list_from_dict (char *volname, dict_t *dict,
if (!dict|| count <= 0)
goto out;
- /*To-Do:
- * Proper error reporting to handle the case where none of the given
- * path arguments are present or have their limits set.
+ /* Need to check if any quota limits are set on the volume before trying
+ * to list them
*/
+ if (!_limits_set_on_volume (volname)) {
+ ret = 0;
+ cli_out ("quota: No quota configured on volume %s", volname);
+ goto out;
+ }
+
+ /* Check if the mount is online before doing any listing */
+ if (!_quota_aux_mount_online (volname)) {
+ ret = -1;
+ goto out;
+ }
cli_out (" Path Hard-limit "
"Soft-limit Used Available");
@@ -2394,9 +2418,7 @@ gf_cli_print_limit_list_from_dict (char *volname, dict_t *dict,
ret = gf_canonicalize_path (path);
if (ret)
goto out;
- snprintf (mountdir, sizeof (mountdir), "/tmp/%s%s", volname,
- path);
-
+ GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, path);
ret = print_quota_list_output (mountdir, default_sl, path);
}
@@ -2520,12 +2542,14 @@ cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- if (rsp.op_ret && strcmp (rsp.op_errstr, "") == 0) {
- cli_err ("quota command : failed");
- goto out;
-
- } else if (strcmp (rsp.op_errstr, ""))
+ if (rsp.op_ret) {
+ ret = -1;
+ if (strcmp (rsp.op_errstr, ""))
cli_err ("quota command failed : %s", rsp.op_errstr);
+ else
+ cli_err ("quota command : failed");
+ goto out;
+ }
if (rsp.dict.dict_len) {
/* Unserialize the dictionary */
@@ -2633,14 +2657,18 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- if (rsp.op_ret && strcmp (rsp.op_errstr, "") == 0) {
- cli_err ("quota command : failed");
-
+ if (rsp.op_ret) {
+ ret = -1;
if (global_state->mode & GLUSTER_MODE_XML)
goto xml_output;
- goto out;
- } else if (strcmp (rsp.op_errstr, ""))
+
+ if (strcmp (rsp.op_errstr, ""))
cli_err ("quota command failed : %s", rsp.op_errstr);
+ else
+ cli_err ("quota command : failed");
+
+ goto out;
+ }
if (rsp.dict.dict_len) {
/* Unserialize the dictionary */
diff --git a/cli/src/cli.h b/cli/src/cli.h
index b71140a..1fe8fff 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -47,6 +47,10 @@ enum argp_option_keys {
#define GLUSTER_MODE_XML (1 << 2)
+#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \
+ snprintf (abspath, sizeof (abspath)-1, \
+ DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path);
+
#define GLUSTERFS_GET_AUX_MOUNT_PIDFILE(pidfile,volname) { \
snprintf (pidfile, PATH_MAX-1, \
DEFAULT_VAR_RUN_DIRECTORY"/%s.pid", volname); \