summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaushal M <kaushal@redhat.com>2013-01-21 12:49:44 +0530
committerAnand Avati <avati@redhat.com>2013-02-06 12:17:49 -0800
commitd831290debf7cc5741c30233d05aa18c9a59e99e (patch)
treeff492ca6dba52df1f819c634c0fa74fef6002fc4
parent02d653931c8967accf766014efce0c2dce340cdf (diff)
glusterd: Use client-op-versions during "volume set"
The supported op-versions of the client and the name of the requested volume, are saved during server_getspec(). These are used during the staging of volume set. If the option being set is not supported by any of the clients which currently have the volume mounted, then set will fail. Change-Id: I4e6b60b274d5200508762dc0204cfa848a6c0aa4 BUG: 907311 Signed-off-by: Kaushal M <kaushal@redhat.com> Reviewed-on: http://review.gluster.org/4424 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amarts@redhat.com> Reviewed-by: Anand Avati <avati@redhat.com>
-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 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);