summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt
diff options
context:
space:
mode:
authorSamikshan Bairagya <samikshan@gmail.com>2016-12-19 15:07:14 +0530
committerAtin Mukherjee <amukherj@redhat.com>2017-01-08 21:16:12 -0800
commit76fbeafbf56a61768c81f622b354e3c95a00e986 (patch)
tree0b8959761c59a86067368b6883feef2240578fbe /xlators/mgmt
parent3fcd790d9ca01a95026026d64385c52b5476174d (diff)
glusterd: Get maximum supported op-version in a cluster
gluster volume get <VOLNAME> cluster.opversion gives us the current op-version on which the cluster is operating. There is no command that lets the user know the maximum supported op-version that the cluster can run on. This patch adds a new global option cluster.max-op-version, that can be used to retrieve the maximum supported op-version in a cluster. Usage: # gluster volume get all cluster.max-op-version Example output: Option Value ------ ----- cluster.max-op-version 30900 NOTE: The only way to test this feature for now is to set the GD_OP_VERSION_MAX macro to different values (30800 for 3.8,30900 for 3.9, and so on) and rebuild glusterd. Since the regression test framework currently doesn't have support to simulate these tests, there are no accompanying regression tests for this feature. It should be possible to add tests once glusto comes in and makes it easier to run a heterogeneous cluster. Change-Id: I547480ee5e7912664784643e436feb198b6d16d0 BUG: 1365822 Signed-off-by: Samikshan Bairagya <samikshan@gmail.com> Reviewed-on: http://review.gluster.org/16283 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Diffstat (limited to 'xlators/mgmt')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c13
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c69
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c21
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c95
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h4
10 files changed, 198 insertions, 29 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 879f1021fd7..9a4b1bf38da 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -4627,7 +4627,8 @@ gd_is_global_option (char *opt_key)
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);
+ strcmp (opt_key, GLUSTERD_GLOBAL_OP_VERSION_KEY) == 0 ||
+ strcmp (opt_key, GLUSTERD_MAX_OP_VERSION_KEY) == 0);
out:
return _gf_false;
@@ -4672,11 +4673,12 @@ glusterd_get_volume_opts (rpcsvc_request_t *req, dict_t *dict)
}
if (strcasecmp (volname, "all") == 0) {
- ret = glusterd_get_global_options_for_all_vols (dict,
+ ret = glusterd_get_global_options_for_all_vols (req, 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 "
@@ -4742,6 +4744,7 @@ 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 "
@@ -4761,7 +4764,11 @@ glusterd_get_volume_opts (rpcsvc_request_t *req, dict_t *dict)
}
}
- if (strcmp (key, "cluster.op-version") == 0) {
+ if (strcmp (key, "cluster.max-op-version") == 0) {
+ ret = glusterd_get_global_max_op_version (req, dict, 1);
+ if (ret)
+ goto out;
+ } else if (strcmp (key, "cluster.op-version") == 0) {
sprintf (dict_key, "key%d", count);
ret = dict_set_str(dict, dict_key, key);
if (ret) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
index 85c98481042..b7b1a3fcbfd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
@@ -200,6 +200,10 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
}
break;
+ case GD_OP_MAX_OPVERSION:
+ ret = 0;
+ break;
+
default:
break;
}
@@ -320,6 +324,18 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
}
break;
}
+ case GD_OP_MAX_OPVERSION:
+ {
+ ret = glusterd_op_get_max_opversion (op_errstr,
+ rsp_dict);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_COMMIT_OP_FAIL,
+ "Commit failed.");
+ goto out;
+ }
+ break;
+ }
default:
break;
@@ -702,6 +718,8 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op,
goto out;
}
break;
+ case GD_OP_MAX_OPVERSION:
+ break;
default:
ret = -1;
gf_msg (this->name, GF_LOG_ERROR, EINVAL,
@@ -915,18 +933,20 @@ glusterd_mgmt_v3_pre_validate (glusterd_op_t op, dict_t *req_dict,
goto out;
}
- ret = glusterd_pre_validate_aggr_rsp_dict (op, req_dict,
- rsp_dict);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_PRE_VALIDATION_FAIL, "%s",
- "Failed to aggregate response from "
- " node/brick");
- goto out;
- }
+ if (op != GD_OP_MAX_OPVERSION) {
+ ret = glusterd_pre_validate_aggr_rsp_dict (op, req_dict,
+ rsp_dict);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_PRE_VALIDATION_FAIL, "%s",
+ "Failed to aggregate response from "
+ " node/brick");
+ goto out;
+ }
- dict_unref (rsp_dict);
- rsp_dict = NULL;
+ dict_unref (rsp_dict);
+ rsp_dict = NULL;
+ }
/* Sending Pre Validation req to other nodes in the cluster */
gd_syncargs_init (&args, req_dict);
@@ -998,13 +1018,14 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
goto out;
switch (op) {
- case GD_OP_SNAP:
- dict_copy (dict, req_dict);
- break;
- case GD_OP_START_VOLUME:
- case GD_OP_ADD_BRICK:
- case GD_OP_REPLACE_BRICK:
- case GD_OP_RESET_BRICK:
+ case GD_OP_MAX_OPVERSION:
+ case GD_OP_SNAP:
+ dict_copy (dict, req_dict);
+ break;
+ case GD_OP_START_VOLUME:
+ case GD_OP_ADD_BRICK:
+ case GD_OP_REPLACE_BRICK:
+ case GD_OP_RESET_BRICK:
{
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
@@ -1025,8 +1046,8 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
dict_copy (dict, req_dict);
}
break;
- default:
- break;
+ default:
+ break;
}
*req = req_dict;
@@ -2070,9 +2091,11 @@ out:
if (op_ret && (op_errno == 0))
op_errno = EG_INTRNL;
- /* SEND CLI RESPONSE */
- glusterd_op_send_cli_response (op, op_ret, op_errno, req,
- dict, op_errstr);
+ if (op != GD_OP_MAX_OPVERSION) {
+ /* SEND CLI RESPONSE */
+ glusterd_op_send_cli_response (op, op_ret, op_errno, req,
+ dict, op_errstr);
+ }
if (req_dict)
dict_unref (req_dict);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index c2b0f53dcc4..ffae6296404 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -67,6 +67,7 @@ glusterd_all_vol_opts valid_all_vol_opts[] = {
{ GLUSTERD_QUORUM_RATIO_KEY },
{ GLUSTERD_SHARED_STORAGE_KEY },
{ GLUSTERD_GLOBAL_OP_VERSION_KEY },
+ { GLUSTERD_MAX_OP_VERSION_KEY },
{ NULL },
};
@@ -2471,6 +2472,25 @@ out:
return ret;
}
+int
+glusterd_op_get_max_opversion (char **op_errstr, dict_t *rsp_dict)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, rsp_dict, out);
+
+ ret = dict_set_int32 (rsp_dict, "max-opversion", GD_OP_VERSION_MAX);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
+ "Setting value for max-opversion to dict failed");
+ goto out;
+ }
+
+out:
+ gf_msg_debug (THIS->name, 0, "Returning %d", ret);
+ return ret;
+}
+
static int
glusterd_set_shared_storage (dict_t *dict, char *key, char *value,
char **op_errstr)
@@ -7955,6 +7975,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx)
case GD_OP_STATEDUMP_VOLUME:
case GD_OP_CLEARLOCKS_VOLUME:
case GD_OP_DEFRAG_BRICK_VOLUME:
+ case GD_OP_MAX_OPVERSION:
dict_unref (ctx);
break;
default:
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index ef5b95273a5..dc955de635a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -145,6 +145,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
case GD_OP_SCRUB_STATUS:
case GD_OP_SCRUB_ONDEMAND:
case GD_OP_RESET_BRICK:
+ case GD_OP_MAX_OPVERSION:
{
/*nothing specific to be done*/
break;
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index 2b7a4477fca..ffc7216b1da 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -314,6 +314,10 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)
case GD_OP_SCRUB_ONDEMAND:
break;
+ case GD_OP_MAX_OPVERSION:
+ ret = glusterd_max_opversion_use_rsp_dict (aggr, rsp);
+ break;
+
default:
break;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 998c5a0d5da..3227923a99e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -46,6 +46,7 @@
#include "glusterd-pmap.h"
#include "glusterfs-acl.h"
#include "glusterd-syncop.h"
+#include "glusterd-mgmt.h"
#include "glusterd-locks.h"
#include "glusterd-messages.h"
#include "glusterd-volgen.h"
@@ -8670,6 +8671,43 @@ out:
}
int
+glusterd_max_opversion_use_rsp_dict (dict_t *dst, dict_t *src)
+{
+ int ret = -1;
+ int src_max_opversion = -1;
+ int max_opversion = -1;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, dst, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, src, out);
+
+ ret = dict_get_int32 (dst, "max-opversion", &max_opversion);
+ if (ret)
+ gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
+ "Maximum supported op-version not set in destination "
+ "dictionary");
+
+ ret = dict_get_int32 (src, "max-opversion", &src_max_opversion);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
+ "Failed to get maximum supported op-version from source");
+ goto out;
+ }
+
+ if (max_opversion == -1 || src_max_opversion < max_opversion)
+ max_opversion = src_max_opversion;
+
+ ret = dict_set_int32 (dst, "max-opversion", max_opversion);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
+ "Failed to set max op-version");
+ goto out;
+ }
+out:
+ return ret;
+}
+
+
+int
glusterd_volume_bitrot_scrub_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
{
int ret = -1;
@@ -10913,7 +10951,51 @@ out:
}
int
-glusterd_get_global_options_for_all_vols (dict_t *ctx, char **op_errstr)
+glusterd_get_global_max_op_version (rpcsvc_request_t *req, dict_t *ctx,
+ int count)
+{
+ int ret = -1;
+ char *def_val = NULL;
+ char dict_key[50] = {0,};
+
+ ret = glusterd_mgmt_v3_initiate_all_phases (req, GD_OP_MAX_OPVERSION,
+ ctx);
+
+ ret = dict_get_str (ctx, "max-opversion", &def_val);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_GET_FAILED,
+ "Failed to get max-opversion value from"
+ " dictionary");
+ goto out;
+ }
+
+ sprintf (dict_key, "key%d", count);
+ ret = dict_set_str (ctx, dict_key, GLUSTERD_MAX_OP_VERSION_KEY);
+ if (ret) {
+ gf_msg (THIS->name, GF_LOG_ERROR, 0,
+ GD_MSG_DICT_SET_FAILED, "Failed to set %s in "
+ "dictionary", GLUSTERD_MAX_OP_VERSION_KEY);
+ 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, GLUSTERD_MAX_OP_VERSION_KEY);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+int
+glusterd_get_global_options_for_all_vols (rpcsvc_request_t *req, dict_t *ctx,
+ char **op_errstr)
{
int ret = -1;
int count = 0;
@@ -10973,6 +11055,17 @@ glusterd_get_global_options_for_all_vols (dict_t *ctx, char **op_errstr)
if (!all_opts && strcmp (key, allvolopt) != 0)
continue;
+ /* Found global option */
+ if (strcmp (allvolopt, GLUSTERD_MAX_OP_VERSION_KEY) == 0) {
+ count++;
+ ret = glusterd_get_global_max_op_version (req, ctx,
+ count);
+ if (ret)
+ goto out;
+ else
+ continue;
+ }
+
ret = dict_get_str (priv->opts, allvolopt, &def_val);
/* If global option isn't set explicitly */
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 914d7977b51..53f4d971998 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -38,9 +38,11 @@
gf_boolean_t _is_valid_opt = _gf_false; \
int32_t i = 0; \
\
- if (strcmp (key, "all") == 0 && !get_opt) { \
+ if (!get_opt && (!strcmp (key, "all") || \
+ !strcmp (key, "cluster.max-op-version"))) { \
ret = -1; \
*op_errstr = gf_strdup ("Not a valid option to set"); \
+ goto out; \
} \
\
for (i = 0; valid_all_vol_opts[i].option; i++) { \
@@ -482,6 +484,9 @@ glusterd_handle_node_rsp (dict_t *req_ctx, void *pending_entry,
glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx,
char **op_errstr, gd_node_type type);
int
+glusterd_max_opversion_use_rsp_dict (dict_t *dst, dict_t *src);
+
+int
glusterd_volume_bitrot_scrub_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
int
@@ -657,7 +662,12 @@ 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);
+glusterd_get_global_max_op_version (rpcsvc_request_t *req, dict_t *ctx,
+ int count);
+
+int
+glusterd_get_global_options_for_all_vols (rpcsvc_request_t *req, dict_t *dict,
+ char **op_errstr);
int
glusterd_get_default_val_for_volopt (dict_t *dict, gf_boolean_t all_opts,
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 5bda3fedd43..b8f92e4fcd5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2593,6 +2593,11 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.voltype = "mgmt/glusterd",
.op_version = GD_OP_VERSION_3_6_0,
},
+ {
+ .key = "cluster.max-op-version",
+ .voltype = "mgmt/glusterd",
+ .op_version = GD_OP_VERSION_3_10_0,
+ },
/*Trash translator options */
{ .key = "features.trash",
.voltype = "features/trash",
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 705ce721ea8..ac5570404a8 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -124,6 +124,7 @@ const char *gd_op_list[GD_OP_MAX + 1] = {
[GD_OP_GSYNC_CREATE] = "Geo-replication Create",
[GD_OP_SNAP] = "Snapshot",
[GD_OP_RESET_BRICK] = "Reset Brick",
+ [GD_OP_MAX_OPVERSION] = "Maximum supported op-version",
[GD_OP_MAX] = "Invalid op"
};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index d7e5964346e..9d3d867e64c 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -44,6 +44,7 @@
#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_MAX_OP_VERSION_KEY "cluster.max-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/" \
@@ -123,6 +124,7 @@ typedef enum glusterd_op_ {
GD_OP_SCRUB_STATUS,
GD_OP_SCRUB_ONDEMAND,
GD_OP_RESET_BRICK,
+ GD_OP_MAX_OPVERSION,
GD_OP_MAX,
} glusterd_op_t;
@@ -1115,6 +1117,8 @@ int glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname,
int glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr,
char **master, char **slave, char **host_uuid);
+int glusterd_op_get_max_opversion (char **op_errstr, dict_t *rsp_dict);
+
int glusterd_start_volume (glusterd_volinfo_t *volinfo, int flags,
gf_boolean_t wait);