diff options
| author | Krutika Dhananjay <kdhananj@redhat.com> | 2013-11-25 15:16:23 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2013-11-30 10:15:05 -0800 | 
| commit | 182bad8bfd099da5e742da28c4820936eb1f3867 (patch) | |
| tree | 50cbf409e303d5bef128c5da08809aef75dc62b4 /cli/src | |
| parent | 72f733a64abeffee23fb87a3cb397baea1dc22a4 (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/src')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 6 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 103 | ||||
| -rw-r--r-- | cli/src/cli-cmd.h | 6 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 64 | ||||
| -rw-r--r-- | cli/src/cli.h | 4 | 
5 files changed, 156 insertions, 27 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index dd7b11bccd4..88fbf96ff9c 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 9bc11d2dbb4..22bf66b4fb5 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 52396bbf755..541b4ff7332 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 07c081affcc..d125a928469 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 b71140a810b..1fe8ffff7fb 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);  \  | 
