diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c index 6d79aca0796..67614977082 100644 --- a/daemons/attrd/attrd_corosync.c +++ b/daemons/attrd/attrd_corosync.c @@ -23,6 +23,8 @@ #include "pacemaker-attrd.h" +pcmk_cluster_t *attrd_cluster = NULL; + /*! * \internal * \brief Nodes removed by \c attrd_peer_remove() @@ -133,21 +135,31 @@ attrd_peer_message(pcmk__node_status_t *peer, xmlNode *xml) } } +#if SUPPORT_COROSYNC +/*! + * \internal + * \brief Callback for when a peer message is received + * + * \param[in] handle The cluster connection + * \param[in] group_name The group that \p nodeid is a member of + * \param[in] nodeid Peer node that sent \p msg + * \param[in] pid Process that sent \p msg + * \param[in,out] msg Received message + * \param[in] msg_len Length of \p msg + */ static void -attrd_cpg_dispatch(cpg_handle_t handle, - const struct cpg_name *groupName, - uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) +attrd_cpg_dispatch(cpg_handle_t handle, const struct cpg_name *group_name, + uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) { xmlNode *xml = NULL; const char *from = NULL; char *data = pcmk__cpg_message_data(handle, nodeid, pid, msg, &from); - if(data == NULL) { + if (data == NULL) { return; } xml = pcmk__xml_parse(data); - if (xml == NULL) { crm_err("Bad message received from %s[%" PRIu32 "]: '%.120s'", from, nodeid, data); @@ -161,6 +173,12 @@ attrd_cpg_dispatch(cpg_handle_t handle, free(data); } +/*! + * \internal + * \brief Callback for when the cluster object is destroyed + * + * \param[in] unused Unused + */ static void attrd_cpg_destroy(gpointer unused) { @@ -173,6 +191,7 @@ attrd_cpg_destroy(gpointer unused) attrd_shutdown(0); } } +#endif // SUPPORT_COROSYNC /*! * \internal @@ -194,6 +213,14 @@ attrd_broadcast_value(const attribute_t *a, const attribute_value_t *v) #define state_text(state) pcmk__s((state), "in unknown state") +/*! + * \internal + * \brief Callback for peer status changes + * + * \param[in] type What changed + * \param[in] node What peer had the change + * \param[in] data Previous value of what changed + */ static void attrd_peer_change_cb(enum pcmk__node_update kind, pcmk__node_status_t *peer, const void *data) @@ -462,19 +489,29 @@ attrd_cluster_connect(void) attrd_cluster = pcmk_cluster_new(); - pcmk_cluster_set_destroy_fn(attrd_cluster, attrd_cpg_destroy); - pcmk_cpg_set_deliver_fn(attrd_cluster, attrd_cpg_dispatch); - pcmk_cpg_set_confchg_fn(attrd_cluster, pcmk__cpg_confchg_cb); +#if SUPPORT_COROSYNC + if (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync) { + pcmk_cluster_set_destroy_fn(attrd_cluster, attrd_cpg_destroy); + pcmk_cpg_set_deliver_fn(attrd_cluster, attrd_cpg_dispatch); + pcmk_cpg_set_confchg_fn(attrd_cluster, pcmk__cpg_confchg_cb); + } +#endif // SUPPORT_COROSYNC pcmk__cluster_set_status_callback(&attrd_peer_change_cb); rc = pcmk_cluster_connect(attrd_cluster); - rc = pcmk_rc2legacy(rc); - if (rc != pcmk_ok) { + if (rc != pcmk_rc_ok) { crm_err("Cluster connection failed"); - return rc; } - return pcmk_ok; + + return rc; +} + +void +attrd_cluster_disconnect(void) +{ + pcmk_cluster_disconnect(attrd_cluster); + pcmk_cluster_free(attrd_cluster); } void diff --git a/daemons/attrd/attrd_messages.c b/daemons/attrd/attrd_messages.c index dd1516a941c..5b9f06976c4 100644 --- a/daemons/attrd/attrd_messages.c +++ b/daemons/attrd/attrd_messages.c @@ -55,7 +55,8 @@ remove_unsupported_sync_points(pcmk__request_t *request) static xmlNode * handle_unknown_request(pcmk__request_t *request) { - crm_err("Unknown IPC request %s from %s %s", + crm_err("Unknown %s request %s from %s %s", + (request->ipc_client != NULL) ? "IPC" : "CPG", request->op, pcmk__request_origin_type(request), pcmk__request_origin(request)); pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, @@ -104,24 +105,24 @@ handle_clear_failure_request(pcmk__request_t *request) static xmlNode * handle_confirm_request(pcmk__request_t *request) { - if (request->peer != NULL) { - int callid; + int callid = 0; - crm_debug("Received confirmation from %s", request->peer); + if (request->ipc_client != NULL) { + return handle_unknown_request(request); + } - if (pcmk__xe_get_int(request->xml, PCMK__XA_CALL_ID, - &callid) != pcmk_rc_ok) { - pcmk__set_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, - "Could not get callid from XML"); - } else { - attrd_handle_confirmation(callid, request->peer); - } + crm_debug("Received confirmation from %s", request->peer); - pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); - return NULL; + if (pcmk__xe_get_int(request->xml, PCMK__XA_CALL_ID, + &callid) != pcmk_rc_ok) { + pcmk__set_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, + "Could not get callid from XML"); } else { - return handle_unknown_request(request); + attrd_handle_confirmation(callid, request->peer); } + + pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); + return NULL; } static xmlNode * @@ -129,29 +130,31 @@ handle_query_request(pcmk__request_t *request) { if (request->peer != NULL) { return handle_unknown_request(request); - } else { - return attrd_client_query(request); } + + return attrd_client_query(request); } static xmlNode * handle_remove_request(pcmk__request_t *request) { - if (request->peer != NULL) { - const char *host = pcmk__xe_get(request->xml, PCMK__XA_ATTR_HOST); - bool reap = false; - - if (pcmk__xe_get_bool(request->xml, PCMK__XA_REAP, - &reap) != pcmk_rc_ok) { - reap = true; // Default to true for backward compatibility - } - attrd_peer_remove(host, reap, request->peer); - pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); + const char *host = NULL; + bool reap = false; - } else { + if (request->ipc_client != NULL) { attrd_client_peer_remove(request); + return NULL; } + host = pcmk__xe_get(request->xml, PCMK__XA_ATTR_HOST); + + if (pcmk__xe_get_bool(request->xml, PCMK__XA_REAP, + &reap) != pcmk_rc_ok) { + reap = true; // Default to true for backward compatibility + } + + attrd_peer_remove(host, reap, request->peer); + pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); return NULL; } @@ -161,6 +164,7 @@ handle_refresh_request(pcmk__request_t *request) if (request->peer != NULL) { return handle_unknown_request(request); } + attrd_client_refresh(request); return NULL; } @@ -168,24 +172,24 @@ handle_refresh_request(pcmk__request_t *request) static xmlNode * handle_sync_response_request(pcmk__request_t *request) { + pcmk__node_status_t *peer = NULL; + bool peer_won = false; + if (request->ipc_client != NULL) { return handle_unknown_request(request); - } else { - if (request->peer != NULL) { - pcmk__node_status_t *peer = - pcmk__get_node(0, request->peer, NULL, - pcmk__node_search_cluster_member); - bool peer_won = attrd_check_for_new_writer(peer, request->xml); - - if (!pcmk__str_eq(peer->name, attrd_cluster->priv->node_name, - pcmk__str_casei)) { - attrd_peer_sync_response(peer, peer_won, request->xml); - } - } + } - pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); - return NULL; + peer = pcmk__get_node(0, request->peer, NULL, + pcmk__node_search_cluster_member); + peer_won = attrd_check_for_new_writer(peer, request->xml); + + if (!pcmk__str_eq(peer->name, attrd_cluster->priv->node_name, + pcmk__str_casei)) { + attrd_peer_sync_response(peer, peer_won, request->xml); } + + pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); + return NULL; } static xmlNode * diff --git a/daemons/attrd/pacemaker-attrd.c b/daemons/attrd/pacemaker-attrd.c index 1bbb129d1ea..363fd6cb351 100644 --- a/daemons/attrd/pacemaker-attrd.c +++ b/daemons/attrd/pacemaker-attrd.c @@ -56,7 +56,6 @@ static pcmk__supported_format_t formats[] = { }; lrmd_t *the_lrmd = NULL; -pcmk_cluster_t *attrd_cluster = NULL; crm_trigger_t *attrd_config_read = NULL; crm_exit_t attrd_exit_status = CRM_EX_OK; @@ -73,7 +72,7 @@ ipc_already_running(void) rc = pcmk__connect_ipc(old_instance, pcmk_ipc_dispatch_sync, 2); if (rc != pcmk_rc_ok) { - crm_debug("No existing %s manager instance found: %s", + crm_debug("No existing %s instance found: %s", pcmk_ipc_name(old_instance, true), pcmk_rc_str(rc)); pcmk_free_ipc_api(old_instance); return false; @@ -164,12 +163,13 @@ main(int argc, char **argv) crm_info("CIB connection active"); } - if (attrd_cluster_connect() != pcmk_ok) { + if (attrd_cluster_connect() != pcmk_rc_ok) { attrd_exit_status = CRM_EX_FATAL; g_set_error(&error, PCMK__EXITC_ERROR, attrd_exit_status, "Could not connect to the cluster"); goto done; } + crm_info("Cluster connection active"); // Initialization that requires the cluster to be connected @@ -203,8 +203,7 @@ main(int argc, char **argv) attrd_free_removed_peers(); attrd_free_waitlist(); - pcmk_cluster_disconnect(attrd_cluster); - pcmk_cluster_free(attrd_cluster); + attrd_cluster_disconnect(); g_hash_table_destroy(attributes); } diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h index e7e980af768..7c07a8fb651 100644 --- a/daemons/attrd/pacemaker-attrd.h +++ b/daemons/attrd/pacemaker-attrd.h @@ -191,6 +191,7 @@ void attrd_free_removed_peers(void); void attrd_erase_removed_peer_attributes(void); int attrd_cluster_connect(void); +void attrd_cluster_disconnect(void); void attrd_broadcast_value(const attribute_t *a, const attribute_value_t *v); void attrd_peer_update(const pcmk__node_status_t *peer, xmlNode *xml, const char *host, bool filter); diff --git a/daemons/execd/execd_messages.c b/daemons/execd/execd_messages.c index 9f9229e77e0..a37d4ebeeff 100644 --- a/daemons/execd/execd_messages.c +++ b/daemons/execd/execd_messages.c @@ -402,7 +402,7 @@ handle_unknown_request(pcmk__request_t *request) PCMK__XE_NACK, NULL, CRM_EX_PROTOCOL); pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, - "Unknown IPC request type '%s' (bug?)", + "Unknown request type '%s' (bug?)", pcmk__s(request->op, "")); return NULL; } diff --git a/daemons/fenced/Makefile.am b/daemons/fenced/Makefile.am index 4df1098d67b..801f4b63655 100644 --- a/daemons/fenced/Makefile.am +++ b/daemons/fenced/Makefile.am @@ -2,7 +2,7 @@ # Original Author: Sun Jiang Dong # Copyright 2004 International Business Machines # -# with later changes copyright 2004-2024 the Pacemaker project contributors. +# with later changes copyright 2004-2025 the Pacemaker project contributors. # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 @@ -42,6 +42,8 @@ pacemaker_fenced_LDADD += $(CLUSTERLIBS) pacemaker_fenced_SOURCES = pacemaker-fenced.c \ fenced_cib.c \ fenced_commands.c \ + fenced_corosync.c \ + fenced_ipc.c \ fenced_remote.c \ fenced_scheduler.c \ fenced_history.c diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c index 8d81ce896c3..5e43ff614a0 100644 --- a/daemons/fenced/fenced_commands.c +++ b/daemons/fenced/fenced_commands.c @@ -3179,13 +3179,29 @@ is_privileged(const pcmk__client_t *c, const char *op) } } +static xmlNode * +handle_unknown_request(pcmk__request_t *request) +{ + crm_err("Unknown %s request %s from %s %s", + (request->ipc_client != NULL) ? "IPC" : "CPG", + request->op, pcmk__request_origin_type(request), + pcmk__request_origin(request)); + pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, + "Unknown request type '%s' (bug?)", + pcmk__s(request->op, "")); + return fenced_construct_reply(request->xml, NULL, &request->result); +} + // CRM_OP_REGISTER static xmlNode * handle_register_request(pcmk__request_t *request) { xmlNode *reply = pcmk__xe_create(NULL, "reply"); - pcmk__assert(request->ipc_client != NULL); + if (request->peer != NULL) { + return handle_unknown_request(request); + } + pcmk__xe_set(reply, PCMK__XA_ST_OP, CRM_OP_REGISTER); pcmk__xe_set(reply, PCMK__XA_ST_CLIENTID, request->ipc_client->id); pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); @@ -3277,7 +3293,10 @@ handle_notify_request(pcmk__request_t *request) { const char *flag_name = NULL; - pcmk__assert(request->ipc_client != NULL); + if (request->peer != NULL) { + return handle_unknown_request(request); + } + flag_name = pcmk__xe_get(request->xml, PCMK__XA_ST_NOTIFY_ACTIVATE); if (flag_name != NULL) { crm_debug("Enabling %s callbacks for client %s", @@ -3539,18 +3558,6 @@ handle_cache_request(pcmk__request_t *request) return NULL; } -static xmlNode * -handle_unknown_request(pcmk__request_t *request) -{ - crm_err("Unknown IPC request %s from %s %s", - request->op, pcmk__request_origin_type(request), - pcmk__request_origin(request)); - pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, - "Unknown IPC request type '%s' (bug?)", - pcmk__s(request->op, "")); - return fenced_construct_reply(request->xml, NULL, &request->result); -} - static void fenced_register_handlers(void) { @@ -3583,17 +3590,23 @@ fenced_unregister_handlers(void) } } -static void -handle_request(pcmk__request_t *request) +void +fenced_handle_request(pcmk__request_t *request) { xmlNode *reply = NULL; + char *log_msg = NULL; + const char *exec_status_s = NULL; const char *reason = NULL; if (fenced_handlers == NULL) { fenced_register_handlers(); } + reply = pcmk__process_request(request, fenced_handlers); + if (reply != NULL) { + crm_log_xml_trace(reply, "Reply"); + if (pcmk__is_set(request->flags, pcmk__request_reuse_options) && (request->ipc_client != NULL)) { /* Certain IPC-only commands must reuse the call options from the @@ -3603,6 +3616,7 @@ handle_request(pcmk__request_t *request) pcmk__ipc_send_xml(request->ipc_client, request->ipc_id, reply, request->ipc_flags); request->ipc_client->request_id = 0; + } else { stonith_send_reply(reply, request->call_options, request->peer, request->ipc_client); @@ -3610,106 +3624,23 @@ handle_request(pcmk__request_t *request) pcmk__xml_free(reply); } + exec_status_s = pcmk_exec_status_str(request->result.execution_status); reason = request->result.exit_reason; - crm_debug("Processed %s request from %s %s: %s%s%s%s", - request->op, pcmk__request_origin_type(request), - pcmk__request_origin(request), - pcmk_exec_status_str(request->result.execution_status), - (reason == NULL)? "" : " (", - (reason == NULL)? "" : reason, - (reason == NULL)? "" : ")"); -} - -static void -handle_reply(pcmk__client_t *client, xmlNode *request, const char *remote_peer) -{ - // Copy, because request might be freed before we want to log this - char *op = pcmk__xe_get_copy(request, PCMK__XA_ST_OP); - - if (pcmk__str_eq(op, STONITH_OP_QUERY, pcmk__str_none)) { - process_remote_stonith_query(request); - - } else if (pcmk__str_any_of(op, STONITH_OP_NOTIFY, STONITH_OP_FENCE, - NULL)) { - fenced_process_fencing_reply(request); - + log_msg = pcmk__assert_asprintf("Processed %s request from %s %s: %s%s%s%s", + request->op, + pcmk__request_origin_type(request), + pcmk__request_origin(request), + exec_status_s, + (reason == NULL)? "" : " (", + pcmk__s(reason, ""), + (reason == NULL)? "" : ")"); + + if (!pcmk__result_ok(&request->result)) { + crm_warn("%s", log_msg); } else { - crm_err("Ignoring unknown %s reply from %s %s", - pcmk__s(op, "untyped"), ((client == NULL)? "peer" : "client"), - ((client == NULL)? remote_peer : pcmk__client_name(client))); - crm_log_xml_warn(request, "UnknownOp"); - free(op); - return; + crm_debug("%s", log_msg); } - crm_debug("Processed %s reply from %s %s", - op, ((client == NULL)? "peer" : "client"), - ((client == NULL)? remote_peer : pcmk__client_name(client))); - free(op); -} - -/*! - * \internal - * \brief Handle a message from an IPC client or CPG peer - * - * \param[in,out] client If not NULL, IPC client that sent message - * \param[in] id If from IPC client, IPC message ID - * \param[in] flags Message flags - * \param[in,out] message Message XML - * \param[in] remote_peer If not NULL, CPG peer that sent message - */ -void -stonith_command(pcmk__client_t *client, uint32_t id, uint32_t flags, - xmlNode *message, const char *remote_peer) -{ - uint32_t call_options = st_opt_none; - int rc = pcmk_rc_ok; - bool is_reply = false; - - CRM_CHECK(message != NULL, return); - if (pcmk__xpath_find_one(message->doc, "//" PCMK__XE_ST_REPLY, - LOG_NEVER) != NULL) { - is_reply = true; - } - - rc = pcmk__xe_get_flags(message, PCMK__XA_ST_CALLOPT, &call_options, - st_opt_none); - if (rc != pcmk_rc_ok) { - crm_warn("Couldn't parse options from message: %s", pcmk_rc_str(rc)); - } - - crm_debug("Processing %ssynchronous %s %s %u from %s %s", - pcmk__is_set(call_options, st_opt_sync_call)? "" : "a", - pcmk__xe_get(message, PCMK__XA_ST_OP), - (is_reply? "reply" : "request"), id, - ((client == NULL)? "peer" : "client"), - ((client == NULL)? remote_peer : pcmk__client_name(client))); - - if (pcmk__is_set(call_options, st_opt_sync_call)) { - pcmk__assert((client == NULL) || (client->request_id == id)); - } - - if (is_reply) { - handle_reply(client, message, remote_peer); - } else { - pcmk__request_t request = { - .ipc_client = client, - .ipc_id = id, - .ipc_flags = flags, - .peer = remote_peer, - .xml = message, - .call_options = call_options, - .result = PCMK__UNKNOWN_RESULT, - }; - - request.op = pcmk__xe_get_copy(request.xml, PCMK__XA_ST_OP); - CRM_CHECK(request.op != NULL, return); - - if (pcmk__is_set(request.call_options, st_opt_sync_call)) { - pcmk__set_request_flags(&request, pcmk__request_sync); - } - - handle_request(&request); - pcmk__reset_request(&request); - } + free(log_msg); + pcmk__reset_request(request); } diff --git a/daemons/fenced/fenced_corosync.c b/daemons/fenced/fenced_corosync.c new file mode 100644 index 00000000000..3888da7671b --- /dev/null +++ b/daemons/fenced/fenced_corosync.c @@ -0,0 +1,206 @@ +/* + * Copyright 2009-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU General Public License version 2 + * or later (GPLv2+) WITHOUT ANY WARRANTY. + */ + +#include + +#include // uint32_t, PRIu32 +#include // NULL, free, size_t + +#include // cpg_handle_t, cpg_name +#include // gpointer +#include // xmlNode + +#include // pcmk_cluster_connect +#include // pcmk_ipc_server +#include // pcmk_rc_* +#include // st_opt_* + +#include "pacemaker-fenced.h" + +pcmk_cluster_t *fenced_cluster = NULL; + +static void +handle_cpg_reply(const char *remote_peer, xmlNode *request) +{ + const char *op = pcmk__xe_get(request, PCMK__XA_ST_OP); + + if (pcmk__str_eq(op, STONITH_OP_QUERY, pcmk__str_none)) { + process_remote_stonith_query(request); + + } else if (pcmk__str_any_of(op, STONITH_OP_NOTIFY, STONITH_OP_FENCE, + NULL)) { + fenced_process_fencing_reply(request); + + } else { + crm_err("Ignoring unknown %s reply from peer %s", pcmk__s(op, "untyped"), + remote_peer); + crm_log_xml_warn(request, "UnknownOp"); + return; + } + + crm_debug("Processed %s reply from peer %s", op, remote_peer); +} + +static void +fenced_peer_message(pcmk__node_status_t *peer, xmlNode *xml) +{ + const char *op = pcmk__xe_get(xml, PCMK__XA_ST_OP); + int rc = pcmk_rc_ok; + + if (pcmk__str_eq(op, STONITH_OP_POKE, pcmk__str_none)) { + return; + } + + if (pcmk__xpath_find_one(xml->doc, "//" PCMK__XE_ST_REPLY, + LOG_NEVER) != NULL) { + handle_cpg_reply(peer->name, xml); + + } else { + pcmk__request_t request = { + .ipc_client = NULL, + .ipc_id = 0, + .ipc_flags = 0, + .peer = peer->name, + .xml = xml, + .call_options = st_opt_none, + .result = PCMK__UNKNOWN_RESULT, + }; + + rc = pcmk__xe_get_flags(xml, PCMK__XA_ST_CALLOPT, + (uint32_t *) &request.call_options, st_opt_none); + if (rc != pcmk_rc_ok) { + crm_warn("Couldn't parse options from request: %s", pcmk_rc_str(rc)); + } + + request.op = pcmk__xe_get_copy(request.xml, PCMK__XA_ST_OP); + CRM_CHECK(request.op != NULL, return); + + if (pcmk__is_set(request.call_options, st_opt_sync_call)) { + pcmk__set_request_flags(&request, pcmk__request_sync); + } + + fenced_handle_request(&request); + } +} + +/*! + * \internal + * \brief Callback for peer status changes + * + * \param[in] type What changed + * \param[in] node What peer had the change + * \param[in] data Previous value of what changed + */ +static void +fenced_peer_change_cb(enum pcmk__node_update type, pcmk__node_status_t *node, + const void *data) +{ + if ((type != pcmk__node_update_processes) + && !pcmk__is_set(node->flags, pcmk__node_status_remote)) { + /* + * This is a hack until we can send to a nodeid and/or we fix node name lookups + * These messages are ignored in stonith_peer_callback() + */ + xmlNode *query = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND); + + pcmk__xe_set(query, PCMK__XA_T, PCMK__VALUE_STONITH_NG); + pcmk__xe_set(query, PCMK__XA_ST_OP, STONITH_OP_POKE); + + crm_debug("Broadcasting our uname because of node %" PRIu32, + node->cluster_layer_id); + pcmk__cluster_send_message(NULL, pcmk_ipc_fenced, query); + + pcmk__xml_free(query); + } +} + +#if SUPPORT_COROSYNC +/*! + * \internal + * \brief Callback for when a peer message is received + * + * \param[in] handle The cluster connection + * \param[in] group_name The group that \p nodeid is a member of + * \param[in] nodeid Peer node that sent \p msg + * \param[in] pid Process that sent \p msg + * \param[in,out] msg Received message + * \param[in] msg_len Length of \p msg + */ +static void +fenced_cpg_dispatch(cpg_handle_t handle, const struct cpg_name *group_name, + uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) +{ + xmlNode *xml = NULL; + const char *from = NULL; + char *data = pcmk__cpg_message_data(handle, nodeid, pid, msg, &from); + + if (data == NULL) { + return; + } + + xml = pcmk__xml_parse(data); + if (xml == NULL) { + crm_err("Bad message received from %s[%" PRIu32 "]: '%.120s'", + from, nodeid, data); + } else { + pcmk__xe_set(xml, PCMK__XA_SRC, from); + fenced_peer_message(pcmk__get_node(nodeid, from, NULL, + pcmk__node_search_cluster_member), + xml); + } + + pcmk__xml_free(xml); + free(data); +} + +/*! + * \internal + * \brief Callback for when the cluster object is destroyed + * + * \param[in] unused Unused + */ +static void +fenced_cpg_destroy(gpointer unused) +{ + crm_crit("Lost connection to cluster layer, shutting down"); + stonith_shutdown(0); +} +#endif // SUPPORT_COROSYNC + +int +fenced_cluster_connect(void) +{ + int rc = pcmk_rc_ok; + + fenced_cluster = pcmk_cluster_new(); + +#if SUPPORT_COROSYNC + if (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync) { + pcmk_cluster_set_destroy_fn(fenced_cluster, fenced_cpg_destroy); + pcmk_cpg_set_deliver_fn(fenced_cluster, fenced_cpg_dispatch); + pcmk_cpg_set_confchg_fn(fenced_cluster, pcmk__cpg_confchg_cb); + } +#endif // SUPPORT_COROSYNC + + pcmk__cluster_set_status_callback(&fenced_peer_change_cb); + + rc = pcmk_cluster_connect(fenced_cluster); + if (rc != pcmk_rc_ok) { + crm_err("Cluster connection failed"); + } + + return rc; +} + +void +fenced_cluster_disconnect(void) +{ + pcmk_cluster_disconnect(fenced_cluster); + pcmk_cluster_free(fenced_cluster); +} diff --git a/daemons/fenced/fenced_ipc.c b/daemons/fenced/fenced_ipc.c new file mode 100644 index 00000000000..df8b1974fe0 --- /dev/null +++ b/daemons/fenced/fenced_ipc.c @@ -0,0 +1,282 @@ +/* + * Copyright 2009-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU General Public License version 2 + * or later (GPLv2+) WITHOUT ANY WARRANTY. + */ + +#include + +#include // ECONNREFUSED, ENOMEM +#include // int32_t, uint32_t, PRIu32 +#include // NULL, size_t +#include // gid_t, uid_t + +#include // xmlNode +#include // g_byte_array_free, TRUE +#include // for qb_ipcs_connection_t + +#include "pacemaker-fenced.h" // fenced_get_local_node + +#include // crm_ipc_flags, pcmk_ipc_fenced +#include // pcmk_rc_*, pcmk_rc_str +#include // STONITH_OP_* +#include // CRM_OP_RM_NODE_CACHE +#include // stonith_call_options + +static qb_ipcs_service_t *ipcs = NULL; + +static void +handle_ipc_reply(pcmk__client_t *client, xmlNode *request) +{ + const char *op = pcmk__xe_get(request, PCMK__XA_ST_OP); + + if (pcmk__str_eq(op, STONITH_OP_QUERY, pcmk__str_none)) { + process_remote_stonith_query(request); + + } else if (pcmk__str_any_of(op, STONITH_OP_NOTIFY, STONITH_OP_FENCE, + NULL)) { + fenced_process_fencing_reply(request); + + } else { + crm_err("Ignoring unknown %s reply from client %s", + pcmk__s(op, "untyped"), pcmk__client_name(client)); + crm_log_xml_warn(request, "UnknownOp"); + return; + } + + crm_debug("Processed %s reply from client %s", op, + pcmk__client_name(client)); +} + +/*! + * \internal + * \brief Accept a new client IPC connection + * + * \param[in,out] c New connection + * \param[in] uid Client user id + * \param[in] gid Client group id + * + * \return 0 on success, -errno otherwise + */ +static int32_t +fenced_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) +{ + crm_trace("New client connection %p", c); + if (stonith_shutdown_flag) { + crm_info("Ignoring new connection from pid %d during shutdown", + pcmk__client_pid(c)); + return -ECONNREFUSED; + } + + if (pcmk__new_client(c, uid, gid) == NULL) { + return -ENOMEM; + } + return 0; +} + +/*! + * \internal + * \brief Handle a message from an IPC connection + * + * \param[in,out] c Established IPC connection + * \param[in] data The message data read from the connection - this can be + * a complete IPC message or just a part of one if it's + * very large + * \param[in] size Unused + * + * \return 0 in all cases + */ +static int32_t +fenced_ipc_dispatch(qb_ipcs_connection_t *c, void *data, size_t size) +{ + uint32_t id = 0; + uint32_t flags = 0; + uint32_t call_options = st_opt_none; + xmlNode *msg = NULL; + pcmk__client_t *client = pcmk__find_client(c); + const char *op = NULL; + int rc = pcmk_rc_ok; + + // Sanity-check, and parse XML from IPC data + CRM_CHECK(client != NULL, return 0); + if (data == NULL) { + crm_debug("No IPC data from PID %d", pcmk__client_pid(c)); + return 0; + } + + rc = pcmk__ipc_msg_append(&client->buffer, data); + + if (rc == pcmk_rc_ipc_more) { + /* We haven't read the complete message yet, so just return. */ + return 0; + + } else if (rc == pcmk_rc_ok) { + /* We've read the complete message and there's already a header on + * the front. Pass it off for processing. + */ + msg = pcmk__client_data2xml(client, &id, &flags); + g_byte_array_free(client->buffer, TRUE); + client->buffer = NULL; + + } else { + /* Some sort of error occurred reassembling the message. All we can + * do is clean up, log an error and return. + */ + crm_err("Error when reading IPC message: %s", pcmk_rc_str(rc)); + + if (client->buffer != NULL) { + g_byte_array_free(client->buffer, TRUE); + client->buffer = NULL; + } + + return 0; + } + + if (msg == NULL) { + crm_debug("Unrecognizable IPC data from PID %d", pcmk__client_pid(c)); + pcmk__ipc_send_ack(client, id, flags, PCMK__XE_NACK, NULL, CRM_EX_PROTOCOL); + return 0; + } + + op = pcmk__xe_get(msg, PCMK__XA_CRM_TASK); + if (pcmk__str_eq(op, CRM_OP_RM_NODE_CACHE, pcmk__str_casei)) { + pcmk__xe_set(msg, PCMK__XA_T, PCMK__VALUE_STONITH_NG); + pcmk__xe_set(msg, PCMK__XA_ST_OP, op); + pcmk__xe_set(msg, PCMK__XA_ST_CLIENTID, client->id); + pcmk__xe_set(msg, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(client)); + pcmk__xe_set(msg, PCMK__XA_ST_CLIENTNODE, fenced_get_local_node()); + + pcmk__cluster_send_message(NULL, pcmk_ipc_fenced, msg); + pcmk__xml_free(msg); + return 0; + } + + if (client->name == NULL) { + const char *value = pcmk__xe_get(msg, PCMK__XA_ST_CLIENTNAME); + + client->name = pcmk__assert_asprintf("%s.%u", pcmk__s(value, "unknown"), + client->pid); + } + + rc = pcmk__xe_get_flags(msg, PCMK__XA_ST_CALLOPT, &call_options, + st_opt_none); + if (rc != pcmk_rc_ok) { + crm_warn("Couldn't parse options from request: %s", pcmk_rc_str(rc)); + } + + crm_trace("Flags %#08" PRIx32 "/%#08x for command %" PRIu32 + " from client %s", flags, call_options, id, pcmk__client_name(client)); + + if (pcmk__is_set(call_options, st_opt_sync_call)) { + pcmk__assert(pcmk__is_set(flags, crm_ipc_client_response)); + /* This means the client has two synchronous events in-flight */ + CRM_LOG_ASSERT(client->request_id == 0); + /* Reply only to the last one */ + client->request_id = id; + } + + pcmk__xe_set(msg, PCMK__XA_ST_CLIENTID, client->id); + pcmk__xe_set(msg, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(client)); + pcmk__xe_set(msg, PCMK__XA_ST_CLIENTNODE, fenced_get_local_node()); + + if (pcmk__xpath_find_one(msg->doc, "//" PCMK__XE_ST_REPLY, + LOG_NEVER) != NULL) { + handle_ipc_reply(client, msg); + + } else { + pcmk__request_t request = { + .ipc_client = client, + .ipc_id = id, + .ipc_flags = flags, + .peer = NULL, + .xml = msg, + .call_options = call_options, + .result = PCMK__UNKNOWN_RESULT, + }; + + request.op = pcmk__xe_get_copy(request.xml, PCMK__XA_ST_OP); + CRM_CHECK(request.op != NULL, return 0); + + if (pcmk__is_set(request.call_options, st_opt_sync_call)) { + pcmk__set_request_flags(&request, pcmk__request_sync); + } + + fenced_handle_request(&request); + } + + pcmk__xml_free(msg); + return 0; +} + +/*! + * \internal + * \brief Destroy a client IPC connection + * + * \param[in] c Connection to destroy + * + * \return 0 (i.e. do not re-run this callback) + */ +static int32_t +fenced_ipc_closed(qb_ipcs_connection_t *c) +{ + pcmk__client_t *client = pcmk__find_client(c); + + if (client == NULL) { + crm_trace("Ignoring request to clean up unknown connection %p", c); + } else { + crm_trace("Cleaning up closed client connection %p", c); + pcmk__free_client(client); + } + + return 0; +} + +/*! + * \internal + * \brief Destroy a client IPC connection + * + * \param[in] c Connection to destroy + * + * \note We handle a destroyed connection the same as a closed one, + * but we need a separate handler because the return type is different. + */ +static void +fenced_ipc_destroy(qb_ipcs_connection_t *c) +{ + crm_trace("Destroying client connection %p", c); + fenced_ipc_closed(c); +} + +static struct qb_ipcs_service_handlers ipc_callbacks = { + .connection_accept = fenced_ipc_accept, + .connection_created = NULL, + .msg_process = fenced_ipc_dispatch, + .connection_closed = fenced_ipc_closed, + .connection_destroyed = fenced_ipc_destroy +}; + +void +fenced_ipc_cleanup(void) +{ + if (ipcs != NULL) { + pcmk__drop_all_clients(ipcs); + qb_ipcs_destroy(ipcs); + ipcs = NULL; + } + + fenced_unregister_handlers(); + pcmk__client_cleanup(); +} + +/*! + * \internal + * \brief Set up fenced IPC communication + */ +void +fenced_ipc_init(void) +{ + pcmk__serve_fenced_ipc(&ipcs, &ipc_callbacks); +} diff --git a/daemons/fenced/pacemaker-fenced.c b/daemons/fenced/pacemaker-fenced.c index 57cb83dc2e7..94441959e37 100644 --- a/daemons/fenced/pacemaker-fenced.c +++ b/daemons/fenced/pacemaker-fenced.c @@ -49,7 +49,6 @@ static GMainLoop *mainloop = NULL; gboolean stonith_shutdown_flag = FALSE; -static qb_ipcs_service_t *ipcs = NULL; static pcmk__output_t *out = NULL; pcmk__supported_format_t formats[] = { @@ -68,190 +67,6 @@ crm_exit_t exit_code = CRM_EX_OK; static void stonith_cleanup(void); -static int32_t -st_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid) -{ - if (stonith_shutdown_flag) { - crm_info("Ignoring new client [%d] during shutdown", - pcmk__client_pid(c)); - return -ECONNREFUSED; - } - - if (pcmk__new_client(c, uid, gid) == NULL) { - return -ENOMEM; - } - return 0; -} - -/* Exit code means? */ -static int32_t -st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) -{ - uint32_t id = 0; - uint32_t flags = 0; - uint32_t call_options = st_opt_none; - xmlNode *request = NULL; - pcmk__client_t *c = pcmk__find_client(qbc); - const char *op = NULL; - int rc = pcmk_rc_ok; - - if (c == NULL) { - crm_info("Invalid client: %p", qbc); - return 0; - } - - rc = pcmk__ipc_msg_append(&c->buffer, data); - - if (rc == pcmk_rc_ipc_more) { - /* We haven't read the complete message yet, so just return. */ - return 0; - - } else if (rc == pcmk_rc_ok) { - /* We've read the complete message and there's already a header on - * the front. Pass it off for processing. - */ - request = pcmk__client_data2xml(c, &id, &flags); - g_byte_array_free(c->buffer, TRUE); - c->buffer = NULL; - - } else { - /* Some sort of error occurred reassembling the message. All we can - * do is clean up, log an error and return. - */ - crm_err("Error when reading IPC message: %s", pcmk_rc_str(rc)); - - if (c->buffer != NULL) { - g_byte_array_free(c->buffer, TRUE); - c->buffer = NULL; - } - - return 0; - } - - if (request == NULL) { - pcmk__ipc_send_ack(c, id, flags, PCMK__XE_NACK, NULL, CRM_EX_PROTOCOL); - return 0; - } - - op = pcmk__xe_get(request, PCMK__XA_CRM_TASK); - if(pcmk__str_eq(op, CRM_OP_RM_NODE_CACHE, pcmk__str_casei)) { - pcmk__xe_set(request, PCMK__XA_T, PCMK__VALUE_STONITH_NG); - pcmk__xe_set(request, PCMK__XA_ST_OP, op); - pcmk__xe_set(request, PCMK__XA_ST_CLIENTID, c->id); - pcmk__xe_set(request, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(c)); - pcmk__xe_set(request, PCMK__XA_ST_CLIENTNODE, fenced_get_local_node()); - - pcmk__cluster_send_message(NULL, pcmk_ipc_fenced, request); - pcmk__xml_free(request); - return 0; - } - - if (c->name == NULL) { - const char *value = pcmk__xe_get(request, PCMK__XA_ST_CLIENTNAME); - - c->name = pcmk__assert_asprintf("%s.%u", pcmk__s(value, "unknown"), - c->pid); - } - - rc = pcmk__xe_get_flags(request, PCMK__XA_ST_CALLOPT, &call_options, - st_opt_none); - if (rc != pcmk_rc_ok) { - crm_warn("Couldn't parse options from IPC request: %s", - pcmk_rc_str(rc)); - } - - crm_trace("Flags %#08" PRIx32 "/%#08x for command %" PRIu32 - " from client %s", flags, call_options, id, pcmk__client_name(c)); - - if (pcmk__is_set(call_options, st_opt_sync_call)) { - pcmk__assert(pcmk__is_set(flags, crm_ipc_client_response)); - CRM_LOG_ASSERT(c->request_id == 0); /* This means the client has two synchronous events in-flight */ - c->request_id = id; /* Reply only to the last one */ - } - - pcmk__xe_set(request, PCMK__XA_ST_CLIENTID, c->id); - pcmk__xe_set(request, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(c)); - pcmk__xe_set(request, PCMK__XA_ST_CLIENTNODE, fenced_get_local_node()); - - crm_log_xml_trace(request, "ipc-received"); - stonith_command(c, id, flags, request, NULL); - - pcmk__xml_free(request); - return 0; -} - -/* Error code means? */ -static int32_t -st_ipc_closed(qb_ipcs_connection_t * c) -{ - pcmk__client_t *client = pcmk__find_client(c); - - if (client == NULL) { - return 0; - } - - crm_trace("Connection %p closed", c); - pcmk__free_client(client); - - /* 0 means: yes, go ahead and destroy the connection */ - return 0; -} - -static void -st_ipc_destroy(qb_ipcs_connection_t * c) -{ - crm_trace("Connection %p destroyed", c); - st_ipc_closed(c); -} - -static void -stonith_peer_callback(xmlNode * msg, void *private_data) -{ - const char *remote_peer = pcmk__xe_get(msg, PCMK__XA_SRC); - const char *op = pcmk__xe_get(msg, PCMK__XA_ST_OP); - - if (pcmk__str_eq(op, STONITH_OP_POKE, pcmk__str_none)) { - return; - } - - crm_log_xml_trace(msg, "Peer[inbound]"); - stonith_command(NULL, 0, 0, msg, remote_peer); -} - -#if SUPPORT_COROSYNC -static void -handle_cpg_message(cpg_handle_t handle, const struct cpg_name *groupName, - uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) -{ - xmlNode *xml = NULL; - const char *from = NULL; - char *data = pcmk__cpg_message_data(handle, nodeid, pid, msg, &from); - - if(data == NULL) { - return; - } - - xml = pcmk__xml_parse(data); - if (xml == NULL) { - crm_err("Invalid XML: '%.120s'", data); - free(data); - return; - } - pcmk__xe_set(xml, PCMK__XA_SRC, from); - stonith_peer_callback(xml, NULL); - - pcmk__xml_free(xml); - free(data); -} - -static void -stonith_peer_cs_destroy(gpointer user_data) -{ - crm_crit("Lost connection to cluster layer, shutting down"); - stonith_shutdown(0); -} -#endif - void do_local_reply(const xmlNode *notify_src, pcmk__client_t *client, int call_options) @@ -461,56 +276,12 @@ static void stonith_cleanup(void) { fenced_cib_cleanup(); - if (ipcs) { - qb_ipcs_destroy(ipcs); - } - + fenced_ipc_cleanup(); pcmk__cluster_destroy_node_caches(); - pcmk__client_cleanup(); free_stonith_remote_op_list(); free_topology_list(); fenced_free_device_table(); free_metadata_cache(); - fenced_unregister_handlers(); -} - -struct qb_ipcs_service_handlers ipc_callbacks = { - .connection_accept = st_ipc_accept, - .connection_created = NULL, - .msg_process = st_ipc_dispatch, - .connection_closed = st_ipc_closed, - .connection_destroyed = st_ipc_destroy -}; - -/*! - * \internal - * \brief Callback for peer status changes - * - * \param[in] type What changed - * \param[in] node What peer had the change - * \param[in] data Previous value of what changed - */ -static void -st_peer_update_callback(enum pcmk__node_update type, pcmk__node_status_t *node, - const void *data) -{ - if ((type != pcmk__node_update_processes) - && !pcmk__is_set(node->flags, pcmk__node_status_remote)) { - /* - * This is a hack until we can send to a nodeid and/or we fix node name lookups - * These messages are ignored in stonith_peer_callback() - */ - xmlNode *query = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND); - - pcmk__xe_set(query, PCMK__XA_T, PCMK__VALUE_STONITH_NG); - pcmk__xe_set(query, PCMK__XA_ST_OP, STONITH_OP_POKE); - - crm_debug("Broadcasting our uname because of node %" PRIu32, - node->cluster_layer_id); - pcmk__cluster_send_message(NULL, pcmk_ipc_fenced, query); - - pcmk__xml_free(query); - } } /* @COMPAT Deprecated since 2.1.8. Use pcmk_list_fence_attrs() or @@ -553,12 +324,37 @@ build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) return context; } +static bool +ipc_already_running(void) +{ + crm_ipc_t *old_instance = NULL; + int rc = pcmk_rc_ok; + + old_instance = crm_ipc_new("stonith-ng", 0); + if (old_instance == NULL) { + /* This is an error - memory allocation failed, etc. - but crm_ipc_new + * will have already logged an error message. + */ + return false; + } + + rc = pcmk__connect_generic_ipc(old_instance); + if (rc != pcmk_rc_ok) { + crm_debug("No existing stonith-ng instance found: %s", + pcmk_rc_str(rc)); + crm_ipc_destroy(old_instance); + return false; + } + + crm_ipc_close(old_instance); + crm_ipc_destroy(old_instance); + return true; +} + int main(int argc, char **argv) { int rc = pcmk_rc_ok; - pcmk_cluster_t *cluster = NULL; - crm_ipc_t *old_instance = NULL; GError *error = NULL; @@ -609,26 +405,12 @@ main(int argc, char **argv) crm_notice("Starting Pacemaker fencer"); - old_instance = crm_ipc_new("stonith-ng", 0); - if (old_instance == NULL) { - /* crm_ipc_new() will have already logged an error message with - * crm_err() - */ - exit_code = CRM_EX_FATAL; - goto done; - } - - if (pcmk__connect_generic_ipc(old_instance) == pcmk_rc_ok) { - // IPC endpoint already up - crm_ipc_close(old_instance); - crm_ipc_destroy(old_instance); - crm_crit("Aborting start-up because another fencer instance is " - "already active"); + if (ipc_already_running()) { + exit_code = CRM_EX_OK; + g_set_error(&error, PCMK__EXITC_ERROR, exit_code, + "Aborting start-up because a fencer instance is already active"); + crm_crit("%s", error->message); goto done; - } else { - // Not up or not authentic, we'll proceed either way - crm_ipc_destroy(old_instance); - old_instance = NULL; } mainloop_add_signal(SIGTERM, stonith_shutdown); @@ -643,24 +425,16 @@ main(int argc, char **argv) goto done; } - cluster = pcmk_cluster_new(); - -#if SUPPORT_COROSYNC - if (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync) { - pcmk_cluster_set_destroy_fn(cluster, stonith_peer_cs_destroy); - pcmk_cpg_set_deliver_fn(cluster, handle_cpg_message); - pcmk_cpg_set_confchg_fn(cluster, pcmk__cpg_confchg_cb); - } -#endif // SUPPORT_COROSYNC - - pcmk__cluster_set_status_callback(&st_peer_update_callback); - - if (pcmk_cluster_connect(cluster) != pcmk_rc_ok) { + if (fenced_cluster_connect() != pcmk_rc_ok) { exit_code = CRM_EX_FATAL; - crm_crit("Cannot sign in to the cluster... terminating"); + g_set_error(&error, PCMK__EXITC_ERROR, exit_code, + "Could not connect to the cluster"); goto done; } - fenced_set_local_node(cluster->priv->node_name); + + crm_info("Cluster connection active"); + + fenced_set_local_node(fenced_cluster->priv->node_name); if (!options.stand_alone) { setup_cib(); @@ -668,8 +442,7 @@ main(int argc, char **argv) fenced_init_device_table(); init_topology_list(); - - pcmk__serve_fenced_ipc(&ipcs, &ipc_callbacks); + fenced_ipc_init(); // Create the mainloop and run it... mainloop = g_main_loop_new(NULL, FALSE); @@ -683,7 +456,7 @@ main(int argc, char **argv) g_strfreev(options.log_files); stonith_cleanup(); - pcmk_cluster_free(cluster); + fenced_cluster_disconnect(); fenced_scheduler_cleanup(); pcmk__output_and_clear_error(&error, out); diff --git a/daemons/fenced/pacemaker-fenced.h b/daemons/fenced/pacemaker-fenced.h index e46f26102e9..d29fbf422a9 100644 --- a/daemons/fenced/pacemaker-fenced.h +++ b/daemons/fenced/pacemaker-fenced.h @@ -309,9 +309,6 @@ void init_stonith_remote_op_hash_table(GHashTable **table); void free_metadata_cache(void); void fenced_unregister_handlers(void); -void stonith_command(pcmk__client_t *client, uint32_t id, uint32_t flags, - xmlNode *op_request, const char *remote_peer); - int fenced_device_register(const xmlNode *dev, bool from_cib); void stonith_device_remove(const char *id, bool from_cib); @@ -377,6 +374,14 @@ const char *fenced_get_local_node(void); void fenced_scheduler_cleanup(void); void fenced_scheduler_run(xmlNode *cib); +void fenced_ipc_init(void); +void fenced_ipc_cleanup(void); + +int fenced_cluster_connect(void); +void fenced_cluster_disconnect(void); + +void fenced_handle_request(pcmk__request_t *request); + /*! * \internal * \brief Get the device flag to use with a given action when searching devices @@ -401,3 +406,4 @@ extern GList *stonith_watchdog_targets; extern GHashTable *stonith_remote_op_list; extern crm_exit_t exit_code; extern gboolean stonith_shutdown_flag; +extern pcmk_cluster_t *fenced_cluster; diff --git a/daemons/pacemakerd/pcmkd_ipc.c b/daemons/pacemakerd/pcmkd_ipc.c index 54e59347ecf..88da9c77fe7 100644 --- a/daemons/pacemakerd/pcmkd_ipc.c +++ b/daemons/pacemakerd/pcmkd_ipc.c @@ -99,7 +99,7 @@ pacemakerd_ipc_destroy(qb_ipcs_connection_t *c) * \param[in] data The message data read from the connection - this can be * a complete IPC message or just a part of one if it's * very large - * \param[size] size Unused + * \param[in] size Unused * * \return 0 in all cases */ diff --git a/daemons/pacemakerd/pcmkd_messages.c b/daemons/pacemakerd/pcmkd_messages.c index 1fc0e57897d..de96edddb50 100644 --- a/daemons/pacemakerd/pcmkd_messages.c +++ b/daemons/pacemakerd/pcmkd_messages.c @@ -153,7 +153,7 @@ handle_unknown_request(pcmk__request_t *request) PCMK__XE_ACK, NULL, CRM_EX_PROTOCOL); pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, - "Unknown IPC request type '%s' (bug?)", + "Unknown request type '%s' (bug?)", pcmk__s(request->op, "")); return NULL; } diff --git a/daemons/schedulerd/schedulerd_ipc.c b/daemons/schedulerd/schedulerd_ipc.c index 81d96a05d17..95468664bc1 100644 --- a/daemons/schedulerd/schedulerd_ipc.c +++ b/daemons/schedulerd/schedulerd_ipc.c @@ -53,7 +53,7 @@ schedulerd_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) * \param[in] data The message data read from the connection - this can be * a complete IPC message or just a part of one if it's * very large - * \param[size] size Unused + * \param[in] size Unused * * \return 0 in all cases */ diff --git a/daemons/schedulerd/schedulerd_messages.c b/daemons/schedulerd/schedulerd_messages.c index a004db00074..bce27a0af48 100644 --- a/daemons/schedulerd/schedulerd_messages.c +++ b/daemons/schedulerd/schedulerd_messages.c @@ -190,7 +190,7 @@ handle_unknown_request(pcmk__request_t *request) PCMK__XE_ACK, NULL, CRM_EX_PROTOCOL); pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, - "Unknown IPC request type '%s' (bug?)", + "Unknown request type '%s' (bug?)", pcmk__s(request->op, "")); return NULL; }