summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/glfs-mgmt.c41
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c40
-rw-r--r--libglusterfs/src/globals.h18
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c72
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h17
5 files changed, 167 insertions, 21 deletions
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
index 2ead93863bc..a76692bfd06 100644
--- a/api/src/glfs-mgmt.c
+++ b/api/src/glfs-mgmt.c
@@ -477,6 +477,13 @@ out:
if (rsp.spec)
free (rsp.spec);
+ // Stop if server is running at an unsupported op-version
+ if (ENOTSUP == ret) {
+ gf_log ("mgmt", GF_LOG_ERROR, "Server is operating at an "
+ "op-version which is not supported");
+ glfs_init_done (fs, -1);
+ }
+
if (ret && ctx && !ctx->active) {
/* Do it only for the first time */
/* Failed to get the volume file, something wrong,
@@ -503,6 +510,7 @@ glfs_volfile_fetch (struct glfs *fs)
int ret = 0;
call_frame_t *frame = NULL;
glusterfs_ctx_t *ctx = NULL;
+ dict_t *dict = NULL;
ctx = fs->ctx;
cmd_args = &ctx->cmd_args;
@@ -512,10 +520,41 @@ glfs_volfile_fetch (struct glfs *fs)
req.key = cmd_args->volfile_id;
req.flags = 0;
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ // Set the supported min and max op-versions, so glusterd can make a
+ // decision
+ ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version"
+ " in request dict");
+ goto out;
+ }
+
+ ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version"
+ " in request dict");
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val,
+ &req.xdata.xdata_len);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to serialize dictionary");
+ goto out;
+ }
+
ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
GF_HNDSK_GETSPEC, mgmt_getspec_cbk,
(xdrproc_t)xdr_gf_getspec_req);
- return ret;
+out:
+ return ret;
}
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index 5bebdaf178c..8082ad3d1d4 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -1639,6 +1639,13 @@ out:
emancipate (ctx, ret);
+ // Stop if server is running at an unsupported op-version
+ if (ENOTSUP == ret) {
+ gf_log ("mgmt", GF_LOG_ERROR, "Server is operating at an "
+ "op-version which is not supported");
+ cleanup_and_exit (0);
+ }
+
if (ret && ctx && !ctx->active) {
/* Do it only for the first time */
/* Failed to get the volume file, something wrong,
@@ -1649,6 +1656,7 @@ out:
cleanup_and_exit (0);
}
+
if (tmpfp)
fclose (tmpfp);
@@ -1663,6 +1671,7 @@ glusterfs_volfile_fetch (glusterfs_ctx_t *ctx)
gf_getspec_req req = {0, };
int ret = 0;
call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
cmd_args = &ctx->cmd_args;
@@ -1671,9 +1680,40 @@ glusterfs_volfile_fetch (glusterfs_ctx_t *ctx)
req.key = cmd_args->volfile_id;
req.flags = 0;
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ // Set the supported min and max op-versions, so glusterd can make a
+ // decision
+ ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version"
+ " in request dict");
+ goto out;
+ }
+
+ ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version"
+ " in request dict");
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val,
+ &req.xdata.xdata_len);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to serialize dictionary");
+ goto out;
+ }
+
ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
GF_HNDSK_GETSPEC, mgmt_getspec_cbk,
(xdrproc_t)xdr_gf_getspec_req);
+out:
return ret;
}
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index e13902b2992..64a1594f5f8 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -13,6 +13,24 @@
#define GF_DEFAULT_BASE_PORT 24007
+#define GD_OP_VERSION_KEY "operating-version"
+#define GD_MIN_OP_VERSION_KEY "minimum-operating-version"
+#define GD_MAX_OP_VERSION_KEY "maximum-operating-version"
+
+/* Gluster versions - OP-VERSION mapping
+ *
+ * 3.3.0 - 1
+ * 3.3.Next/3.Next - 2
+ *
+ * TODO: Change above comment once gluster version is finalised
+ * TODO: Finalize the op-version ranges
+ */
+#define GD_OP_VERSION_MIN 1 /* MIN is the fresh start op-version, mostly
+ should not change */
+#define GD_OP_VERSION_MAX 2 /* MAX VERSION is the maximum count in VME table,
+ should keep changing with introduction of newer
+ versions */
+
#include "xlator.h"
/* THIS */
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 6a273df54b6..5b3299d549a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -124,7 +124,17 @@ server_getspec (rpcsvc_request_t *req)
gf_getspec_req args = {0,};
gf_getspec_rsp rsp = {0,};
char addrstr[RPCSVC_PEER_STRLEN] = {0};
+ dict_t *dict = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ int client_min_op_version = 0;
+ int client_max_op_version = 0;
+ this = THIS;
+ GF_ASSERT (this);
+
+ conf = this->private;
+ GF_ASSERT (conf);
ret = xdr_to_generic (req->msg[0], &args,
(xdrproc_t)xdr_gf_getspec_req);
@@ -134,6 +144,63 @@ server_getspec (rpcsvc_request_t *req)
goto fail;
}
+ if (!args.xdata.xdata_len) {
+ // For clients <= 3.3.0, only allow if op_version = 1
+ if (1 != conf->op_version) {
+ ret = -1;
+ op_errno = ENOTSUP;
+ gf_log (this->name, GF_LOG_INFO,
+ "Client %s doesn't support required op-version. "
+ "Rejecting getspec request.",
+ req->trans->peerinfo.identifier);
+ goto fail;
+ }
+ } else {
+ // For clients > 3.3, only allow if they can support
+ // clusters' op_version
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto fail;
+ }
+
+ ret = dict_unserialize (args.xdata.xdata_val,
+ args.xdata.xdata_len, &dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to unserialize request dictionary");
+ goto fail;
+ }
+
+ ret = dict_get_int32 (dict, "min-op-version",
+ &client_min_op_version);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get client-min-op-version");
+ goto fail;
+ }
+
+ ret = dict_get_int32 (dict, "max-op-version",
+ &client_max_op_version);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get client-max-op-version");
+ goto fail;
+ }
+
+ if ((client_min_op_version > conf->op_version) ||
+ (client_max_op_version < conf->op_version)) {
+ ret = -1;
+ op_errno = ENOTSUP;
+ //TODO: Add client identifier
+ gf_log (this->name, GF_LOG_INFO,
+ "Client %s doesn't support required op-version. "
+ "Rejecting getspec request.",
+ req->trans->peerinfo.identifier);
+ goto fail;
+ }
+ }
+
volume = args.key;
trans = req->trans;
@@ -387,7 +454,7 @@ glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
glusterd_conf_t *conf = NULL;
int ret = -1;
int op_errno = EINVAL;
- int32_t peer_op_version = 0;
+ int peer_op_version = 0;
gf_mgmt_hndsk_req args = {{0,},};
gf_mgmt_hndsk_rsp rsp = {0,};
@@ -406,8 +473,7 @@ glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
(args.hndsk.hndsk_len), ret, op_errno,
out);
- ret = dict_get_int32 (clnt_dict, GD_OP_VERSION_KEY,
- &peer_op_version);
+ ret = dict_get_int32 (clnt_dict, GD_OP_VERSION_KEY, &peer_op_version);
if (ret) {
gf_log (this->name, GF_LOG_WARNING,
"failed to get the op-version key peer=%s",
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index f7bfad697e8..95e23674c57 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -114,23 +114,6 @@ typedef struct {
gf_boolean_t online;
} nodesrv_t;
-#define GD_OP_VERSION_KEY "operating-version"
-#define GD_MIN_OP_VERSION_KEY "minimum-operating-version"
-#define GD_MAX_OP_VERSION_KEY "maxium-operating-version"
-
-/* Gluster versions - OP-VERSION mapping
- *
- * 3.3.0 - 1
- * 3.3.Next/3.Next - 2
- *
- * (TODO: Change above comment once gluster version is finalised)
- */
-#define GD_OP_VERSION_MIN 1 /* MIN is the fresh start op-version, mostly
- should not change */
-#define GD_OP_VERSION_MAX 2 /* MAX VERSION is the maximum count in VME table,
- should keep changing with introduction of newer
- versions */
-
typedef struct {
gf_boolean_t quorum;
double quorum_ratio;