diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-rpc-ops.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 142 |
1 files changed, 110 insertions, 32 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index 10d5d7f2752..19b66ac06d8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -214,25 +214,32 @@ int __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { - gd1_mgmt_probe_rsp rsp = {{0},}; - int ret = 0; - glusterd_peerinfo_t *peerinfo = NULL; - glusterd_friend_sm_event_t *event = NULL; - glusterd_probe_ctx_t *ctx = NULL; + gd1_mgmt_probe_rsp rsp = {{0},}; + int ret = 0; + glusterd_peerinfo_t *peerinfo = NULL; + glusterd_friend_sm_event_t *event = NULL; + glusterd_probe_ctx_t *ctx = NULL; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; if (-1 == req->rpc_status) { goto out; } + this = THIS; + GF_ASSERT (this != NULL); + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out); + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_probe_rsp); if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); + gf_log (this->name, GF_LOG_ERROR, "error"); //rsp.op_ret = -1; //rsp.op_errno = EINVAL; goto out; } - gf_log ("glusterd", GF_LOG_INFO, + gf_log (this->name, GF_LOG_INFO, "Received probe resp from uuid: %s, host: %s", uuid_utoa (rsp.uuid), rsp.hostname); if (rsp.op_ret != 0) { @@ -254,12 +261,82 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, ret = rsp.op_ret; goto out; } - ret = glusterd_friend_find (rsp.uuid, rsp.hostname, &peerinfo); - if (ret) { + + peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname); + if (peerinfo == NULL) { GF_ASSERT (0); } - if (strncasecmp (rsp.hostname, peerinfo->hostname, 1024)) { + /* + * In the case of a fresh probe rsp.uuid and peerinfo.uuid will not + * match, as peerinfo->uuid will be NULL. + * + * In the case of a peer probe being done to add a new network to a + * peer, rsp.uuid will match an existing peerinfo.uuid. If we have this + * stage it means that the current address/hostname being used isn't + * present in the found peerinfo. If it were, we would have found out + * earlier in the probe process and wouldn't even reach till here. So, + * we need to add the new hostname to the peer. + * + * This addition should only be done for cluster op-version >= + * GD_OP_VERSION_3_6_0 as address lists are only supported from then on. + * Also, this update should only be done when an explicit CLI probe + * command was used to begin the probe process. + */ + if ((conf->op_version >= GD_OP_VERSION_3_6_0) && + (uuid_compare (rsp.uuid, peerinfo->uuid) == 0)) { + ctx = ((call_frame_t *)myframe)->local; + /* Presence of ctx->req implies this probe was started by a cli + * probe command + */ + if (ctx->req == NULL) + goto cont; + + gf_log (this->name, GF_LOG_DEBUG, "Adding address '%s' to " + "existing peer %s", rsp.hostname, uuid_utoa (rsp.uuid)); + + ret = glusterd_friend_remove (NULL, rsp.hostname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Could not remove " + "stale peerinfo with name %s", rsp.hostname); + goto reply; + } + + ret = gd_add_address_to_peer (peerinfo, rsp.hostname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Couldn't add hostname to peer list"); + goto reply; + } + + /* Injecting LOCAL_ACC to send update */ + ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_LOCAL_ACC, + &event); + if (!ret) { + event->peerinfo = peerinfo; + ret = glusterd_friend_sm_inject_event (event); + } + rsp.op_errno = GF_PROBE_FRIEND; + +reply: + ctx = ((call_frame_t *)myframe)->local; + ((call_frame_t *)myframe)->local = NULL; + + GF_ASSERT (ctx); + + if (ctx->req) { + glusterd_xfer_cli_probe_resp (ctx->req, ret, + rsp.op_errno, + rsp.op_errstr, + ctx->hostname, ctx->port, + ctx->dict); + } + + glusterd_destroy_probe_ctx (ctx); + + goto out; + + } else if (strncasecmp (rsp.hostname, peerinfo->hostname, 1024)) { gf_log (THIS->name, GF_LOG_INFO, "Host: %s with uuid: %s " "already present in cluster with alias hostname: %s", rsp.hostname, uuid_utoa (rsp.uuid), peerinfo->hostname); @@ -283,7 +360,7 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, ret = rsp.op_ret; goto out; } - +cont: uuid_copy (peerinfo->uuid, rsp.uuid); ret = glusterd_friend_sm_new_event @@ -358,9 +435,9 @@ __glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov, "Received %s from uuid: %s, host: %s, port: %d", (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port); - ret = glusterd_friend_find (rsp.uuid, rsp.hostname, &peerinfo); - - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname); + if (peerinfo == NULL) { + ret = -1; gf_log ("", GF_LOG_ERROR, "received friend add response from" " unknown peer uuid: %s", uuid_utoa (rsp.uuid)); goto out; @@ -469,11 +546,11 @@ __glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov, (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port); inject: - ret = glusterd_friend_find (rsp.uuid, ctx->hostname, &peerinfo); - - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, ctx->hostname); + if (peerinfo == NULL) { //can happen as part of rpc clnt connection cleanup //when the frame timeout happens after 30 minutes + ret = -1; goto respond; } @@ -610,9 +687,9 @@ out: "Received lock %s from uuid: %s", (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid)); - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { + ret = -1; gf_log (this->name, GF_LOG_CRITICAL, "Lock response received " "from unknown peer: %s", uuid_utoa (rsp.uuid)); } @@ -687,8 +764,9 @@ glusterd_mgmt_v3_lock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov, "Received mgmt_v3 lock %s from uuid: %s", (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid)); - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { + ret = -1; gf_log (this->name, GF_LOG_CRITICAL, "mgmt_v3 lock response received " "from unknown peer: %s. Ignoring response", @@ -768,9 +846,9 @@ glusterd_mgmt_v3_unlock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov, (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid)); - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { + ret = -1; gf_log (this->name, GF_LOG_CRITICAL, "mgmt_v3 unlock response received " "from unknown peer: %s. Ignoring response", @@ -851,9 +929,8 @@ out: "Received unlock %s from uuid: %s", (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid)); - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { gf_log (this->name, GF_LOG_CRITICAL, "Unlock response received " "from unknown peer %s", uuid_utoa (rsp.uuid)); } @@ -959,11 +1036,12 @@ out: gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - if (ret) + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { gf_log (this->name, GF_LOG_CRITICAL, "Stage response received " "from unknown peer: %s. Ignoring response.", uuid_utoa (rsp.uuid)); + } if (op_ret) { event_type = GD_OP_EVENT_RCVD_RJT; @@ -1094,8 +1172,8 @@ __glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov, gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); - ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo); - if (ret) { + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { gf_log (this->name, GF_LOG_CRITICAL, "Commit response for " "'Volume %s' received from unknown peer: %s", gd_op_list[opinfo.op], uuid_utoa (rsp.uuid)); |