summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaushal M <kaushal@redhat.com>2014-07-15 09:06:58 +0530
committerKrishnan Parthasarathi <kparthas@redhat.com>2014-07-15 06:59:35 -0700
commitfde2b73746e73ea16ba246b8261b552ed2d894dd (patch)
treed7494fb45a4a2daf08cdffb2a0397af11a261264
parentc74ff569ca40c7484c197d23ec342f8445c09b9c (diff)
glusterd: Improvements to peer identification
This patch improves the peer identification mechanism in glusterd and lays down the framework for further improvements, including better multi network support in glusterd. This patch mainly does two things, 1. Extend the peerinfo object to store a list of addresses instead of a single hostname as it does now. This also includes changes to make the peer update behaviour of 'peer probe' to add to the list. 2. Improve glusterd_friend_find_by_hostname() to perform better matching of hostnames. glusterd_friend_find_by_hostname() now does and initial quick string compare against all the peer addresses known to glusterd, after which it tries a more thorough search using address resolution and matching the struc sockaddr's. The above two changes together improve the peer identification situation in glusterd a lot. More information regarding the problem this patch attempts to resolve and the approach chosen can be found at http://www.gluster.org/community/documentation/index.php/Features/Better_peer_identification This commit is a squashed commit of the following changes, the development branch of which can be viewed at, https://github.com/kshlm/glusterfs/tree/better-peer-identification or, https://forge.gluster.org/~kshlm/glusterfs-core/kshlms-glusterfs/commits/better-peer-identification commit 198f86e60fab74faf082eaa02657a4d8f60b92f0 Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 15 14:34:06 2014 +0530 Update gluster.8 commit 35d597f3a6b3248373e727f7b7e889c92554d56c Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 15 09:01:01 2014 +0530 Address review comments https://review.gluster.org/#/c/8238/3 commit 47b5331e17304477322bd2daed5bbed503c34ca1 Merge: c71b12c 78128af Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 15 08:41:39 2014 +0530 Merge branch 'master' into better-peer-identification commit c71b12c164330e8d19d1df4734ab34ef9a8caad2 Merge: 57bc9de 0f5719a Author: Kaushal M <kaushal@redhat.com> Date: Thu Jul 10 19:50:19 2014 +0530 Merge branch 'master' into better-peer-identification commit 57bc9de9e4f49ff2b1620df9906cda50a3527a25 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jul 10 19:49:08 2014 +0530 More fixes to review comments commit 5482cc363a687a9e246a0780ec88acd53e218501 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jul 10 18:36:40 2014 +0530 Code refactoring in peer-utils based on review comments https://review.gluster.org/#/c/8238/2/xlators/mgmt/glusterd/src/glusterd-peer-utils.c commit 89b22c34757178f64d5fbaffa31e6302f841c060 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jul 10 12:30:00 2014 +0530 Hostnames in peer status commit 63ebf9485cf50d736cf640238a1ab241671fcaf1 Merge: c8c8fdd f5f9721 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jul 10 12:06:33 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit c8c8fdd2104b5b6b8a1af739b1dd952b74e6dd66 Author: Kaushal M <kaushal@redhat.com> Date: Wed Jul 9 18:35:27 2014 +0530 Hostnames in xml output commit 732a92a0167ad7b1d70edbc35ebd8307c2766ae1 Author: Kaushal M <kaushal@redhat.com> Date: Wed Jul 9 15:12:10 2014 +0530 Add hostnames to cli rsp dict during list-friends commit fcf43e3e317508f0c225024738a988a4af8e9205 Merge: c0e2624 72d96e2 Author: Kaushal M <kaushal@redhat.com> Date: Wed Jul 9 12:53:03 2014 +0530 Merge branch 'master' into better-peer-identification commit c0e262416728a3c536a8347a216e471eb2251535 Author: Kaushal M <kaushal@redhat.com> Date: Mon Jul 7 16:11:19 2014 +0530 Use list_for_each_entry_safe when cleaning peer hostnames commit 6132e60224eb592f3657e535a12a3e72c772da42 Author: Kaushal M <kaushal@redhat.com> Date: Mon Jul 7 15:52:19 2014 +0530 Fix crash in gd_add_friend_to_dict commit 88ffa9a508fd5aac0b2a76e6e76487ce0cab786a Author: Kaushal M <kaushal@redhat.com> Date: Mon Jul 7 13:19:44 2014 +0530 gd_peerinfo_destroy -> glusterd_peerinfo_destroy commit 4b36930a715b1e13cd1a77d136ef1cf78a06d574 Author: Kaushal M <kaushal@redhat.com> Date: Mon Jul 7 12:50:12 2014 +0530 More refactoring commit ee559b081d608c6501c10ae22166f26eeb65690e Author: Kaushal M <kaushal@redhat.com> Date: Mon Jul 7 12:14:40 2014 +0530 Major refactoring of code based on review comments at https://review.gluster.org/#/c/8238/1/xlators/mgmt/glusterd/src/glusterd-peer-utils.h commit e96dbc7bbb05fad2a9c424de41a394b8023fe48d Merge: 2613d1d 83c09b7 Author: Kaushal M <kaushal@redhat.com> Date: Mon Jul 7 09:47:05 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit 2613d1daebff0c56812de821c06ed4c16bb9d447 Merge: b242cf6 9a50211 Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 15:28:57 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit b242cf66d95dd3dd5e3975aa430baa6bd74b8a29 Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 15:08:18 2014 +0530 Fix a silly mistake, if (ctx->req) => if (ctx->req == NULL) commit c835ed26433830ceed57289143f596cf60421558 Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 14:58:23 2014 +0530 Fix reverse probe. commit 9ede17f9329b854b02e8ad159f173244789fd08c Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 13:31:32 2014 +0530 Fix friend import for existing peers commit 891bf74c7350064dfb008d1b7294bcec28d680fd Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 13:08:36 2014 +0530 Set first hostname in peerinfo->hostnames to peerinfo->hostname commit 9421d6a217381a7427a7d84f369280883ca4297a Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 12:21:40 2014 +0530 Fix gf_asprintf return val check in glusterd_store_peer_write commit defac978c1d94011ce8195e311839b9ffce057e7 Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 11:16:13 2014 +0530 Fix store_retrieve_peers to correctly cleanup. commit 00a799f5de1121b0cb7421da8285f9407063e1bd Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 10:52:11 2014 +0530 Update address list in glusterd_probe_cbk only when needed. commit 7a628e8a9c562d85709c69cfa13fb1774c521b75 Merge: d191985 dc46d5e Author: Kaushal M <kaushal@redhat.com> Date: Fri Jul 4 09:24:12 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit d1919858e6639d2b54d716a61f662d9752ec5ff1 Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 18:59:49 2014 +0530 gf_compare_addrinfo -> gf_compare_sockaddr commit 31d8ef730d408f8d9ba8f504fa648f7dcd59da87 Merge: 93bbede 86ee233 Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 18:16:13 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit 93bbedeac5181e29f59b2acd08f638146812ec41 Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 18:15:16 2014 +0530 Improve glusterd_friend_find_by_hostname glusterd_friend_find_by_hostname will now do an initial quick search for the peerinfo performing string comparisions on the given host string. It follows it with a more thorough match, by resolving the addresses and comparing addrinfos instead of strings. commit 2542cdbc45aa9cfcaf1f174686158d5565cdd07b Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 17:21:10 2014 +0530 New utility gf_compare_addrinfo commit 338676e8389a44bd91136eebd110197429c2566c Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 14:55:56 2014 +0530 Use gd_peer_has_address instead of strcmp commit 28d45be51f594328741c44455bd80ac9d64ca501 Merge: 728266e 991dd5e Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 14:54:40 2014 +0530 Merge branch 'master' into better-peer-identification commit 728266eb16d5f5a4bf36266044425ae164337f99 Merge: 7d9b87b 2417de9 Author: Kaushal M <kaushal@redhat.com> Date: Tue Jul 1 09:55:13 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit 7d9b87b84955ec17daeaf88a3e7462914039430f Merge: b890625 e02275c Author: Kaushal M <kshlmster@gmail.com> Date: Tue Jul 1 08:41:40 2014 +0530 Merge pull request #4 from vpshastry/better-peer-identification Better peer identification commit e02275c52fb83c72ad082c098fd3e432c2b9c526 Merge: 75ee90d b890625 Author: Varun Shastry <vshastry@redhat.com> Date: Mon Jun 30 16:44:29 2014 +0530 Merge branch 'better-peer-identification' of https://github.com/kshlm/glusterfs into better-peer-identification-kaushal-github commit 75ee90d2f272e49b94d24c9ca4571e89a83055ff Author: Varun Shastry <vshastry@redhat.com> Date: Mon Jun 30 15:36:10 2014 +0530 glusterd: add to the list if the probed uuid pre-exists Signed-off-by: Varun Shastry <vshastry@redhat.com> commit b890625d8164c660695daef3285c67979eef723e Merge: 04c5d60 187a7a9 Author: Kaushal M <kaushal@redhat.com> Date: Mon Jun 30 11:44:13 2014 +0530 Merge remote-tracking branch 'origin/master' into better-peer-identification commit 04c5d60cb938c8d94b214689580b40abb1b0ffcd Merge: 3a5bfa1 e01edb6 Author: Kaushal M <kshlmster@gmail.com> Date: Sat Jun 28 19:23:33 2014 +0530 Merge pull request #3 from vpshastry/better-peer-identification glusterd: search through the list of hostnames in the peerinfo commit 0c64f3346a977f9165ac55a84a1e03c40a7573a7 Merge: e01edb6 3a5bfa1 Author: Varun Shastry <vshastry@redhat.com> Date: Sat Jun 28 10:43:29 2014 +0530 Merge branch 'better-peer-identification' of https://github.com/kshlm/glusterfs into better-peer-identification-kaushal-github commit e01edb63153a1008db70b8fa76ae5b535e099326 Author: Varun Shastry <vshastry@redhat.com> Date: Fri Jun 27 12:29:36 2014 +0530 glusterd: search through the list of hostnames in the peerinfo Signed-off-by: Varun Shastry <vshastry@redhat.com> commit 3a5bfa15855e660db2bfde644727371dd2d618cc Merge: cda6d31 371ea35 Author: Kaushal M <kshlmster@gmail.com> Date: Fri Jun 27 11:31:17 2014 +0530 Merge pull request #1 from vpshastry/better-peer-identification glusterd: Add hostname to list instead of replaceing upon update commit 371ea354f198b4182382d5403c5960c0b2add6b6 Author: Varun Shastry <vshastry@redhat.com> Date: Fri Jun 27 11:24:54 2014 +0530 glusterd: Add hostname to list instead of replaceing upon update Signed-off-by: Varun Shastry <vshastry@redhat.com> commit cda6d3152886623ecbf46baf0048ebe0119b30b6 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jun 26 19:52:52 2014 +0530 Import address lists commit 6649b54aa0440130c08e827e0a1d1bbfb840eca9 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jun 26 19:15:37 2014 +0530 Implement export address list commit 55990034eead92bc9b936240029e460a4bf152d5 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jun 26 18:11:59 2014 +0530 Use first address in list to when setting up the peer RPC. commit a35fde8d19b9988eb04c652fb3a5e4f84d90ad00 Author: Kaushal M <kaushal@redhat.com> Date: Thu Jun 26 18:03:04 2014 +0530 Properly free addresses on glusterd_peer_destroy commit 1988081db09ac9205f3dc7268cef8be267f3ce8b Author: Kaushal M <kaushal@redhat.com> Date: Thu Jun 26 17:52:35 2014 +0530 Restore peerinfo with address list implemented. commit 66f524d5749a12f4910dd6b06c9d91f37e1d831e Author: Kaushal M <kaushal@redhat.com> Date: Mon Jun 23 13:02:23 2014 +0530 Move out all peer related utilities from glusterd-utils to glusterd-peer-utils commit 14a2a326a4dff11b55490dca2a14f39320931340 Author: Kaushal M <kaushal@redhat.com> Date: Tue May 27 12:16:41 2014 +0530 Compilation fix commit c59cd351d0a102d0d5f3ea9001fd33c4edcb262f Author: Kaushal M <kaushal@redhat.com> Date: Mon May 5 12:51:11 2014 +0530 Add store support for hostname list commit b70325f0beb884ad12645ef40185f0bf6cedd741 Author: Kaushal M <kaushal@redhat.com> Date: Fri May 2 15:58:07 2014 +0530 Add a hostnames list to glusterd_peerinfo_t glusterd_peerinfo_new will now init this list and add the given hostname as the lists first member. Signed-off-by: Kaushal M <kaushal@redhat.com> Signed-off-by: Varun Shastry <vshastry@redhat.com> Change-Id: Ief3c5d6d6f16571ee2fab0a45e638b9d6506a06e BUG: 1119547 Reviewed-on: http://review.gluster.org/8238 Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
-rw-r--r--cli/src/cli-rpc-ops.c39
-rw-r--r--cli/src/cli-xml-output.c47
-rw-r--r--doc/gluster.82
-rw-r--r--libglusterfs/src/common-utils.c33
-rw-r--r--libglusterfs/src/common-utils.h3
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c310
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c18
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.c902
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.h87
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c142
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c20
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c91
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c407
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h44
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h8
20 files changed, 1462 insertions, 722 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index ee7d3b2c841..b7c6691abd5 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -215,6 +215,31 @@ out:
}
int
+gf_cli_output_peer_hostnames (dict_t *dict, int count, char *prefix)
+{
+ int ret = -1;
+ char key[256] = {0,};
+ int i = 0;
+ char *hostname = NULL;
+
+ cli_out ("Other names:");
+ /* Starting from friend.hostname1, as friend.hostname0 will be the same
+ * as friend.hostname
+ */
+ for (i = 1; i < count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname%d", prefix, i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ break;
+ cli_out ("%s", hostname);
+ hostname = NULL;
+ }
+
+ return ret;
+}
+
+int
gf_cli_output_peer_status (dict_t *dict, int count)
{
int ret = -1;
@@ -225,6 +250,7 @@ gf_cli_output_peer_status (dict_t *dict, int count)
char *state = NULL;
int32_t connected = 0;
char *connected_str = NULL;
+ int hostname_count = 0;
cli_out ("Number of Peers: %d", count);
i = 1;
@@ -256,6 +282,19 @@ gf_cli_output_peer_status (dict_t *dict, int count)
cli_out ("\nHostname: %s\nUuid: %s\nState: %s (%s)",
hostname_buf, uuid_buf, state, connected_str);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.hostname_count", i);
+ ret = dict_get_int32 (dict, key, &hostname_count);
+ /* Print other addresses only if there are more than 1.
+ */
+ if ((ret == 0) && (hostname_count > 1)) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d", i);
+ ret = gf_cli_output_peer_hostnames (dict,
+ hostname_count,
+ key);
+ }
i++;
}
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
index dd38a51c6c0..78d131583e9 100644
--- a/cli/src/cli-xml-output.c
+++ b/cli/src/cli-xml-output.c
@@ -3018,6 +3018,41 @@ out:
#endif
}
+#if (HAVE_LIB_XML)
+static int
+cli_xml_output_peer_hostnames (xmlTextWriterPtr writer, dict_t *dict,
+ const char *prefix, int count)
+{
+ int ret = -1;
+ int i = 0;
+ char *hostname = NULL;
+ char key[1024] = {0,};
+
+ /* <hostnames> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"hostnames");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (i = 0; i < count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname%d", prefix, i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement
+ (writer, (xmlChar *)"hostname", "%s", hostname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ hostname = NULL;
+ }
+
+ /* </hostnames> */
+ ret = xmlTextWriterEndElement (writer);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+#endif
+
int
cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
char *op_errstr)
@@ -3032,6 +3067,7 @@ cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
int connected = 0;
int state_id = 0;
char *state_str = NULL;
+ int hostname_count = 0;
int i = 1;
char key[1024] = {0,};
@@ -3082,6 +3118,17 @@ cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
XML_RET_CHECK_AND_GOTO (ret, out);
memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.hostname_count", i);
+ ret = dict_get_int32 (dict, key, &hostname_count);
+ if ((ret == 0) && (hostname_count > 0)) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d", i);
+ ret = cli_xml_output_peer_hostnames (writer, dict, key,
+ hostname_count);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
+ memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "friend%d.connected", i);
ret = dict_get_int32 (dict, key, &connected);
if (ret)
diff --git a/doc/gluster.8 b/doc/gluster.8
index de3eee1b0e2..87b83956ce6 100644
--- a/doc/gluster.8
+++ b/doc/gluster.8
@@ -95,7 +95,7 @@ Rotate the log file for corresponding volume/brick.
.SS "Peer Commands"
.TP
\fB\ peer probe <HOSTNAME> \fR
-Probe the specified peer.
+Probe the specified peer. In case the <HOSTNAME> given belongs to an already probed peer, the peer probe command will add the hostname to the peer if required.
.TP
\fB\ peer detach <HOSTNAME> \fR
Detach the specified peer.
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 124b312f4a1..54ee3e53818 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -3199,3 +3199,36 @@ gf_check_logger (const char *value)
return logger;
}
+
+/* gf_compare_sockaddr compares the given addresses @addr1 and @addr2 for
+ * equality, ie. if they both refer to the same address.
+ *
+ * This was inspired by sock_addr_cmp_addr() from
+ * https://www.opensource.apple.com/source/postfix/postfix-197/postfix/src/util/sock_addr.c
+ */
+gf_boolean_t
+gf_compare_sockaddr (const struct sockaddr *addr1,
+ const struct sockaddr *addr2)
+{
+ GF_ASSERT (addr1 != NULL);
+ GF_ASSERT (addr2 != NULL);
+
+ /* Obviously, the addresses don't match if their families are different
+ */
+ if (addr1->sa_family != addr2->sa_family)
+ return _gf_false;
+
+
+ if (AF_INET == addr1->sa_family) {
+ if (((struct sockaddr_in *)addr1)->sin_addr.s_addr ==
+ ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
+ return _gf_true;
+
+ } else if (AF_INET6 == addr1->sa_family) {
+ if (memcmp ((char *)&((struct sockaddr_in6 *)addr1)->sin6_addr,
+ (char *)&((struct sockaddr_in6 *)addr2)->sin6_addr,
+ sizeof (struct in6_addr)) == 0)
+ return _gf_true;
+ }
+ return _gf_false;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index b4372f10bbc..1ddb46c6758 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -639,4 +639,7 @@ gf_check_log_format (const char *value);
int
gf_check_logger (const char *value);
+gf_boolean_t
+gf_compare_sockaddr (const struct sockaddr *addr1,
+ const struct sockaddr *addr2);
#endif /* _COMMON_UTILS_H */
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
index e4636089ee7..7f3e8ddd88f 100644
--- a/xlators/mgmt/glusterd/src/Makefile.am
+++ b/xlators/mgmt/glusterd/src/Makefile.am
@@ -12,8 +12,8 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \
glusterd-geo-rep.c glusterd-replace-brick.c glusterd-log-ops.c \
glusterd-volume-ops.c glusterd-brick-ops.c glusterd-mountbroker.c \
glusterd-syncop.c glusterd-hooks.c glusterd-volume-set.c \
- glusterd-locks.c glusterd-snapshot.c glusterd-mgmt-handler.c \
- glusterd-mgmt.c
+ glusterd-locks.c glusterd-snapshot.c glusterd-mgmt-handler.c \
+ glusterd-mgmt.c glusterd-peer-utils.c
glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la \
@@ -24,7 +24,7 @@ noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h \
glusterd-sm.h glusterd-store.h glusterd-mem-types.h \
glusterd-pmap.h glusterd-volgen.h glusterd-mountbroker.h \
glusterd-syncop.h glusterd-hooks.h glusterd-locks.h \
- glusterd-mgmt.h glusterd-messages.h
+ glusterd-mgmt.h glusterd-messages.h glusterd-peer-utils.h
AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
-I$(rpclibdir) -I$(CONTRIBDIR)/rbtree \
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;
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c b/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c
index 48e390f5692..c0c1cfcba18 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c
@@ -122,7 +122,6 @@ glusterd_handle_mgmt_v3_lock_fn (rpcsvc_request_t *req)
{
gd1_mgmt_v3_lock_req lock_req = {{0},};
int32_t ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
glusterd_op_lock_ctx_t *ctx = NULL;
xlator_t *this = NULL;
gf_boolean_t is_synctasked = _gf_false;
@@ -144,7 +143,7 @@ glusterd_handle_mgmt_v3_lock_fn (rpcsvc_request_t *req)
gf_log (this->name, GF_LOG_DEBUG, "Received mgmt_v3 lock req "
"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));
@@ -247,7 +246,6 @@ glusterd_handle_pre_validate_fn (rpcsvc_request_t *req)
{
int32_t ret = -1;
gd1_mgmt_v3_pre_val_req op_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
xlator_t *this = NULL;
char *op_errstr = NULL;
dict_t *dict = NULL;
@@ -267,7 +265,7 @@ glusterd_handle_pre_validate_fn (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));
@@ -374,7 +372,6 @@ glusterd_handle_brick_op_fn (rpcsvc_request_t *req)
{
int32_t ret = -1;
gd1_mgmt_v3_brick_op_req op_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
xlator_t *this = NULL;
char *op_errstr = NULL;
dict_t *dict = NULL;
@@ -393,7 +390,7 @@ glusterd_handle_brick_op_fn (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));
@@ -499,7 +496,6 @@ glusterd_handle_commit_fn (rpcsvc_request_t *req)
{
int32_t ret = -1;
gd1_mgmt_v3_commit_req op_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
xlator_t *this = NULL;
char *op_errstr = NULL;
dict_t *dict = NULL;
@@ -518,7 +514,7 @@ glusterd_handle_commit_fn (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));
@@ -625,7 +621,6 @@ glusterd_handle_post_validate_fn (rpcsvc_request_t *req)
{
int32_t ret = -1;
gd1_mgmt_v3_post_val_req op_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
xlator_t *this = NULL;
char *op_errstr = NULL;
dict_t *dict = NULL;
@@ -645,7 +640,7 @@ glusterd_handle_post_validate_fn (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));
@@ -794,7 +789,6 @@ glusterd_handle_mgmt_v3_unlock_fn (rpcsvc_request_t *req)
gd1_mgmt_v3_unlock_req lock_req = {{0},};
int32_t ret = -1;
glusterd_op_lock_ctx_t *ctx = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
xlator_t *this = NULL;
gf_boolean_t is_synctasked = _gf_false;
gf_boolean_t free_ctx = _gf_false;
@@ -815,7 +809,7 @@ glusterd_handle_mgmt_v3_unlock_fn (rpcsvc_request_t *req)
gf_log (this->name, GF_LOG_DEBUG, "Received volume unlock req "
"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));
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 66276bd466d..52ab039b9ec 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1200,8 +1200,9 @@ glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr)
ret = 0;
}
} else {
- ret = glusterd_friend_find (NULL, hostname, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (NULL, hostname);
+ if (peerinfo == NULL) {
+ ret = -1;
snprintf (msg, sizeof (msg), "%s, is not a friend",
hostname);
*op_errstr = gf_strdup (msg);
diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
new file mode 100644
index 00000000000..be8ae76c77a
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
@@ -0,0 +1,902 @@
+/*
+ Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#include "glusterd-peer-utils.h"
+#include "glusterd-store.h"
+#include "common-utils.h"
+
+int32_t
+glusterd_peerinfo_cleanup (glusterd_peerinfo_t *peerinfo)
+{
+ GF_ASSERT (peerinfo);
+ glusterd_peerctx_t *peerctx = NULL;
+ gf_boolean_t quorum_action = _gf_false;
+ glusterd_conf_t *priv = THIS->private;
+
+ if (peerinfo->quorum_contrib != QUORUM_NONE)
+ quorum_action = _gf_true;
+ if (peerinfo->rpc) {
+ peerctx = peerinfo->rpc->mydata;
+ peerinfo->rpc->mydata = NULL;
+ peerinfo->rpc = glusterd_rpc_clnt_unref (priv, peerinfo->rpc);
+ peerinfo->rpc = NULL;
+ if (peerctx) {
+ GF_FREE (peerctx->errstr);
+ GF_FREE (peerctx);
+ }
+ }
+ glusterd_peerinfo_destroy (peerinfo);
+
+ if (quorum_action)
+ glusterd_do_quorum_action ();
+ return 0;
+}
+
+int32_t
+glusterd_peerinfo_destroy (glusterd_peerinfo_t *peerinfo)
+{
+ int32_t ret = -1;
+ glusterd_peer_hostname_t *hostname = NULL;
+ glusterd_peer_hostname_t *tmp = NULL;
+
+ if (!peerinfo)
+ goto out;
+
+ list_del_init (&peerinfo->uuid_list);
+
+ ret = glusterd_store_delete_peerinfo (peerinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Deleting peer info failed");
+ }
+
+ GF_FREE (peerinfo->hostname);
+ peerinfo->hostname = NULL;
+
+ list_for_each_entry_safe (hostname, tmp, &peerinfo->hostnames,
+ hostname_list) {
+ glusterd_peer_hostname_free (hostname);
+ }
+
+ glusterd_sm_tr_log_delete (&peerinfo->sm_log);
+ GF_FREE (peerinfo);
+ peerinfo = NULL;
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/* 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.
+ *
+ * It first attempts a quick search by string matching @hoststr. If that fails,
+ * it'll attempt a more thorough match by resolving the addresses and matching
+ * the resolved addrinfos.
+ */
+glusterd_peerinfo_t *
+glusterd_peerinfo_find_by_hostname (const char *hoststr)
+{
+ int ret = -1;
+ struct addrinfo *addr = NULL;
+ struct addrinfo *p = NULL;
+ xlator_t *this = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+
+
+ this = THIS;
+ GF_ASSERT (hoststr);
+
+ peerinfo = NULL;
+
+ peerinfo = gd_peerinfo_find_from_hostname (hoststr);
+ if (peerinfo)
+ return peerinfo;
+
+ ret = getaddrinfo (hoststr, NULL, NULL, &addr);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error in getaddrinfo: %s\n",
+ gai_strerror(ret));
+ goto out;
+ }
+
+ for (p = addr; p != NULL; p = p->ai_next) {
+ peerinfo = gd_peerinfo_find_from_addrinfo (p);
+ if (peerinfo) {
+ freeaddrinfo (addr);
+ return peerinfo;
+ }
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Unable to find friend: %s", hoststr);
+ if (addr)
+ freeaddrinfo (addr);
+ return NULL;
+}
+
+int
+glusterd_hostname_to_uuid (char *hostname, uuid_t uuid)
+{
+ GF_ASSERT (hostname);
+ GF_ASSERT (uuid);
+
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ int ret = -1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ peerinfo = glusterd_peerinfo_find_by_hostname (hostname);
+ if (peerinfo) {
+ ret = 0;
+ uuid_copy (uuid, peerinfo->uuid);
+ } else {
+ if (gf_is_local_addr (hostname)) {
+ uuid_copy (uuid, MY_UUID);
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
+
+/* glusterd_peerinfo_find_by_uuid searches for a peer which matches the
+ * uuid @uuid and if found returns the pointer to peerinfo object.
+ * Returns NULL otherwise.
+ */
+glusterd_peerinfo_t *
+glusterd_peerinfo_find_by_uuid (uuid_t uuid)
+{
+ glusterd_conf_t *priv = NULL;
+ glusterd_peerinfo_t *entry = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+
+ GF_ASSERT (priv);
+
+ if (uuid_is_null (uuid))
+ return NULL;
+
+ list_for_each_entry (entry, &priv->peers, uuid_list) {
+ if (!uuid_compare (entry->uuid, uuid)) {
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Friend found... state: %s",
+ glusterd_friend_sm_state_name_get (entry->state.state));
+ return entry;
+ }
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG, "Friend with uuid: %s, not found",
+ uuid_utoa (uuid));
+ return NULL;
+}
+
+/* glusterd_peerinfo_find will search for a peer matching either @uuid or
+ * @hostname and return a pointer to the peerinfo object
+ * Returns NULL otherwise.
+ */
+glusterd_peerinfo_t *
+glusterd_peerinfo_find (uuid_t uuid, const char *hostname)
+{
+ glusterd_peerinfo_t *peerinfo = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+
+ if (uuid) {
+ peerinfo = glusterd_peerinfo_find_by_uuid (uuid);
+
+ if (peerinfo) {
+ return peerinfo;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Unable to find peer by uuid: %s",
+ uuid_utoa (uuid));
+ }
+
+ }
+
+ if (hostname) {
+ peerinfo = glusterd_peerinfo_find_by_hostname (hostname);
+
+ if (peerinfo) {
+ return peerinfo;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Unable to find hostname: %s", hostname);
+ }
+ }
+ return NULL;
+}
+
+/* glusterd_peerinfo_new will create a new peerinfo object and set it's members
+ * values using the passed parameters.
+ * @hostname is added as the first entry in peerinfo->hostnames list and also
+ * set to peerinfo->hostname.
+ * It returns a pointer to peerinfo object if successfull and returns NULL
+ * otherwise. The caller should take care of freeing the created peerinfo
+ * object.
+ */
+glusterd_peerinfo_t *
+glusterd_peerinfo_new (glusterd_friend_sm_state_t state, uuid_t *uuid,
+ const char *hostname, int port)
+{
+ glusterd_peerinfo_t *new_peer = NULL;
+ int ret = -1;
+
+ new_peer = GF_CALLOC (1, sizeof (*new_peer), gf_gld_mt_peerinfo_t);
+ if (!new_peer)
+ goto out;
+
+ INIT_LIST_HEAD (&new_peer->uuid_list);
+
+ new_peer->state.state = state;
+
+ INIT_LIST_HEAD (&new_peer->hostnames);
+ if (hostname) {
+ ret = gd_add_address_to_peer (new_peer, hostname);
+ if (ret)
+ goto out;
+ /* Also set it to peerinfo->hostname. Doing this as we use
+ * peerinfo->hostname in a lot of places and is really hard to
+ * get everything right
+ */
+ new_peer->hostname = gf_strdup (hostname);
+ }
+
+ if (uuid) {
+ uuid_copy (new_peer->uuid, *uuid);
+ }
+
+ ret = glusterd_sm_tr_log_init (&new_peer->sm_log,
+ glusterd_friend_sm_state_name_get,
+ glusterd_friend_sm_event_name_get,
+ GLUSTERD_TR_LOG_SIZE);
+ if (ret)
+ goto out;
+
+ if (new_peer->state.state == GD_FRIEND_STATE_BEFRIENDED)
+ new_peer->quorum_contrib = QUORUM_WAITING;
+ new_peer->port = port;
+out:
+ if (ret && new_peer) {
+ glusterd_peerinfo_cleanup (new_peer);
+ new_peer = NULL;
+ }
+ return new_peer;
+}
+
+/* Check if the all peers are connected and befriended, except the peer
+ * specified (the peer being detached)
+ */
+gf_boolean_t
+glusterd_chk_peers_connected_befriended (uuid_t skip_uuid)
+{
+ gf_boolean_t ret = _gf_true;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+
+ priv= THIS->private;
+ GF_ASSERT (priv);
+
+ list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
+
+ if (!uuid_is_null (skip_uuid) && !uuid_compare (skip_uuid,
+ peerinfo->uuid))
+ continue;
+
+ if ((GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state)
+ || !(peerinfo->connected)) {
+ ret = _gf_false;
+ break;
+ }
+ }
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %s",
+ (ret?"TRUE":"FALSE"));
+ return ret;
+}
+
+/* Return hostname for given uuid if it exists
+ * else return NULL
+ */
+char *
+glusterd_uuid_to_hostname (uuid_t uuid)
+{
+ char *hostname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_peerinfo_t *entry = NULL;
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ if (!uuid_compare (MY_UUID, uuid)) {
+ hostname = gf_strdup ("localhost");
+ }
+ if (!list_empty (&priv->peers)) {
+ list_for_each_entry (entry, &priv->peers, uuid_list) {
+ if (!uuid_compare (entry->uuid, uuid)) {
+ hostname = gf_strdup (entry->hostname);
+ break;
+ }
+ }
+ }
+
+ return hostname;
+}
+
+char*
+gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo)
+{
+ if ((peerinfo == NULL) || uuid_is_null (peerinfo->uuid))
+ return NULL;
+
+ if (peerinfo->uuid_str[0] == '\0')
+ uuid_utoa_r (peerinfo->uuid, peerinfo->uuid_str);
+
+ return peerinfo->uuid_str;
+}
+
+gf_boolean_t
+glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
+ struct list_head *peers,
+ char **down_peerstr)
+{
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ gf_boolean_t ret = _gf_false;
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (!uuid_compare (brickinfo->uuid, MY_UUID))
+ continue;
+
+ list_for_each_entry (peerinfo, peers, uuid_list) {
+ if (uuid_compare (peerinfo->uuid, brickinfo->uuid))
+ continue;
+
+ /*Found peer who owns the brick, return false
+ * if peer is not connected or not friend */
+ if (!(peerinfo->connected) ||
+ (peerinfo->state.state !=
+ GD_FRIEND_STATE_BEFRIENDED)) {
+ *down_peerstr = gf_strdup (peerinfo->hostname);
+ gf_log ("", GF_LOG_DEBUG, "Peer %s is down. ",
+ peerinfo->hostname);
+ goto out;
+ }
+ }
+ }
+
+ ret = _gf_true;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_peer_hostname_new (const char *hostname,
+ glusterd_peer_hostname_t **name)
+{
+ glusterd_peer_hostname_t *peer_hostname = NULL;
+ int32_t ret = -1;
+
+ GF_ASSERT (hostname);
+ GF_ASSERT (name);
+
+ peer_hostname = GF_CALLOC (1, sizeof (*peer_hostname),
+ gf_gld_mt_peer_hostname_t);
+
+ if (!peer_hostname)
+ goto out;
+
+ peer_hostname->hostname = gf_strdup (hostname);
+ INIT_LIST_HEAD (&peer_hostname->hostname_list);
+
+ *name = peer_hostname;
+ ret = 0;
+
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+void
+glusterd_peer_hostname_free (glusterd_peer_hostname_t *name)
+{
+ if (!name)
+ return;
+
+ list_del_init (&name->hostname_list);
+
+ GF_FREE (name->hostname);
+ name->hostname = NULL;
+
+ GF_FREE (name);
+
+ return;
+}
+
+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);
+ GF_VALIDATE_OR_GOTO ("glusterd", (address != NULL), out);
+
+ list_for_each_entry (hostname, &peerinfo->hostnames, hostname_list) {
+ if (strcmp (hostname->hostname, address) == 0) {
+ ret = _gf_true;
+ break;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int
+gd_add_address_to_peer (glusterd_peerinfo_t *peerinfo, const char *address)
+{
+
+ int ret = -1;
+ glusterd_peer_hostname_t *hostname = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", (peerinfo != NULL), out);
+ GF_VALIDATE_OR_GOTO ("glusterd", (address != NULL), out);
+
+ if (gd_peer_has_address (peerinfo, address)) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = glusterd_peer_hostname_new (address, &hostname);
+ if (ret)
+ goto out;
+
+ list_add_tail (&hostname->hostname_list, &peerinfo->hostnames);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+/* gd_add_friend_to_dict() adds details of @friend into @dict with the given
+ * @prefix. All the parameters are compulsary.
+ *
+ * The complete address list is added to the dict only if the cluster op-version
+ * is >= GD_OP_VERSION_3_6_0
+ */
+int
+gd_add_friend_to_dict (glusterd_peerinfo_t *friend, dict_t *dict,
+ const char *prefix)
+{
+ int ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ char key[100] = {0,};
+ glusterd_peer_hostname_t *address = NULL;
+ int count = 0;
+
+ this = THIS;
+ GF_VALIDATE_OR_GOTO ("glusterd", (this != NULL), out);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
+
+ GF_VALIDATE_OR_GOTO (this->name, (friend != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
+
+ snprintf (key, sizeof (key), "%s.uuid", prefix);
+ ret = dict_set_dynstr_with_alloc (dict, key, uuid_utoa (friend->uuid));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set key %s in dict", key);
+ goto out;
+ }
+
+ /* Setting the first hostname from the list with this key for backward
+ * compatability
+ */
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname", prefix);
+ address = list_entry (&friend->hostnames, glusterd_peer_hostname_t,
+ hostname_list);
+ if (!address) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "Could not retrieve first "
+ "address for peer");
+ goto out;
+ }
+ ret = dict_set_dynstr_with_alloc (dict, key, address->hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set key %s in dict", key);
+ goto out;
+ }
+
+ if (conf->op_version < GD_OP_VERSION_3_6_0) {
+ ret = 0;
+ goto out;
+ }
+
+ address = NULL;
+ count = 0;
+ list_for_each_entry (address, &friend->hostnames, hostname_list) {
+ GF_VALIDATE_OR_GOTO (this->name, (address != NULL), out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname%d", prefix, count);
+ ret = dict_set_dynstr_with_alloc (dict, key, address->hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set key %s in dict", key);
+ goto out;
+ }
+ count++;
+ }
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.address-count", prefix);
+ ret = dict_set_int32 (dict, key, count);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set key %s in dict", key);
+
+out:
+ gf_log (this ? this->name : "glusterd", GF_LOG_DEBUG, "Returning %d",
+ ret);
+ 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_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);
+
+ list_for_each_entry (peer, &priv->peers, uuid_list) {
+ list_for_each_entry (tmphost, &peer->hostnames,hostname_list) {
+ if (!strncasecmp (tmphost->hostname, hoststr, 1024)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Friend %s found.. state: %d",
+ tmphost->hostname, peer->state.state);
+ return peer;
+ }
+ }
+ }
+out:
+ return NULL;
+}
+
+/* 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_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);
+
+ list_for_each_entry (peer, &conf->peers, uuid_list) {
+ list_for_each_entry (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_log (this->name, GF_LOG_TRACE,
+ "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)) {
+ freeaddrinfo (paddr);
+ return peer;
+ }
+ }
+ }
+ }
+out:
+ return NULL;
+}
+
+/* gd_update_peerinfo_from_dict will update the hostnames for @peerinfo from
+ * peer details with @prefix in @dict.
+ * Returns 0 on sucess and -1 on failure.
+ */
+int
+gd_update_peerinfo_from_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[100] = {0,};
+ char *hostname = NULL;
+ int count = 0;
+ int i = 0;
+
+ this = THIS;
+ GF_ASSERT (this != NULL);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
+
+ GF_VALIDATE_OR_GOTO (this->name, (peerinfo != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname", prefix);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Key %s not present in "
+ "dictionary", key);
+ goto out;
+ }
+ ret = gd_add_address_to_peer (peerinfo, hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Could not add address to peer");
+ goto out;
+ }
+ /* Also set peerinfo->hostname to the first address */
+ if (peerinfo->hostname != NULL)
+ GF_FREE (peerinfo->hostname);
+ peerinfo->hostname = gf_strdup (hostname);
+
+ if (conf->op_version < GD_OP_VERSION_3_6_0) {
+ ret = 0;
+ goto out;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.address-count", prefix);
+ ret = dict_get_int32 (dict, key, &count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Key %s not present in "
+ "dictionary", key);
+ goto out;
+ }
+ hostname = NULL;
+ for (i = 0; i < count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname%d",prefix, i);
+ ret = dict_get_str (dict, key, &hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Key %s not present "
+ "in dictionary", key);
+ goto out;
+ }
+ ret = gd_add_address_to_peer (peerinfo, hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Could not add address to peer");
+ goto out;
+ }
+
+ hostname = NULL;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+/* gd_peerinfo_from_dict creates a peerinfo object from details of peer with
+ * @prefix in @dict.
+ * Returns a pointer to the created peerinfo object on success, and NULL on
+ * failure.
+ */
+glusterd_peerinfo_t *
+gd_peerinfo_from_dict (dict_t *dict, const char *prefix)
+{
+ int ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ glusterd_peerinfo_t *new_peer = NULL;
+ char key[100] = {0,};
+ char *uuid_str = NULL;
+
+ this = THIS;
+ GF_VALIDATE_OR_GOTO ("glusterd", (this != NULL), out);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
+
+ GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
+
+ new_peer = glusterd_peerinfo_new (GD_FRIEND_STATE_DEFAULT, NULL, NULL,
+ 0);
+ if (new_peer == NULL) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "Could not create peerinfo "
+ "object");
+ goto out;
+ }
+
+ snprintf (key, sizeof (key), "%s.uuid", prefix);
+ ret = dict_get_str (dict, key, &uuid_str);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Key %s not present in "
+ "dictionary", key);
+ goto out;
+ }
+ uuid_parse (uuid_str, new_peer->uuid);
+
+ ret = gd_update_peerinfo_from_dict (new_peer, dict, prefix);
+
+out:
+ if ((ret != 0) && (new_peer != NULL)) {
+ glusterd_peerinfo_cleanup (new_peer);
+ new_peer = NULL;
+ }
+
+ return new_peer;
+}
+
+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] = {0,};
+ glusterd_peer_hostname_t *addr = NULL;
+ int count = 0;
+
+ this = THIS;
+ GF_ASSERT (this != NULL);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
+
+ if (conf->op_version < GD_OP_VERSION_3_6_0) {
+ ret = 0;
+ goto out;
+ }
+
+ GF_VALIDATE_OR_GOTO (this->name, (peerinfo != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
+ GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
+
+ list_for_each_entry (addr, &peerinfo->hostnames, hostname_list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname%d", prefix, count);
+ ret = dict_set_dynstr_with_alloc (dict, key, addr->hostname);
+ if (ret)
+ goto out;
+ count++;
+ }
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.hostname_count", prefix);
+ ret = dict_set_int32 (dict, key, count);
+
+out:
+ return ret;
+}
+
+int
+gd_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, sizeof (key), "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;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.hostname", count);
+ ret = dict_set_str (friends, key, peerinfo->hostname);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.port", count);
+ ret = dict_set_int32 (friends, key, peerinfo->port);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.stateId", count);
+ ret = dict_set_int32 (friends, key, peerinfo->state.state);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.state", count);
+ ret = dict_set_str (friends, key,
+ glusterd_friend_sm_state_name_get(peerinfo->state.state));
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d.connected", count);
+ ret = dict_set_int32 (friends, key, (int32_t)peerinfo->connected);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d", count);
+ ret = gd_add_peer_hostnames_to_dict (peerinfo, friends, key);
+
+out:
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h
new file mode 100644
index 00000000000..9877d861af7
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h
@@ -0,0 +1,87 @@
+/*
+ Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _GLUSTERD_PEER_UTILS_H
+#define _GLUSTERD_PEER_UTILS_H
+
+#include "glusterd.h"
+#include "glusterd-utils.h"
+
+int32_t
+glusterd_peerinfo_cleanup (glusterd_peerinfo_t *peerinfo);
+
+int32_t
+glusterd_peerinfo_destroy (glusterd_peerinfo_t *peerinfo);
+
+glusterd_peerinfo_t *
+glusterd_peerinfo_find_by_hostname (const char *hoststr);
+
+int
+glusterd_hostname_to_uuid (char *hostname, uuid_t uuid);
+
+glusterd_peerinfo_t *
+glusterd_peerinfo_find_by_uuid (uuid_t uuid);
+
+glusterd_peerinfo_t *
+glusterd_peerinfo_find (uuid_t uuid, const char *hostname);
+
+glusterd_peerinfo_t *
+glusterd_peerinfo_new (glusterd_friend_sm_state_t state, uuid_t *uuid,
+ const char *hostname, int port);
+
+gf_boolean_t
+glusterd_chk_peers_connected_befriended (uuid_t skip_uuid);
+
+char *
+glusterd_uuid_to_hostname (uuid_t uuid);
+
+char*
+gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo);
+
+gf_boolean_t
+glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
+ struct list_head *peers, char **down_peerstr);
+
+int32_t
+glusterd_peer_hostname_new (const char *hostname,
+ glusterd_peer_hostname_t **name);
+void
+glusterd_peer_hostname_free (glusterd_peer_hostname_t *name);
+
+gf_boolean_t
+gd_peer_has_address (glusterd_peerinfo_t *peerinfo, const char *address);
+
+int
+gd_add_address_to_peer (glusterd_peerinfo_t *peerinfo, const char *address);
+
+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);
+
+glusterd_peerinfo_t *
+gd_peerinfo_from_dict (dict_t *dict, const char *prefix);
+
+int
+gd_add_peer_hostnames_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict,
+ const char *prefix);
+int
+gd_add_peer_detail_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *friends,
+ int count);
+#endif /* _GLUSTERD_PEER_UTILS_H */
diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
index d33dc7a32ee..7c2b545905d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
@@ -521,8 +521,9 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
}
if (!gf_is_local_addr (host)) {
- ret = glusterd_friend_find (NULL, host, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (NULL, host);
+ if (peerinfo == NULL) {
+ ret = -1;
snprintf (msg, sizeof (msg), "%s, is not a friend",
host);
*op_errstr = gf_strdup (msg);
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index 10d5d7f2752..19b66ac06d8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -214,25 +214,32 @@ int
__glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- gd1_mgmt_probe_rsp rsp = {{0},};
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_probe_ctx_t *ctx = NULL;
+ gd1_mgmt_probe_rsp rsp = {{0},};
+ int ret = 0;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_friend_sm_event_t *event = NULL;
+ glusterd_probe_ctx_t *ctx = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
if (-1 == req->rpc_status) {
goto out;
}
+ this = THIS;
+ GF_ASSERT (this != NULL);
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
+
ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error");
+ gf_log (this->name, GF_LOG_ERROR, "error");
//rsp.op_ret = -1;
//rsp.op_errno = EINVAL;
goto out;
}
- gf_log ("glusterd", GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_INFO,
"Received probe resp from uuid: %s, host: %s",
uuid_utoa (rsp.uuid), rsp.hostname);
if (rsp.op_ret != 0) {
@@ -254,12 +261,82 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
ret = rsp.op_ret;
goto out;
}
- ret = glusterd_friend_find (rsp.uuid, rsp.hostname, &peerinfo);
- if (ret) {
+
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname);
+ if (peerinfo == NULL) {
GF_ASSERT (0);
}
- if (strncasecmp (rsp.hostname, peerinfo->hostname, 1024)) {
+ /*
+ * In the case of a fresh probe rsp.uuid and peerinfo.uuid will not
+ * match, as peerinfo->uuid will be NULL.
+ *
+ * In the case of a peer probe being done to add a new network to a
+ * peer, rsp.uuid will match an existing peerinfo.uuid. If we have this
+ * stage it means that the current address/hostname being used isn't
+ * present in the found peerinfo. If it were, we would have found out
+ * earlier in the probe process and wouldn't even reach till here. So,
+ * we need to add the new hostname to the peer.
+ *
+ * This addition should only be done for cluster op-version >=
+ * GD_OP_VERSION_3_6_0 as address lists are only supported from then on.
+ * Also, this update should only be done when an explicit CLI probe
+ * command was used to begin the probe process.
+ */
+ if ((conf->op_version >= GD_OP_VERSION_3_6_0) &&
+ (uuid_compare (rsp.uuid, peerinfo->uuid) == 0)) {
+ ctx = ((call_frame_t *)myframe)->local;
+ /* Presence of ctx->req implies this probe was started by a cli
+ * probe command
+ */
+ if (ctx->req == NULL)
+ goto cont;
+
+ gf_log (this->name, GF_LOG_DEBUG, "Adding address '%s' to "
+ "existing peer %s", rsp.hostname, uuid_utoa (rsp.uuid));
+
+ ret = glusterd_friend_remove (NULL, rsp.hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Could not remove "
+ "stale peerinfo with name %s", rsp.hostname);
+ goto reply;
+ }
+
+ ret = gd_add_address_to_peer (peerinfo, rsp.hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Couldn't add hostname to peer list");
+ goto reply;
+ }
+
+ /* Injecting LOCAL_ACC to send update */
+ ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_LOCAL_ACC,
+ &event);
+ if (!ret) {
+ event->peerinfo = peerinfo;
+ ret = glusterd_friend_sm_inject_event (event);
+ }
+ rsp.op_errno = GF_PROBE_FRIEND;
+
+reply:
+ ctx = ((call_frame_t *)myframe)->local;
+ ((call_frame_t *)myframe)->local = NULL;
+
+ GF_ASSERT (ctx);
+
+ if (ctx->req) {
+ glusterd_xfer_cli_probe_resp (ctx->req, ret,
+ rsp.op_errno,
+ rsp.op_errstr,
+ ctx->hostname, ctx->port,
+ ctx->dict);
+ }
+
+ glusterd_destroy_probe_ctx (ctx);
+
+ goto out;
+
+ } else if (strncasecmp (rsp.hostname, peerinfo->hostname, 1024)) {
gf_log (THIS->name, GF_LOG_INFO, "Host: %s with uuid: %s "
"already present in cluster with alias hostname: %s",
rsp.hostname, uuid_utoa (rsp.uuid), peerinfo->hostname);
@@ -283,7 +360,7 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
ret = rsp.op_ret;
goto out;
}
-
+cont:
uuid_copy (peerinfo->uuid, rsp.uuid);
ret = glusterd_friend_sm_new_event
@@ -358,9 +435,9 @@ __glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
"Received %s from uuid: %s, host: %s, port: %d",
(op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port);
- ret = glusterd_friend_find (rsp.uuid, rsp.hostname, &peerinfo);
-
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname);
+ if (peerinfo == NULL) {
+ ret = -1;
gf_log ("", GF_LOG_ERROR, "received friend add response from"
" unknown peer uuid: %s", uuid_utoa (rsp.uuid));
goto out;
@@ -469,11 +546,11 @@ __glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov,
(op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port);
inject:
- ret = glusterd_friend_find (rsp.uuid, ctx->hostname, &peerinfo);
-
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, ctx->hostname);
+ if (peerinfo == NULL) {
//can happen as part of rpc clnt connection cleanup
//when the frame timeout happens after 30 minutes
+ ret = -1;
goto respond;
}
@@ -610,9 +687,9 @@ out:
"Received lock %s from uuid: %s", (op_ret) ? "RJT" : "ACC",
uuid_utoa (rsp.uuid));
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
-
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
+ ret = -1;
gf_log (this->name, GF_LOG_CRITICAL, "Lock response received "
"from unknown peer: %s", uuid_utoa (rsp.uuid));
}
@@ -687,8 +764,9 @@ glusterd_mgmt_v3_lock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov,
"Received mgmt_v3 lock %s from uuid: %s",
(op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid));
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
+ ret = -1;
gf_log (this->name, GF_LOG_CRITICAL,
"mgmt_v3 lock response received "
"from unknown peer: %s. Ignoring response",
@@ -768,9 +846,9 @@ glusterd_mgmt_v3_unlock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov,
(op_ret) ? "RJT" : "ACC",
uuid_utoa (rsp.uuid));
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
-
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
+ ret = -1;
gf_log (this->name, GF_LOG_CRITICAL,
"mgmt_v3 unlock response received "
"from unknown peer: %s. Ignoring response",
@@ -851,9 +929,8 @@ out:
"Received unlock %s from uuid: %s",
(op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid));
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
-
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
gf_log (this->name, GF_LOG_CRITICAL, "Unlock response received "
"from unknown peer %s", uuid_utoa (rsp.uuid));
}
@@ -959,11 +1036,12 @@ out:
gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
uuid_utoa (*txn_id));
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
- if (ret)
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
gf_log (this->name, GF_LOG_CRITICAL, "Stage response received "
"from unknown peer: %s. Ignoring response.",
uuid_utoa (rsp.uuid));
+ }
if (op_ret) {
event_type = GD_OP_EVENT_RCVD_RJT;
@@ -1094,8 +1172,8 @@ __glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
uuid_utoa (*txn_id));
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
gf_log (this->name, GF_LOG_CRITICAL, "Commit response for "
"'Volume %s' received from unknown peer: %s",
gd_op_list[opinfo.op], uuid_utoa (rsp.uuid));
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index 8807ef94a72..ca047bd3322 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -313,8 +313,8 @@ glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx)
GF_ASSERT (conf);
- ret = glusterd_friend_find (NULL, probe_ctx->hostname, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (NULL, probe_ctx->hostname);
+ if (peerinfo == NULL) {
//We should not reach this state ideally
GF_ASSERT (0);
goto out;
@@ -456,7 +456,6 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
glusterd_conf_t *priv = NULL;
dict_t *friends = NULL;
char key[100] = {0,};
- char *dup_buf = NULL;
int32_t count = 0;
GF_ASSERT (event);
@@ -483,17 +482,12 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
continue;
count++;
- snprintf (key, sizeof (key), "friend%d.uuid", count);
- dup_buf = gf_strdup (uuid_utoa (peerinfo->uuid));
- ret = dict_set_dynstr (friends, key, dup_buf);
- if (ret)
- goto out;
- snprintf (key, sizeof (key), "friend%d.hostname", count);
- ret = dict_set_str (friends, key, peerinfo->hostname);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "friend%d", count);
+ ret = gd_add_friend_to_dict (peerinfo, friends, key);
if (ret)
goto out;
- gf_log ("", GF_LOG_INFO, "Added uuid: %s, host: %s",
- dup_buf, peerinfo->hostname);
}
ret = dict_set_int32 (friends, "count", count);
@@ -622,7 +616,7 @@ glusterd_ac_friend_remove (glusterd_friend_sm_event_t *event, void *ctx)
gf_msg (THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_CLEANUP_FAIL,
"Volumes cleanup failed");
- ret = glusterd_friend_cleanup (event->peerinfo);
+ ret = glusterd_peerinfo_cleanup (event->peerinfo);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR, "Cleanup returned: %d", ret);
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h
index 6b3b61dfc5c..294dbacc9d0 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.h
@@ -59,7 +59,7 @@ typedef struct glusterd_peer_state_info_ {
typedef struct glusterd_peer_hostname_ {
char *hostname;
struct list_head hostname_list;
-}glusterd_peer_hostname_t;
+} glusterd_peer_hostname_t;
typedef struct glusterd_sm_transition_ {
int old_state;
@@ -84,6 +84,7 @@ struct glusterd_peerinfo_ {
*/
glusterd_peer_state_info_t state;
char *hostname;
+ struct list_head hostnames;
int port;
struct list_head uuid_list;
struct list_head op_peers_list;
@@ -92,7 +93,7 @@ struct glusterd_peerinfo_ {
rpc_clnt_prog_t *peer;
rpc_clnt_prog_t *mgmt_v3;
int connected;
- gf_store_handle_t *shandle;
+ gf_store_handle_t *shandle;
glusterd_sm_tr_log_t sm_log;
gf_boolean_t quorum_action;
gd_quorum_contrib_t quorum_contrib;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 086a6550a72..06e8101a3a5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -3853,7 +3853,7 @@ glusterd_store_create_peer_shandle (glusterd_peerinfo_t *peerinfo)
GF_ASSERT (peerinfo);
- if (glusterd_peerinfo_is_uuid_unknown (peerinfo)) {
+ if (uuid_is_null (peerinfo->uuid)) {
ret = glusterd_store_peerinfo_hostname_shandle_create (peerinfo);
} else {
ret = glusterd_peerinfo_hostname_shandle_check_destroy (peerinfo);
@@ -3865,8 +3865,11 @@ glusterd_store_create_peer_shandle (glusterd_peerinfo_t *peerinfo)
int32_t
glusterd_store_peer_write (int fd, glusterd_peerinfo_t *peerinfo)
{
- char buf[50] = {0};
- int32_t ret = 0;
+ char buf[50] = {0};
+ int32_t ret = 0;
+ int32_t i = 1;
+ glusterd_peer_hostname_t *hostname = NULL;
+ char *key = NULL;
ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_PEER_UUID,
uuid_utoa (peerinfo->uuid));
@@ -3878,10 +3881,18 @@ glusterd_store_peer_write (int fd, glusterd_peerinfo_t *peerinfo)
if (ret)
goto out;
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_PEER_HOSTNAME "1",
- peerinfo->hostname);
- if (ret)
- goto out;
+ list_for_each_entry (hostname, &peerinfo->hostnames, hostname_list) {
+ ret = gf_asprintf (&key, GLUSTERD_STORE_KEY_PEER_HOSTNAME"%d",
+ i);
+ if (ret < 0)
+ goto out;
+ ret = gf_store_save_value (fd, key, hostname->hostname);
+ if (ret)
+ goto out;
+ GF_FREE (key);
+ key = NULL;
+ i++;
+ }
out:
gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
@@ -3938,22 +3949,21 @@ out:
int32_t
glusterd_store_retrieve_peers (xlator_t *this)
{
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- char path[PATH_MAX] = {0,};
- glusterd_peerinfo_t *peerinfo = NULL;
- uuid_t uuid = {0,};
- char *hostname = NULL;
- int32_t state = 0;
- gf_store_handle_t *shandle = NULL;
- char filepath[PATH_MAX] = {0,};
- gf_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- glusterd_peerctx_args_t args = {0};
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
+ int32_t ret = 0;
+ glusterd_conf_t *priv = NULL;
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+ char path[PATH_MAX] = {0,};
+ glusterd_peerinfo_t *peerinfo = NULL;
+ char *hostname = NULL;
+ gf_store_handle_t *shandle = NULL;
+ char filepath[PATH_MAX] = {0,};
+ gf_store_iter_t *iter = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ glusterd_peerctx_args_t args = {0};
+ gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
+ glusterd_peer_hostname_t *address = NULL;
GF_ASSERT (this);
priv = this->private;
@@ -3987,20 +3997,30 @@ glusterd_store_retrieve_peers (xlator_t *this)
if (ret)
goto out;
+ /* Create an empty peerinfo object before reading in the
+ * details
+ */
+ peerinfo = glusterd_peerinfo_new (GD_FRIEND_STATE_DEFAULT, NULL,
+ NULL, 0);
+ if (peerinfo == NULL) {
+ ret = -1;
+ goto out;
+ }
+
while (!ret) {
if (!strncmp (GLUSTERD_STORE_KEY_PEER_UUID, key,
strlen (GLUSTERD_STORE_KEY_PEER_UUID))) {
if (value)
- uuid_parse (value, uuid);
+ uuid_parse (value, peerinfo->uuid);
} else if (!strncmp (GLUSTERD_STORE_KEY_PEER_STATE,
key,
strlen (GLUSTERD_STORE_KEY_PEER_STATE))) {
- state = atoi (value);
+ peerinfo->state.state = atoi (value);
} else if (!strncmp (GLUSTERD_STORE_KEY_PEER_HOSTNAME,
key,
strlen (GLUSTERD_STORE_KEY_PEER_HOSTNAME))) {
- hostname = gf_strdup (value);
+ ret = gd_add_address_to_peer (peerinfo, value);
} else {
gf_log ("", GF_LOG_ERROR, "Unknown key: %s",
key);
@@ -4021,14 +4041,23 @@ glusterd_store_retrieve_peers (xlator_t *this)
(void) gf_store_iter_destroy (iter);
- ret = glusterd_friend_add (hostname, 0, state, &uuid,
- &peerinfo, 1, NULL);
+ /* Set first hostname from peerinfo->hostnames to
+ * peerinfo->hostname
+ */
+ address = list_entry (peerinfo->hostnames.next,
+ glusterd_peer_hostname_t, hostname_list);
+ if (!address) {
+ ret = -1;
+ goto out;
+ }
+ peerinfo->hostname = gf_strdup (address->hostname);
- GF_FREE (hostname);
+ ret = glusterd_friend_add_from_peerinfo (peerinfo, 1, NULL);
if (ret)
goto out;
peerinfo->shandle = shandle;
+ peerinfo = NULL;
glusterd_for_each_entry (entry, dir);
}
@@ -4038,8 +4067,12 @@ glusterd_store_retrieve_peers (xlator_t *this)
if (ret)
goto out;
}
+ peerinfo = NULL;
out:
+ if (peerinfo)
+ glusterd_peerinfo_cleanup (peerinfo);
+
if (dir)
closedir (dir);
gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index 6e7a9b6c8be..67ceb20c2e7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -673,8 +673,9 @@ _gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
}
}
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
+ ret = -1;
gf_log (this->name, GF_LOG_CRITICAL, "Staging response "
"for 'Volume %s' received from unknown "
"peer: %s", gd_op_list[rsp.op],
@@ -929,8 +930,9 @@ _gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
}
}
- ret = glusterd_friend_find (rsp.uuid, NULL, &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
+ if (peerinfo == NULL) {
+ ret = -1;
gf_log (this->name, GF_LOG_CRITICAL, "Commit response "
"for 'Volume %s' received from unknown "
"peer: %s", gd_op_list[rsp.op],
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index baa845b0a91..7eddb753dc6 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -82,18 +82,6 @@
static glusterd_lock_t lock;
-char*
-gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo)
-{
- if ((peerinfo == NULL) || uuid_is_null (peerinfo->uuid))
- return NULL;
-
- if (peerinfo->uuid_str[0] == '\0')
- uuid_utoa_r (peerinfo->uuid, peerinfo->uuid_str);
-
- return peerinfo->uuid_str;
-}
-
int32_t
glusterd_get_lock_owner (uuid_t *uuid)
@@ -1403,38 +1391,6 @@ out:
return decommissioned;
}
-int32_t
-glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo)
-{
- GF_ASSERT (peerinfo);
- glusterd_peerctx_t *peerctx = NULL;
- gf_boolean_t quorum_action = _gf_false;
- glusterd_conf_t *priv = THIS->private;
-
- if (peerinfo->quorum_contrib != QUORUM_NONE)
- quorum_action = _gf_true;
- if (peerinfo->rpc) {
- /* cleanup the saved-frames before last unref */
- synclock_unlock (&priv->big_lock);
- rpc_clnt_connection_cleanup (&peerinfo->rpc->conn);
- synclock_lock (&priv->big_lock);
-
- peerctx = peerinfo->rpc->mydata;
- peerinfo->rpc->mydata = NULL;
- peerinfo->rpc = glusterd_rpc_clnt_unref (priv, peerinfo->rpc);
- peerinfo->rpc = NULL;
- if (peerctx) {
- GF_FREE (peerctx->errstr);
- GF_FREE (peerctx);
- }
- }
- glusterd_peer_destroy (peerinfo);
-
- if (quorum_action)
- glusterd_do_quorum_action ();
- return 0;
-}
-
int
glusterd_volinfo_find_by_volume_id (uuid_t volume_id, glusterd_volinfo_t **volinfo)
{
@@ -1986,32 +1942,6 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
return ret;
}
-int32_t
-glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name)
-{
- glusterd_peer_hostname_t *peer_hostname = NULL;
- int32_t ret = -1;
-
- GF_ASSERT (hostname);
- GF_ASSERT (name);
-
- peer_hostname = GF_CALLOC (1, sizeof (*peer_hostname),
- gf_gld_mt_peer_hostname_t);
-
- if (!peer_hostname)
- goto out;
-
- peer_hostname->hostname = gf_strdup (hostname);
- INIT_LIST_HEAD (&peer_hostname->hostname_list);
-
- *name = peer_hostname;
- ret = 0;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
/* Free LINE[0..N-1] and then the LINE buffer. */
static void
free_lines (char **line, size_t n)
@@ -7671,163 +7601,6 @@ out:
return ret;
}
-int
-glusterd_friend_find_by_uuid (uuid_t uuid,
- glusterd_peerinfo_t **peerinfo)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *entry = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peerinfo);
-
- *peerinfo = NULL;
- priv = this->private;
-
- 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)) {
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Friend found... state: %s",
- glusterd_friend_sm_state_name_get (entry->state.state));
- *peerinfo = entry;
- return 0;
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Friend with uuid: %s, not found",
- uuid_utoa (uuid));
- return ret;
-}
-
-
-int
-glusterd_friend_find_by_hostname (const char *hoststr,
- glusterd_peerinfo_t **peerinfo)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *entry = NULL;
- struct addrinfo *addr = NULL;
- struct addrinfo *p = NULL;
- char *host = NULL;
- struct sockaddr_in6 *s6 = NULL;
- struct sockaddr_in *s4 = NULL;
- struct in_addr *in_addr = NULL;
- char hname[1024] = {0,};
- xlator_t *this = NULL;
-
-
- this = THIS;
- GF_ASSERT (hoststr);
- GF_ASSERT (peerinfo);
-
- *peerinfo = NULL;
- priv = this->private;
-
- GF_ASSERT (priv);
-
- list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!strncasecmp (entry->hostname, hoststr,
- 1024)) {
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Friend %s found.. state: %d", hoststr,
- entry->state.state);
- *peerinfo = entry;
- return 0;
- }
- }
-
- ret = getaddrinfo (hoststr, NULL, NULL, &addr);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "error in getaddrinfo: %s\n",
- gai_strerror(ret));
- goto out;
- }
-
- for (p = addr; p != NULL; p = p->ai_next) {
- switch (p->ai_family) {
- case AF_INET:
- s4 = (struct sockaddr_in *) p->ai_addr;
- in_addr = &s4->sin_addr;
- break;
- case AF_INET6:
- s6 = (struct sockaddr_in6 *) p->ai_addr;
- in_addr =(struct in_addr *) &s6->sin6_addr;
- break;
- default: ret = -1;
- goto out;
- }
- host = inet_ntoa(*in_addr);
-
- ret = getnameinfo (p->ai_addr, p->ai_addrlen, hname,
- 1024, NULL, 0, 0);
- if (ret)
- goto out;
-
- list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!strncasecmp (entry->hostname, host,
- 1024) || !strncasecmp (entry->hostname,hname,
- 1024)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Friend %s found.. state: %d",
- hoststr, entry->state.state);
- *peerinfo = entry;
- freeaddrinfo (addr);
- return 0;
- }
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Unable to find friend: %s", hoststr);
- if (addr)
- freeaddrinfo (addr);
- return -1;
-}
-
-int
-glusterd_hostname_to_uuid (char *hostname, uuid_t uuid)
-{
- GF_ASSERT (hostname);
- GF_ASSERT (uuid);
-
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = glusterd_friend_find_by_hostname (hostname, &peerinfo);
- if (ret) {
- if (gf_is_local_addr (hostname)) {
- uuid_copy (uuid, MY_UUID);
- ret = 0;
- } else {
- goto out;
- }
- } else {
- uuid_copy (uuid, peerinfo->uuid);
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
int
glusterd_brick_stop (glusterd_volinfo_t *volinfo,
@@ -7946,9 +7719,9 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
}
} else {
- ret = glusterd_friend_find_by_uuid (newbrickinfo->uuid,
- &peerinfo);
- if (ret) {
+ peerinfo = glusterd_peerinfo_find_by_uuid (newbrickinfo->uuid);
+ if (peerinfo == NULL) {
+ ret = -1;
snprintf (op_errstr, len, "Failed to find host %s",
newbrickinfo->hostname);
goto out;
@@ -8375,76 +8148,6 @@ out:
}
int
-glusterd_peerinfo_new (glusterd_peerinfo_t **peerinfo,
- glusterd_friend_sm_state_t state, uuid_t *uuid,
- const char *hostname, int port)
-{
- glusterd_peerinfo_t *new_peer = NULL;
- int ret = -1;
-
- GF_ASSERT (peerinfo);
- if (!peerinfo)
- goto out;
-
- new_peer = GF_CALLOC (1, sizeof (*new_peer), gf_gld_mt_peerinfo_t);
- if (!new_peer)
- goto out;
-
- new_peer->state.state = state;
- if (hostname)
- new_peer->hostname = gf_strdup (hostname);
-
- INIT_LIST_HEAD (&new_peer->uuid_list);
-
- if (uuid) {
- uuid_copy (new_peer->uuid, *uuid);
- }
-
- ret = glusterd_sm_tr_log_init (&new_peer->sm_log,
- glusterd_friend_sm_state_name_get,
- glusterd_friend_sm_event_name_get,
- GLUSTERD_TR_LOG_SIZE);
- if (ret)
- goto out;
-
- if (new_peer->state.state == GD_FRIEND_STATE_BEFRIENDED)
- new_peer->quorum_contrib = QUORUM_WAITING;
- new_peer->port = port;
- *peerinfo = new_peer;
-out:
- if (ret && new_peer)
- glusterd_friend_cleanup (new_peer);
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo)
-{
- int32_t ret = -1;
-
- if (!peerinfo)
- goto out;
-
- ret = glusterd_store_delete_peerinfo (peerinfo);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Deleting peer info failed");
- }
-
- list_del_init (&peerinfo->uuid_list);
- GF_FREE (peerinfo->hostname);
- glusterd_sm_tr_log_delete (&peerinfo->sm_log);
- GF_FREE (peerinfo);
- peerinfo = NULL;
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int
glusterd_remove_pending_entry (struct list_head *list, void *elem)
{
glusterd_pending_node_t *pending_node = NULL;
@@ -8479,16 +8182,6 @@ glusterd_clear_pending_nodes (struct list_head *list)
return 0;
}
-gf_boolean_t
-glusterd_peerinfo_is_uuid_unknown (glusterd_peerinfo_t *peerinfo)
-{
- GF_ASSERT (peerinfo);
-
- if (uuid_is_null (peerinfo->uuid))
- return _gf_true;
- return _gf_false;
-}
-
int32_t
glusterd_delete_volume (glusterd_volinfo_t *volinfo)
{
@@ -9149,36 +8842,6 @@ out:
return ret;
}
-/* Check if the all peers are connected and befriended, except the peer
- * specified (the peer being detached)
- */
-gf_boolean_t
-glusterd_chk_peers_connected_befriended (uuid_t skip_uuid)
-{
- gf_boolean_t ret = _gf_true;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
-
- priv= THIS->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
-
- if (!uuid_is_null (skip_uuid) && !uuid_compare (skip_uuid,
- peerinfo->uuid))
- continue;
-
- if ((GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state)
- || !(peerinfo->connected)) {
- ret = _gf_false;
- break;
- }
- }
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %s",
- (ret?"TRUE":"FALSE"));
- return ret;
-}
-
void
glusterd_get_client_filepath (char *filepath, glusterd_volinfo_t *volinfo,
gf_transport_type type)
@@ -9303,34 +8966,6 @@ glusterd_volinfo_reset_defrag_stats (glusterd_volinfo_t *volinfo)
}
-/* Return hostname for given uuid if it exists
- * else return NULL
- */
-char *
-glusterd_uuid_to_hostname (uuid_t uuid)
-{
- char *hostname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *entry = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- if (!uuid_compare (MY_UUID, uuid)) {
- hostname = gf_strdup ("localhost");
- }
- if (!list_empty (&priv->peers)) {
- list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!uuid_compare (entry->uuid, uuid)) {
- hostname = gf_strdup (entry->hostname);
- break;
- }
- }
- }
-
- return hostname;
-}
-
gf_boolean_t
glusterd_is_local_brick (xlator_t *this, glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo)
@@ -11787,42 +11422,6 @@ gd_is_remove_brick_committed (glusterd_volinfo_t *volinfo)
}
gf_boolean_t
-glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
- struct list_head *peers,
- char **down_peerstr)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- gf_boolean_t ret = _gf_false;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- list_for_each_entry (peerinfo, peers, uuid_list) {
- if (uuid_compare (peerinfo->uuid, brickinfo->uuid))
- continue;
-
- /*Found peer who owns the brick, return false
- * if peer is not connected or not friend */
- if (!(peerinfo->connected) ||
- (peerinfo->state.state !=
- GD_FRIEND_STATE_BEFRIENDED)) {
- *down_peerstr = gf_strdup (peerinfo->hostname);
- gf_log ("", GF_LOG_DEBUG, "Peer %s is down. ",
- peerinfo->hostname);
- goto out;
- }
- }
- }
-
- ret = _gf_true;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-gf_boolean_t
glusterd_is_status_tasks_op (glusterd_op_t op, dict_t *dict)
{
int ret = -1;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index aef28de1b8d..f8dfce7ca82 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -29,6 +29,7 @@
#include "protocol-common.h"
#include "glusterfs3-xdr.h"
+#include "glusterd-peer-utils.h"
#define GLUSTERD_SOCK_DIR "/var/run"
#define GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO(brickinfo, volinfo, brickid) do {\
@@ -125,15 +126,6 @@ int32_t
glusterd_brickinfo_new_from_brick (char *brick, glusterd_brickinfo_t **brickinfo);
int32_t
-glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo);
-
-int32_t
-glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo);
-
-int32_t
-glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name);
-
-int32_t
glusterd_snap_volinfo_find (char *volname, glusterd_snap_t *snap,
glusterd_volinfo_t **volinfo);
int32_t
@@ -312,12 +304,6 @@ gf_boolean_t
glusterd_is_brick_started (glusterd_brickinfo_t *brickinfo);
int
-glusterd_friend_find_by_hostname (const char *hoststr,
- glusterd_peerinfo_t **peerinfo);
-int
-glusterd_hostname_to_uuid (char *hostname, uuid_t uuid);
-
-int
glusterd_friend_brick_belongs (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo, void *uuid);
int
@@ -339,9 +325,6 @@ int32_t
glusterd_volinfo_bricks_delete (glusterd_volinfo_t *volinfo);
int
-glusterd_friend_find_by_uuid (uuid_t uuid,
- glusterd_peerinfo_t **peerinfo);
-int
glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
char *op_errstr, size_t len);
int32_t
@@ -385,10 +368,6 @@ glusterd_sm_tr_log_transition_add (glusterd_sm_tr_log_t *log,
int old_state, int new_state,
int event);
int
-glusterd_peerinfo_new (glusterd_peerinfo_t **peerinfo,
- glusterd_friend_sm_state_t state, uuid_t *uuid,
- const char *hostname, int port);
-int
glusterd_sm_tr_log_init (glusterd_sm_tr_log_t *log,
char * (*state_name_get) (int),
char * (*event_name_get) (int),
@@ -403,8 +382,6 @@ int
glusterd_remove_pending_entry (struct list_head *list, void *elem);
int
glusterd_clear_pending_nodes (struct list_head *list);
-gf_boolean_t
-glusterd_peerinfo_is_uuid_unknown (glusterd_peerinfo_t *peerinfo);
int32_t
glusterd_brick_connect (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo, char *socketpath);
@@ -481,9 +458,6 @@ glusterd_friend_contains_vol_bricks (glusterd_volinfo_t *volinfo,
int
glusterd_friend_remove_cleanup_vols (uuid_t uuid);
-gf_boolean_t
-glusterd_chk_peers_connected_befriended (uuid_t skip_uuid);
-
void
glusterd_get_client_filepath (char *filepath,
glusterd_volinfo_t *volinfo,
@@ -503,9 +477,6 @@ int
glusterd_add_node_to_dict (char *server, dict_t *dict, int count,
dict_t *vol_opts);
-char *
-glusterd_uuid_to_hostname (uuid_t uuid);
-
int
glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo);
@@ -577,11 +548,6 @@ glusterd_profile_volume_brick_rsp (void *pending_entry,
dict_t *rsp_dict, dict_t *op_ctx,
char **op_errstr, gd_node_type type);
-gf_boolean_t
-glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
- struct list_head *peers,
- char **down_peerstr);
-
int32_t
glusterd_set_originator_uuid (dict_t *dict);
@@ -632,17 +598,9 @@ gd_update_volume_op_versions (glusterd_volinfo_t *volinfo);
int
op_version_check (xlator_t *this, int min_op_version, char *msg, int msglen);
-char*
-gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo);
-
gf_boolean_t
gd_is_remove_brick_committed (glusterd_volinfo_t *volinfo);
-gf_boolean_t
-glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
- struct list_head *peers,
- char **down_peerstr);
-
int
glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo,
dict_t *dict, char **slave_url,
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index ddbb2c81338..ec036f8cf06 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -651,16 +651,16 @@ glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *myhostname,
int32_t op_errno);
int
-glusterd_friend_find (uuid_t uuid, char *hostname,
- glusterd_peerinfo_t **peerinfo);
-
-int
glusterd_friend_add (const char *hoststr, int port,
glusterd_friend_sm_state_t state,
uuid_t *uuid, glusterd_peerinfo_t **friend,
gf_boolean_t restore, glusterd_peerctx_args_t *args);
int
+glusterd_friend_add_from_peerinfo (glusterd_peerinfo_t *friend,
+ gf_boolean_t restore,
+ glusterd_peerctx_args_t *args);
+int
glusterd_friend_rpc_create (xlator_t *this, glusterd_peerinfo_t *peerinfo,
glusterd_peerctx_args_t *args);
int