summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-peer-utils.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.c312
1 files changed, 168 insertions, 144 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
index 5b5959ee721..18d355cb186 100644
--- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
@@ -48,6 +48,7 @@ glusterd_peerinfo_destroy(struct rcu_head *head)
}
glusterd_sm_tr_log_delete(&peerinfo->sm_log);
+ pthread_mutex_unlock(&peerinfo->delete_lock);
pthread_mutex_destroy(&peerinfo->delete_lock);
GF_FREE(peerinfo);
@@ -81,10 +82,112 @@ glusterd_peerinfo_cleanup(glusterd_peerinfo_t *peerinfo)
call_rcu(&peerinfo->rcu_head.head, glusterd_peerinfo_destroy);
if (quorum_action)
+ /* coverity[SLEEP] */
glusterd_do_quorum_action();
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.
@@ -99,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;
@@ -176,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;
@@ -214,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) {
@@ -266,8 +367,10 @@ glusterd_peerinfo_new(glusterd_friend_sm_state_t state, uuid_t *uuid,
GF_ASSERT(conf);
new_peer = GF_CALLOC(1, sizeof(*new_peer), gf_gld_mt_peerinfo_t);
- if (!new_peer)
+ if (!new_peer) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL);
goto out;
+ }
CDS_INIT_LIST_HEAD(&new_peer->uuid_list);
@@ -357,6 +460,7 @@ glusterd_uuid_to_hostname(uuid_t uuid)
if (!gf_uuid_compare(MY_UUID, uuid)) {
hostname = gf_strdup("localhost");
+ return hostname;
}
RCU_READ_LOCK;
if (!cds_list_empty(&priv->peers)) {
@@ -439,9 +543,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;
}
}
@@ -463,12 +566,16 @@ glusterd_peer_hostname_new(const char *hostname,
GF_ASSERT(hostname);
GF_ASSERT(name);
+ xlator_t *this = THIS;
+ GF_ASSERT(this);
peer_hostname = GF_CALLOC(1, sizeof(*peer_hostname),
gf_gld_mt_peer_hostname_t);
- if (!peer_hostname)
+ if (!peer_hostname) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL);
goto out;
+ }
peer_hostname->hostname = gf_strdup(hostname);
CDS_INIT_LIST_HEAD(&peer_hostname->hostname_list);
@@ -500,7 +607,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);
@@ -509,13 +615,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
@@ -624,112 +729,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.
@@ -830,7 +829,7 @@ gd_peerinfo_from_dict(dict_t *dict, const char *prefix)
xlator_t *this = NULL;
glusterd_conf_t *conf = NULL;
glusterd_peerinfo_t *new_peer = NULL;
- char key[100] = {
+ char key[64] = {
0,
};
char *uuid_str = NULL;
@@ -875,14 +874,14 @@ out:
return new_peer;
}
-int
+static int
gd_add_peer_hostnames_to_dict(glusterd_peerinfo_t *peerinfo, dict_t *dict,
const char *prefix)
{
int ret = -1;
xlator_t *this = NULL;
glusterd_conf_t *conf = NULL;
- char key[256] = {
+ char key[64] = {
0,
};
glusterd_peer_hostname_t *addr = NULL;
@@ -907,8 +906,11 @@ gd_add_peer_hostnames_to_dict(glusterd_peerinfo_t *peerinfo, dict_t *dict,
{
snprintf(key, sizeof(key), "%s.hostname%d", prefix, count);
ret = dict_set_dynstr_with_alloc(dict, key, addr->hostname);
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
+ "Key=%s", key, NULL);
goto out;
+ }
count++;
}
@@ -924,47 +926,67 @@ gd_add_peer_detail_to_dict(glusterd_peerinfo_t *peerinfo, dict_t *friends,
int count)
{
int ret = -1;
- char key[64] = {
+ char key[32] = {
0,
};
int keylen;
char *peer_uuid_str = NULL;
+ xlator_t *this = THIS;
+ GF_ASSERT(this);
GF_ASSERT(peerinfo);
GF_ASSERT(friends);
peer_uuid_str = gd_peer_uuid_str(peerinfo);
keylen = snprintf(key, sizeof(key), "friend%d.uuid", count);
ret = dict_set_strn(friends, key, keylen, peer_uuid_str);
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
+ key, NULL);
goto out;
+ }
keylen = snprintf(key, sizeof(key), "friend%d.hostname", count);
ret = dict_set_strn(friends, key, keylen, peerinfo->hostname);
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
+ key, NULL);
goto out;
+ }
keylen = snprintf(key, sizeof(key), "friend%d.port", count);
ret = dict_set_int32n(friends, key, keylen, peerinfo->port);
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
+ key, NULL);
goto out;
+ }
keylen = snprintf(key, sizeof(key), "friend%d.stateId", count);
ret = dict_set_int32n(friends, key, keylen, peerinfo->state.state);
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
+ "Key=%s in dict", key, NULL);
goto out;
+ }
keylen = snprintf(key, sizeof(key), "friend%d.state", count);
ret = dict_set_strn(
friends, key, keylen,
glusterd_friend_sm_state_name_get(peerinfo->state.state));
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "key=%s",
+ key, NULL);
goto out;
+ }
keylen = snprintf(key, sizeof(key), "friend%d.connected", count);
ret = dict_set_int32n(friends, key, keylen, (int32_t)peerinfo->connected);
- if (ret)
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
+ key, NULL);
goto out;
+ }
snprintf(key, sizeof(key), "friend%d", count);
ret = gd_add_peer_hostnames_to_dict(peerinfo, friends, key);
@@ -983,9 +1005,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;
@@ -996,15 +1018,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);