Patchwork [BUG:1594] cli, mgmt/glusterd: disallow probe to a cluster

login
register
Submitter Pranith K
Date 2010-09-15 12:19:56
Message ID <20100915121956.GA22870@dev.gluster.com>
Download mbox | patch
Permalink /patch/4804/
State Accepted
Headers show

Comments

Pranith K - 2010-09-15 12:19:56
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
---
 cli/src/cli3_1-cops.c                        |   42 ++++++++++++++----
 rpc/rpc-lib/src/protocol-common.h            |    1 +
 rpc/rpc-transport/socket/src/socket.c        |    2 +-
 rpc/xdr/src/glusterd1-xdr.c                  |   61 +++++++++++++++++++++++--
 rpc/xdr/src/glusterd1-xdr.h                  |   12 +++--
 rpc/xdr/src/glusterd1.x                      |    3 +
 xlators/mgmt/glusterd/src/glusterd-handler.c |   60 +++++++++++++++++++++----
 xlators/mgmt/glusterd/src/glusterd-sm.c      |   29 +-----------
 xlators/mgmt/glusterd/src/glusterd-utils.c   |   27 +++++++++++-
 xlators/mgmt/glusterd/src/glusterd-utils.h   |    3 +
 xlators/mgmt/glusterd/src/glusterd.h         |    2 +
 xlators/mgmt/glusterd/src/glusterd3_1-mops.c |   15 ++++++-
 xlators/protocol/client/src/client.c         |    2 +-
 13 files changed, 199 insertions(+), 60 deletions(-)

Patch

diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c
index 7e0e210..a3c0a25 100644
--- a/cli/src/cli3_1-cops.c
+++ b/cli/src/cli3_1-cops.c
@@ -90,11 +90,22 @@  gf_cli3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
 		      		break;
 	 	}
 	 }
-	 if (rsp.op_ret) {
-		 cli_out ("Probe unsuccessfull"); 		
-		 gf_log ("glusterd",GF_LOG_ERROR,"Probe failed with op_ret %d"
-			 " and op_errno %d", rsp.op_ret, rsp.op_errno);
-	 }
+
+        if (rsp.op_ret) {
+                switch (rsp.op_errno) {
+                        case GF_PROBE_ANOTHER_CLUSTER:
+                                cli_out ("%s is already part of "
+                                         "another cluster", rsp.hostname);
+                                break;
+                        default:
+                                cli_out ("Probe returned with unknown errno %d",
+                                        rsp.op_errno);
+                                break;
+                }
+                cli_out ("Probe unsuccessful");
+                gf_log ("glusterd",GF_LOG_ERROR,"Probe failed with op_ret %d"
+                        " and op_errno %d", rsp.op_ret, rsp.op_errno);
+        }
         ret = rsp.op_ret;
 
 out:
@@ -145,6 +156,8 @@  gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
         char                       key[256] = {0,};
         int32_t                    state = 0;
         int32_t                    port = 0;
