diff options
-rw-r--r-- | rpc/rpc-lib/src/rpc-transport.h | 5 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 16 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 45 |
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 91d802220e2..272de9d7ddc 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 5b3299d549a..8b964702669 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 ea2aa0e21db..26e61b4f61c 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); |