From 6792809bcd9dfef5e919d09ea57c0345213fb6fe Mon Sep 17 00:00:00 2001 From: Aleksei Burlakov Date: Fri, 27 Sep 2024 11:22:01 +0200 Subject: [PATCH] Fix: crmadmin: leave xml-src attribute empty when no DC selected #2902 Right after starting the cluster the DC is offline for short time, and if you call 'crmadmin --dc_lookup' during this time, it would hang. This change leaves the xml-src attribute that the crmadmin receives from the pacemaker-controld empty, so that crmadmin knows the DC was not selected. ref: https://projects.clusterlabs.org/T735 --- daemons/controld/controld_control.c | 1 + daemons/controld/controld_messages.c | 39 +++++++++++++++++++++------- lib/common/ipc_controld.c | 2 ++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/daemons/controld/controld_control.c b/daemons/controld/controld_control.c index ff1951854de..0c5a79e5b81 100644 --- a/daemons/controld/controld_control.c +++ b/daemons/controld/controld_control.c @@ -117,6 +117,7 @@ do_shutdown_req(long long action, controld_set_fsa_input_flags(R_SHUTDOWN); //controld_set_fsa_input_flags(R_STAYDOWN); + crm_info("Sending shutdown request to all peers (DC is %s)", pcmk__s(controld_globals.dc_name, "not set")); msg = pcmk__new_request(pcmk_ipc_controld, CRM_SYSTEM_CRMD, NULL, diff --git a/daemons/controld/controld_messages.c b/daemons/controld/controld_messages.c index 1730989983e..d1f0f062f80 100644 --- a/daemons/controld/controld_messages.c +++ b/daemons/controld/controld_messages.c @@ -23,11 +23,12 @@ static enum crmd_fsa_input handle_message(xmlNode *msg, enum crmd_fsa_cause cause); +static xmlNode* create_ping_reply(const xmlNode *msg); static void handle_response(xmlNode *stored_msg); static enum crmd_fsa_input handle_request(xmlNode *stored_msg, enum crmd_fsa_cause cause); static enum crmd_fsa_input handle_shutdown_request(xmlNode *stored_msg); -static void send_msg_via_ipc(xmlNode * msg, const char *sys); +static void send_msg_via_ipc(xmlNode * msg, const char *sys, const char *src); /* debug only, can wrap all it likes */ static int last_data_id = 0; @@ -439,6 +440,18 @@ relay_message(xmlNode * msg, gboolean originated_locally) } } + // If the DC is not yet selected + if ((strcmp(task, CRM_OP_PING) == 0) && (controld_globals.dc_name == NULL)) { + if (is_for_dc) { + xmlNode *reply = create_ping_reply(msg); + sys_to = crm_element_value(reply, PCMK__XA_CRM_SYS_TO); + // Explicitly leave src empty. It indicates that dc is "not yet selected" + send_msg_via_ipc(reply, sys_to, NULL /* explicitly leave src empty */); + pcmk__xml_free(reply); + return TRUE; + } + } + // Check whether message should be relayed if (is_for_dc || is_for_dcib || is_for_te) { @@ -447,9 +460,11 @@ relay_message(xmlNode * msg, gboolean originated_locally) crm_trace("Route message %s locally as transition request", ref); crm_log_xml_trace(msg, sys_to); - send_msg_via_ipc(msg, sys_to); + send_msg_via_ipc(msg, sys_to, controld_globals.cluster->priv->node_name); + return TRUE; // No further processing of message is needed } + crm_trace("Route message %s locally as DC request", ref); return FALSE; // More to be done by caller } @@ -483,7 +498,7 @@ relay_message(xmlNode * msg, gboolean originated_locally) } crm_trace("Relay message %s locally to %s", ref, sys_to); crm_log_xml_trace(msg, "IPC-relay"); - send_msg_via_ipc(msg, sys_to); + send_msg_via_ipc(msg, sys_to, controld_globals.cluster->priv->node_name); return TRUE; } @@ -809,8 +824,8 @@ handle_remote_state(const xmlNode *msg) * * \return Next FSA input */ -static enum crmd_fsa_input -handle_ping(const xmlNode *msg) +static xmlNode* +create_ping_reply(const xmlNode *msg) { const char *value = NULL; xmlNode *ping = NULL; @@ -831,9 +846,15 @@ handle_ping(const xmlNode *msg) // @TODO maybe do some checks to determine meaningful status crm_xml_add(ping, PCMK_XA_RESULT, "ok"); - // Send reply reply = pcmk__new_reply(msg, ping); pcmk__xml_free(ping); + return reply; +} + +static enum crmd_fsa_input +handle_ping(const xmlNode *msg) +{ + xmlNode *reply = create_ping_reply(msg); if (reply != NULL) { (void) relay_message(reply, TRUE); pcmk__xml_free(reply); @@ -1079,6 +1100,7 @@ handle_request(xmlNode *stored_msg, enum crmd_fsa_cause cause) } } + /*========== common actions ==========*/ if (strcmp(op, CRM_OP_NOVOTE) == 0) { ha_msg_input_t fsa_input; @@ -1272,7 +1294,7 @@ handle_shutdown_request(xmlNode * stored_msg) } static void -send_msg_via_ipc(xmlNode * msg, const char *sys) +send_msg_via_ipc(xmlNode * msg, const char *sys, const char *src) { pcmk__client_t *client_channel = NULL; @@ -1281,8 +1303,7 @@ send_msg_via_ipc(xmlNode * msg, const char *sys) client_channel = pcmk__find_client_by_id(sys); if (crm_element_value(msg, PCMK__XA_SRC) == NULL) { - crm_xml_add(msg, PCMK__XA_SRC, - controld_globals.cluster->priv->node_name); + crm_xml_add(msg, PCMK__XA_SRC, src); } if (client_channel != NULL) { diff --git a/lib/common/ipc_controld.c b/lib/common/ipc_controld.c index 37e1f50aa68..896a92269db 100644 --- a/lib/common/ipc_controld.c +++ b/lib/common/ipc_controld.c @@ -333,6 +333,7 @@ create_controller_request(const pcmk_ipc_api_t *api, const char *op, if (api == NULL) { return NULL; } + private = api->api_data; if ((node == NULL) && !strcmp(op, CRM_OP_PING)) { sys_to = CRM_SYSTEM_DC; @@ -459,6 +460,7 @@ pcmk_controld_api_ping(pcmk_ipc_api_t *api, const char *node_name) if (request == NULL) { return EINVAL; } + rc = send_controller_request(api, request, true); pcmk__xml_free(request); return rc;