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/" \  | 
