summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-rpc-ops.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c142
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));