+        int32_t                    connected = 0;
+        char                       *connected_str = NULL;
 
         if (-1 == req->rpc_status) {
                 goto out;
@@ -208,6 +221,15 @@  gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
                         if (ret)
                                 goto out;
 
+                        snprintf (key, 256, "friend%d.connected", i);
+                        ret = dict_get_int32 (dict, key, &connected);
+                        if (ret)
+                                goto out;
+                        if (connected)
+                                connected_str = "connected";
+                        else
+                                connected_str = "disconnected";
+
                         snprintf (key, 256, "friend%d.port", i);
                         ret = dict_get_int32 (dict, key, &port);
                         if (ret)
@@ -219,11 +241,13 @@  gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
                                 goto out;
 
                         if (!port) {
-                                cli_out ("hostname:%s, uuid:%s, state:%d",
-                                         hostname_buf, uuid_buf, state);
+                                cli_out ("hostname:%s, uuid:%s, state:%d (%s)",
+                                         hostname_buf, uuid_buf, state,
+                                         connected_str);
                         } else {
-                                cli_out ("hostname:%s, port:%d, uuid:%s, state:%d",
-                                         hostname_buf, port, uuid_buf, state);
+                                cli_out ("hostname:%s, port:%d, uuid:%s, "
+                                         "state:%d, (%s)", hostname_buf, port,
+                                         uuid_buf, state, connected_str);
                         }
                         i++;
                 }
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index 8f79a03..c18f468 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -145,6 +145,7 @@  enum gf_probe_resp {
 	GF_PROBE_SUCCESS,
 	GF_PROBE_LOCALHOST,
 	GF_PROBE_FRIEND,
+        GF_PROBE_ANOTHER_CLUSTER
 };
 
 enum gf_cbk_procnum {
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c
index ca3505d..3c5638e 100644
--- a/rpc/rpc-transport/socket/src/socket.c
+++ b/rpc/rpc-transport/socket/src/socket.c
@@ -1696,7 +1696,7 @@  socket_event_handler (int fd, int idx, void *data,
         if ((ret < 0) || poll_err) {
                 gf_log ("transport", GF_LOG_TRACE, "disconnecting now");
                 socket_event_poll_err (this);
-                rpc_transport_unref (this);
+                //rpc_transport_unref (this);
         }
 
 out:
diff --git a/rpc/xdr/src/glusterd1-xdr.c b/rpc/xdr/src/glusterd1-xdr.c
index 7c9038d..fce8b87 100644
--- a/rpc/xdr/src/glusterd1-xdr.c
+++ b/rpc/xdr/src/glusterd1-xdr.c
@@ -27,6 +27,7 @@ 
 bool_t
 xdr_glusterd_volume_status (XDR *xdrs, glusterd_volume_status *objp)
 {
+
 	 if (!xdr_enum (xdrs, (enum_t *) objp))
 		 return FALSE;
 	return TRUE;
@@ -57,6 +58,10 @@  xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp)
 		 return FALSE;
 	 if (!xdr_int (xdrs, &objp->port))
 		 return FALSE;
+	 if (!xdr_int (xdrs, &objp->op_ret))
+		 return FALSE;
+	 if (!xdr_int (xdrs, &objp->op_errno))
+		 return FALSE;
 	return TRUE;
 }
 
@@ -192,6 +197,52 @@  bool_t
 xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp)
 {
 
+        register int32_t *buf;
+
+	if (xdrs->x_op == XDR_ENCODE) {
+		 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
+			sizeof (u_char), (xdrproc_t) xdr_u_char))
+			 return FALSE;
+		buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+		if (buf == NULL) {
+			 if (!xdr_int (xdrs, &objp->op))
+				 return FALSE;
+			 if (!xdr_int (xdrs, &objp->op_ret))
+				 return FALSE;
+			 if (!xdr_int (xdrs, &objp->op_errno))
+				 return FALSE;
+
+		} else {
+		IXDR_PUT_LONG(buf, objp->op);
+		IXDR_PUT_LONG(buf, objp->op_ret);
+		IXDR_PUT_LONG(buf, objp->op_errno);
+		}
+		 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+			 return FALSE;
+		return TRUE;
+	} else if (xdrs->x_op == XDR_DECODE) {
+		 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
+			sizeof (u_char), (xdrproc_t) xdr_u_char))
+			 return FALSE;
+		buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+		if (buf == NULL) {
+			 if (!xdr_int (xdrs, &objp->op))
+				 return FALSE;
+			 if (!xdr_int (xdrs, &objp->op_ret))
+				 return FALSE;
+			 if (!xdr_int (xdrs, &objp->op_errno))
+				 return FALSE;
+
+		} else {
+		objp->op = IXDR_GET_LONG(buf);
+		objp->op_ret = IXDR_GET_LONG(buf);
+		objp->op_errno = IXDR_GET_LONG(buf);
+		}
+		 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+			 return FALSE;
+	 return TRUE;
+	}
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -225,6 +276,7 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 {
 	register int32_t *buf;
 
+
 	if (xdrs->x_op == XDR_ENCODE) {
 		 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 			sizeof (u_char), (xdrproc_t) xdr_u_char))
@@ -237,8 +289,6 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 				 return FALSE;
 			 if (!xdr_int (xdrs, &objp->op_errno))
 				 return FALSE;
-			 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
-				 return FALSE;
 
 		} else {
 		IXDR_PUT_LONG(buf, objp->op);
@@ -247,6 +297,8 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 		}
 		 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
 			 return FALSE;
