diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-handler.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 310 |
1 files changed, 139 insertions, 171 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index e10dc22b56b..8e4071221de 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -101,9 +101,9 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, port = GF_DEFAULT_BASE_PORT; ret = glusterd_remote_hostname_get (req, rhost, sizeof (rhost)); - ret = glusterd_friend_find (uuid, rhost, &peerinfo); + peerinfo = glusterd_peerinfo_find (uuid, rhost); - if (ret) { + if (peerinfo == NULL) { ret = glusterd_xfer_friend_add_resp (req, hostname, rhost, port, -1, GF_PROBE_UNKNOWN_PEER); if (friend_req->vols.vols_val) { @@ -196,9 +196,9 @@ glusterd_handle_unfriend_req (rpcsvc_request_t *req, uuid_t uuid, if (!port) port = GF_DEFAULT_BASE_PORT; - ret = glusterd_friend_find (uuid, hostname, &peerinfo); + peerinfo = glusterd_peerinfo_find (uuid, hostname); - if (ret) { + if (peerinfo == NULL) { gf_log ("glusterd", GF_LOG_CRITICAL, "Received remove-friend from unknown peer %s", hostname); @@ -252,54 +252,6 @@ out: return ret; } -static int -glusterd_add_peer_detail_to_dict (glusterd_peerinfo_t *peerinfo, - dict_t *friends, int count) -{ - - int ret = -1; - char key[256] = {0, }; - char *peer_uuid_str = NULL; - - GF_ASSERT (peerinfo); - GF_ASSERT (friends); - - snprintf (key, 256, "friend%d.uuid", count); - peer_uuid_str = gd_peer_uuid_str (peerinfo); - ret = dict_set_str (friends, key, peer_uuid_str); - if (ret) - goto out; - - snprintf (key, 256, "friend%d.hostname", count); - ret = dict_set_str (friends, key, peerinfo->hostname); - if (ret) - goto out; - - snprintf (key, 256, "friend%d.port", count); - ret = dict_set_int32 (friends, key, peerinfo->port); - if (ret) - goto out; - - snprintf (key, 256, "friend%d.stateId", count); - ret = dict_set_int32 (friends, key, peerinfo->state.state); - if (ret) - goto out; - - snprintf (key, 256, "friend%d.state", count); - ret = dict_set_str (friends, key, - glusterd_friend_sm_state_name_get(peerinfo->state.state)); - 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; -} - struct args_pack { dict_t *dict; int vol_count; @@ -561,44 +513,6 @@ out: return ret; } -int -glusterd_friend_find (uuid_t uuid, char *hostname, - glusterd_peerinfo_t **peerinfo) -{ - int ret = -1; - xlator_t *this = NULL; - - this = THIS; - GF_ASSERT (this); - - if (uuid) { - ret = glusterd_friend_find_by_uuid (uuid, peerinfo); - - if (ret) { - gf_log (this->name, GF_LOG_DEBUG, - "Unable to find peer by uuid: %s", - uuid_utoa (uuid)); - } else { - goto out; - } - - } - - if (hostname) { - ret = glusterd_friend_find_by_hostname (hostname, peerinfo); - - if (ret) { - gf_log (this->name, GF_LOG_DEBUG, - "Unable to find hostname: %s", hostname); - } else { - goto out; - } - } - -out: - return ret; -} - int32_t glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, char *err_str, size_t err_len) @@ -752,7 +666,6 @@ __glusterd_handle_cluster_lock (rpcsvc_request_t *req) gd1_mgmt_cluster_lock_req lock_req = {{0},}; glusterd_op_lock_ctx_t *ctx = NULL; glusterd_op_t op = GD_OP_EVENT_LOCK; - glusterd_peerinfo_t *peerinfo = NULL; glusterd_op_info_t txn_op_info = {{0},}; glusterd_conf_t *priv = NULL; uuid_t *txn_id = NULL; @@ -778,7 +691,7 @@ __glusterd_handle_cluster_lock (rpcsvc_request_t *req) gf_log (this->name, GF_LOG_DEBUG, "Received LOCK from uuid: %s", uuid_utoa (lock_req.uuid)); - if (glusterd_friend_find_by_uuid (lock_req.uuid, &peerinfo)) { + if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (lock_req.uuid)); @@ -891,7 +804,6 @@ __glusterd_handle_stage_op (rpcsvc_request_t *req) int32_t ret = -1; glusterd_req_ctx_t *req_ctx = NULL; gd1_mgmt_stage_op_req op_req = {{0},}; - glusterd_peerinfo_t *peerinfo = NULL; xlator_t *this = NULL; uuid_t *txn_id = NULL; glusterd_op_info_t txn_op_info = {{0},}; @@ -927,7 +839,7 @@ __glusterd_handle_stage_op (rpcsvc_request_t *req) gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s", uuid_utoa (*txn_id)); - if (glusterd_friend_find_by_uuid (op_req.uuid, &peerinfo)) { + if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (op_req.uuid)); @@ -982,7 +894,6 @@ __glusterd_handle_commit_op (rpcsvc_request_t *req) int32_t ret = -1; glusterd_req_ctx_t *req_ctx = NULL; gd1_mgmt_commit_op_req op_req = {{0},}; - glusterd_peerinfo_t *peerinfo = NULL; xlator_t *this = NULL; uuid_t *txn_id = NULL; glusterd_conf_t *priv = NULL; @@ -1004,7 +915,7 @@ __glusterd_handle_commit_op (rpcsvc_request_t *req) goto out; } - if (glusterd_friend_find_by_uuid (op_req.uuid, &peerinfo)) { + if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (op_req.uuid)); @@ -1119,16 +1030,13 @@ __glusterd_handle_cli_probe (rpcsvc_request_t *req) goto out; } - if (!(ret = glusterd_friend_find_by_hostname (hostname, &peerinfo))) { - if (strcmp (peerinfo->hostname, hostname) == 0) { - - gf_log ("glusterd", GF_LOG_DEBUG, "Probe host %s port " - "%d already a peer", hostname, port); - glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND, - NULL, hostname, port, - dict); - goto out; - } + peerinfo = glusterd_peerinfo_find_by_hostname (hostname); + if (peerinfo && gd_peer_has_address (peerinfo, hostname)) { + gf_log ("glusterd", GF_LOG_DEBUG, "Probe host %s port %d " + "already a peer", hostname, port); + glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND, NULL, + hostname, port, dict); + goto out; } ret = glusterd_probe_begin (req, hostname, port, dict, &op_errno); @@ -2021,9 +1929,8 @@ __glusterd_handle_fsm_log (rpcsvc_request_t *req) conf = this->private; log = &conf->op_sm_log; } else { - ret = glusterd_friend_find_by_hostname (cli_req.name, - &peerinfo); - if (ret) { + peerinfo = glusterd_peerinfo_find_by_hostname (cli_req.name); + if (!peerinfo) { snprintf (msg, sizeof (msg), "%s is not a peer", cli_req.name); goto out; @@ -2150,7 +2057,6 @@ __glusterd_handle_cluster_unlock (rpcsvc_request_t *req) gd1_mgmt_cluster_unlock_req unlock_req = {{0}, }; int32_t ret = -1; glusterd_op_lock_ctx_t *ctx = NULL; - glusterd_peerinfo_t *peerinfo = NULL; xlator_t *this = NULL; uuid_t *txn_id = NULL; glusterd_conf_t *priv = NULL; @@ -2176,7 +2082,7 @@ __glusterd_handle_cluster_unlock (rpcsvc_request_t *req) gf_log (this->name, GF_LOG_DEBUG, "Received UNLOCK from uuid: %s", uuid_utoa (unlock_req.uuid)); - if (glusterd_friend_find_by_uuid (unlock_req.uuid, &peerinfo)) { + if (glusterd_peerinfo_find_by_uuid (unlock_req.uuid) == NULL) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (unlock_req.uuid)); @@ -2402,24 +2308,21 @@ out: } int -glusterd_friend_hostname_update (glusterd_peerinfo_t *peerinfo, - char *hostname, - gf_boolean_t store_update) +glusterd_peer_hostname_update (glusterd_peerinfo_t *peerinfo, + const char *hostname, gf_boolean_t store_update) { - char *new_hostname = NULL; int ret = 0; GF_ASSERT (peerinfo); GF_ASSERT (hostname); - new_hostname = gf_strdup (hostname); - if (!new_hostname) { - ret = -1; + ret = gd_add_address_to_peer (peerinfo, hostname); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, + "Couldn't add address to the peer info"); goto out; } - GF_FREE (peerinfo->hostname); - peerinfo->hostname = new_hostname; if (store_update) ret = glusterd_store_peerinfo (peerinfo); out: @@ -2435,12 +2338,10 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) glusterd_peerinfo_t *peerinfo = NULL; glusterd_conf_t *priv = NULL; xlator_t *this = NULL; - glusterd_peerinfo_t *tmp = NULL; gd1_mgmt_friend_update_rsp rsp = {{0},}; dict_t *dict = NULL; char key[100] = {0,}; char *uuid_buf = NULL; - char *hostname = NULL; int i = 1; int count = 0; uuid_t uuid = {0,}; @@ -2462,8 +2363,8 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) goto out; } - ret = glusterd_friend_find (friend_req.uuid, NULL, &tmp); - if (ret) { + if (glusterd_peerinfo_find (friend_req.uuid, NULL) == NULL) { + ret = -1; gf_log ("", GF_LOG_CRITICAL, "Received friend update request " "from unknown peer %s", uuid_utoa (friend_req.uuid)); goto out; @@ -2503,46 +2404,59 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) args.mode = GD_MODE_ON; while ( i <= count) { + memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "friend%d.uuid", i); ret = dict_get_str (dict, key, &uuid_buf); if (ret) goto out; uuid_parse (uuid_buf, uuid); - snprintf (key, sizeof (key), "friend%d.hostname", i); - ret = dict_get_str (dict, key, &hostname); - if (ret) - goto out; - - 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, MY_UUID)) { - gf_log ("", GF_LOG_INFO, "Received my uuid as Friend"); + gf_log (this->name, GF_LOG_INFO, + "Received my uuid as Friend"); i++; continue; } - ret = glusterd_friend_find (uuid, hostname, &tmp); + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "friend%d", i); + + peerinfo = glusterd_peerinfo_find (uuid, NULL); + if (peerinfo == NULL) { + /* Create a new peer and add it to the list as there is + * no existing peer with the uuid + */ + peerinfo = gd_peerinfo_from_dict (dict, key); + if (peerinfo == NULL) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "Could not create peerinfo from dict " + "for prefix %s", key); + goto out; + } + + /* As this is a new peer, it should be added as a + * friend. The friend state machine will take care of + * correcting the state as required + */ + peerinfo->state.state = GD_FRIEND_STATE_BEFRIENDED; - if (!ret) { - if (strcmp (hostname, tmp->hostname) != 0) { - glusterd_friend_hostname_update (tmp, hostname, - _gf_true); + ret = glusterd_friend_add_from_peerinfo (peerinfo, 0, + &args); + } else { + /* As an existing peer was found, update it with the new + * information + */ + ret = gd_update_peerinfo_from_dict (peerinfo, dict, + key); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "update peer %s", peerinfo->hostname); + goto out; } - i++; - continue; } - ret = glusterd_friend_add (hostname, friend_req.port, - GD_FRIEND_STATE_BEFRIENDED, - &uuid, &peerinfo, 0, &args); - + peerinfo = NULL; i++; } @@ -2558,6 +2472,9 @@ out: free (friend_req.friends.friends_val);//malloced by xdr } + if (peerinfo) + glusterd_peerinfo_cleanup (peerinfo); + glusterd_friend_sm (); glusterd_op_sm (); @@ -2625,11 +2542,11 @@ __glusterd_handle_probe_query (rpcsvc_request_t *req) gf_log ("", GF_LOG_ERROR, "Unable to get the remote hostname"); goto out; } - ret = glusterd_friend_find (probe_req.uuid, remote_hostname, &peerinfo); - if ((ret != 0 ) && (!list_empty (&conf->peers))) { + peerinfo = glusterd_peerinfo_find (probe_req.uuid, remote_hostname); + if ((peerinfo == NULL) && (!list_empty (&conf->peers))) { rsp.op_ret = -1; rsp.op_errno = GF_PROBE_ANOTHER_CLUSTER; - } else if (ret) { + } else if (peerinfo == NULL) { gf_log ("glusterd", GF_LOG_INFO, "Unable to find peerinfo" " for host: %s (%d)", remote_hostname, port); args.mode = GD_MODE_ON; @@ -2951,17 +2868,17 @@ glusterd_handle_umount (rpcsvc_request_t *req) int glusterd_friend_remove (uuid_t uuid, char *hostname) { - int ret = 0; + int ret = -1; glusterd_peerinfo_t *peerinfo = NULL; - ret = glusterd_friend_find (uuid, hostname, &peerinfo); - if (ret) + peerinfo = glusterd_peerinfo_find (uuid, hostname); + if (peerinfo == NULL) goto out; ret = glusterd_friend_remove_cleanup_vols (peerinfo->uuid); if (ret) gf_log (THIS->name, GF_LOG_WARNING, "Volumes cleanup failed"); - ret = glusterd_friend_cleanup (peerinfo); + ret = glusterd_peerinfo_cleanup (peerinfo); out: gf_log ("", GF_LOG_DEBUG, "returning %d", ret); return ret; @@ -3068,10 +2985,10 @@ int glusterd_friend_rpc_create (xlator_t *this, glusterd_peerinfo_t *peerinfo, glusterd_peerctx_args_t *args) { - dict_t *options = NULL; - int ret = -1; - glusterd_peerctx_t *peerctx = NULL; - data_t *data = NULL; + dict_t *options = NULL; + int ret = -1; + glusterd_peerctx_t *peerctx = NULL; + data_t *data = NULL; peerctx = GF_CALLOC (1, sizeof (*peerctx), gf_gld_mt_peerctx_t); if (!peerctx) @@ -3136,9 +3053,11 @@ glusterd_friend_add (const char *hoststr, int port, conf = this->private; GF_ASSERT (conf); GF_ASSERT (hoststr); + GF_ASSERT (friend); - ret = glusterd_peerinfo_new (friend, state, uuid, hoststr, port); - if (ret) { + *friend = glusterd_peerinfo_new (state, uuid, hoststr, port); + if (*friend == NULL) { + ret = -1; goto out; } @@ -3167,7 +3086,7 @@ glusterd_friend_add (const char *hoststr, int port, } if (ret) { - (void) glusterd_friend_cleanup (*friend); + (void) glusterd_peerinfo_cleanup (*friend); *friend = NULL; } @@ -3176,6 +3095,54 @@ out: return ret; } +/* glusterd_friend_add_from_peerinfo() adds a new peer into the local friends + * list from a pre created @peerinfo object. It otherwise works similarly to + * glusterd_friend_add() + */ +int +glusterd_friend_add_from_peerinfo (glusterd_peerinfo_t *friend, + gf_boolean_t restore, + glusterd_peerctx_args_t *args) +{ + int ret = 0; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + + this = THIS; + conf = this->private; + GF_ASSERT (conf); + + GF_VALIDATE_OR_GOTO (this->name, (friend != NULL), out); + + /* + * We can't add to the list after calling glusterd_friend_rpc_create, + * even if it succeeds, because by then the callback to take it back + * off and free might have happened already (notably in the case of an + * invalid peer name). That would mean we're adding something that had + * just been free, and we're likely to crash later. + */ + list_add_tail (&friend->uuid_list, &conf->peers); + + //restore needs to first create the list of peers, then create rpcs + //to keep track of quorum in race-free manner. In restore for each peer + //rpc-create calls rpc_notify when the friend-list is partially + //constructed, leading to wrong quorum calculations. + if (!restore) { + ret = glusterd_store_peerinfo (friend); + if (ret == 0) { + ret = glusterd_friend_rpc_create (this, friend, args); + } + else { + gf_log (this->name, GF_LOG_ERROR, + "Failed to store peerinfo"); + } + } + +out: + gf_log (this->name, GF_LOG_INFO, "connect returned %d", ret); + return ret; +} + int glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port, dict_t *dict, int *op_errno) @@ -3187,15 +3154,15 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port, GF_ASSERT (hoststr); - ret = glusterd_friend_find (NULL, (char *)hoststr, &peerinfo); + peerinfo = glusterd_peerinfo_find (NULL, hoststr); - if (ret) { + if (peerinfo == NULL) { gf_log ("glusterd", GF_LOG_INFO, "Unable to find peerinfo" " for host: %s (%d)", hoststr, port); args.mode = GD_MODE_ON; args.req = req; args.dict = dict; - ret = glusterd_friend_add ((char *)hoststr, port, + ret = glusterd_friend_add (hoststr, port, GD_FRIEND_STATE_DEFAULT, NULL, &peerinfo, 0, &args); if ((!ret) && (!peerinfo->connected)) { @@ -3210,8 +3177,8 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port, *op_errno = GF_PROBE_FRIEND_DETACHING; goto out; } - ret = glusterd_friend_hostname_update (peerinfo, (char*)hoststr, - _gf_false); + ret = glusterd_peer_hostname_update (peerinfo, hoststr, + _gf_false); if (ret) goto out; //this is just to rename so inject local acc for cluster update @@ -3246,9 +3213,10 @@ glusterd_deprobe_begin (rpcsvc_request_t *req, const char *hoststr, int port, GF_ASSERT (hoststr); GF_ASSERT (req); - ret = glusterd_friend_find (uuid, (char *)hoststr, &peerinfo); + peerinfo = glusterd_peerinfo_find (uuid, hoststr); - if (ret) { + if (peerinfo == NULL) { + ret = -1; gf_log ("glusterd", GF_LOG_INFO, "Unable to find peerinfo" " for host: %s %d", hoststr, port); goto out; @@ -3614,7 +3582,7 @@ glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags) if (!list_empty (&priv->peers)) { list_for_each_entry (entry, &priv->peers, uuid_list) { count++; - ret = glusterd_add_peer_detail_to_dict (entry, + ret = gd_add_peer_detail_to_dict (entry, friends, count); if (ret) goto out; |