summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-rpc-ops.c6
-rw-r--r--tests/bugs/cli/bug-1378842-volume-get-all.t26
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c39
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c34
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c120
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h36
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h1
7 files changed, 233 insertions, 29 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 53f5ef36a1f..97cf7410aea 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -11398,12 +11398,18 @@ gf_cli_get_vol_opt_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
+ ret = dict_get_str (dict, "warning", &value);
+ if (!ret) {
+ cli_out ("%s", value);
+ }
+
ret = dict_get_int32 (dict, "count", &count);
if (ret) {
gf_log ("cli", GF_LOG_ERROR, "Failed to retrieve count "
"from the dictionary");
goto out;
}
+
if (count <= 0) {
gf_log ("cli", GF_LOG_ERROR, "Value of count :%d is "
"invalid", count);
diff --git a/tests/bugs/cli/bug-1378842-volume-get-all.t b/tests/bugs/cli/bug-1378842-volume-get-all.t
new file mode 100644
index 00000000000..c798ce5ceff
--- /dev/null
+++ b/tests/bugs/cli/bug-1378842-volume-get-all.t
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+
+cleanup;
+TEST glusterd
+TEST pidof glusterd
+
+TEST $CLI volume set all server-quorum-ratio 80
+
+# Execute volume get without having an explicit option, this should fail
+TEST ! $CLI volume get all
+
+# Also volume get on an option not applicable for all volumes should fail
+TEST ! $CLI volume get all cluster.tier-mode
+
+# Execute volume get with an explicit global option
+TEST $CLI volume get all server-quorum-ratio
+EXPECT '80' volume_get_field all 'cluster.server-quorum-ratio'
+
+# Execute volume get with 'all'
+TEST $CLI volume get all all
+
+cleanup;
+
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index aec03922f7b..879f1021fd7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -4620,6 +4620,19 @@ glusterd_handle_barrier (rpcsvc_request_t *req)
return glusterd_big_locked_handler (req, __glusterd_handle_barrier);
}
+static gf_boolean_t
+gd_is_global_option (char *opt_key)
+{
+ GF_VALIDATE_OR_GOTO (THIS->name, opt_key, out);
+
+ return (strcmp (opt_key, GLUSTERD_SHARED_STORAGE_KEY) == 0 ||
+ strcmp (opt_key, GLUSTERD_QUORUM_RATIO_KEY) == 0 ||
+ strcmp (opt_key, GLUSTERD_GLOBAL_OP_VERSION_KEY) == 0);
+
+out:
+ return _gf_false;
+}
+
int32_t
glusterd_get_volume_opts (rpcsvc_request_t *req, dict_t *dict)
{
@@ -4632,6 +4645,7 @@ glusterd_get_volume_opts (rpcsvc_request_t *req, dict_t *dict)
char *volname = NULL;
char *value = NULL;
char err_str[2048] = {0,};
+ char warn_str[2048] = {0,};
char dict_key[50] = {0,};
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
@@ -4657,6 +4671,12 @@ glusterd_get_volume_opts (rpcsvc_request_t *req, dict_t *dict)
goto out;
}
+ if (strcasecmp (volname, "all") == 0) {
+ ret = glusterd_get_global_options_for_all_vols (dict,
+ &rsp.op_errstr);
+ goto out;
+ }
+
ret = dict_get_str (dict, "key", &key);
if (ret) {
snprintf (err_str, sizeof (err_str), "Failed to get key "
@@ -4722,6 +4742,25 @@ glusterd_get_volume_opts (rpcsvc_request_t *req, dict_t *dict)
orig_key = key;
key = key_fixed;
}
+ if (gd_is_global_option (key)) {
+ snprintf (warn_str, sizeof (warn_str),
+ "Warning: Support to get "
+ "global option value using "
+ "`volume get <volname>` will be "
+ "deprecated from next release. "
+ "Consider using `volume get all` "
+ "instead for global options");
+
+ ret = dict_set_str (dict, "warning", warn_str);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR,
+ 0, GD_MSG_DICT_SET_FAILED,
+ "Failed to set warning "
+ "message in dictionary");
+ goto out;
+ }
+ }
+
if (strcmp (key, "cluster.op-version") == 0) {
sprintf (dict_key, "key%d", count);
ret = dict_set_str(dict, dict_key, key);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 3d9372a5357..c2b0f53dcc4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -63,38 +63,13 @@ glusterd_set_shared_storage (dict_t *dict, char *key, char *value,
* all volumes, we can just add more entries to this *
* table *
*/
-glusterd_all_vol_opts valid_all_vol_opts[] = {
+glusterd_all_vol_opts valid_all_vol_opts[] = {
{ GLUSTERD_QUORUM_RATIO_KEY },
{ GLUSTERD_SHARED_STORAGE_KEY },
+ { GLUSTERD_GLOBAL_OP_VERSION_KEY },
{ NULL },
};
-#define ALL_VOLUME_OPTION_CHECK(volname, key, ret, op_errstr, label) \
- do { \
- gf_boolean_t _all = !strcmp ("all", volname); \
- gf_boolean_t _ratio = _gf_false; \
- int32_t i = 0; \
- \
- for (i = 0; valid_all_vol_opts[i].option; i++) { \
- if (!strcmp (key, valid_all_vol_opts[i].option)) { \
- _ratio = _gf_true; \
- break; \
- } \
- } \
- \
- if (_all && !_ratio) { \
- ret = -1; \
- *op_errstr = gf_strdup ("Not a valid option for all " \
- "volumes"); \
- goto label; \
- } else if (!_all && _ratio) { \
- ret = -1; \
- *op_errstr = gf_strdup ("Not a valid option for " \
- "single volume"); \
- goto label; \
- } \
- } while (0)
-
static struct cds_list_head gd_op_sm_queue;
synclock_t gd_op_sm_lock;
glusterd_op_info_t opinfo = {{0},};
@@ -1202,7 +1177,8 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
goto cont;
}
- ALL_VOLUME_OPTION_CHECK (volname, key, ret, op_errstr, out);
+ ALL_VOLUME_OPTION_CHECK (volname, _gf_false, key, ret,
+ op_errstr, out);
ret = glusterd_validate_quorum_options (this, key, value,
op_errstr);
if (ret)
@@ -1562,7 +1538,7 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr)
ret = -1;
goto out;
}
- ALL_VOLUME_OPTION_CHECK (volname, key, ret,
+ ALL_VOLUME_OPTION_CHECK (volname, _gf_false, key, ret,
op_errstr, out);
}
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index a1c9132feda..998c5a0d5da 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -93,6 +93,7 @@
#define NLMV1_VERSION 1
extern struct volopt_map_entry glusterd_volopt_map[];
+extern glusterd_all_vol_opts valid_all_vol_opts[];
static glusterd_lock_t lock;
@@ -10912,6 +10913,125 @@ out:
}
int
+glusterd_get_global_options_for_all_vols (dict_t *ctx, char **op_errstr)
+{
+ int ret = -1;
+ int count = 0;
+ gf_boolean_t all_opts = _gf_false;
+ gf_boolean_t key_found = _gf_false;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ char *key = NULL;
+ char *key_fixed = NULL;
+ char dict_key[50] = {0,};
+ char *def_val = NULL;
+ char err_str[PATH_MAX] = {0,};
+ char *allvolopt = NULL;
+ int32_t i = 0;
+ gf_boolean_t exists = _gf_false;
+
+ this = THIS;
+ GF_VALIDATE_OR_GOTO (THIS->name, this, out);
+
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
+ GF_VALIDATE_OR_GOTO (this->name, ctx, out);
+
+ ret = dict_get_str (ctx, "key", &key);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Failed to get option key from dictionary");
+ goto out;
+ }
+
+ if (strcasecmp (key, "all") == 0)
+ all_opts = _gf_true;
+ else {
+ exists = glusterd_check_option_exists (key, &key_fixed);
+ if (!exists) {
+ snprintf (err_str, sizeof (err_str), "Option "
+ "with name: %s does not exist", key);
+ gf_msg (this->name, GF_LOG_ERROR, EINVAL,
+ GD_MSG_UNKNOWN_KEY, "%s", err_str);
+ if (key_fixed)
+ snprintf (err_str, sizeof (err_str),
+ "Did you mean %s?", key_fixed);
+ ret = -1;
+ goto out;
+ }
+ if (key_fixed)
+ key = key_fixed;
+ }
+
+ ALL_VOLUME_OPTION_CHECK ("all", _gf_true, key, ret, op_errstr, out);
+
+ for (i = 0; valid_all_vol_opts[i].option; i++) {
+ allvolopt = gf_strdup (valid_all_vol_opts[i].option);
+
+ if (!all_opts && strcmp (key, allvolopt) != 0)
+ continue;
+
+ ret = dict_get_str (priv->opts, allvolopt, &def_val);
+
+ /* If global option isn't set explicitly */
+ if (!def_val) {
+ if (!strcmp (allvolopt, GLUSTERD_GLOBAL_OP_VERSION_KEY))
+ gf_asprintf (&def_val, "%d", priv->op_version);
+ else if (!strcmp (allvolopt, GLUSTERD_QUORUM_RATIO_KEY))
+ gf_asprintf (&def_val, "%d", 0);
+ else if (!strcmp (allvolopt, GLUSTERD_SHARED_STORAGE_KEY))
+ gf_asprintf (&def_val, "%s", "disable");
+ }
+
+ count++;
+ sprintf (dict_key, "key%d", count);
+ ret = dict_set_str (ctx, dict_key, allvolopt);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Failed to set %s in dictionary", allvolopt);
+ goto out;
+ }
+
+ sprintf (dict_key, "value%d", count);
+ ret = dict_set_dynstr_with_alloc (ctx, dict_key, def_val);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED,
+ "Failed to set %s for key %s in dictionary",
+ def_val, allvolopt);
+ goto out;
+ }
+
+ def_val = NULL;
+ allvolopt = NULL;
+
+ if (!all_opts)
+ break;
+ }
+
+ ret = dict_set_int32 (ctx, "count", count);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
+ "Failed to set count in dictionary");
+ }
+
+out:
+ if (ret && !all_opts && !key_found) {
+ if (err_str == NULL)
+ snprintf (err_str, sizeof (err_str),
+ "option %s does not exist", key);
+ if (*op_errstr == NULL)
+ *op_errstr = gf_strdup (err_str);
+ }
+ gf_msg_debug (THIS->name, 0, "Returning %d", ret);
+
+ return ret;
+}
+
+int
glusterd_get_default_val_for_volopt (dict_t *ctx, gf_boolean_t all_opts,
char *input_key, char *orig_key,
dict_t *vol_dict, char **op_errstr)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 419ab48323a..914d7977b51 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -32,6 +32,39 @@
volinfo->volname, brickid);\
} while (0)
+#define ALL_VOLUME_OPTION_CHECK(volname, get_opt, key, ret, op_errstr, label) \
+ do { \
+ gf_boolean_t _all = !strcmp ("all", volname); \
+ gf_boolean_t _is_valid_opt = _gf_false; \
+ int32_t i = 0; \
+ \
+ if (strcmp (key, "all") == 0 && !get_opt) { \
+ ret = -1; \
+ *op_errstr = gf_strdup ("Not a valid option to set"); \
+ } \
+ \
+ for (i = 0; valid_all_vol_opts[i].option; i++) { \
+ if (!strcmp (key, "all") || \
+ !strcmp (key, valid_all_vol_opts[i].option)) { \
+ _is_valid_opt = _gf_true; \
+ break; \
+ } \
+ } \
+ \
+ if (_all && !_is_valid_opt) { \
+ ret = -1; \
+ *op_errstr = gf_strdup ("Not a valid option for all " \
+ "volumes"); \
+ goto label; \
+ } else if (!_all && _is_valid_opt) { \
+ ret = -1; \
+ *op_errstr = gf_strdup ("Not a valid option for " \
+ "single volume"); \
+ goto label; \
+ } \
+ } while (0) \
+
+
struct glusterd_lock_ {
uuid_t owner;
time_t timestamp;
@@ -624,6 +657,9 @@ int
glusterd_get_volopt_content (dict_t *dict, gf_boolean_t xml_out);
int
+glusterd_get_global_options_for_all_vols (dict_t *dict, char **op_errstr);
+
+int
glusterd_get_default_val_for_volopt (dict_t *dict, gf_boolean_t all_opts,
char *key, char *orig_key,
dict_t *vol_dict, char **err_str);
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 02d9e85e487..d7e5964346e 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -43,6 +43,7 @@
#define GLUSTERD_QUORUM_TYPE_KEY "cluster.server-quorum-type"
#define GLUSTERD_QUORUM_RATIO_KEY "cluster.server-quorum-ratio"
#define GLUSTERD_GLOBAL_OPT_VERSION "global-option-version"
+#define GLUSTERD_GLOBAL_OP_VERSION_KEY "cluster.op-version"
#define GLUSTERD_COMMON_PEM_PUB_FILE "/geo-replication/common_secret.pem.pub"
#define GEO_CONF_MAX_OPT_VALS 6
#define GLUSTERD_CREATE_HOOK_SCRIPT "/hooks/1/gsync-create/post/" \