+		 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+			 return FALSE;
 		return TRUE;
 	} else if (xdrs->x_op == XDR_DECODE) {
 		 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
@@ -260,8 +312,6 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 				 return FALSE;
 			 if (!xdr_int (xdrs, &objp->op_errno))
 				 return FALSE;
-			 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
-				 return FALSE;
 
 		} else {
 		objp->op = IXDR_GET_LONG(buf);
@@ -270,6 +320,8 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 		}
 		 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
 			 return FALSE;
+		 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
+			 return FALSE;
 	 return TRUE;
 	}
 
@@ -286,7 +338,6 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 		 return FALSE;
 	 if (!xdr_string (xdrs, &objp->op_errstr, ~0))
 		 return FALSE;
-
 	return TRUE;
 }
 
diff --git a/rpc/xdr/src/glusterd1-xdr.h b/rpc/xdr/src/glusterd1-xdr.h
index fe7c44e..74e4d9d 100644
--- a/rpc/xdr/src/glusterd1-xdr.h
+++ b/rpc/xdr/src/glusterd1-xdr.h
@@ -52,6 +52,8 @@  struct gd1_mgmt_probe_rsp {
 	u_char uuid[16];
 	char *hostname;
 	int port;
+	int op_ret;
+	int op_errno;
 };
 typedef struct gd1_mgmt_probe_rsp gd1_mgmt_probe_rsp;
 
@@ -149,11 +151,11 @@  struct gd1_mgmt_commit_op_rsp {
 	int op;
 	int op_ret;
 	int op_errno;
-        struct {
-                u_int dict_len;
-                char *dict_val;
-        } dict;
-        char *op_errstr;
+	struct {
+		u_int dict_len;
+		char *dict_val;
+	} dict;
+	char *op_errstr;
 };
 typedef struct gd1_mgmt_commit_op_rsp gd1_mgmt_commit_op_rsp;
 
diff --git a/rpc/xdr/src/glusterd1.x b/rpc/xdr/src/glusterd1.x
index a4f7b85..ad6d322 100644
--- a/rpc/xdr/src/glusterd1.x
+++ b/rpc/xdr/src/glusterd1.x
@@ -14,6 +14,8 @@ 
         unsigned char  uuid[16];
         string  hostname<>;
         int     port;
+        int     op_ret;
+        int     op_errno;
 }  ;
 
 struct gd1_mgmt_friend_req {
@@ -92,6 +94,7 @@  struct gd1_mgmt_commit_op_rsp {
         int     op;
         int     op_ret;
         int     op_errno;
+        opaque  dict<>;
         string  op_errstr<>;
 }  ;
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index a069e0e..102cc01 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -103,6 +103,9 @@  glusterd_friend_find_by_uuid (uuid_t uuid,
 
         GF_ASSERT (priv);
 
+        if (uuid_is_null (uuid))
+                return -1;
+
         list_for_each_entry (entry, &priv->peers, uuid_list) {
                 if (!uuid_compare (entry->uuid, uuid)) {
 
@@ -285,6 +288,11 @@  glusterd_add_peer_detail_to_dict (glusterd_peerinfo_t   *peerinfo,
         if (ret)
                 goto out;
 
+        snprintf (key, 256, "friend%d.connected", count);
+        ret = dict_set_int32 (friends, key, (int32_t)peerinfo->connected);
+        if (ret)
+                goto out;
+
 out:
         return ret;
 }
@@ -2349,6 +2357,8 @@  glusterd_handle_probe_query (rpcsvc_request_t *req)
         gd1_mgmt_probe_req  probe_req = {{0},};
         gd1_mgmt_probe_rsp  rsp = {{0},};
         glusterd_peer_hostname_t        *name = NULL;
+        glusterd_peerinfo_t             *peerinfo = NULL;
+        char               remote_hostname[UNIX_PATH_MAX + 1] = {0,};
 
         GF_ASSERT (req);
 
@@ -2367,23 +2377,35 @@  glusterd_handle_probe_query (rpcsvc_request_t *req)
         gf_log ("glusterd", GF_LOG_NORMAL,
                 "Received probe from uuid: %s", str);
 
-        ret = glusterd_peer_hostname_new (probe_req.hostname, &name);
-
+        ret = glusterd_remote_hostname_get (req, remote_hostname,
+                                            sizeof (remote_hostname));
         if (ret) {
-                gf_log ("", GF_LOG_ERROR, "Unable to get new peer_hostname");
-        } else {
-                list_add_tail (&name->hostname_list, &conf->hostnames);
+                GF_ASSERT (0);
+                goto out;
         }
+        ret = glusterd_friend_find (NULL, remote_hostname, &peerinfo);
+        if ((ret == 0 ) || list_empty (&conf->peers)) {
+                ret = glusterd_peer_hostname_new (probe_req.hostname, &name);
 
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR, "Unable to get new peer_hostname");
+                } else {
+                        list_add_tail (&name->hostname_list, &conf->hostnames);
+                }
+                uuid_copy (rsp.uuid, conf->uuid);
+        } else {
+                rsp.op_ret = -1;
+                rsp.op_errno = GF_PROBE_ANOTHER_CLUSTER;
+        }
 
-        uuid_copy (rsp.uuid, conf->uuid);
         rsp.hostname = probe_req.hostname;
 
         ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
                                      gd_xdr_serialize_mgmt_probe_rsp);
 
-        gf_log ("glusterd", GF_LOG_NORMAL,
-                "Responded to %s, ret: %d", probe_req.hostname, ret);
+        gf_log ("glusterd", GF_LOG_NORMAL, "Responded to %s, op_ret: %d, "
+                "op_errno: %d, ret: %d", probe_req.hostname,
+                rsp.op_ret, rsp.op_errno, ret);
 
 out:
         if (probe_req.hostname)
@@ -2392,6 +2414,22 @@  out:
 }
 
 int
