|
|
3d71c6 |
From: Andrew Beekhof <andrew@beekhof.net>
|
|
|
3d71c6 |
Date: Thu, 3 Sep 2015 11:36:21 +1000
|
|
|
3d71c6 |
Subject: [PATCH] Refactor: Tools: Isolate the paths which truely require
|
|
|
3d71c6 |
corosync-2.x
|
|
|
3d71c6 |
|
|
|
3d71c6 |
(cherry picked from commit 32c05b99f6a3e953668dcda71ce24e03927d83cb)
|
|
|
3d71c6 |
---
|
|
|
3d71c6 |
tools/crm_node.c | 243 +++++++++++++++++++++++++++++++------------------------
|
|
|
3d71c6 |
1 file changed, 139 insertions(+), 104 deletions(-)
|
|
|
3d71c6 |
|
|
|
3d71c6 |
diff --git a/tools/crm_node.c b/tools/crm_node.c
|
|
|
3d71c6 |
index ed02ee7..308d4f9 100644
|
|
|
3d71c6 |
--- a/tools/crm_node.c
|
|
|
3d71c6 |
+++ b/tools/crm_node.c
|
|
|
3d71c6 |
@@ -60,6 +60,9 @@ static struct crm_option long_options[] = {
|
|
|
3d71c6 |
#if SUPPORT_COROSYNC
|
|
|
3d71c6 |
{"openais", 0, 0, 'A', "\tOnly try connecting to an OpenAIS-based cluster"},
|
|
|
3d71c6 |
#endif
|
|
|
3d71c6 |
+#ifdef SUPPORT_CS_QUORUM
|
|
|
3d71c6 |
+ {"corosync", 0, 0, 'C', "\tOnly try connecting to an Corosync-based cluster"},
|
|
|
3d71c6 |
+#endif
|
|
|
3d71c6 |
#ifdef SUPPORT_HEARTBEAT
|
|
|
3d71c6 |
{"heartbeat", 0, 0, 'H', "Only try connecting to a Heartbeat-based cluster"},
|
|
|
3d71c6 |
#endif
|
|
|
3d71c6 |
@@ -223,6 +226,138 @@ int tools_remove_node_cache(const char *node, const char *target)
|
|
|
3d71c6 |
return rc > 0 ? 0 : rc;
|
|
|
3d71c6 |
}
|
|
|
3d71c6 |
|
|
|
3d71c6 |
+static gint
|
|
|
3d71c6 |
+compare_node_uname(gconstpointer a, gconstpointer b)
|
|
|
3d71c6 |
+{
|
|
|
3d71c6 |
+ const crm_node_t *a_node = a;
|
|
|
3d71c6 |
+ const crm_node_t *b_node = b;
|
|
|
3d71c6 |
+ return strcmp(a_node->uname?a_node->uname:"", b_node->uname?b_node->uname:"");
|
|
|
3d71c6 |
+}
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+static int
|
|
|
3d71c6 |
+node_mcp_dispatch(const char *buffer, ssize_t length, gpointer userdata)
|
|
|
3d71c6 |
+{
|
|
|
3d71c6 |
+ xmlNode *msg = string2xml(buffer);
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ if (msg) {
|
|
|
3d71c6 |
+ xmlNode *node = NULL;
|
|
|
3d71c6 |
+ GListPtr nodes = NULL;
|
|
|
3d71c6 |
+ GListPtr iter = NULL;
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ crm_log_xml_trace(msg, "message");
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ for (node = __xml_first_child(msg); node != NULL; node = __xml_next(node)) {
|
|
|
3d71c6 |
+ crm_node_t *peer = calloc(1, sizeof(crm_node_t));
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ nodes = g_list_insert_sorted(nodes, peer, compare_node_uname);
|
|
|
3d71c6 |
+ peer->uname = (char*)crm_element_value_copy(node, "uname");
|
|
|
3d71c6 |
+ peer->state = (char*)crm_element_value_copy(node, "state");
|
|
|
3d71c6 |
+ crm_element_value_int(node, "id", (int*)&peer->id);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ for(iter = nodes; iter; iter = iter->next) {
|
|
|
3d71c6 |
+ crm_node_t *peer = iter->data;
|
|
|
3d71c6 |
+ if (command == 'l') {
|
|
|
3d71c6 |
+ fprintf(stdout, "%u %s %s\n", peer->id, peer->uname, peer->state);
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ } else if (command == 'p') {
|
|
|
3d71c6 |
+ if(safe_str_eq(peer->state, CRM_NODE_MEMBER)) {
|
|
|
3d71c6 |
+ fprintf(stdout, "%s ", peer->uname);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ } else if (command == 'i') {
|
|
|
3d71c6 |
+ if(safe_str_eq(peer->state, CRM_NODE_MEMBER)) {
|
|
|
3d71c6 |
+ fprintf(stdout, "%u ", peer->id);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ g_list_free_full(nodes, free);
|
|
|
3d71c6 |
+ free_xml(msg);
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ if (command == 'p') {
|
|
|
3d71c6 |
+ fprintf(stdout, "\n");
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ crm_exit(pcmk_ok);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ return 0;
|
|
|
3d71c6 |
+}
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+static void
|
|
|
3d71c6 |
+node_mcp_destroy(gpointer user_data)
|
|
|
3d71c6 |
+{
|
|
|
3d71c6 |
+ crm_exit(ENOTCONN);
|
|
|
3d71c6 |
+}
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+static gboolean
|
|
|
3d71c6 |
+try_pacemaker(int command, enum cluster_type_e stack)
|
|
|
3d71c6 |
+{
|
|
|
3d71c6 |
+ struct ipc_client_callbacks node_callbacks = {
|
|
|
3d71c6 |
+ .dispatch = node_mcp_dispatch,
|
|
|
3d71c6 |
+ .destroy = node_mcp_destroy
|
|
|
3d71c6 |
+ };
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ if (stack == pcmk_cluster_heartbeat) {
|
|
|
3d71c6 |
+ /* Nothing to do for them */
|
|
|
3d71c6 |
+ return FALSE;
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ switch (command) {
|
|
|
3d71c6 |
+ case 'e':
|
|
|
3d71c6 |
+ /* Age only applies to heartbeat clusters */
|
|
|
3d71c6 |
+ fprintf(stdout, "1\n");
|
|
|
3d71c6 |
+ crm_exit(pcmk_ok);
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ case 'q':
|
|
|
3d71c6 |
+ /* Implement one day?
|
|
|
3d71c6 |
+ * Wouldn't be much for pacemakerd to track it and include in the poke reply
|
|
|
3d71c6 |
+ */
|
|
|
3d71c6 |
+ return FALSE;
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ case 'R':
|
|
|
3d71c6 |
+ {
|
|
|
3d71c6 |
+ int lpc = 0;
|
|
|
3d71c6 |
+ const char *daemons[] = {
|
|
|
3d71c6 |
+ CRM_SYSTEM_CRMD,
|
|
|
3d71c6 |
+ "stonith-ng",
|
|
|
3d71c6 |
+ T_ATTRD,
|
|
|
3d71c6 |
+ CRM_SYSTEM_MCP,
|
|
|
3d71c6 |
+ };
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ for(lpc = 0; lpc < DIMOF(daemons); lpc++) {
|
|
|
3d71c6 |
+ if (tools_remove_node_cache(target_uname, daemons[lpc])) {
|
|
|
3d71c6 |
+ crm_err("Failed to connect to %s to remove node '%s'", daemons[lpc], target_uname);
|
|
|
3d71c6 |
+ crm_exit(pcmk_err_generic);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ crm_exit(pcmk_ok);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ break;
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ case 'i':
|
|
|
3d71c6 |
+ case 'l':
|
|
|
3d71c6 |
+ case 'p':
|
|
|
3d71c6 |
+ /* Go to pacemakerd */
|
|
|
3d71c6 |
+ {
|
|
|
3d71c6 |
+ GMainLoop *amainloop = g_main_new(FALSE);
|
|
|
3d71c6 |
+ mainloop_io_t *ipc =
|
|
|
3d71c6 |
+ mainloop_add_ipc_client(CRM_SYSTEM_MCP, G_PRIORITY_DEFAULT, 0, NULL, &node_callbacks);
|
|
|
3d71c6 |
+ if (ipc != NULL) {
|
|
|
3d71c6 |
+ /* Sending anything will get us a list of nodes */
|
|
|
3d71c6 |
+ xmlNode *poke = create_xml_node(NULL, "poke");
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
+ crm_ipc_send(mainloop_get_ipc_client(ipc), poke, 0, 0, NULL);
|
|
|
3d71c6 |
+ free_xml(poke);
|
|
|
3d71c6 |
+ g_main_run(amainloop);
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ break;
|
|
|
3d71c6 |
+ }
|
|
|
3d71c6 |
+ return FALSE;
|
|
|
3d71c6 |
+}
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
#if SUPPORT_HEARTBEAT
|
|
|
3d71c6 |
# include <ocf/oc_event.h>
|
|
|
3d71c6 |
# include <ocf/oc_membership.h>
|
|
|
3d71c6 |
@@ -626,66 +761,6 @@ ais_membership_dispatch(cpg_handle_t handle,
|
|
|
3d71c6 |
# include <corosync/quorum.h>
|
|
|
3d71c6 |
# include <corosync/cpg.h>
|
|
|
3d71c6 |
|
|
|
3d71c6 |
-static gint
|
|
|
3d71c6 |
-compare_node_uname(gconstpointer a, gconstpointer b)
|
|
|
3d71c6 |
-{
|
|
|
3d71c6 |
- const crm_node_t *a_node = a;
|
|
|
3d71c6 |
- const crm_node_t *b_node = b;
|
|
|
3d71c6 |
- return strcmp(a_node->uname?a_node->uname:"", b_node->uname?b_node->uname:"");
|
|
|
3d71c6 |
-}
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
-static int
|
|
|
3d71c6 |
-node_mcp_dispatch(const char *buffer, ssize_t length, gpointer userdata)
|
|
|
3d71c6 |
-{
|
|
|
3d71c6 |
- xmlNode *msg = string2xml(buffer);
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- if (msg) {
|
|
|
3d71c6 |
- xmlNode *node = NULL;
|
|
|
3d71c6 |
- GListPtr nodes = NULL;
|
|
|
3d71c6 |
- GListPtr iter = NULL;
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- crm_log_xml_trace(msg, "message");
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- for (node = __xml_first_child(msg); node != NULL; node = __xml_next(node)) {
|
|
|
3d71c6 |
- crm_node_t *peer = calloc(1, sizeof(crm_node_t));
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- nodes = g_list_insert_sorted(nodes, peer, compare_node_uname);
|
|
|
3d71c6 |
- peer->uname = (char*)crm_element_value_copy(node, "uname");
|
|
|
3d71c6 |
- peer->state = (char*)crm_element_value_copy(node, "state");
|
|
|
3d71c6 |
- crm_element_value_int(node, "id", (int*)&peer->id);
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- for(iter = nodes; iter; iter = iter->next) {
|
|
|
3d71c6 |
- crm_node_t *peer = iter->data;
|
|
|
3d71c6 |
- if (command == 'l') {
|
|
|
3d71c6 |
- fprintf(stdout, "%u %s\n", peer->id, peer->uname);
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- } else if (command == 'p') {
|
|
|
3d71c6 |
- if(safe_str_eq(peer->state, CRM_NODE_MEMBER)) {
|
|
|
3d71c6 |
- fprintf(stdout, "%s ", peer->uname);
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- g_list_free_full(nodes, free);
|
|
|
3d71c6 |
- free_xml(msg);
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- if (command == 'p') {
|
|
|
3d71c6 |
- fprintf(stdout, "\n");
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- crm_exit(pcmk_ok);
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- return 0;
|
|
|
3d71c6 |
-}
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
-static void
|
|
|
3d71c6 |
-node_mcp_destroy(gpointer user_data)
|
|
|
3d71c6 |
-{
|
|
|
3d71c6 |
- crm_exit(ENOTCONN);
|
|
|
3d71c6 |
-}
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
static gboolean
|
|
|
3d71c6 |
try_corosync(int command, enum cluster_type_e stack)
|
|
|
3d71c6 |
{
|
|
|
3d71c6 |
@@ -696,36 +771,7 @@ try_corosync(int command, enum cluster_type_e stack)
|
|
|
3d71c6 |
cpg_handle_t c_handle = 0;
|
|
|
3d71c6 |
quorum_handle_t q_handle = 0;
|
|
|
3d71c6 |
|
|
|
3d71c6 |
- mainloop_io_t *ipc = NULL;
|
|
|
3d71c6 |
- GMainLoop *amainloop = NULL;
|
|
|
3d71c6 |
- const char *daemons[] = {
|
|
|
3d71c6 |
- CRM_SYSTEM_CRMD,
|
|
|
3d71c6 |
- "stonith-ng",
|
|
|
3d71c6 |
- T_ATTRD,
|
|
|
3d71c6 |
- CRM_SYSTEM_MCP,
|
|
|
3d71c6 |
- };
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- struct ipc_client_callbacks node_callbacks = {
|
|
|
3d71c6 |
- .dispatch = node_mcp_dispatch,
|
|
|
3d71c6 |
- .destroy = node_mcp_destroy
|
|
|
3d71c6 |
- };
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
switch (command) {
|
|
|
3d71c6 |
- case 'R':
|
|
|
3d71c6 |
- for(rc = 0; rc < DIMOF(daemons); rc++) {
|
|
|
3d71c6 |
- if (tools_remove_node_cache(target_uname, daemons[rc])) {
|
|
|
3d71c6 |
- crm_err("Failed to connect to %s to remove node '%s'", daemons[rc], target_uname);
|
|
|
3d71c6 |
- crm_exit(pcmk_err_generic);
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
- crm_exit(pcmk_ok);
|
|
|
3d71c6 |
- break;
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- case 'e':
|
|
|
3d71c6 |
- /* Age makes no sense (yet) in an AIS cluster */
|
|
|
3d71c6 |
- fprintf(stdout, "1\n");
|
|
|
3d71c6 |
- crm_exit(pcmk_ok);
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
case 'q':
|
|
|
3d71c6 |
/* Go direct to the Quorum API */
|
|
|
3d71c6 |
rc = quorum_initialize(&q_handle, NULL, &quorum_type);
|
|
|
3d71c6 |
@@ -766,21 +812,8 @@ try_corosync(int command, enum cluster_type_e stack)
|
|
|
3d71c6 |
cpg_finalize(c_handle);
|
|
|
3d71c6 |
crm_exit(pcmk_ok);
|
|
|
3d71c6 |
|
|
|
3d71c6 |
- case 'l':
|
|
|
3d71c6 |
- case 'p':
|
|
|
3d71c6 |
- /* Go to pacemakerd */
|
|
|
3d71c6 |
- amainloop = g_main_new(FALSE);
|
|
|
3d71c6 |
- ipc =
|
|
|
3d71c6 |
- mainloop_add_ipc_client(CRM_SYSTEM_MCP, G_PRIORITY_DEFAULT, 0, NULL,
|
|
|
3d71c6 |
- &node_callbacks);
|
|
|
3d71c6 |
- if (ipc != NULL) {
|
|
|
3d71c6 |
- /* Sending anything will get us a list of nodes */
|
|
|
3d71c6 |
- xmlNode *poke = create_xml_node(NULL, "poke");
|
|
|
3d71c6 |
-
|
|
|
3d71c6 |
- crm_ipc_send(mainloop_get_ipc_client(ipc), poke, 0, 0, NULL);
|
|
|
3d71c6 |
- free_xml(poke);
|
|
|
3d71c6 |
- g_main_run(amainloop);
|
|
|
3d71c6 |
- }
|
|
|
3d71c6 |
+ default:
|
|
|
3d71c6 |
+ try_pacemaker(command, stack);
|
|
|
3d71c6 |
break;
|
|
|
3d71c6 |
}
|
|
|
3d71c6 |
return FALSE;
|
|
|
3d71c6 |
@@ -963,5 +996,7 @@ main(int argc, char **argv)
|
|
|
3d71c6 |
}
|
|
|
3d71c6 |
#endif
|
|
|
3d71c6 |
|
|
|
3d71c6 |
+ try_pacemaker(command, try_stack);
|
|
|
3d71c6 |
+
|
|
|
3d71c6 |
return (1);
|
|
|
3d71c6 |
}
|