From c109ffb893ab80dd7b9dac038f5778961859ceff Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Wed, 15 Sep 2010 06:49:56 +0000 Subject: cli, mgmt/glusterd: disallow probe to a cluster Signed-off-by: Pranith Kumar K Signed-off-by: Vijay Bellur BUG: 1594 (make probe oneway) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1594 --- 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(-) diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index 7e0e2103177..a3c0a2518cd 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 8f79a03a465..c18f468c20b 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 0c2d6d8178f..17c66d9a374 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 7c9038dcfc4..fce8b87cb63 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 fe7c44eb29f..74e4d9d7656 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 a4f7b8558f7..ad6d32219e2 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 a069e0ec582..102cc01c98f 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) @@ -2391,6 +2413,22 @@ out: return ret; } +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, @@ -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 b1dc1ddac85..602494b1412 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 4ef0bd17bc2..845fcbbe9ad 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 18364281119..19ca43fa190 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 708080a1365..e888b7c9dd4 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 a9dfa6d411b..9435099906c 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 03e0ec44266..9b9873cfe85 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"); -- cgit