summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rpc/rpc-lib/src/rpc-transport.h5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c45
3 files changed, 64 insertions, 2 deletions
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
index 91d802220..272de9d7d 100644
--- a/rpc/rpc-lib/src/rpc-transport.h
+++ b/rpc/rpc-lib/src/rpc-transport.h
@@ -71,6 +71,11 @@ struct peer_info {
struct sockaddr_storage sockaddr;
socklen_t sockaddr_len;
char identifier[UNIX_PATH_MAX];
+ // OP-VERSION of clients
+ uint32_t max_op_version;
+ uint32_t min_op_version;
+ //Volume mounted by client
+ char volname[1024];
};
typedef struct peer_info peer_info_t;
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 5b3299d54..8b9647026 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -127,8 +127,8 @@ server_getspec (rpcsvc_request_t *req)
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;
+ int client_min_op_version = 1; // OP-VERSIONs start at 1
+ int client_max_op_version = 1;
this = THIS;
GF_ASSERT (this);
@@ -199,10 +199,22 @@ server_getspec (rpcsvc_request_t *req)
req->trans->peerinfo.identifier);
goto fail;
}
+
}
+ // Store the op-versions supported by the client
+ req->trans->peerinfo.max_op_version = client_max_op_version;
+ req->trans->peerinfo.min_op_version = client_min_op_version;
+
volume = args.key;
+ // Store the name of volume being mounted
+ if (volume[0] == '/')
+ strncpy (req->trans->peerinfo.volname, &volume[1],
+ strlen(&volume[1]));
+ else
+ strncpy (req->trans->peerinfo.volname, volume, strlen(volume));
+
trans = req->trans;
ret = rpcsvc_transport_peername (trans, (char *)&addrstr,
sizeof (addrstr));
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index ea2aa0e21..26e61b4f6 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -339,6 +339,44 @@ out:
}
static int
+glusterd_check_client_op_version_support (char *volname, uint32_t op_version,
+ char **op_errstr)
+{
+ int ret = 0;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ rpc_transport_t *xprt = NULL;
+
+ this = THIS;
+ GF_ASSERT(this);
+ priv = this->private;
+ GF_ASSERT(priv);
+
+ pthread_mutex_lock (&priv->xprt_lock);
+ list_for_each_entry (xprt, &priv->xprt_list, list) {
+ if ((!strcmp(volname, xprt->peerinfo.volname)) &&
+ ((op_version > xprt->peerinfo.max_op_version) ||
+ (op_version < xprt->peerinfo.min_op_version))) {
+ ret = -1;
+ break;
+ }
+ }
+ pthread_mutex_unlock (&priv->xprt_lock);
+
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "One or more clients "
+ "don't support the required op-version");
+ ret = gf_asprintf (op_errstr, "One or more connected clients "
+ "cannot support the feature being set. "
+ "These clients need to be upgraded or "
+ "disconnected before running this command"
+ " again");
+ return -1;
+ }
+ return 0;
+}
+
+static int
glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
{
int ret = -1;
@@ -622,6 +660,13 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
}
}
+ // Check if all the connected clients support the new op-version
+ ret = glusterd_check_client_op_version_support (volname,
+ local_new_op_version,
+ op_errstr);
+ if (ret)
+ goto out;
+
if (origin_glusterd) {
ret = dict_set_uint32 (dict, "new-op-version",
local_new_op_version);