summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrishnan Parthasarathi <kp@gluster.com>2012-03-12 14:26:36 +0530
committerVijay Bellur <vijay@gluster.com>2012-03-12 05:19:23 -0700
commitc9322f64cc4b8c661cf282bf1a2b08e0d6567b16 (patch)
treef02f0eb625870eb310216dcb48a5ea145f4843ad
parente7d9f599ee52408819be649ef41ffc00c77e785e (diff)
glusterd: Peer(s) mustn't send updates about members not yet in cluster
Also, peerinfo is added to peers list synchoronous with the request triggering it. This ensures that atmost one request sees that the peer (in question) is not in peers list. Earlier, 'concurrent' handle_friend_update requests would see that a particular peer is not in the peers list yet, as the addition of the 'peer' into the list happened asynchronously, on the 'connect' event of the 'peer'. Change-Id: I6f017fb43079862fbe5ae7db8f9f4e4fefaa091d BUG: 801731 Signed-off-by: Krishnan Parthasarathi <kp@gluster.com> Reviewed-on: http://review.gluster.com/2918 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amarts@redhat.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c33
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c21
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c6
3 files changed, 41 insertions, 19 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index f446d2b58c5..6138b592542 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -1667,6 +1667,12 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
gf_log ("", GF_LOG_INFO, "Received uuid: %s, hostname:%s",
uuid_buf, hostname);
+ if (uuid_is_null (uuid)) {
+ gf_log (this->name, GF_LOG_WARNING, "Updates mustn't "
+ "contain peer with 'null' uuid");
+ continue;
+ }
+
if (!uuid_compare (uuid, priv->uuid)) {
gf_log ("", GF_LOG_INFO, "Received my uuid as Friend");
i++;
@@ -2129,12 +2135,14 @@ glusterd_friend_add (const char *hoststr, int port,
glusterd_peerctx_args_t *args)
{
int ret = 0;
+ xlator_t *this = NULL;
glusterd_conf_t *conf = NULL;
glusterd_peerctx_t *peerctx = NULL;
dict_t *options = NULL;
gf_boolean_t handover = _gf_false;
- conf = THIS->private;
+ this = THIS;
+ conf = this->private;
GF_ASSERT (conf);
GF_ASSERT (hoststr);
@@ -2158,11 +2166,21 @@ glusterd_friend_add (const char *hoststr, int port,
if (ret)
goto out;
+ if (!restore) {
+ ret = glusterd_store_peerinfo (*friend);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to store "
+ "peerinfo");
+
+ goto out;
+ }
+ }
+ list_add_tail (&(*friend)->uuid_list, &conf->peers);
ret = glusterd_rpc_create (&(*friend)->rpc, options,
glusterd_peer_rpc_notify,
peerctx);
if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "failed to create rpc for"
+ gf_log (this->name, GF_LOG_ERROR, "failed to create rpc for"
" peer %s", (char*)hoststr);
goto out;
}
@@ -2174,7 +2192,7 @@ out:
*friend = NULL;
}
- gf_log ("glusterd", GF_LOG_INFO, "connect returned %d", ret);
+ gf_log (this->name, GF_LOG_INFO, "connect returned %d", ret);
return ret;
}
@@ -2831,15 +2849,6 @@ glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata,
{
gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
peerinfo->connected = 1;
- ret = glusterd_store_peerinfo (peerinfo);
- if (ret) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Failed to store "
- "peerinfo");
- break;
- }
-
- list_add_tail (&peerinfo->uuid_list, &conf->peers);
ret = glusterd_peer_handshake (this, rpc, peerctx);
if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index 4e55c383c47..648ab418d15 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -488,21 +488,30 @@ int32_t
glusterd3_1_friend_update_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- int ret = -1;
- int32_t op_ret = 0;
- char str[50] = {0,};
+ int ret = -1;
+ gd1_mgmt_friend_update_rsp rsp = {{0}, };
+ xlator_t *this = NULL;
GF_ASSERT (req);
+ this = THIS;
if (-1 == req->rpc_status) {
+ gf_log (this->name, GF_LOG_ERROR, "RPC Error");
goto out;
}
- gf_log ("glusterd", GF_LOG_INFO,
- "Received %s from uuid: %s",
- (op_ret)?"RJT":"ACC", str);
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to serialize friend"
+ " update repsonse");
+ goto out;
+ }
out:
+ gf_log (this->name, GF_LOG_INFO, "Received %s from uuid: %s",
+ (ret)?"RJT":"ACC", uuid_utoa (rsp.uuid));
+
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index 259c247f401..a53057fab44 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -478,6 +478,9 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
goto out;
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
+ if (!peerinfo->connected || !peerinfo->peer ||
+ peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
+ continue;
count++;
snprintf (key, sizeof (key), "friend%d.uuid", count);
dup_buf = gf_strdup (uuid_utoa (peerinfo->uuid));
@@ -497,7 +500,8 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
goto out;
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- if (!peerinfo->connected || !peerinfo->peer)
+ if (!peerinfo->connected || !peerinfo->peer ||
+ peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
continue;
ret = dict_set_static_ptr (friends, "peerinfo", peerinfo);