From 2aeb9fb17087434d87497a85077073ea3bf94869 Mon Sep 17 00:00:00 2001 From: Yaniv Kaul Date: Tue, 30 Jul 2019 10:15:42 +0300 Subject: multiple files: reduce minor work under RCU_READ_LOCK 1. Try to unlock faster - in error paths. 2. Remove memory allocations - do them before the lock. Change-Id: I1e9ddd80b99de45ad0f557d62a5f28951dfd54c8 updates: bz#1193929 Signed-off-by: Yaniv Kaul --- xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 4 +- xlators/mgmt/glusterd/src/glusterd-handler.c | 31 +-- xlators/mgmt/glusterd/src/glusterd-handshake.c | 21 +- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 6 +- xlators/mgmt/glusterd/src/glusterd-peer-utils.c | 254 ++++++++++----------- xlators/mgmt/glusterd/src/glusterd-peer-utils.h | 6 - xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 13 +- xlators/mgmt/glusterd/src/glusterd-reset-brick.c | 13 +- xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 12 +- xlators/mgmt/glusterd/src/glusterd-sm.c | 133 ++++++----- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 2 +- xlators/mgmt/glusterd/src/glusterd-syncop.c | 6 +- 12 files changed, 261 insertions(+), 240 deletions(-) (limited to 'xlators') diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index 20ca14ca6d7..870e30d8f22 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -1662,23 +1662,23 @@ glusterd_remove_brick_validate_bricks(gf1_op_commands cmd, int32_t brick_count, RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find_by_uuid(brickinfo->uuid); if (!peerinfo) { + RCU_READ_UNLOCK; snprintf(msg, sizeof(msg), "Host node of the " "brick %s is not in cluster", brick); *errstr = gf_strdup(msg); ret = -1; - RCU_READ_UNLOCK; goto out; } if (!peerinfo->connected) { + RCU_READ_UNLOCK; snprintf(msg, sizeof(msg), "Host node of the " "brick %s is down", brick); *errstr = gf_strdup(msg); ret = -1; - RCU_READ_UNLOCK; goto out; } RCU_READ_UNLOCK; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 462991776a1..f2f44147ec2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -91,15 +91,16 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, glusterd_friend_sm_event_t *event = NULL; glusterd_friend_req_ctx_t *ctx = NULL; char rhost[UNIX_PATH_MAX + 1] = {0}; - uuid_t friend_uuid = {0}; dict_t *dict = NULL; - gf_uuid_parse(uuid_utoa(uuid), friend_uuid); if (!port) port = GF_DEFAULT_BASE_PORT; ret = glusterd_remote_hostname_get(req, rhost, sizeof(rhost)); + ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_friend_req_ctx_t); + dict = dict_new(); + RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(uuid, rhost); @@ -126,8 +127,6 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, event->peername = gf_strdup(peerinfo->hostname); gf_uuid_copy(event->peerid, peerinfo->uuid); - ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_friend_req_ctx_t); - if (!ctx) { gf_msg("glusterd", GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, "Unable to allocate memory"); @@ -140,7 +139,6 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, ctx->hostname = gf_strdup(hostname); ctx->req = req; - dict = dict_new(); if (!dict) { ret = -1; goto out; @@ -204,11 +202,14 @@ glusterd_handle_unfriend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, if (!port) port = GF_DEFAULT_BASE_PORT; + ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_friend_req_ctx_t); + RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(uuid, hostname); if (peerinfo == NULL) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_CRITICAL, 0, GD_MSG_REQ_FROM_UNKNOWN_PEER, "Received remove-friend from unknown peer %s", hostname); ret = glusterd_xfer_friend_remove_resp(req, hostname, port); @@ -219,6 +220,7 @@ glusterd_handle_unfriend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, &event); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_NEW_GET_FAIL, "event generation failed: %d", ret); goto out; @@ -229,12 +231,11 @@ glusterd_handle_unfriend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, gf_uuid_copy(event->peerid, uuid); - ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_friend_req_ctx_t); - if (!ctx) { + RCU_READ_UNLOCK; + ret = -1; gf_msg("glusterd", GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, "Unable to allocate memory"); - ret = -1; goto out; } @@ -248,6 +249,7 @@ glusterd_handle_unfriend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, ret = glusterd_friend_sm_inject_event(event); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_INJECT_FAIL, "Unable to inject event %d, " "ret = %d", @@ -255,10 +257,11 @@ glusterd_handle_unfriend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, goto out; } - ret = 0; + RCU_READ_UNLOCK; + + return 0; out: - RCU_READ_UNLOCK; if (0 != ret) { if (ctx && ctx->hostname) @@ -2138,13 +2141,13 @@ __glusterd_handle_fsm_log(rpcsvc_request_t *req) peerinfo = glusterd_peerinfo_find_by_hostname(cli_req.name); if (!peerinfo) { + RCU_READ_UNLOCK; ret = -1; snprintf(msg, sizeof(msg), "%s is not a peer", cli_req.name); } else { ret = glusterd_sm_tr_log_add_to_dict(dict, &peerinfo->sm_log); + RCU_READ_UNLOCK; } - - RCU_READ_UNLOCK; } out: @@ -3203,10 +3206,10 @@ glusterd_friend_remove(uuid_t uuid, char *hostname) } ret = glusterd_friend_remove_cleanup_vols(peerinfo->uuid); + RCU_READ_UNLOCK; if (ret) gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_CLEANUP_FAIL, "Volumes cleanup failed"); - RCU_READ_UNLOCK; /* Giving up the critical section here as glusterd_peerinfo_cleanup must * be called from outside a critical section */ @@ -5478,8 +5481,8 @@ glusterd_get_state(rpcsvc_request_t *req, dict_t *dict) if (priv->opts) dict_foreach(priv->opts, glusterd_print_global_options, fp); - RCU_READ_LOCK; fprintf(fp, "\n[Peers]\n"); + RCU_READ_LOCK; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index bfd39cb7eab..a6cdbcef82c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -1816,12 +1816,13 @@ glusterd_event_connected_inject(glusterd_peerctx_t *peerctx) peerinfo = glusterd_peerinfo_find_by_generation(peerctx->peerinfo_gen); if (!peerinfo) { + RCU_READ_UNLOCK; ret = -1; gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", peerctx->peername, uuid_utoa(peerctx->peerid)); GF_FREE(ctx); - goto unlock; + goto out; } ctx->hostname = gf_strdup(peerinfo->hostname); ctx->port = peerinfo->port; @@ -1834,13 +1835,13 @@ glusterd_event_connected_inject(glusterd_peerctx_t *peerctx) ret = glusterd_friend_sm_inject_event(event); + RCU_READ_UNLOCK; + if (ret) gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_INJECT_FAIL, "Unable to inject " "EVENT_CONNECTED ret = %d", ret); -unlock: - RCU_READ_UNLOCK; out: gf_msg_debug("glusterd", 0, "returning %d", ret); @@ -2162,18 +2163,21 @@ glusterd_mgmt_handshake(xlator_t *this, glusterd_peerctx_t *peerctx) peerinfo = glusterd_peerinfo_find_by_generation(peerctx->peerinfo_gen); if (!peerinfo) { + RCU_READ_UNLOCK; gf_msg_debug(THIS->name, 0, "Could not find peer %s(%s)", peerctx->peername, uuid_utoa(peerctx->peerid)); - goto unlock; + goto out; } ret = glusterd_submit_request( peerinfo->rpc, &req, frame, &gd_clnt_mgmt_hndsk_prog, GD_MGMT_HNDSK_VERSIONS, NULL, this, glusterd_mgmt_hndsk_version_cbk, (xdrproc_t)xdr_gf_mgmt_hndsk_req); - ret = 0; -unlock: + RCU_READ_UNLOCK; + + ret = 0; + out: if (req_dict) dict_unref(req_dict); @@ -2420,9 +2424,10 @@ glusterd_peer_dump_version(xlator_t *this, struct rpc_clnt *rpc, peerinfo = glusterd_peerinfo_find_by_generation(peerctx->peerinfo_gen); if (!peerinfo) { + RCU_READ_UNLOCK; gf_msg_debug(this->name, 0, "Couldn't find peer %s(%s)", peerctx->peername, uuid_utoa(peerctx->peerid)); - goto unlock; + goto out; } req.gfs_id = 0xcafe; @@ -2430,7 +2435,7 @@ glusterd_peer_dump_version(xlator_t *this, struct rpc_clnt *rpc, ret = glusterd_submit_request( peerinfo->rpc, &req, frame, &glusterd_dump_prog, GF_DUMP_DUMP, NULL, this, glusterd_peer_dump_version_cbk, (xdrproc_t)xdr_gf_dump_req); -unlock: + RCU_READ_UNLOCK; out: if (ret && frame) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index f8e0bfe1178..da0d8c945e2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1683,17 +1683,21 @@ glusterd_op_stage_sync_volume(dict_t *dict, char **op_errstr) peerinfo = glusterd_peerinfo_find(NULL, hostname); if (peerinfo == NULL) { + RCU_READ_UNLOCK; ret = -1; snprintf(msg, sizeof(msg), "%s, is not a friend", hostname); *op_errstr = gf_strdup(msg); + goto out; } else if (!peerinfo->connected) { + RCU_READ_UNLOCK; + ret = -1; snprintf(msg, sizeof(msg), "%s, is not connected at " "the moment", hostname); *op_errstr = gf_strdup(msg); - ret = -1; + goto out; } RCU_READ_UNLOCK; diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c index ce4805b8d6d..1a55a5a5375 100644 --- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c @@ -87,6 +87,107 @@ glusterd_peerinfo_cleanup(glusterd_peerinfo_t *peerinfo) return 0; } +/* gd_peerinfo_find_from_hostname iterates over all the addresses saved for each + * peer and matches it to @hoststr. + * Returns the matched peer if found else returns NULL + */ +static glusterd_peerinfo_t * +gd_peerinfo_find_from_hostname(const char *hoststr) +{ + xlator_t *this = THIS; + glusterd_conf_t *priv = NULL; + glusterd_peerinfo_t *peer = NULL; + glusterd_peerinfo_t *found = NULL; + glusterd_peer_hostname_t *tmphost = NULL; + + GF_ASSERT(this != NULL); + priv = this->private; + GF_VALIDATE_OR_GOTO(this->name, (priv != NULL), out); + + GF_VALIDATE_OR_GOTO(this->name, (hoststr != NULL), out); + + RCU_READ_LOCK; + cds_list_for_each_entry_rcu(peer, &priv->peers, uuid_list) + { + cds_list_for_each_entry_rcu(tmphost, &peer->hostnames, hostname_list) + { + if (!strncasecmp(tmphost->hostname, hoststr, 1024)) { + gf_msg_debug(this->name, 0, "Friend %s found.. state: %d", + tmphost->hostname, peer->state.state); + found = peer; /* Probably needs to be + dereferenced*/ + goto unlock; + } + } + } +unlock: + RCU_READ_UNLOCK; +out: + return found; +} + +/* gd_peerinfo_find_from_addrinfo iterates over all the addresses saved for each + * peer, resolves them and compares them to @addr. + * + * + * NOTE: As getaddrinfo is a blocking call and is being performed multiple times + * in this function, it could lead to the calling thread to be blocked for + * significant amounts of time. + * + * Returns the matched peer if found else returns NULL + */ +static glusterd_peerinfo_t * +gd_peerinfo_find_from_addrinfo(const struct addrinfo *addr) +{ + xlator_t *this = THIS; + glusterd_conf_t *conf = NULL; + glusterd_peerinfo_t *peer = NULL; + glusterd_peerinfo_t *found = NULL; + glusterd_peer_hostname_t *address = NULL; + int ret = 0; + struct addrinfo *paddr = NULL; + struct addrinfo *tmp = NULL; + + GF_ASSERT(this != NULL); + conf = this->private; + GF_VALIDATE_OR_GOTO(this->name, (conf != NULL), out); + + RCU_READ_LOCK; + cds_list_for_each_entry_rcu(peer, &conf->peers, uuid_list) + { + cds_list_for_each_entry_rcu(address, &peer->hostnames, hostname_list) + { + /* TODO: Cache the resolved addrinfos to improve + * performance + */ + ret = getaddrinfo(address->hostname, NULL, NULL, &paddr); + if (ret) { + /* Don't fail if getaddrinfo fails, continue + * onto the next address + */ + gf_msg_trace(this->name, 0, "getaddrinfo for %s failed (%s)", + address->hostname, gai_strerror(ret)); + continue; + } + + for (tmp = paddr; tmp != NULL; tmp = tmp->ai_next) { + if (gf_compare_sockaddr(addr->ai_addr, tmp->ai_addr)) { + found = peer; /* (de)referenced? */ + break; + } + } + + freeaddrinfo(paddr); + if (found) + goto unlock; + } + } +unlock: + RCU_READ_UNLOCK; +out: + return found; +} + /* glusterd_peerinfo_find_by_hostname searches for a peer which matches the * hostname @hoststr and if found returns the pointer to peerinfo object. * Returns NULL otherwise. @@ -101,14 +202,11 @@ glusterd_peerinfo_find_by_hostname(const char *hoststr) int ret = -1; struct addrinfo *addr = NULL; struct addrinfo *p = NULL; - xlator_t *this = NULL; + xlator_t *this = THIS; glusterd_peerinfo_t *peerinfo = NULL; - this = THIS; GF_ASSERT(hoststr); - peerinfo = NULL; - peerinfo = gd_peerinfo_find_from_hostname(hoststr); if (peerinfo) return peerinfo; @@ -178,31 +276,33 @@ glusterd_peerinfo_find_by_uuid(uuid_t uuid) glusterd_conf_t *priv = NULL; glusterd_peerinfo_t *entry = NULL; glusterd_peerinfo_t *found = NULL; - xlator_t *this = NULL; + xlator_t *this = THIS; + glusterd_friend_sm_state_t state; - this = THIS; GF_ASSERT(this); + if (gf_uuid_is_null(uuid)) + return NULL; + priv = this->private; GF_ASSERT(priv); - if (gf_uuid_is_null(uuid)) - return NULL; - RCU_READ_LOCK; cds_list_for_each_entry_rcu(entry, &priv->peers, uuid_list) { if (!gf_uuid_compare(entry->uuid, uuid)) { - gf_msg_debug(this->name, 0, "Friend found... state: %s", - glusterd_friend_sm_state_name_get(entry->state.state)); found = entry; /* Probably should be rcu_dereferenced */ + state = found->state.state; break; } } RCU_READ_UNLOCK; - if (!found) + if (found) + gf_msg_debug(this->name, 0, "Friend found... state: %s", + glusterd_friend_sm_state_name_get(state)); + else gf_msg_debug(this->name, 0, "Friend with uuid: %s, not found", uuid_utoa(uuid)); return found; @@ -216,9 +316,8 @@ glusterd_peerinfo_t * glusterd_peerinfo_find(uuid_t uuid, const char *hostname) { glusterd_peerinfo_t *peerinfo = NULL; - xlator_t *this = NULL; + xlator_t *this = THIS; - this = THIS; GF_ASSERT(this); if (uuid) { @@ -442,9 +541,8 @@ glusterd_are_vol_all_peers_up(glusterd_volinfo_t *volinfo, if (!(peerinfo->connected) || (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)) { *down_peerstr = gf_strdup(peerinfo->hostname); - gf_msg_debug(THIS->name, 0, "Peer %s is down. ", - peerinfo->hostname); RCU_READ_UNLOCK; + gf_msg_debug(THIS->name, 0, "Peer %s is down. ", *down_peerstr); goto out; } } @@ -503,7 +601,6 @@ glusterd_peer_hostname_free(glusterd_peer_hostname_t *name) gf_boolean_t gd_peer_has_address(glusterd_peerinfo_t *peerinfo, const char *address) { - gf_boolean_t ret = _gf_false; glusterd_peer_hostname_t *hostname = NULL; GF_VALIDATE_OR_GOTO("glusterd", (peerinfo != NULL), out); @@ -512,13 +609,12 @@ gd_peer_has_address(glusterd_peerinfo_t *peerinfo, const char *address) cds_list_for_each_entry(hostname, &peerinfo->hostnames, hostname_list) { if (strcmp(hostname->hostname, address) == 0) { - ret = _gf_true; - break; + return _gf_true; } } out: - return ret; + return _gf_false; } int @@ -627,112 +723,6 @@ out: return ret; } -/* gd_peerinfo_find_from_hostname iterates over all the addresses saved for each - * peer and matches it to @hoststr. - * Returns the matched peer if found else returns NULL - */ -glusterd_peerinfo_t * -gd_peerinfo_find_from_hostname(const char *hoststr) -{ - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - glusterd_peerinfo_t *peer = NULL; - glusterd_peerinfo_t *found = NULL; - glusterd_peer_hostname_t *tmphost = NULL; - - this = THIS; - GF_ASSERT(this != NULL); - priv = this->private; - GF_VALIDATE_OR_GOTO(this->name, (priv != NULL), out); - - GF_VALIDATE_OR_GOTO(this->name, (hoststr != NULL), out); - - RCU_READ_LOCK; - cds_list_for_each_entry_rcu(peer, &priv->peers, uuid_list) - { - cds_list_for_each_entry_rcu(tmphost, &peer->hostnames, hostname_list) - { - if (!strncasecmp(tmphost->hostname, hoststr, 1024)) { - gf_msg_debug(this->name, 0, "Friend %s found.. state: %d", - tmphost->hostname, peer->state.state); - found = peer; /* Probably needs to be - dereferenced*/ - goto unlock; - } - } - } -unlock: - RCU_READ_UNLOCK; -out: - return found; -} - -/* gd_peerinfo_find_from_addrinfo iterates over all the addresses saved for each - * peer, resolves them and compares them to @addr. - * - * - * NOTE: As getaddrinfo is a blocking call and is being performed multiple times - * in this function, it could lead to the calling thread to be blocked for - * significant amounts of time. - * - * Returns the matched peer if found else returns NULL - */ -glusterd_peerinfo_t * -gd_peerinfo_find_from_addrinfo(const struct addrinfo *addr) -{ - xlator_t *this = NULL; - glusterd_conf_t *conf = NULL; - glusterd_peerinfo_t *peer = NULL; - glusterd_peerinfo_t *found = NULL; - glusterd_peer_hostname_t *address = NULL; - int ret = 0; - struct addrinfo *paddr = NULL; - struct addrinfo *tmp = NULL; - - this = THIS; - GF_ASSERT(this != NULL); - conf = this->private; - GF_VALIDATE_OR_GOTO(this->name, (conf != NULL), out); - - GF_VALIDATE_OR_GOTO(this->name, (addr != NULL), out); - - RCU_READ_LOCK; - cds_list_for_each_entry_rcu(peer, &conf->peers, uuid_list) - { - cds_list_for_each_entry_rcu(address, &peer->hostnames, hostname_list) - { - /* TODO: Cache the resolved addrinfos to improve - * performance - */ - ret = getaddrinfo(address->hostname, NULL, NULL, &paddr); - if (ret) { - /* Don't fail if getaddrinfo fails, continue - * onto the next address - */ - gf_msg_trace(this->name, 0, "getaddrinfo for %s failed (%s)", - address->hostname, gai_strerror(ret)); - ret = 0; - continue; - } - - for (tmp = paddr; tmp != NULL; tmp = tmp->ai_next) { - if (gf_compare_sockaddr(addr->ai_addr, tmp->ai_addr)) { - found = peer; /* (de)referenced? */ - break; - } - } - - freeaddrinfo(paddr); - if (found) - goto unlock; - } - } -unlock: - RCU_READ_UNLOCK; -out: - return found; -} - /* gd_update_peerinfo_from_dict will update the hostnames for @peerinfo from * peer details with @prefix in @dict. * Returns 0 on success and -1 on failure. @@ -986,9 +976,9 @@ glusterd_peerinfo_find_by_generation(uint32_t generation) glusterd_conf_t *priv = NULL; glusterd_peerinfo_t *entry = NULL; glusterd_peerinfo_t *found = NULL; - xlator_t *this = NULL; + xlator_t *this = THIS; + glusterd_friend_sm_state_t state; - this = THIS; GF_ASSERT(this); priv = this->private; @@ -999,15 +989,17 @@ glusterd_peerinfo_find_by_generation(uint32_t generation) cds_list_for_each_entry_rcu(entry, &priv->peers, uuid_list) { if (entry->generation == generation) { - gf_msg_debug(this->name, 0, "Friend found... state: %s", - glusterd_friend_sm_state_name_get(entry->state.state)); found = entry; /* Probably should be rcu_dereferenced */ + state = found->state.state; break; } } RCU_READ_UNLOCK; - if (!found) + if (found) + gf_msg_debug(this->name, 0, "Friend found... state: %s", + glusterd_friend_sm_state_name_get(state)); + else gf_msg_debug(this->name, 0, "Friend with generation: %" PRIu32 ", not found", generation); diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h index 47cbf6ee13d..375fdf94607 100644 --- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h @@ -64,12 +64,6 @@ int gd_add_friend_to_dict(glusterd_peerinfo_t *friend, dict_t *dict, const char *prefix); -glusterd_peerinfo_t * -gd_peerinfo_find_from_hostname(const char *hoststr); - -glusterd_peerinfo_t * -gd_peerinfo_find_from_addrinfo(const struct addrinfo *addr); - int gd_update_peerinfo_from_dict(glusterd_peerinfo_t *peerinfo, dict_t *dict, const char *prefix); diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c index ca1de1a915f..efaddde67e2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c @@ -272,31 +272,34 @@ glusterd_op_stage_replace_brick(dict_t *dict, char **op_errstr, peerinfo = glusterd_peerinfo_find(NULL, host); if (peerinfo == NULL) { + RCU_READ_UNLOCK; ret = -1; snprintf(msg, sizeof(msg), "%s, is not a friend", host); *op_errstr = gf_strdup(msg); + goto out; } else if (!peerinfo->connected) { + RCU_READ_UNLOCK; + ret = -1; snprintf(msg, sizeof(msg), "%s, is not connected at " "the moment", host); *op_errstr = gf_strdup(msg); - ret = -1; + goto out; } else if (GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state) { + RCU_READ_UNLOCK; + ret = -1; snprintf(msg, sizeof(msg), "%s, is not befriended " "at the moment", host); *op_errstr = gf_strdup(msg); - ret = -1; + goto out; } RCU_READ_UNLOCK; - if (ret) - goto out; - } else if (priv->op_version >= GD_OP_VERSION_3_6_0) { /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 diff --git a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c index cf04ce85541..b591d8424b8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c @@ -157,31 +157,34 @@ glusterd_reset_brick_prevalidate(dict_t *dict, char **op_errstr, peerinfo = glusterd_peerinfo_find(NULL, host); if (peerinfo == NULL) { + RCU_READ_UNLOCK; ret = -1; snprintf(msg, sizeof(msg), "%s, is not a friend.", host); *op_errstr = gf_strdup(msg); + goto out; } else if (!peerinfo->connected) { + RCU_READ_UNLOCK; + ret = -1; snprintf(msg, sizeof(msg), "%s," "is not connected at " "the moment.", host); *op_errstr = gf_strdup(msg); - ret = -1; + goto out; } else if (GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state) { + RCU_READ_UNLOCK; + ret = -1; snprintf(msg, sizeof(msg), "%s, is not befriended " "at the moment.", host); *op_errstr = gf_strdup(msg); - ret = -1; + goto out; } RCU_READ_UNLOCK; - - if (ret) - goto out; } if (!(gf_uuid_compare(dst_brickinfo->uuid, MY_UUID))) { diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index 95b68f0b506..a8e35f32a15 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -275,11 +275,12 @@ __glusterd_probe_cbk(struct rpc_req *req, struct iovec *iov, int count, RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(rsp.uuid, rsp.hostname); if (peerinfo == NULL) { + RCU_READ_UNLOCK ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peerd %s(%s)", rsp.hostname, uuid_utoa(rsp.uuid)); - goto unlock; + goto out; } /* @@ -393,9 +394,10 @@ cont: ret = glusterd_friend_sm_new_event(GD_FRIEND_EVENT_INIT_FRIEND_REQ, &event); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_NEW_FRIEND_SM_EVENT_GET_FAIL, "Unable to get event"); - goto unlock; + goto out; } event->peername = gf_strdup(peerinfo->hostname); @@ -477,12 +479,13 @@ __glusterd_friend_add_cbk(struct rpc_req *req, struct iovec *iov, int count, peerinfo = glusterd_peerinfo_find(rsp.uuid, rsp.hostname); if (peerinfo == NULL) { + RCU_READ_UNLOCK ret = -1; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_RESP_FROM_UNKNOWN_PEER, "received friend add response from" " unknown peer uuid: %s", uuid_utoa(rsp.uuid)); - goto unlock; + goto out; } if (op_ret) @@ -1528,12 +1531,13 @@ glusterd_rpc_friend_add(call_frame_t *frame, xlator_t *this, void *data) goto out; } - gf_uuid_copy(req.uuid, MY_UUID); req.hostname = gf_strdup(peerinfo->hostname); req.port = peerinfo->port; RCU_READ_UNLOCK; + gf_uuid_copy(req.uuid, MY_UUID); + peer_data = dict_new(); if (!peer_data) { errno = ENOMEM; diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c index bb9b5cbf300..7b67592e27c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-sm.c @@ -175,9 +175,10 @@ glusterd_broadcast_friend_delete(char *hostname, uuid_t uuid) */ ret = dict_set_static_ptr(friends, "peerinfo", peerinfo); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); - goto unlock; + goto out; } proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE]; @@ -185,15 +186,13 @@ glusterd_broadcast_friend_delete(char *hostname, uuid_t uuid) ret = proc->fn(NULL, this, friends); } } -unlock: - RCU_READ_UNLOCK; - - gf_msg_debug("glusterd", 0, "Returning with %d", ret); + RCU_READ_UNLOCK; out: if (friends) dict_unref(friends); + gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } @@ -229,29 +228,32 @@ glusterd_ac_reverse_probe_begin(glusterd_friend_sm_event_t *event, void *ctx) GF_ASSERT(event); GF_ASSERT(ctx); + new_ev_ctx = GF_CALLOC(1, sizeof(*new_ev_ctx), gf_gld_mt_probe_ctx_t); + RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { + RCU_READ_UNLOCK; + ret = -1; gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); - ret = -1; goto out; } ret = glusterd_friend_sm_new_event(GD_FRIEND_EVENT_PROBE, &new_event); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_NEW_GET_FAIL, "Unable to get new new_event"); ret = -1; goto out; } - new_ev_ctx = GF_CALLOC(1, sizeof(*new_ev_ctx), gf_gld_mt_probe_ctx_t); - if (!new_ev_ctx) { + RCU_READ_UNLOCK; ret = -1; goto out; } @@ -266,6 +268,8 @@ glusterd_ac_reverse_probe_begin(glusterd_friend_sm_event_t *event, void *ctx) ret = glusterd_friend_sm_inject_event(new_event); + RCU_READ_UNLOCK; + if (ret) { gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_EVENT_INJECT_FAIL, "Unable to inject new_event %d, " @@ -274,8 +278,6 @@ glusterd_ac_reverse_probe_begin(glusterd_friend_sm_event_t *event, void *ctx) } out: - RCU_READ_UNLOCK; - if (ret) { if (new_event) GF_FREE(new_event->peername); @@ -309,27 +311,30 @@ glusterd_ac_friend_add(glusterd_friend_sm_event_t *event, void *ctx) peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { + RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); goto out; } - if (!peerinfo->peer) + if (!peerinfo->peer) { + RCU_READ_UNLOCK; goto out; + } proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_ADD]; if (proc->fn) { frame = create_frame(this, this->ctx->pool); if (!frame) { + RCU_READ_UNLOCK; goto out; } frame->local = ctx; ret = proc->fn(frame, this, event); } -out: RCU_READ_UNLOCK; - +out: if (ret && frame) STACK_DESTROY(frame->root); @@ -366,29 +371,29 @@ glusterd_ac_friend_probe(glusterd_friend_sm_event_t *event, void *ctx) if (peerinfo == NULL) { // We should not reach this state ideally ret = -1; - goto out; + goto unlock; } if (!peerinfo->peer) - goto out; + goto unlock; proc = &peerinfo->peer->proctable[GLUSTERD_PROBE_QUERY]; if (proc->fn) { frame = create_frame(this, this->ctx->pool); if (!frame) { - goto out; + goto unlock; } frame->local = ctx; dict = dict_new(); if (!dict) - goto out; + goto unlock; ret = dict_set_strn(dict, "hostname", SLEN("hostname"), probe_ctx->hostname); if (ret) - goto out; + goto unlock; ret = dict_set_int32n(dict, "port", SLEN("port"), probe_ctx->port); if (ret) - goto out; + goto unlock; /* The peerinfo reference being set here is going to be used * only within this critical section, in glusterd_rpc_probe @@ -396,6 +401,7 @@ glusterd_ac_friend_probe(glusterd_friend_sm_event_t *event, void *ctx) */ ret = dict_set_static_ptr(dict, "peerinfo", peerinfo); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; @@ -403,11 +409,11 @@ glusterd_ac_friend_probe(glusterd_friend_sm_event_t *event, void *ctx) ret = proc->fn(frame, this, dict); if (ret) - goto out; + goto unlock; } - -out: +unlock: RCU_READ_UNLOCK; +out: if (dict) dict_unref(dict); @@ -444,6 +450,8 @@ glusterd_ac_send_friend_remove_req(glusterd_friend_sm_event_t *event, peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { + RCU_READ_UNLOCK; + ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); @@ -471,23 +479,24 @@ glusterd_ac_send_friend_remove_req(glusterd_friend_sm_event_t *event, glusterd_broadcast_friend_delete(ctx->hostname, NULL); glusterd_destroy_probe_ctx(ctx); } - goto out; + goto unlock; } if (!peerinfo->peer) - goto out; + goto unlock; proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_REMOVE]; if (proc->fn) { frame = create_frame(this, this->ctx->pool); if (!frame) { - goto out; + goto unlock; } frame->local = data; ret = proc->fn(frame, this, event); } -out: +unlock: RCU_READ_UNLOCK; +out: gf_msg_debug("glusterd", 0, "Returning with %d", ret); @@ -501,13 +510,11 @@ static gf_boolean_t glusterd_should_update_peer(glusterd_peerinfo_t *peerinfo, glusterd_peerinfo_t *cur_peerinfo) { - gf_boolean_t is_valid = _gf_false; - if ((peerinfo == cur_peerinfo) || (peerinfo->state.state == GD_FRIEND_STATE_BEFRIENDED)) - is_valid = _gf_true; + return _gf_true; - return is_valid; + return _gf_false; } static int @@ -534,27 +541,28 @@ glusterd_ac_send_friend_update(glusterd_friend_sm_event_t *event, void *ctx) GF_ASSERT(priv); + keylen = snprintf(key, sizeof(key), "op"); + friends = dict_new(); + RCU_READ_LOCK; cur_peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!cur_peerinfo) { + RCU_READ_UNLOCK; + ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); - ret = -1; goto out; } - ev_ctx.op = GD_FRIEND_UPDATE_ADD; - - friends = dict_new(); if (!friends) - goto out; + goto unlock; - keylen = snprintf(key, sizeof(key), "op"); + ev_ctx.op = GD_FRIEND_UPDATE_ADD; ret = dict_set_int32n(friends, key, keylen, ev_ctx.op); if (ret) - goto out; + goto unlock; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { @@ -566,12 +574,12 @@ glusterd_ac_send_friend_update(glusterd_friend_sm_event_t *event, void *ctx) snprintf(key, sizeof(key), "friend%d", count); ret = gd_add_friend_to_dict(peerinfo, friends, key); if (ret) - goto out; + goto unlock; } ret = dict_set_int32n(friends, "count", SLEN("count"), count); if (ret) - goto out; + goto unlock; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { @@ -583,6 +591,7 @@ glusterd_ac_send_friend_update(glusterd_friend_sm_event_t *event, void *ctx) ret = dict_set_static_ptr(friends, "peerinfo", peerinfo); if (ret) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; @@ -594,14 +603,14 @@ glusterd_ac_send_friend_update(glusterd_friend_sm_event_t *event, void *ctx) } } - gf_msg_debug("glusterd", 0, "Returning with %d", ret); - -out: +unlock: RCU_READ_UNLOCK; +out: if (friends) dict_unref(friends); + gf_msg_debug("glusterd", 0, "Returning with %d", ret); return ret; } @@ -632,14 +641,18 @@ glusterd_ac_update_friend(glusterd_friend_sm_event_t *event, void *ctx) GF_ASSERT(priv); + friends = dict_new(); + keylen = snprintf(key, sizeof(key), "op"); + RCU_READ_LOCK; cur_peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!cur_peerinfo) { + RCU_READ_UNLOCK; + ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); - ret = -1; goto out; } @@ -649,19 +662,16 @@ glusterd_ac_update_friend(glusterd_friend_sm_event_t *event, void *ctx) */ if (!cur_peerinfo->connected || !cur_peerinfo->peer) { ret = 0; - goto out; + goto unlock; } - ev_ctx.op = GD_FRIEND_UPDATE_ADD; - - friends = dict_new(); if (!friends) goto out; - keylen = snprintf(key, sizeof(key), "op"); + ev_ctx.op = GD_FRIEND_UPDATE_ADD; ret = dict_set_int32n(friends, key, keylen, ev_ctx.op); if (ret) - goto out; + goto unlock; cds_list_for_each_entry_rcu(peerinfo, &priv->peers, uuid_list) { @@ -673,15 +683,16 @@ glusterd_ac_update_friend(glusterd_friend_sm_event_t *event, void *ctx) snprintf(key, sizeof(key), "friend%d", count); ret = gd_add_friend_to_dict(peerinfo, friends, key); if (ret) - goto out; + goto unlock; } ret = dict_set_int32n(friends, "count", SLEN("count"), count); if (ret) - goto out; + goto unlock; ret = dict_set_static_ptr(friends, "peerinfo", cur_peerinfo); if (ret) { + RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "failed to set peerinfo"); goto out; @@ -693,8 +704,9 @@ glusterd_ac_update_friend(glusterd_friend_sm_event_t *event, void *ctx) gf_msg_debug(this->name, 0, "Returning with %d", ret); -out: +unlock: RCU_READ_UNLOCK; +out: if (friends) dict_unref(friends); @@ -846,18 +858,18 @@ glusterd_ac_friend_remove(glusterd_friend_sm_event_t *event, void *ctx) peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { + RCU_READ_UNLOCK; gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); - RCU_READ_UNLOCK; goto out; } ret = glusterd_friend_remove_cleanup_vols(peerinfo->uuid); + RCU_READ_UNLOCK; if (ret) gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_CLEANUP_FAIL, "Volumes cleanup failed"); - RCU_READ_UNLOCK; /* Exiting read critical section as glusterd_peerinfo_cleanup calls * synchronize_rcu before freeing the peerinfo */ @@ -908,11 +920,11 @@ glusterd_ac_handle_friend_add_req(glusterd_friend_sm_event_t *event, void *ctx) RCU_READ_LOCK; peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { + RCU_READ_UNLOCK; + ret = -1; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", event->peername, uuid_utoa(event->peerid)); - ret = -1; - RCU_READ_UNLOCK; goto out; } @@ -1417,21 +1429,20 @@ glusterd_friend_sm() peerinfo = glusterd_peerinfo_find(event->peerid, event->peername); if (!peerinfo) { + RCU_READ_UNLOCK; gf_msg("glusterd", GF_LOG_CRITICAL, 0, GD_MSG_PEER_NOT_FOUND, "Received" " event %s with empty peer info", glusterd_friend_sm_event_name_get(event_type)); GF_FREE(event); - RCU_READ_UNLOCK; continue; } + old_state = peerinfo->state.state; + RCU_READ_UNLOCK; gf_msg_debug("glusterd", 0, "Dequeued event of type: '%s'", glusterd_friend_sm_event_name_get(event_type)); - old_state = peerinfo->state.state; - - RCU_READ_UNLOCK; /* Giving up read-critical section here as we only need * the current state to call the handler. * @@ -1514,11 +1525,11 @@ glusterd_friend_sm() } ret = glusterd_store_peerinfo(peerinfo); + RCU_READ_UNLOCK; if (ret) { gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_PEERINFO_CREATE_FAIL, "Failed to store peerinfo"); } - RCU_READ_UNLOCK; glusterd_destroy_friend_event_context(event); GF_FREE(event); diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 3cd9a505a9e..97bd9ec511d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -217,13 +217,13 @@ glusterd_find_missed_snap(dict_t *rsp_dict, glusterd_volinfo_t *vol, ret = glusterd_add_missed_snaps_to_dict( rsp_dict, vol, brickinfo, brick_count + 1, op); if (ret) { + RCU_READ_UNLOCK; gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MISSED_SNAP_CREATE_FAIL, "Failed to add missed snapshot " "info for %s:%s in the " "rsp_dict", brickinfo->hostname, brickinfo->path); - RCU_READ_UNLOCK; goto out; } } diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c index 466f3e32223..b7039f83885 100644 --- a/xlators/mgmt/glusterd/src/glusterd-syncop.c +++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c @@ -571,14 +571,15 @@ _gd_syncop_mgmt_lock_cbk(struct rpc_req *req, struct iovec *iov, int count, /* Set peer as locked, so we unlock only the locked peers */ if (rsp.op_ret == 0) peerinfo->locked = _gf_true; + RCU_READ_UNLOCK; } else { + RCU_READ_UNLOCK; rsp.op_ret = -1; gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_PEER_NOT_FOUND, "Could not find peer with " "ID %s", uuid_utoa(*peerid)); } - RCU_READ_UNLOCK; op_ret = rsp.op_ret; op_errno = rsp.op_errno; @@ -670,14 +671,15 @@ _gd_syncop_mgmt_unlock_cbk(struct rpc_req *req, struct iovec *iov, int count, peerinfo = glusterd_peerinfo_find(*peerid, NULL); if (peerinfo) { peerinfo->locked = _gf_false; + RCU_READ_UNLOCK; } else { + RCU_READ_UNLOCK; rsp.op_ret = -1; gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_PEER_NOT_FOUND, "Could not find peer with " "ID %s", uuid_utoa(*peerid)); } - RCU_READ_UNLOCK; op_ret = rsp.op_ret; op_errno = rsp.op_errno; -- cgit