diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2013-07-31 13:19:19 +0530 |
---|---|---|
committer | Krutika Dhananjay <kdhananj@redhat.com> | 2013-08-09 15:20:11 +0530 |
commit | a09f9e94fd800fb0bbd8617de566aa57381d6048 (patch) | |
tree | e881b700c01cb154139a665443ab2c782815f81b | |
parent | 7f7e77956499f447695af2458582effd3adf08d1 (diff) |
glusterd: club limit-usage and soft-limit into a single command
Change-Id: I5f680675576aeec584b497eb25dd804a9dd6d690
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
-rw-r--r-- | cli/src/cli-cmd-parser.c | 59 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 85 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 9 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 248 |
6 files changed, 183 insertions, 221 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 98ed0fdd..18bc53f8 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -532,10 +532,9 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) uint64_t value = 0; gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE; char *opwords[] = { "enable", "disable", "limit-usage", - "remove", "list", "soft-limit", - "alert-time", "soft-timeout", - "hard-timeout", "default-soft-limit", - NULL}; + "remove", "list", "alert-time", + "soft-timeout", "hard-timeout", + "default-soft-limit", NULL}; char *w = NULL; uint32_t time = 0; double percent = 0; @@ -610,7 +609,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) } if (strcmp (w, "limit-usage") == 0) { - if (wordcount != 6) { + if (wordcount < 6 || wordcount > 7) { ret = -1; goto out; } @@ -638,10 +637,24 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) goto out; } - ret = dict_set_str (dict, "limit", (char *) words[5]); + ret = dict_set_str (dict, "hard-limit", (char *) words[5]); if (ret < 0) goto out; + if (wordcount == 7) { + + ret = gf_string2percent (words[6], &percent); + if (ret != 0) { + cli_err ("Please enter a correct value"); + goto out; + } + + ret = dict_set_str (dict, "soft-limit", + (char *) words[6]); + if (ret < 0) + goto out; + } + goto set_type; } if (strcmp (w, "remove") == 0) { @@ -688,41 +701,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) goto set_type; } - if (strcmp (w, "soft-limit") == 0) { - if (wordcount != 6) { - ret = -1; - goto out; - } - type = GF_QUOTA_OPTION_TYPE_SOFT_LIMIT; - 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) - goto out; - - if (!words[5]) { - cli_err ("Please enter the limit value to be set"); - ret = -1; - goto out; - } - - ret = gf_string2percent (words[5], &percent); - if (ret != 0) { - cli_err ("Please enter a correct value"); - goto out; - } - - ret = dict_set_str (dict, "limit", (char *) words[5]); - if (ret < 0) - goto out; - - goto set_type; - - } if (strcmp (w, "alert-time") == 0) { if (wordcount != 5) { ret = -1; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index f10df335..21572edf 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1898,7 +1898,7 @@ struct cli_cmd volume_cmds[] = { "volume profile operations"}, { "volume quota <VOLNAME> {enable|disable|list [<path> ...]|remove <path>| default-soft-limit <percent>} |\n" - "volume quota <VOLNAME> {limit-usage <path> <size> |soft-limit <path> <percent>} |\n" + "volume quota <VOLNAME> {limit-usage <path> <size> [<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 008b74c4..a1977397 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2558,6 +2558,60 @@ out: return ret; } +static int +gf_cli_create_auxiliary_mount (char *volname) +{ + int ret = -1; + char mountdir[PATH_MAX] = {0,}; + + snprintf (mountdir, sizeof (mountdir)-1, "/tmp/%s", volname); + ret = mkdir (mountdir, 0777); + if (ret && errno != EEXIST) + goto out; + + ret = runcmd (SBIN_DIR"/glusterfs", "-s", + "localhost", "--volfile-id", volname, "-l", + DEFAULT_LOG_FILE_DIRECTORY"/quota-enable.log", + mountdir, "--client-pid", "-42", NULL); + if (ret) { + gf_log ("cli", GF_LOG_WARNING, "failed to mount glusterfs " + "client"); + ret = -1; + goto out; + } + ret = 0; + +out: + return ret; +} + +static int +gf_cli_remove_auxiliary_mount (char *volname) +{ + int ret = -1; + runner_t runner = {0,}; + char mountdir [PATH_MAX] = {0,}; + + snprintf (mountdir, sizeof (mountdir)-1, "/tmp/%s", volname); + + runinit (&runner); + runner_add_args (&runner, "umount", + +#if GF_LINUX_HOST_OS + "-l", +#endif + mountdir, NULL); + ret = runner_run_reuse (&runner); + if (ret) + gf_log ("cli", GF_LOG_WARNING, "umount on %s failed, " + "reason : %s", mountdir, strerror (errno)); + runner_end (&runner); + + rmdir (mountdir); + return ret; + +} + int gf_cli_quota_list_run_crawler (char *volname, char *limit_list, dict_t *dict, int count, char *op_errstr, uint32_t op_version, @@ -2711,7 +2765,17 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, gf_log (frame->this->name, GF_LOG_TRACE, "failed to get entry " "count"); - if (type == GF_QUOTA_OPTION_TYPE_LIST) { + if (type == GF_QUOTA_OPTION_TYPE_ENABLE) { + ret = gf_cli_create_auxiliary_mount (volname); + if (ret) + goto out; + + } else if (type == GF_QUOTA_OPTION_TYPE_DISABLE) { + ret = gf_cli_remove_auxiliary_mount (volname); + if (ret) + goto out; + + } else if (type == GF_QUOTA_OPTION_TYPE_LIST) { if (global_state->mode & GLUSTER_MODE_XML) { ret = cli_xml_output_vol_quota_limit_list (volname, limit_list, rsp.op_ret, @@ -2720,22 +2784,25 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, gf_log ("cli", GF_LOG_ERROR, "Error outputting to xml"); goto out; - } - gf_log ("cli", GF_LOG_INFO, "Received resp to quota command"); - gf_cli_quota_list_run_crawler (volname, limit_list, dict, count, rsp.op_errstr, op_version, default_sl, entry_count); if (rsp.op_errstr) - snprintf (msg, sizeof (msg), "%s", rsp.op_errstr); + snprintf (msg, sizeof (msg)-1, "%s", rsp.op_errstr); + } + + gf_log ("cli", GF_LOG_DEBUG, "Received resp to quota command"); + + if (rsp.op_errstr) { + snprintf (msg, sizeof (msg)-1, "%s", rsp.op_errstr); } else { - gf_log ("cli", GF_LOG_INFO, "Received resp to quota command"); - if (rsp.op_errstr) - snprintf (msg, sizeof (msg), "%s", rsp.op_errstr); + if (!rsp.op_ret) + snprintf (msg, sizeof (msg)-1, "Quota command " + "successful"); else - snprintf (msg, sizeof (msg), "successful"); + snprintf (msg, sizeof (msg)-1, "Quota command failed"); } xml_output: diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 476ba594..d8d2bf5c 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -88,11 +88,10 @@ enum gf_quota_type { GF_QUOTA_OPTION_TYPE_REMOVE = 0 + 4, GF_QUOTA_OPTION_TYPE_LIST = 0 + 5, GF_QUOTA_OPTION_TYPE_VERSION = 0 + 6, - GF_QUOTA_OPTION_TYPE_SOFT_LIMIT = 0 + 7, - GF_QUOTA_OPTION_TYPE_ALERT_TIME = 0 + 8, - GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT = 0 + 9, - GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT = 0 + 10, - GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT = 0 + 11, + GF_QUOTA_OPTION_TYPE_ALERT_TIME = 0 + 7, + GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT = 0 + 8, + GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT = 0 + 9, + GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT = 0 + 10, }; typedef enum gf_quota_type gf_quota_type; diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index e58329a3..15805655 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -48,7 +48,6 @@ enum gf_quota_type { GF_QUOTA_OPTION_TYPE_REMOVE, GF_QUOTA_OPTION_TYPE_LIST, GF_QUOTA_OPTION_TYPE_VERSION, - GF_QUOTA_OPTION_TYPE_SOFT_LIMIT, GF_QUOTA_OPTION_TYPE_ALERT_TIME, GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT, GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT, diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 307b16d8..474d24ad 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -21,6 +21,9 @@ #include "glusterd-utils.h" #include "glusterd-volgen.h" #include "run.h" +#include "syscall.h" +#include "byte-order.h" +#include "compat-errno.h" #include <sys/wait.h> @@ -33,7 +36,6 @@ const char *gd_quota_op_list[GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT+1] = { [GF_QUOTA_OPTION_TYPE_REMOVE] = "remove", [GF_QUOTA_OPTION_TYPE_LIST] = "list", [GF_QUOTA_OPTION_TYPE_VERSION] = "version", - [GF_QUOTA_OPTION_TYPE_SOFT_LIMIT] = "soft-limit", [GF_QUOTA_OPTION_TYPE_ALERT_TIME] = "alert-time", [GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT] = "soft-timeout", [GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT] = "hard-timeout", @@ -600,143 +602,97 @@ out: return ret; } -static void -gd_quota_get_formatted_limit_list (char **value, char *existing_list, - char *path, char *hard_limit, - char *soft_limit) +static int +glusterd_set_quota_limit (char *volname, char *path, char *hard_limit, + char *soft_limit, char **op_errstr) { - if (!existing_list) { - if (!soft_limit) - gf_asprintf (value, "%s:%s", path, hard_limit); - else - gf_asprintf (value, "%s:%s:%s", path, hard_limit, - soft_limit); - } else { - if (!soft_limit) - gf_asprintf (value, "%s,%s:%s", existing_list, path, - hard_limit); - else - gf_asprintf (value, "%s,%s:%s:%s", existing_list, path, - hard_limit, soft_limit); - } -} + int ret = -1; + xlator_t *this = NULL; + char abspath[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + double soft_lim = 0; -int32_t -glusterd_quota_limit_usage (glusterd_volinfo_t *volinfo, dict_t *dict, - char **op_errstr) -{ - int32_t ret = -1; - char *path = NULL; - char *limit = NULL; - char *value = NULL; - char *sl = NULL; - char msg[5120] = {0,}; - char *quota_limits = NULL; - char *new_list = NULL; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - char *removed_path = NULL; + struct { + uint64_t hl; + uint64_t sl; + } existing_limit, new_limit; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); - GF_VALIDATE_OR_GOTO (this->name, dict, out); - GF_VALIDATE_OR_GOTO (this->name, volinfo, out); - GF_VALIDATE_OR_GOTO (this->name, op_errstr, out); - - ret = glusterd_check_if_quota_trans_enabled (volinfo); - if (ret == -1) { - *op_errstr = gf_strdup ("Quota is disabled, please enable " - "quota"); - goto out; - } + snprintf (abspath, sizeof (abspath)-1, "/tmp/%s%s", volname, path); - ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE, - "a_limits); + ret = gf_lstat_dir (abspath, NULL); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "failed to get quota limits"); + gf_asprintf (op_errstr, "Failed to find the directory %s. " + "Reason : %s", abspath, strerror (errno)); goto out; } - ret = dict_get_str (dict, "path", &path); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to fetch path"); - goto out; - } - ret = gf_canonicalize_path (path); - if (ret) - goto out; - - ret = dict_get_str (dict, "limit", &limit); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to fetch limit"); - goto out; - } - - if (quota_limits == NULL) { - ; //do nothing and go past the else block - } else { - ret = _glusterd_quota_remove_limits (quota_limits, path, NULL, - &new_list, &removed_path); - if (ret == -1) { - gf_log (this->name, GF_LOG_ERROR, "Unable to remove " - "limit"); + if (!soft_limit) { + ret = sys_lgetxattr (abspath, + "trusted.glusterfs.quota.limit-set", + (void *)&existing_limit, + sizeof (existing_limit)); + if((ret < 0) && (errno != ENOATTR)) { + gf_asprintf (op_errstr, "Failed to get the xattr " + "'trusted.glusterfs.quota.limit-set' from " + "%s. Reason : %s", abspath, + strerror (errno)); goto out; } + existing_limit.hl = ntoh64 (existing_limit.hl); + existing_limit.sl = ntoh64 (existing_limit.sl); + new_limit.sl = existing_limit.sl; - if (removed_path && (priv->op_version > GD_OP_VERSION_MIN)) { - ret = gf_get_soft_limit (removed_path, &sl); - if (ret == -1) - goto out; - } + } else { + ret = gf_string2percent (soft_limit, &soft_lim); + if (ret) + goto out; + new_limit.sl = (uint64_t) soft_lim; } - gd_quota_get_formatted_limit_list (&value, new_list, path, limit, sl); - ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE, - value); + new_limit.sl = hton64 (new_limit.sl); + + ret = gf_string2bytesize (hard_limit, &new_limit.hl); + if (ret) + goto out; + + new_limit.hl = hton64 (new_limit.hl); + + ret = sys_lsetxattr (abspath, "trusted.glusterfs.quota.limit-set", + (char *)(void *)&new_limit, sizeof (new_limit), 0); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to set quota limits"); + gf_asprintf (op_errstr, "setxattr of " + "'trusted.glusterfs.quota.limit-set' failed on %s." + " Reason : %s", abspath, strerror (errno)); goto out; } - - snprintf (msg, sizeof (msg), "hard limit set on %s", path); - *op_errstr = gf_strdup (msg); ret = 0; -out: - GF_FREE (sl); - GF_FREE (removed_path); - GF_FREE (new_list); - if (ret && op_errstr && !*op_errstr) - gf_asprintf (op_errstr, "Failed to set hard limit on path %s " - "for volume %s", path, volinfo->volname); +out: return ret; } -int -glusterd_quota_soft_limit (glusterd_volinfo_t *volinfo, dict_t *dict, - char **op_errstr) +int32_t +glusterd_quota_limit_usage (glusterd_volinfo_t *volinfo, dict_t *dict, + char **op_errstr) { - int ret = 0; - char *path = NULL; - char *limit = NULL; - char *quota_limits = NULL; - char *new_list = NULL; - char *removed_path = NULL; - char msg[1024] = {0,}; - char *hl = NULL; - char *value = NULL; - xlator_t *this = NULL; + int32_t ret = -1; + char *path = NULL; + char *hard_limit = NULL; + char *soft_limit = NULL; + char msg[5120] = {0,}; + xlator_t *this = NULL; this = THIS; GF_ASSERT (this); - if (!volinfo || !dict || !op_errstr) { - ret = -1; - goto out; - } + GF_VALIDATE_OR_GOTO (this->name, dict, out); + GF_VALIDATE_OR_GOTO (this->name, volinfo, out); + GF_VALIDATE_OR_GOTO (this->name, op_errstr, out); ret = glusterd_check_if_quota_trans_enabled (volinfo); if (ret == -1) { @@ -745,77 +701,46 @@ glusterd_quota_soft_limit (glusterd_volinfo_t *volinfo, dict_t *dict, goto out; } - ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE, - "a_limits); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "failed to get quota limits"); - goto out; - } - ret = dict_get_str (dict, "path", &path); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Unable to fetch path"); goto out; } - ret = gf_canonicalize_path (path); if (ret) goto out; - ret = dict_get_str (dict, "limit", &limit); + ret = dict_get_str (dict, "hard-limit", &hard_limit); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to fetch limit"); + gf_log (this->name, GF_LOG_ERROR, "Unable to fetch hard limit"); goto out; } - if (quota_limits == NULL) { - gf_asprintf (op_errstr, "Soft-limit cannot be set on path %s, " - "without setting hard-limit on it first.", path); - ret = -1; - goto out; - } else { - ret = _glusterd_quota_remove_limits (quota_limits, path, NULL, - &new_list, &removed_path); - if (ret == -1) { - gf_log (this->name, GF_LOG_ERROR, "Failed to remove " - "limit"); - goto out; - } - - if (!removed_path) { - gf_asprintf (op_errstr, "Soft-limit cannot be set on " - "path %s without setting hard-limit on it " - "first.", path); - ret = -1; + if (dict_get (dict, "soft-limit")) { + ret = dict_get_str (dict, "soft-limit", &soft_limit); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Unable to fetch " + "soft limit"); goto out; - } else { - ret = gf_get_hard_limit (removed_path, &hl); - if (ret) - goto out; } - } - - gd_quota_get_formatted_limit_list (&value, new_list, path, hl, limit); - - ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE, - value); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to set quota limits"); - goto out; - } + } - snprintf (msg, sizeof (msg), "soft limit set on %s", path); - *op_errstr = gf_strdup (msg); - ret = 0; + if (is_origin_glusterd ()) { + ret = glusterd_set_quota_limit (volinfo->volname, path, + hard_limit, soft_limit, + op_errstr); + if (ret) + goto out; + } + snprintf (msg, sizeof (msg)-1, "Quota limit set on %s", path); + *op_errstr = gf_strdup (msg); + ret = 0; out: - GF_FREE (hl); - GF_FREE (removed_path); - GF_FREE (new_list); if (ret && op_errstr && !*op_errstr) - gf_asprintf (op_errstr, "Failed to set soft limit for path %s " - "on volume %s", path, volinfo->volname); + gf_asprintf (op_errstr, "Failed to set hard limit on path %s " + "for volume %s", path, volinfo->volname); return ret; } @@ -1061,13 +986,6 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) goto out; } - if (type == GF_QUOTA_OPTION_TYPE_SOFT_LIMIT) { - ret = glusterd_quota_soft_limit (volinfo, dict, op_errstr); - if (ret < 0) - goto out; - goto create_vol; - } - if (type == GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT) { ret = glusterd_set_quota_option (volinfo, dict, "features.soft-timeout", |