+glusterd_friend_remove (uuid_t uuid, char *hostname)
+{
+        int                           ret = 0;
+        glusterd_peerinfo_t           *peerinfo = NULL;
+
+        ret = glusterd_friend_find (uuid, hostname, &peerinfo);
+        if (ret)
+                goto out;
+
+        ret = glusterd_friend_cleanup (peerinfo);
+out:
+        gf_log ("", GF_LOG_DEBUG, "returning %d");
+        return ret;
+}
+
+int
 glusterd_friend_add (const char *hoststr, int port,
                      glusterd_friend_sm_state_t state,
                      uuid_t *uuid,
@@ -2665,6 +2703,8 @@  glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port,
 
         gf_log ("glusterd", GF_LOG_NORMAL,
                 "Responded to %s (%d), ret: %d", hostname, port, ret);
+        if (rsp.hostname)
+                GF_FREE (rsp.hostname)
         return ret;
 }
 
@@ -3169,7 +3209,7 @@  glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
         case RPC_CLNT_CONNECT:
         {
 
-                gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
+                gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
                 peerinfo->connected = 1;
                 glusterd_friend_sm ();
                 glusterd_op_sm ();
@@ -3188,7 +3228,7 @@  glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
 
                 //Inject friend disconnected here
 
-                gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
+                gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT");
                 peerinfo->connected = 0;
 
                 //default_notify (this, GF_EVENT_CHILD_DOWN, NULL);
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index b1dc1dd..602494b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -296,7 +296,7 @@  glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event,
         ret = glusterd_xfer_friend_remove_resp (ev_ctx->req, ev_ctx->hostname,
                                                 ev_ctx->port);
 
-        rpc_clnt_destroy (peerinfo->rpc);
+        peerinfo->rpc = rpc_clnt_unref (peerinfo->rpc);
         peerinfo->rpc = NULL;
 
         ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_REMOVE_FRIEND,
@@ -340,31 +340,6 @@  glusterd_ac_none (void *ctx)
         return ret;
 }*/
 
-int
-glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
-{
-        GF_ASSERT (req);
-        GF_ASSERT (remote_host);
-        GF_ASSERT (req->trans);
-
-        char *name = NULL;
-        char *delimiter = NULL;
-
-        name = req->trans->peerinfo.identifier;
-        strncpy (remote_host, name, len);
-        delimiter = strchr (remote_host, ':');
-
-        GF_ASSERT (delimiter);
-        if (!delimiter) {
-                memset (remote_host, 0, len);
-                return -1;
-        }
-
-        *delimiter = '\0';
-
-        return 0;
-}
-
 static int
 glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
 {
@@ -377,7 +352,7 @@  glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
         glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
         int                             status = 0;
         int32_t                         op_ret = -1;
-        char                            remote_hostname[UNIX_PATH_MAX + 1] = {0,};
+        char               remote_hostname[UNIX_PATH_MAX + 1] = {0,};
 
         GF_ASSERT (ctx);
         ev_ctx = ctx;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 4ef0bd1..845fcbb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -729,7 +729,7 @@  glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo)
 {
         GF_ASSERT (peerinfo);
         if (peerinfo->rpc) {
-                rpc_clnt_destroy (peerinfo->rpc);
+                peerinfo->rpc = rpc_clnt_unref (peerinfo->rpc);
                 peerinfo->rpc = NULL;
         }
         glusterd_peer_destroy (peerinfo);
@@ -1696,3 +1696,28 @@  glusterd_are_all_volumes_stopped ()
 
 }
 
