diff options
-rw-r--r-- | cli/src/cli-rpc-ops.c | 6 | ||||
-rw-r--r-- | tests/bugs/cli/bug-1378842-volume-get-all.t | 26 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 39 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 34 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 120 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 36 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 1 |
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/" \ |