summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2013-07-31 13:19:19 +0530
committerKrutika Dhananjay <kdhananj@redhat.com>2013-08-09 15:20:11 +0530
commita09f9e94fd800fb0bbd8617de566aa57381d6048 (patch)
treee881b700c01cb154139a665443ab2c782815f81b
parent7f7e77956499f447695af2458582effd3adf08d1 (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.c59
-rw-r--r--cli/src/cli-cmd-volume.c2
-rw-r--r--cli/src/cli-rpc-ops.c85
-rw-r--r--rpc/xdr/src/cli1-xdr.h9
-rw-r--r--rpc/xdr/src/cli1-xdr.x1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c248
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,
- &quota_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,
- &quota_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",