+int
+glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
+{
+        GF_ASSERT (req);
+        GF_ASSERT (remote_host);
+        GF_ASSERT (req->trans);
+
+        char *name = NULL;
+        char *delimiter = NULL;
+
+        name = req->trans->peerinfo.identifier;
+        strncpy (remote_host, name, len);
+        delimiter = strchr (remote_host, ':');
+
+        GF_ASSERT (delimiter);
+        if (!delimiter) {
+                memset (remote_host, 0, len);
+                return -1;
+        }
+
+        *delimiter = '\0';
+
+        return 0;
+}
+
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 1836428..19ca43f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -142,4 +142,7 @@  glusterd_file_copy (int out, int in);
 gf_boolean_t
 glusterd_are_all_volumes_stopped ();
 
+int
+glusterd_remote_hostname_get (rpcsvc_request_t *req,
+                              char *remote_host, int len);
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 708080a..e888b7c 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -238,6 +238,8 @@  glusterd_friend_add (const char *hoststr, int port,
                      glusterd_peerinfo_t **friend,
                      gf_boolean_t restore);
 
+int
+glusterd_friend_remove (uuid_t uuid, char *hostname);
 
 int
 glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status);
diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
index a9dfa6d..9435099 100644
--- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
+++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
@@ -60,6 +60,7 @@  glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
         glusterd_peerinfo_t           *dup_peerinfo = NULL;
         glusterd_friend_sm_event_t    *event = NULL;
         glusterd_peer_hostname_t      *name = NULL;
+        glusterd_probe_ctx_t          *ctx = NULL;
 
         conf  = THIS->private;
 
@@ -79,9 +80,20 @@  glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
         gf_log ("glusterd", GF_LOG_NORMAL,
                 "Received probe resp from uuid: %s, host: %s",
                 str, rsp.hostname);
+        if (rsp.op_ret != 0) {
+                ctx = ((call_frame_t *)myframe)->local;
+                ((call_frame_t *)myframe)->local = NULL;
 
-        ret = glusterd_friend_find (rsp.uuid, rsp.hostname, &peerinfo);
+                GF_ASSERT (ctx);
 
+                glusterd_xfer_cli_probe_resp (ctx->req, rsp.op_ret,
+                                              rsp.op_errno,
+                                              ctx->hostname, ctx->port);
+                ret = rsp.op_ret;
+                (void) glusterd_friend_remove (rsp.uuid, rsp.hostname);
+                goto out;
+        }
+        ret = glusterd_friend_find (rsp.uuid, rsp.hostname, &peerinfo);
         if (ret) {
                 GF_ASSERT (0);
         }
@@ -93,6 +105,7 @@  glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
                 glusterd_peer_hostname_new (rsp.hostname, &name);
                 list_add_tail (&name->hostname_list, &peerinfo->hostnames);
                 peerinfo->rpc = dup_peerinfo->rpc;
+                peerinfo->connected = dup_peerinfo->connected;
                 glusterd_peer_destroy  (dup_peerinfo);
         }
         if (!peerinfo->hostname)
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
index 03e0ec4..9b9873c 100644
--- a/xlators/protocol/client/src/client.c
+++ b/xlators/protocol/client/src/client.c
@@ -1697,7 +1697,7 @@  client_destroy_rpc (xlator_t *this)
         conf = this->private;
 
         if (conf->rpc) {
-                rpc_clnt_destroy (conf->rpc);
+                conf->rpc = rpc_clnt_unref (conf->rpc);
                 ret = 0;
                 gf_log (this->name, GF_LOG_DEBUG,
                         "Client rpc conn destroyed");