diff --git a/daemons/pacemakerd/pcmkd_messages.c b/daemons/pacemakerd/pcmkd_messages.c index 21ebb7d8b3..48fe51a6f9 100644 --- a/daemons/pacemakerd/pcmkd_messages.c +++ b/daemons/pacemakerd/pcmkd_messages.c @@ -1,309 +1,309 @@ /* * Copyright 2010-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 "pacemakerd.h" #include #include #include #include #include #include #include #include static GHashTable *pcmkd_handlers = NULL; static xmlNode * handle_node_cache_request(pcmk__request_t *request) { crm_trace("Ignoring request from client %s to purge node " "because peer cache is not used", pcmk__client_name(request->ipc_client)); pcmk__ipc_send_ack(request->ipc_client, request->ipc_id, request->ipc_flags, PCMK__XE_ACK, NULL, CRM_EX_OK); return NULL; } static xmlNode * handle_ping_request(pcmk__request_t *request) { xmlNode *msg = request->xml; const char *value = NULL; xmlNode *ping = NULL; xmlNode *reply = NULL; const char *from = crm_element_value(msg, PCMK__XA_CRM_SYS_FROM); /* Pinged for status */ crm_trace("Pinged from " PCMK__XA_CRM_SYS_FROM "='%s' " PCMK_XA_ORIGIN "='%s'", pcmk__s(from, ""), pcmk__s(crm_element_value(msg, PCMK_XA_ORIGIN), "")); pcmk__ipc_send_ack(request->ipc_client, request->ipc_id, request->ipc_flags, PCMK__XE_ACK, NULL, CRM_EX_INDETERMINATE); ping = pcmk__xe_create(NULL, PCMK__XE_PING_RESPONSE); value = crm_element_value(msg, PCMK__XA_CRM_SYS_TO); crm_xml_add(ping, PCMK__XA_CRM_SUBSYSTEM, value); crm_xml_add(ping, PCMK__XA_PACEMAKERD_STATE, pacemakerd_state); - crm_xml_add_ll(ping, PCMK_XA_CRM_TIMESTAMP, + crm_xml_add_ll(ping, PCMK__XA_CRM_TIMESTAMP, (long long) subdaemon_check_progress); crm_xml_add(ping, PCMK_XA_RESULT, "ok"); reply = pcmk__new_reply(msg, ping); pcmk__xml_free(ping); if (reply == NULL) { pcmk__format_result(&request->result, CRM_EX_ERROR, PCMK_EXEC_ERROR, "Failed building ping reply for client %s", pcmk__client_name(request->ipc_client)); } else { pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); } /* just proceed state on sbd pinging us */ if (from && strstr(from, "sbd")) { if (pcmk__str_eq(pacemakerd_state, PCMK__VALUE_SHUTDOWN_COMPLETE, pcmk__str_none)) { if (pcmk__get_sbd_sync_resource_startup()) { crm_notice("Shutdown-complete-state passed to SBD."); } shutdown_complete_state_reported_to = request->ipc_client->pid; } else if (pcmk__str_eq(pacemakerd_state, PCMK__VALUE_WAIT_FOR_PING, pcmk__str_none)) { crm_notice("Received startup-trigger from SBD."); pacemakerd_state = PCMK__VALUE_STARTING_DAEMONS; mainloop_set_trigger(startup_trigger); } } return reply; } static xmlNode * handle_shutdown_request(pcmk__request_t *request) { xmlNode *msg = request->xml; xmlNode *shutdown = NULL; xmlNode *reply = NULL; /* Only allow privileged users (i.e. root or hacluster) to shut down * Pacemaker from the command line (or direct IPC), so that other users * are forced to go through the CIB and have ACLs applied. */ bool allowed = pcmk_is_set(request->ipc_client->flags, pcmk__client_privileged); pcmk__ipc_send_ack(request->ipc_client, request->ipc_id, request->ipc_flags, PCMK__XE_ACK, NULL, CRM_EX_INDETERMINATE); shutdown = pcmk__xe_create(NULL, PCMK__XE_SHUTDOWN); if (allowed) { crm_notice("Shutting down in response to IPC request %s from %s", crm_element_value(msg, PCMK_XA_REFERENCE), crm_element_value(msg, PCMK_XA_ORIGIN)); crm_xml_add_int(shutdown, PCMK__XA_OP_STATUS, CRM_EX_OK); } else { crm_warn("Ignoring shutdown request from unprivileged client %s", pcmk__client_name(request->ipc_client)); crm_xml_add_int(shutdown, PCMK__XA_OP_STATUS, CRM_EX_INSUFFICIENT_PRIV); } reply = pcmk__new_reply(msg, shutdown); pcmk__xml_free(shutdown); if (reply == NULL) { pcmk__format_result(&request->result, CRM_EX_ERROR, PCMK_EXEC_ERROR, "Failed building shutdown reply for client %s", pcmk__client_name(request->ipc_client)); } else { pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); } if (allowed) { pcmk_shutdown(15); } return reply; } static xmlNode * handle_unknown_request(pcmk__request_t *request) { pcmk__ipc_send_ack(request->ipc_client, request->ipc_id, request->ipc_flags, PCMK__XE_ACK, NULL, CRM_EX_PROTOCOL); pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID, "Unknown IPC request type '%s' (bug?)", pcmk__s(request->op, "")); return NULL; } static void pcmkd_register_handlers(void) { pcmk__server_command_t handlers[] = { { CRM_OP_RM_NODE_CACHE, handle_node_cache_request }, { CRM_OP_PING, handle_ping_request }, { CRM_OP_QUIT, handle_shutdown_request }, { NULL, handle_unknown_request }, }; pcmkd_handlers = pcmk__register_handlers(handlers); } static int32_t pcmk_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid) { crm_trace("Connection %p", c); if (pcmk__new_client(c, uid, gid) == NULL) { return -ENOMEM; } return 0; } /* Error code means? */ static int32_t pcmk_ipc_closed(qb_ipcs_connection_t * c) { pcmk__client_t *client = pcmk__find_client(c); if (client == NULL) { return 0; } crm_trace("Connection %p", c); if (shutdown_complete_state_reported_to == client->pid) { shutdown_complete_state_reported_client_closed = TRUE; if (shutdown_trigger) { mainloop_set_trigger(shutdown_trigger); } } pcmk__free_client(client); return 0; } static void pcmk_ipc_destroy(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); pcmk_ipc_closed(c); } /* Exit code means? */ static int32_t pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) { int rc = pcmk_rc_ok; uint32_t id = 0; uint32_t flags = 0; xmlNode *msg = NULL; pcmk__client_t *c = pcmk__find_client(qbc); CRM_CHECK(c != NULL, return 0); if (pcmkd_handlers == NULL) { pcmkd_register_handlers(); } 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. */ msg = 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 (msg == NULL) { pcmk__ipc_send_ack(c, id, flags, PCMK__XE_ACK, NULL, CRM_EX_PROTOCOL); return 0; } else { char *log_msg = NULL; const char *reason = NULL; xmlNode *reply = NULL; pcmk__request_t request = { .ipc_client = c, .ipc_id = id, .ipc_flags = flags, .peer = NULL, .xml = msg, .call_options = 0, .result = PCMK__UNKNOWN_RESULT, }; request.op = crm_element_value_copy(request.xml, PCMK__XA_CRM_TASK); CRM_CHECK(request.op != NULL, return 0); reply = pcmk__process_request(&request, pcmkd_handlers); if (reply != NULL) { pcmk__ipc_send_xml(c, id, reply, crm_ipc_server_event); pcmk__xml_free(reply); } reason = request.result.exit_reason; log_msg = crm_strdup_printf("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)? "" : ")"); if (!pcmk__result_ok(&request.result)) { crm_warn("%s", log_msg); } else { crm_debug("%s", log_msg); } free(log_msg); pcmk__reset_request(&request); } pcmk__xml_free(msg); return 0; } struct qb_ipcs_service_handlers pacemakerd_ipc_callbacks = { .connection_accept = pcmk_ipc_accept, .connection_created = NULL, .msg_process = pcmk_ipc_dispatch, .connection_closed = pcmk_ipc_closed, .connection_destroyed = pcmk_ipc_destroy }; diff --git a/include/crm/common/Makefile.am b/include/crm/common/Makefile.am index a928273781..947e8d20dc 100644 --- a/include/crm/common/Makefile.am +++ b/include/crm/common/Makefile.am @@ -1,54 +1,55 @@ # # 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 # or later (GPLv2+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk headerdir=$(pkgincludedir)/crm/common header_HEADERS = acl.h \ acl_compat.h \ actions.h \ agents.h \ cib.h \ ipc.h \ ipc_client_compat.h \ ipc_controld.h \ ipc_pacemakerd.h \ ipc_schedulerd.h \ iso8601.h \ logging.h \ logging_compat.h \ mainloop.h \ nodes.h \ nvpair.h \ nvpair_compat.h \ options.h \ output.h \ probes.h \ resources.h \ results.h \ results_compat.h \ roles.h \ rules.h \ scheduler.h \ scheduler_types.h \ schemas.h \ scores.h \ scores_compat.h \ strings.h \ util.h \ util_compat.h \ xml.h \ xml_compat.h \ xml_element.h \ xml_element_compat.h \ xml_io.h \ - xml_names.h + xml_names.h \ + xml_names_compat.h noinst_HEADERS = $(wildcard *internal.h) diff --git a/include/crm/common/xml_names.h b/include/crm/common/xml_names.h index 2e937660da..4285e97c89 100644 --- a/include/crm/common/xml_names.h +++ b/include/crm/common/xml_names.h @@ -1,465 +1,464 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef PCMK__CRM_COMMON_XML_NAMES__H #define PCMK__CRM_COMMON_XML_NAMES__H #ifdef __cplusplus extern "C" { #endif /*! * \file * \brief Defined string constants for XML element and attribute names * \ingroup core */ /* For consistency, new constants should start with "PCMK_", followed by: * - "XE" for XML element names * - "XA" for XML attribute names * - "OPT" for cluster option (property) names * - "META" for meta-attribute names * - "VALUE" for enumerated values (such as for options or for XML attributes) * - "NODE_ATTR" for node attribute names * * Old names that don't follow this policy should eventually be deprecated and * replaced with names that do. * * Symbols should be public if the user may specify them somewhere (especially * the CIB) or if they're part of a well-defined structure that a user may need * to parse. They should be internal if they're used only internally to * Pacemaker (such as daemon IPC/CPG message XML). * * Constants belong in the following locations: * * "XE" and "XA": xml_names.h and xml_names_internal.h * * "OPT", "META", and "VALUE": options.h and options_internal.h * * "NODE_ATTR": nodes.h and nodes_internal.h * * For meta-attributes that can be specified as either XML attributes or nvpair * names, use "META" unless using both "XA" and "META" constants adds clarity. * An example is operation attributes, which can be specified either as * attributes of the PCMK_XE_OP element or as nvpairs in a meta-attribute set * beneath the PCMK_XE_OP element. */ /* * XML elements */ #define PCMK_XE_ACL_GROUP "acl_group" #define PCMK_XE_ACL_PERMISSION "acl_permission" #define PCMK_XE_ACL_ROLE "acl_role" #define PCMK_XE_ACL_TARGET "acl_target" #define PCMK_XE_ACLS "acls" #define PCMK_XE_ACTION "action" #define PCMK_XE_ACTIONS "actions" #define PCMK_XE_AGENT "agent" #define PCMK_XE_AGENT_STATUS "agent-status" #define PCMK_XE_AGENTS "agents" #define PCMK_XE_ALERT "alert" #define PCMK_XE_ALERTS "alerts" #define PCMK_XE_ALLOCATIONS "allocations" #define PCMK_XE_ALLOCATIONS_UTILIZATIONS "allocations_utilizations" #define PCMK_XE_ATTRIBUTE "attribute" #define PCMK_XE_BAN "ban" #define PCMK_XE_BANS "bans" #define PCMK_XE_BUNDLE "bundle" #define PCMK_XE_CAPACITY "capacity" #define PCMK_XE_CHANGE "change" #define PCMK_XE_CHANGE_ATTR "change-attr" #define PCMK_XE_CHANGE_LIST "change-list" #define PCMK_XE_CHANGE_RESULT "change-result" #define PCMK_XE_CHECK "check" #define PCMK_XE_CIB "cib" #define PCMK_XE_CLONE "clone" #define PCMK_XE_CLUSTER_ACTION "cluster_action" #define PCMK_XE_CLUSTER_INFO "cluster-info" #define PCMK_XE_CLUSTER_OPTIONS "cluster_options" #define PCMK_XE_CLUSTER_PROPERTY_SET "cluster_property_set" #define PCMK_XE_CLUSTER_STATUS "cluster_status" #define PCMK_XE_COMMAND "command" #define PCMK_XE_CONFIGURATION "configuration" #define PCMK_XE_CONSTRAINT "constraint" #define PCMK_XE_CONSTRAINTS "constraints" #define PCMK_XE_CONTENT "content" #define PCMK_XE_CRM_CONFIG "crm_config" #define PCMK_XE_CRM_MON "crm_mon" #define PCMK_XE_CRM_MON_DISCONNECTED "crm-mon-disconnected" #define PCMK_XE_CURRENT_DC "current_dc" #define PCMK_XE_DATE "date" #define PCMK_XE_DATE_EXPRESSION "date_expression" #define PCMK_XE_DATE_SPEC "date_spec" #define PCMK_XE_DC "dc" #define PCMK_XE_DEPRECATED "deprecated" #define PCMK_XE_DIFF "diff" #define PCMK_XE_DIGEST "digest" #define PCMK_XE_DIGESTS "digests" #define PCMK_XE_DOCKER "docker" #define PCMK_XE_DURATION "duration" #define PCMK_XE_DURATION_ENDS "duration_ends" #define PCMK_XE_END "end" #define PCMK_XE_ERROR "error" #define PCMK_XE_ERRORS "errors" #define PCMK_XE_EXPRESSION "expression" #define PCMK_XE_FAILURE "failure" #define PCMK_XE_FAILURES "failures" #define PCMK_XE_FEATURE "feature" #define PCMK_XE_FEATURES "features" #define PCMK_XE_FENCE_EVENT "fence_event" #define PCMK_XE_FENCE_HISTORY "fence_history" #define PCMK_XE_FENCING_ACTION "fencing_action" #define PCMK_XE_FENCING_LEVEL "fencing-level" #define PCMK_XE_FENCING_TOPOLOGY "fencing-topology" #define PCMK_XE_GROUP "group" #define PCMK_XE_INJECT_ATTR "inject_attr" #define PCMK_XE_INJECT_SPEC "inject_spec" #define PCMK_XE_INSTANCE_ATTRIBUTES "instance_attributes" #define PCMK_XE_INSTRUCTION "instruction" #define PCMK_XE_ITEM "item" #define PCMK_XE_LAST_CHANGE "last_change" #define PCMK_XE_LAST_FENCED "last-fenced" #define PCMK_XE_LAST_UPDATE "last_update" #define PCMK_XE_LIST "list" #define PCMK_XE_LONGDESC "longdesc" #define PCMK_XE_META_ATTRIBUTES "meta_attributes" #define PCMK_XE_METADATA "metadata" #define PCMK_XE_MODIFICATIONS "modifications" #define PCMK_XE_MODIFY_NODE "modify_node" #define PCMK_XE_MODIFY_TICKET "modify_ticket" #define PCMK_XE_NETWORK "network" #define PCMK_XE_NODE "node" #define PCMK_XE_NODE_ACTION "node_action" #define PCMK_XE_NODE_ATTRIBUTES "node_attributes" #define PCMK_XE_NODE_HISTORY "node_history" #define PCMK_XE_NODE_INFO "node-info" #define PCMK_XE_NODE_WEIGHT "node_weight" #define PCMK_XE_NODES "nodes" #define PCMK_XE_NODES_CONFIGURED "nodes_configured" #define PCMK_XE_NVPAIR "nvpair" #define PCMK_XE_OBJ_REF "obj_ref" #define PCMK_XE_OP "op" #define PCMK_XE_OP_DEFAULTS "op_defaults" #define PCMK_XE_OP_EXPRESSION "op_expression" #define PCMK_XE_OPERATION "operation" #define PCMK_XE_OPERATION_HISTORY "operation_history" #define PCMK_XE_OPERATIONS "operations" #define PCMK_XE_OPTION "option" #define PCMK_XE_OUTPUT "output" #define PCMK_XE_OVERRIDE "override" #define PCMK_XE_OVERRIDES "overrides" #define PCMK_XE_PACEMAKER_RESULT "pacemaker-result" #define PCMK_XE_PACEMAKERD "pacemakerd" #define PCMK_XE_PARAMETER "parameter" #define PCMK_XE_PARAMETERS "parameters" #define PCMK_XE_PATCHSET "patchset" #define PCMK_XE_PERIOD "period" #define PCMK_XE_PODMAN "podman" #define PCMK_XE_PORT_MAPPING "port-mapping" #define PCMK_XE_POSITION "position" #define PCMK_XE_PRIMITIVE "primitive" #define PCMK_XE_PROMOTION_SCORE "promotion_score" #define PCMK_XE_PROVIDER "provider" #define PCMK_XE_PROVIDERS "providers" #define PCMK_XE_PSEUDO_ACTION "pseudo_action" #define PCMK_XE_REASON "reason" #define PCMK_XE_RECIPIENT "recipient" #define PCMK_XE_REPLICA "replica" #define PCMK_XE_RESOURCE "resource" #define PCMK_XE_RESOURCE_AGENT "resource-agent" #define PCMK_XE_RESOURCE_AGENT_ACTION "resource-agent-action" #define PCMK_XE_RESOURCE_CONFIG "resource_config" #define PCMK_XE_RESOURCE_HISTORY "resource_history" #define PCMK_XE_RESOURCE_REF "resource_ref" #define PCMK_XE_RESOURCE_SET "resource_set" #define PCMK_XE_RESOURCES "resources" #define PCMK_XE_RESOURCES_CONFIGURED "resources_configured" #define PCMK_XE_RESULT_CODE "result-code" #define PCMK_XE_REVISED_CLUSTER_STATUS "revised_cluster_status" #define PCMK_XE_ROLE "role" #define PCMK_XE_RSC_ACTION "rsc_action" #define PCMK_XE_RSC_COLOCATION "rsc_colocation" #define PCMK_XE_RSC_DEFAULTS "rsc_defaults" #define PCMK_XE_RSC_EXPRESSION "rsc_expression" #define PCMK_XE_RSC_LOCATION "rsc_location" #define PCMK_XE_RSC_ORDER "rsc_order" #define PCMK_XE_RSC_TICKET "rsc_ticket" #define PCMK_XE_RULE "rule" #define PCMK_XE_RULE_CHECK "rule-check" #define PCMK_XE_SELECT "select" #define PCMK_XE_SELECT_ATTRIBUTES "select_attributes" #define PCMK_XE_SELECT_FENCING "select_fencing" #define PCMK_XE_SELECT_NODES "select_nodes" #define PCMK_XE_SELECT_RESOURCES "select_resources" #define PCMK_XE_SHADOW "shadow" #define PCMK_XE_SHORTDESC "shortdesc" #define PCMK_XE_SOURCE "source" #define PCMK_XE_SPECIAL "special" #define PCMK_XE_STACK "stack" #define PCMK_XE_START "start" #define PCMK_XE_STATUS "status" #define PCMK_XE_STORAGE "storage" #define PCMK_XE_STORAGE_MAPPING "storage-mapping" #define PCMK_XE_SUMMARY "summary" #define PCMK_XE_TAG "tag" #define PCMK_XE_TAGS "tags" #define PCMK_XE_TARGET "target" #define PCMK_XE_TEMPLATE "template" #define PCMK_XE_TICKET "ticket" #define PCMK_XE_TICKETS "tickets" #define PCMK_XE_TIMING "timing" #define PCMK_XE_TIMINGS "timings" #define PCMK_XE_TRANSITION "transition" #define PCMK_XE_UPDATED "updated" #define PCMK_XE_UTILIZATION "utilization" #define PCMK_XE_UTILIZATIONS "utilizations" #define PCMK_XE_VALIDATE "validate" #define PCMK_XE_VERSION "version" #define PCMK_XE_XML "xml" #define PCMK_XE_XML_PATCHSET "xml-patchset" /* * XML attributes */ #define PCMK_XA_ACTION "action" #define PCMK_XA_ACTIVE "active" #define PCMK_XA_ADD_HOST "add-host" #define PCMK_XA_ADMIN_EPOCH "admin_epoch" #define PCMK_XA_ADVANCED "advanced" #define PCMK_XA_AGENT "agent" #define PCMK_XA_API_VERSION "api-version" #define PCMK_XA_ATTRIBUTE "attribute" #define PCMK_XA_AUTHOR "author" #define PCMK_XA_AUTOMATIC "automatic" #define PCMK_XA_BLOCKED "blocked" #define PCMK_XA_BOOLEAN_OP "boolean-op" #define PCMK_XA_BUILD "build" #define PCMK_XA_CACHED "cached" #define PCMK_XA_CALL "call" #define PCMK_XA_CIB_LAST_WRITTEN "cib-last-written" #define PCMK_XA_CIB_NODE "cib_node" #define PCMK_XA_CLASS "class" #define PCMK_XA_CLIENT "client" #define PCMK_XA_CODE "code" #define PCMK_XA_COMMENT "comment" #define PCMK_XA_COMPLETED "completed" #define PCMK_XA_CONTROL_PORT "control-port" #define PCMK_XA_COUNT "count" #define PCMK_XA_CRM_DEBUG_ORIGIN "crm-debug-origin" #define PCMK_XA_CRM_FEATURE_SET "crm_feature_set" -#define PCMK_XA_CRM_TIMESTAMP "crm-timestamp" #define PCMK_XA_CRMD "crmd" #define PCMK_XA_DAYS "days" #define PCMK_XA_DC_UUID "dc-uuid" #define PCMK_XA_DEFAULT "default" #define PCMK_XA_DELEGATE "delegate" #define PCMK_XA_DESCRIPTION "description" #define PCMK_XA_DEST "dest" #define PCMK_XA_DEVICE "device" #define PCMK_XA_DEVICES "devices" #define PCMK_XA_DISABLED "disabled" #define PCMK_XA_DURATION "duration" #define PCMK_XA_END "end" #define PCMK_XA_EPOCH "epoch" #define PCMK_XA_EXEC "exec" #define PCMK_XA_EXEC_TIME "exec-time" #define PCMK_XA_EXECUTION_CODE "execution_code" #define PCMK_XA_EXECUTION_DATE "execution-date" #define PCMK_XA_EXECUTION_MESSAGE "execution_message" #define PCMK_XA_EXIT_REASON "exit-reason" #define PCMK_XA_EXITCODE "exitcode" #define PCMK_XA_EXITREASON "exitreason" #define PCMK_XA_EXITSTATUS "exitstatus" #define PCMK_XA_EXPECTED "expected" #define PCMK_XA_EXPECTED_UP "expected_up" #define PCMK_XA_EXPIRES "expires" #define PCMK_XA_EXTENDED_STATUS "extended-status" #define PCMK_XA_FAIL_COUNT "fail-count" #define PCMK_XA_FAILED "failed" #define PCMK_XA_FAILURE_IGNORED "failure_ignored" #define PCMK_XA_FEATURE_SET "feature_set" #define PCMK_XA_FEATURES "features" #define PCMK_XA_FILE "file" #define PCMK_XA_FIRST "first" #define PCMK_XA_FIRST_ACTION "first-action" #define PCMK_XA_FOR "for" #define PCMK_XA_FORMAT "format" #define PCMK_XA_FUNCTION "function" #define PCMK_XA_GENERATED "generated" #define PCMK_XA_HASH "hash" #define PCMK_XA_HAVE_QUORUM "have-quorum" #define PCMK_XA_HEALTH "health" #define PCMK_XA_HOST "host" #define PCMK_XA_HOST_INTERFACE "host-interface" #define PCMK_XA_HOST_NETMASK "host-netmask" #define PCMK_XA_HOURS "hours" #define PCMK_XA_ID "id" #define PCMK_XA_ID_AS_RESOURCE "id_as_resource" #define PCMK_XA_ID_REF "id-ref" #define PCMK_XA_IMAGE "image" #define PCMK_XA_INDEX "index" #define PCMK_XA_INFLUENCE "influence" #define PCMK_XA_INSTANCE "instance" #define PCMK_XA_INTERNAL_PORT "internal-port" #define PCMK_XA_INTERVAL "interval" #define PCMK_XA_IP_RANGE_START "ip-range-start" #define PCMK_XA_IS_DC "is_dc" #define PCMK_XA_KIND "kind" #define PCMK_XA_LANG "lang" #define PCMK_XA_LAST_FAILURE "last-failure" #define PCMK_XA_LAST_GRANTED "last-granted" #define PCMK_XA_LAST_RC_CHANGE "last-rc-change" #define PCMK_XA_LAST_UPDATED "last_updated" #define PCMK_XA_LOCKED_TO "locked_to" #define PCMK_XA_LOCKED_TO_HYPHEN "locked-to" #define PCMK_XA_LOSS_POLICY "loss-policy" #define PCMK_XA_MAINTENANCE "maintenance" #define PCMK_XA_MAINTENANCE_MODE "maintenance-mode" #define PCMK_XA_MANAGED "managed" #define PCMK_XA_MESSAGE "message" #define PCMK_XA_MINUTES "minutes" #define PCMK_XA_MIXED_VERSION "mixed_version" #define PCMK_XA_MONTHDAYS "monthdays" #define PCMK_XA_MONTHS "months" #define PCMK_XA_MULTI_STATE "multi_state" #define PCMK_XA_NAME "name" #define PCMK_XA_NETWORK "network" #define PCMK_XA_NEXT_ROLE "next-role" #define PCMK_XA_NO_QUORUM_PANIC "no-quorum-panic" #define PCMK_XA_NO_QUORUM_POLICY "no-quorum-policy" #define PCMK_XA_NODE "node" #define PCMK_XA_NODE_ATTRIBUTE "node-attribute" #define PCMK_XA_NODE_NAME "node_name" #define PCMK_XA_NODE_PATH "node_path" #define PCMK_XA_NODEID "nodeid" #define PCMK_XA_NODES_RUNNING_ON "nodes_running_on" #define PCMK_XA_NUM_UPDATES "num_updates" #define PCMK_XA_NUMBER "number" #define PCMK_XA_NUMBER_RESOURCES "number_resources" #define PCMK_XA_OBJECT_TYPE "object-type" #define PCMK_XA_ON_TARGET "on_target" #define PCMK_XA_ONLINE "online" #define PCMK_XA_OP "op" #define PCMK_XA_OP_KEY "op_key" #define PCMK_XA_OPERATION "operation" #define PCMK_XA_OPTIONS "options" #define PCMK_XA_ORIGIN "origin" #define PCMK_XA_ORPHAN "orphan" #define PCMK_XA_ORPHANED "orphaned" #define PCMK_XA_PACEMAKERD_STATE "pacemakerd-state" #define PCMK_XA_PATH "path" #define PCMK_XA_PENDING "pending" #define PCMK_XA_PORT "port" #define PCMK_XA_PRESENT "present" #define PCMK_XA_PRIORITY_FENCING_DELAY_MS "priority-fencing-delay-ms" #define PCMK_XA_PROGRAM "program" #define PCMK_XA_PROMOTABLE "promotable" #define PCMK_XA_PROMOTED_MAX "promoted-max" #define PCMK_XA_PROMOTED_ONLY "promoted-only" #define PCMK_XA_PROVIDER "provider" #define PCMK_XA_QUEUE_TIME "queue-time" #define PCMK_XA_QUEUED "queued" #define PCMK_XA_QUORUM "quorum" #define PCMK_XA_RANGE "range" #define PCMK_XA_RC "rc" #define PCMK_XA_RC_TEXT "rc_text" #define PCMK_XA_REASON "reason" #define PCMK_XA_REFERENCE "reference" #define PCMK_XA_RELOADABLE "reloadable" #define PCMK_XA_REMAIN_STOPPED "remain_stopped" #define PCMK_XA_REMOTE_CLEAR_PORT "remote-clear-port" #define PCMK_XA_REMOTE_NODE "remote_node" #define PCMK_XA_REMOTE_TLS_PORT "remote-tls-port" #define PCMK_XA_REPLICAS "replicas" #define PCMK_XA_REPLICAS_PER_HOST "replicas-per-host" #define PCMK_XA_REQUEST "request" #define PCMK_XA_REQUIRE_ALL "require-all" #define PCMK_XA_RESOURCE "resource" #define PCMK_XA_RESOURCE_AGENT "resource_agent" #define PCMK_XA_RESOURCE_DISCOVERY "resource-discovery" #define PCMK_XA_RESOURCES_RUNNING "resources_running" #define PCMK_XA_RESULT "result" #define PCMK_XA_ROLE "role" #define PCMK_XA_RSC "rsc" #define PCMK_XA_RSC_PATTERN "rsc-pattern" #define PCMK_XA_RSC_ROLE "rsc-role" #define PCMK_XA_RULE_ID "rule-id" #define PCMK_XA_RUN_COMMAND "run-command" #define PCMK_XA_RUNNING "running" #define PCMK_XA_RUNNING_ON "running_on" #define PCMK_XA_SCOPE "scope" #define PCMK_XA_SCORE "score" #define PCMK_XA_SCORE_ATTRIBUTE "score-attribute" #define PCMK_XA_SEQUENTIAL "sequential" #define PCMK_XA_SECONDS "seconds" #define PCMK_XA_SHUTDOWN "shutdown" #define PCMK_XA_SOURCE "source" #define PCMK_XA_SOURCE_DIR "source-dir" #define PCMK_XA_SOURCE_DIR_ROOT "source-dir-root" #define PCMK_XA_SPEC "spec" #define PCMK_XA_STANDARD "standard" #define PCMK_XA_STANDBY "standby" #define PCMK_XA_STANDBY_ONFAIL "standby_onfail" #define PCMK_XA_START "start" #define PCMK_XA_STATE "state" #define PCMK_XA_STATUS "status" #define PCMK_XA_STONITH_ENABLED "stonith-enabled" #define PCMK_XA_STONITH_TIMEOUT_MS "stonith-timeout-ms" #define PCMK_XA_STOP_ALL_RESOURCES "stop-all-resources" #define PCMK_XA_SYMMETRIC_CLUSTER "symmetric-cluster" #define PCMK_XA_SYMMETRICAL "symmetrical" #define PCMK_XA_SYS_FROM "sys_from" #define PCMK_XA_TAG "tag" #define PCMK_XA_TARGET "target" #define PCMK_XA_TARGET_ATTRIBUTE "target-attribute" #define PCMK_XA_TARGET_DIR "target-dir" #define PCMK_XA_TARGET_PATTERN "target-pattern" #define PCMK_XA_TARGET_ROLE "target_role" #define PCMK_XA_TARGET_VALUE "target-value" #define PCMK_XA_TASK "task" #define PCMK_XA_TEMPLATE "template" #define PCMK_XA_TICKET "ticket" #define PCMK_XA_TIME "time" #define PCMK_XA_THEN "then" #define PCMK_XA_THEN_ACTION "then-action" #define PCMK_XA_TYPE "type" #define PCMK_XA_UNAME "uname" #define PCMK_XA_UNCLEAN "unclean" #define PCMK_XA_UNHEALTHY "unhealthy" #define PCMK_XA_UNIQUE "unique" #define PCMK_XA_UNMANAGED "unmanaged" #define PCMK_XA_UPDATE_CLIENT "update-client" #define PCMK_XA_UPDATE_ORIGIN "update-origin" #define PCMK_XA_UPDATE_USER "update-user" #define PCMK_XA_USER "user" #define PCMK_XA_VALID "valid" #define PCMK_XA_VALIDATE_WITH "validate-with" #define PCMK_XA_VALUE "value" #define PCMK_XA_VALUE_SOURCE "value-source" #define PCMK_XA_VERSION "version" #define PCMK_XA_WATCHDOG "watchdog" #define PCMK_XA_WEEKDAYS "weekdays" #define PCMK_XA_WEEKS "weeks" #define PCMK_XA_WEEKYEARS "weekyears" #define PCMK_XA_WEIGHT "weight" #define PCMK_XA_WHEN "when" #define PCMK_XA_WITH_QUORUM "with_quorum" #define PCMK_XA_WITH_RSC "with-rsc" #define PCMK_XA_WITH_RSC_ROLE "with-rsc-role" #define PCMK_XA_XPATH "xpath" #define PCMK_XA_YEARDAYS "yeardays" #define PCMK_XA_YEARS "years" #ifdef __cplusplus } #endif #endif // PCMK__CRM_COMMON_XML_NAMES__H diff --git a/include/crm/common/xml_names_compat.h b/include/crm/common/xml_names_compat.h new file mode 100644 index 0000000000..a8a6944a85 --- /dev/null +++ b/include/crm/common/xml_names_compat.h @@ -0,0 +1,33 @@ +/* + * 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 Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. + */ + +#ifndef PCMK__CRM_COMMON_XML_NAMES_COMPAT__H +#define PCMK__CRM_COMMON_XML_NAMES_COMPAT__H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file + * \brief Deprecated defined constants for Pacemaker XML element/attribute names + * \ingroup core + * \deprecated Do not include this header directly. The nvpair APIs in this + * header, and the header itself, will be removed in a future + * release. + */ + +//! \deprecated Do not use +#define PCMK_XA_CRM_TIMESTAMP "crm-timestamp" + +#ifdef __cplusplus +} +#endif + +#endif // PCMK__CRM_COMMON_XML_NAMES_COMPAT__H diff --git a/include/crm/common/xml_names_internal.h b/include/crm/common/xml_names_internal.h index 6a789ba0e0..b1bfef0c03 100644 --- a/include/crm/common/xml_names_internal.h +++ b/include/crm/common/xml_names_internal.h @@ -1,296 +1,297 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef PCMK__CRM_COMMON_XML_NAMES_INTERNAL__H #define PCMK__CRM_COMMON_XML_NAMES_INTERNAL__H #ifdef __cplusplus extern "C" { #endif /* * XML element names used only by internal code */ #define PCMK__XE_ACK "ack" #define PCMK__XE_ACTION_SET "action_set" #define PCMK__XE_ATTRIBUTES "attributes" #define PCMK__XE_CIB_CALLBACK "cib-callback" #define PCMK__XE_CIB_CALLDATA "cib_calldata" #define PCMK__XE_CIB_COMMAND "cib_command" #define PCMK__XE_CIB_REPLY "cib-reply" #define PCMK__XE_CIB_RESULT "cib_result" #define PCMK__XE_CIB_TRANSACTION "cib_transaction" #define PCMK__XE_CIB_UPDATE_RESULT "cib_update_result" #define PCMK__XE_COPY "copy" #define PCMK__XE_CRM_EVENT "crm_event" #define PCMK__XE_CRM_XML "crm_xml" #define PCMK__XE_DIV "div" #define PCMK__XE_DOWNED "downed" #define PCMK__XE_EXIT_NOTIFICATION "exit-notification" #define PCMK__XE_FAILED_UPDATE "failed_update" #define PCMK__XE_FILE "file" #define PCMK__XE_GENERATION_TUPLE "generation_tuple" #define PCMK__XE_INPUTS "inputs" #define PCMK__XE_LRM "lrm" #define PCMK__XE_LRM_RESOURCE "lrm_resource" #define PCMK__XE_LRM_RESOURCES "lrm_resources" #define PCMK__XE_LRM_RSC_OP "lrm_rsc_op" #define PCMK__XE_LRMD_ALERT "lrmd_alert" #define PCMK__XE_LRMD_CALLDATA "lrmd_calldata" #define PCMK__XE_LRMD_COMMAND "lrmd_command" #define PCMK__XE_LRMD_IPC_MSG "lrmd_ipc_msg" #define PCMK__XE_LRMD_IPC_PROXY "lrmd_ipc_proxy" #define PCMK__XE_LRMD_NOTIFY "lrmd_notify" #define PCMK__XE_LRMD_REPLY "lrmd_reply" #define PCMK__XE_LRMD_RSC "lrmd_rsc" #define PCMK__XE_LRMD_RSC_OP "lrmd_rsc_op" #define PCMK__XE_MAINTENANCE "maintenance" #define PCMK__XE_MESSAGE "message" #define PCMK__XE_META "meta" #define PCMK__XE_NACK "nack" #define PCMK__XE_NODE_STATE "node_state" #define PCMK__XE_NOTIFY "notify" #define PCMK__XE_OPTIONS "options" #define PCMK__XE_PARAM "param" #define PCMK__XE_PING "ping" #define PCMK__XE_PING_RESPONSE "ping_response" #define PCMK__XE_PSEUDO_EVENT "pseudo_event" #define PCMK__XE_RESOURCE_SETTINGS "resource-settings" #define PCMK__XE_RSC_OP "rsc_op" #define PCMK__XE_SHUTDOWN "shutdown" #define PCMK__XE_SPAN "span" #define PCMK__XE_ST_ASYNC_TIMEOUT_VALUE "st-async-timeout-value" #define PCMK__XE_ST_CALLDATA "st_calldata" #define PCMK__XE_ST_DEVICE_ACTION "st_device_action" #define PCMK__XE_ST_DEVICE_ID "st_device_id" #define PCMK__XE_ST_HISTORY "st_history" #define PCMK__XE_ST_NOTIFY_FENCE "st_notify_fence" #define PCMK__XE_ST_REPLY "st-reply" #define PCMK__XE_STONITH_COMMAND "stonith_command" #define PCMK__XE_SYNAPSE "synapse" #define PCMK__XE_TICKET_STATE "ticket_state" #define PCMK__XE_TRANSIENT_ATTRIBUTES "transient_attributes" #define PCMK__XE_TRANSITION_GRAPH "transition_graph" #define PCMK__XE_TRIGGER "trigger" #define PCMK__XE_XPATH_QUERY "xpath-query" #define PCMK__XE_XPATH_QUERY_PATH "xpath-query-path" /* @COMPAT Deprecate somehow. It's undocumented and behaves the same as * PCMK__XE_CIB in places where it's recognized. */ #define PCMK__XE_ALL "all" // @COMPAT Deprecated since 2.1.8 #define PCMK__XE_FAILED "failed" /* * XML attribute names used only by internal code */ #define PCMK__XA_ACL_TARGET "acl_target" #define PCMK__XA_ATTR_CLEAR_INTERVAL "attr_clear_interval" #define PCMK__XA_ATTR_CLEAR_OPERATION "attr_clear_operation" #define PCMK__XA_ATTR_DAMPENING "attr_dampening" #define PCMK__XA_ATTR_HOST "attr_host" #define PCMK__XA_ATTR_HOST_ID "attr_host_id" #define PCMK__XA_ATTR_IS_PRIVATE "attr_is_private" #define PCMK__XA_ATTR_IS_REMOTE "attr_is_remote" #define PCMK__XA_ATTR_NAME "attr_name" #define PCMK__XA_ATTR_REGEX "attr_regex" #define PCMK__XA_ATTR_RESOURCE "attr_resource" #define PCMK__XA_ATTR_SECTION "attr_section" #define PCMK__XA_ATTR_SET "attr_set" #define PCMK__XA_ATTR_SET_TYPE "attr_set_type" #define PCMK__XA_ATTR_SYNC_POINT "attr_sync_point" #define PCMK__XA_ATTR_USER "attr_user" #define PCMK__XA_ATTR_VALUE "attr_value" #define PCMK__XA_ATTR_VERSION "attr_version" #define PCMK__XA_ATTR_WRITER "attr_writer" #define PCMK__XA_ATTRD_IS_FORCE_WRITE "attrd_is_force_write" #define PCMK__XA_CALL_ID "call-id" #define PCMK__XA_CIB_CALLID "cib_callid" #define PCMK__XA_CIB_CALLOPT "cib_callopt" #define PCMK__XA_CIB_CLIENTID "cib_clientid" #define PCMK__XA_CIB_CLIENTNAME "cib_clientname" #define PCMK__XA_CIB_DELEGATED_FROM "cib_delegated_from" #define PCMK__XA_CIB_HOST "cib_host" #define PCMK__XA_CIB_ISREPLYTO "cib_isreplyto" #define PCMK__XA_CIB_NOTIFY_ACTIVATE "cib_notify_activate" #define PCMK__XA_CIB_NOTIFY_TYPE "cib_notify_type" #define PCMK__XA_CIB_OP "cib_op" #define PCMK__XA_CIB_PING_ID "cib_ping_id" #define PCMK__XA_CIB_RC "cib_rc" #define PCMK__XA_CIB_SCHEMA_MAX "cib_schema_max" #define PCMK__XA_CIB_SECTION "cib_section" #define PCMK__XA_CIB_UPDATE "cib_update" #define PCMK__XA_CIB_UPGRADE_RC "cib_upgrade_rc" #define PCMK__XA_CIB_USER "cib_user" #define PCMK__XA_CLIENT_NAME "client_name" #define PCMK__XA_CLIENT_UUID "client_uuid" #define PCMK__XA_CONFIRM "confirm" #define PCMK__XA_CONNECTION_HOST "connection_host" #define PCMK__XA_CONTENT "content" #define PCMK__XA_CRMD_STATE "crmd_state" #define PCMK__XA_CRM_HOST_TO "crm_host_to" #define PCMK__XA_CRM_LIMIT_MAX "crm-limit-max" #define PCMK__XA_CRM_LIMIT_MODE "crm-limit-mode" #define PCMK__XA_CRM_SUBSYSTEM "crm_subsystem" #define PCMK__XA_CRM_SYS_FROM "crm_sys_from" #define PCMK__XA_CRM_SYS_TO "crm_sys_to" #define PCMK__XA_CRM_TASK "crm_task" #define PCMK__XA_CRM_TGRAPH_IN "crm-tgraph-in" +#define PCMK__XA_CRM_TIMESTAMP "crm-timestamp" #define PCMK__XA_CRM_USER "crm_user" #define PCMK__XA_DC_LEAVING "dc-leaving" #define PCMK__XA_DIGEST "digest" #define PCMK__XA_ELECTION_AGE_SEC "election-age-sec" #define PCMK__XA_ELECTION_AGE_NANO_SEC "election-age-nano-sec" #define PCMK__XA_ELECTION_ID "election-id" #define PCMK__XA_ELECTION_OWNER "election-owner" #define PCMK__XA_FAILED_START_OFFSET "failed-start-offset" #define PCMK__XA_FAILED_STOP_OFFSET "failed-stop-offset" #define PCMK__XA_GRANTED "granted" #define PCMK__XA_HIDDEN "hidden" #define PCMK__XA_HTTP_EQUIV "http-equiv" #define PCMK__XA_IN_CCM "in_ccm" #define PCMK__XA_IPC_PROTO_VERSION "ipc-protocol-version" #define PCMK__XA_JOIN "join" #define PCMK__XA_JOIN_ID "join_id" #define PCMK__XA_LINE "line" #define PCMK__XA_LONG_ID "long-id" #define PCMK__XA_LRMD_ALERT_ID "lrmd_alert_id" #define PCMK__XA_LRMD_ALERT_PATH "lrmd_alert_path" #define PCMK__XA_LRMD_CALLID "lrmd_callid" #define PCMK__XA_LRMD_CALLOPT "lrmd_callopt" #define PCMK__XA_LRMD_CLASS "lrmd_class" #define PCMK__XA_LRMD_CLIENTID "lrmd_clientid" #define PCMK__XA_LRMD_CLIENTNAME "lrmd_clientname" #define PCMK__XA_LRMD_EXEC_OP_STATUS "lrmd_exec_op_status" #define PCMK__XA_LRMD_EXEC_RC "lrmd_exec_rc" #define PCMK__XA_LRMD_EXEC_TIME "lrmd_exec_time" #define PCMK__XA_LRMD_IPC_CLIENT "lrmd_ipc_client" #define PCMK__XA_LRMD_IPC_MSG_FLAGS "lrmd_ipc_msg_flags" #define PCMK__XA_LRMD_IPC_MSG_ID "lrmd_ipc_msg_id" #define PCMK__XA_LRMD_IPC_OP "lrmd_ipc_op" #define PCMK__XA_LRMD_IPC_SERVER "lrmd_ipc_server" #define PCMK__XA_LRMD_IPC_SESSION "lrmd_ipc_session" #define PCMK__XA_LRMD_IPC_USER "lrmd_ipc_user" #define PCMK__XA_LRMD_IS_IPC_PROVIDER "lrmd_is_ipc_provider" #define PCMK__XA_LRMD_OP "lrmd_op" #define PCMK__XA_LRMD_ORIGIN "lrmd_origin" #define PCMK__XA_LRMD_PROTOCOL_VERSION "lrmd_protocol_version" #define PCMK__XA_LRMD_PROVIDER "lrmd_provider" #define PCMK__XA_LRMD_QUEUE_TIME "lrmd_queue_time" #define PCMK__XA_LRMD_RC "lrmd_rc" #define PCMK__XA_LRMD_RCCHANGE_TIME "lrmd_rcchange_time" #define PCMK__XA_LRMD_REMOTE_MSG_ID "lrmd_remote_msg_id" #define PCMK__XA_LRMD_REMOTE_MSG_TYPE "lrmd_remote_msg_type" #define PCMK__XA_LRMD_RSC_ACTION "lrmd_rsc_action" #define PCMK__XA_LRMD_RSC_DELETED "lrmd_rsc_deleted" #define PCMK__XA_LRMD_RSC_EXIT_REASON "lrmd_rsc_exit_reason" #define PCMK__XA_LRMD_RSC_ID "lrmd_rsc_id" #define PCMK__XA_LRMD_RSC_INTERVAL "lrmd_rsc_interval" #define PCMK__XA_LRMD_RSC_OUTPUT "lrmd_rsc_output" #define PCMK__XA_LRMD_RSC_START_DELAY "lrmd_rsc_start_delay" #define PCMK__XA_LRMD_RSC_USERDATA_STR "lrmd_rsc_userdata_str" #define PCMK__XA_LRMD_RUN_TIME "lrmd_run_time" #define PCMK__XA_LRMD_TIMEOUT "lrmd_timeout" #define PCMK__XA_LRMD_TYPE "lrmd_type" #define PCMK__XA_LRMD_WATCHDOG "lrmd_watchdog" #define PCMK__XA_MAJOR_VERSION "major_version" #define PCMK__XA_MINOR_VERSION "minor_version" #define PCMK__XA_MODE "mode" #define PCMK__XA_NAMESPACE "namespace" #define PCMK__XA_NODE_FENCED "node_fenced" #define PCMK__XA_NODE_IN_MAINTENANCE "node_in_maintenance" #define PCMK__XA_NODE_START_STATE "node_start_state" #define PCMK__XA_NODE_STATE "node_state" #define PCMK__XA_OP_DIGEST "op-digest" #define PCMK__XA_OP_FORCE_RESTART "op-force-restart" #define PCMK__XA_OP_RESTART_DIGEST "op-restart-digest" #define PCMK__XA_OP_SECURE_DIGEST "op-secure-digest" #define PCMK__XA_OP_SECURE_PARAMS "op-secure-params" #define PCMK__XA_OP_STATUS "op-status" #define PCMK__XA_OPERATION_KEY "operation_key" #define PCMK__XA_ORIGINAL_CIB_OP "original_cib_op" #define PCMK__XA_PACEMAKERD_STATE "pacemakerd_state" #define PCMK__XA_PASSWORD "password" #define PCMK__XA_PRIORITY "priority" #define PCMK__XA_RC_CODE "rc-code" #define PCMK__XA_REAP "reap" /* Actions to be executed on Pacemaker Remote nodes are routed through the * controller on the cluster node hosting the remote connection. That cluster * node is considered the router node for the action. */ #define PCMK__XA_ROUTER_NODE "router_node" #define PCMK__XA_RSC_ID "rsc-id" #define PCMK__XA_RSC_PROVIDES "rsc_provides" #define PCMK__XA_SCHEMA "schema" #define PCMK__XA_SCHEMAS "schemas" #define PCMK__XA_SET "set" #define PCMK__XA_SRC "src" #define PCMK__XA_ST_ACTION_DISALLOWED "st_action_disallowed" #define PCMK__XA_ST_ACTION_TIMEOUT "st_action_timeout" #define PCMK__XA_ST_AVAILABLE_DEVICES "st-available-devices" #define PCMK__XA_ST_CALLID "st_callid" #define PCMK__XA_ST_CALLOPT "st_callopt" #define PCMK__XA_ST_CLIENTID "st_clientid" #define PCMK__XA_ST_CLIENTNAME "st_clientname" #define PCMK__XA_ST_CLIENTNODE "st_clientnode" #define PCMK__XA_ST_DATE "st_date" #define PCMK__XA_ST_DATE_NSEC "st_date_nsec" #define PCMK__XA_ST_DELAY "st_delay" #define PCMK__XA_ST_DELAY_BASE "st_delay_base" #define PCMK__XA_ST_DELAY_MAX "st_delay_max" #define PCMK__XA_ST_DELEGATE "st_delegate" #define PCMK__XA_ST_DEVICE_ACTION "st_device_action" #define PCMK__XA_ST_DEVICE_ID "st_device_id" #define PCMK__XA_ST_DEVICE_SUPPORT_FLAGS "st_device_support_flags" #define PCMK__XA_ST_DIFFERENTIAL "st_differential" #define PCMK__XA_ST_MONITOR_VERIFIED "st_monitor_verified" #define PCMK__XA_ST_NOTIFY_ACTIVATE "st_notify_activate" #define PCMK__XA_ST_NOTIFY_DEACTIVATE "st_notify_deactivate" #define PCMK__XA_ST_OP "st_op" #define PCMK__XA_ST_OP_MERGED "st_op_merged" #define PCMK__XA_ST_ORIGIN "st_origin" #define PCMK__XA_ST_OUTPUT "st_output" #define PCMK__XA_ST_RC "st_rc" #define PCMK__XA_ST_REMOTE_OP "st_remote_op" #define PCMK__XA_ST_REMOTE_OP_RELAY "st_remote_op_relay" #define PCMK__XA_ST_REQUIRED "st_required" #define PCMK__XA_ST_STATE "st_state" #define PCMK__XA_ST_TARGET "st_target" #define PCMK__XA_ST_TIMEOUT "st_timeout" #define PCMK__XA_ST_TOLERANCE "st_tolerance" #define PCMK__XA_SUBT "subt" // subtype #define PCMK__XA_T "t" // type #define PCMK__XA_TRANSITION_KEY "transition-key" #define PCMK__XA_TRANSITION_MAGIC "transition-magic" #define PCMK__XA_UPTIME "uptime" // @COMPAT Deprecated since 2.1.7 #define PCMK__XA_ORDERING "ordering" // @COMPAT Deprecated alias for PCMK_XA_PROMOTED_ONLY since 2.0.0 #define PCMK__XA_PROMOTED_ONLY_LEGACY "master_only" // @COMPAT Deprecated since 2.1.6 #define PCMK__XA_REPLACE "replace" // @COMPAT Deprecated alias for \c PCMK_XA_AUTOMATIC since 1.1.14 #define PCMK__XA_REQUIRED "required" #ifdef __cplusplus } #endif #endif // PCMK__CRM_COMMON_XML_NAMES_INTERNAL__H diff --git a/lib/common/ipc_pacemakerd.c b/lib/common/ipc_pacemakerd.c index 8febcc5875..db09836bf6 100644 --- a/lib/common/ipc_pacemakerd.c +++ b/lib/common/ipc_pacemakerd.c @@ -1,345 +1,345 @@ /* * Copyright 2020-2025 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include #include #include #include #include #include #include "crmcommon_private.h" typedef struct pacemakerd_api_private_s { enum pcmk_pacemakerd_state state; char *client_uuid; } pacemakerd_api_private_t; static const char *pacemakerd_state_str[] = { PCMK__VALUE_INIT, PCMK__VALUE_STARTING_DAEMONS, PCMK__VALUE_WAIT_FOR_PING, PCMK__VALUE_RUNNING, PCMK__VALUE_SHUTTING_DOWN, PCMK__VALUE_SHUTDOWN_COMPLETE, PCMK_VALUE_REMOTE, }; enum pcmk_pacemakerd_state pcmk_pacemakerd_api_daemon_state_text2enum(const char *state) { int i; if (state == NULL) { return pcmk_pacemakerd_state_invalid; } for (i=pcmk_pacemakerd_state_init; i <= pcmk_pacemakerd_state_max; i++) { if (pcmk__str_eq(state, pacemakerd_state_str[i], pcmk__str_none)) { return i; } } return pcmk_pacemakerd_state_invalid; } const char * pcmk_pacemakerd_api_daemon_state_enum2text( enum pcmk_pacemakerd_state state) { if ((state >= pcmk_pacemakerd_state_init) && (state <= pcmk_pacemakerd_state_max)) { return pacemakerd_state_str[state]; } return "invalid"; } /*! * \internal * \brief Return a friendly string representation of a \p pacemakerd state * * \param[in] state \p pacemakerd state * * \return A user-friendly string representation of \p state, or * "Invalid pacemakerd state" */ const char * pcmk__pcmkd_state_enum2friendly(enum pcmk_pacemakerd_state state) { switch (state) { case pcmk_pacemakerd_state_init: return "Initializing pacemaker"; case pcmk_pacemakerd_state_starting_daemons: return "Pacemaker daemons are starting"; case pcmk_pacemakerd_state_wait_for_ping: return "Waiting for startup trigger from SBD"; case pcmk_pacemakerd_state_running: return "Pacemaker is running"; case pcmk_pacemakerd_state_shutting_down: return "Pacemaker daemons are shutting down"; case pcmk_pacemakerd_state_shutdown_complete: /* Assuming pacemakerd won't process messages while in * shutdown_complete state unless reporting to SBD */ return "Pacemaker daemons are shut down (reporting to SBD)"; case pcmk_pacemakerd_state_remote: return PCMK__SERVER_REMOTED " is running " "(on a Pacemaker Remote node)"; default: return "Invalid pacemakerd state"; } } /*! * \internal * \brief Get a string representation of a \p pacemakerd API reply type * * \param[in] reply \p pacemakerd API reply type * * \return String representation of a \p pacemakerd API reply type */ const char * pcmk__pcmkd_api_reply2str(enum pcmk_pacemakerd_api_reply reply) { switch (reply) { case pcmk_pacemakerd_reply_ping: return "ping"; case pcmk_pacemakerd_reply_shutdown: return "shutdown"; default: return "unknown"; } } // \return Standard Pacemaker return code static int new_data(pcmk_ipc_api_t *api) { struct pacemakerd_api_private_s *private = NULL; api->api_data = calloc(1, sizeof(struct pacemakerd_api_private_s)); if (api->api_data == NULL) { return errno; } private = api->api_data; private->state = pcmk_pacemakerd_state_invalid; /* other as with cib, controld, ... we are addressing pacemakerd just from the local node -> pid is unique and thus sufficient as an ID */ private->client_uuid = pcmk__getpid_s(); return pcmk_rc_ok; } static void free_data(void *data) { free(((struct pacemakerd_api_private_s *) data)->client_uuid); free(data); } // \return Standard Pacemaker return code static int post_connect(pcmk_ipc_api_t *api) { struct pacemakerd_api_private_s *private = NULL; if (api->api_data == NULL) { return EINVAL; } private = api->api_data; private->state = pcmk_pacemakerd_state_invalid; return pcmk_rc_ok; } static void post_disconnect(pcmk_ipc_api_t *api) { struct pacemakerd_api_private_s *private = NULL; if (api->api_data == NULL) { return; } private = api->api_data; private->state = pcmk_pacemakerd_state_invalid; return; } static bool reply_expected(pcmk_ipc_api_t *api, const xmlNode *request) { const char *command = crm_element_value(request, PCMK__XA_CRM_TASK); if (command == NULL) { return false; } // We only need to handle commands that functions in this file can send return pcmk__str_any_of(command, CRM_OP_PING, CRM_OP_QUIT, NULL); } static bool dispatch(pcmk_ipc_api_t *api, xmlNode *reply) { crm_exit_t status = CRM_EX_OK; xmlNode *wrapper = NULL; xmlNode *msg_data = NULL; pcmk_pacemakerd_api_reply_t reply_data = { pcmk_pacemakerd_reply_unknown }; const char *value = NULL; if (pcmk__xe_is(reply, PCMK__XE_ACK)) { long long int ack_status = 0; const char *status = crm_element_value(reply, PCMK_XA_STATUS); int rc = pcmk__scan_ll(status, &ack_status, CRM_EX_OK); if (rc != pcmk_rc_ok) { crm_warn("Ack reply from %s has invalid " PCMK_XA_STATUS " '%s' (bug?)", pcmk_ipc_name(api, true), pcmk__s(status, "")); } return ack_status == CRM_EX_INDETERMINATE; } value = crm_element_value(reply, PCMK__XA_T); if (pcmk__parse_server(value) != pcmk_ipc_pacemakerd) { /* @COMPAT pacemakerd <3.0.0 sets PCMK__VALUE_CRMD as the message type, * so we can't enforce this check until we no longer support * Pacemaker Remote nodes connecting to cluster nodes older than that. */ crm_trace("Message from %s has unexpected message type '%s' " "(bug if not from pacemakerd <3.0.0)", pcmk_ipc_name(api, true), pcmk__s(value, "")); } value = crm_element_value(reply, PCMK__XA_SUBT); if (!pcmk__str_eq(value, PCMK__VALUE_RESPONSE, pcmk__str_none)) { crm_info("Unrecognizable message from %s: " "message type '%s' not '" PCMK__VALUE_RESPONSE "'", pcmk_ipc_name(api, true), pcmk__s(value, "")); status = CRM_EX_PROTOCOL; goto done; } if (pcmk__str_empty(crm_element_value(reply, PCMK_XA_REFERENCE))) { crm_info("Unrecognizable message from %s: no reference", pcmk_ipc_name(api, true)); status = CRM_EX_PROTOCOL; goto done; } value = crm_element_value(reply, PCMK__XA_CRM_TASK); // Parse useful info from reply wrapper = pcmk__xe_first_child(reply, PCMK__XE_CRM_XML, NULL, NULL); msg_data = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); if (pcmk__str_eq(value, CRM_OP_PING, pcmk__str_none)) { reply_data.reply_type = pcmk_pacemakerd_reply_ping; reply_data.data.ping.state = pcmk_pacemakerd_api_daemon_state_text2enum( crm_element_value(msg_data, PCMK__XA_PACEMAKERD_STATE)); reply_data.data.ping.status = pcmk__str_eq(crm_element_value(msg_data, PCMK_XA_RESULT), "ok", pcmk__str_casei)?pcmk_rc_ok:pcmk_rc_error; - pcmk__xe_get_time(msg_data, PCMK_XA_CRM_TIMESTAMP, + pcmk__xe_get_time(msg_data, PCMK__XA_CRM_TIMESTAMP, &reply_data.data.ping.last_good); if (reply_data.data.ping.last_good < 0) { reply_data.data.ping.last_good = 0; } reply_data.data.ping.sys_from = crm_element_value(msg_data, PCMK__XA_CRM_SUBSYSTEM); } else if (pcmk__str_eq(value, CRM_OP_QUIT, pcmk__str_none)) { const char *op_status = crm_element_value(msg_data, PCMK__XA_OP_STATUS); reply_data.reply_type = pcmk_pacemakerd_reply_shutdown; reply_data.data.shutdown.status = atoi(op_status); } else { crm_info("Unrecognizable message from %s: unknown command '%s'", pcmk_ipc_name(api, true), pcmk__s(value, "")); status = CRM_EX_PROTOCOL; goto done; } done: pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data); return false; } pcmk__ipc_methods_t * pcmk__pacemakerd_api_methods(void) { pcmk__ipc_methods_t *cmds = calloc(1, sizeof(pcmk__ipc_methods_t)); if (cmds != NULL) { cmds->new_data = new_data; cmds->free_data = free_data; cmds->post_connect = post_connect; cmds->reply_expected = reply_expected; cmds->dispatch = dispatch; cmds->post_disconnect = post_disconnect; } return cmds; } static int do_pacemakerd_api_call(pcmk_ipc_api_t *api, const char *ipc_name, const char *task) { pacemakerd_api_private_t *private; char *sender_system = NULL; xmlNode *cmd; int rc; if (api == NULL) { return EINVAL; } private = api->api_data; pcmk__assert(private != NULL); sender_system = crm_strdup_printf("%s_%s", private->client_uuid, pcmk__ipc_sys_name(ipc_name, "client")); cmd = pcmk__new_request(pcmk_ipc_pacemakerd, sender_system, NULL, CRM_SYSTEM_MCP, task, NULL); free(sender_system); if (cmd) { rc = pcmk__send_ipc_request(api, cmd); if (rc != pcmk_rc_ok) { crm_debug("Couldn't send request to %s: %s rc=%d", pcmk_ipc_name(api, true), pcmk_rc_str(rc), rc); } pcmk__xml_free(cmd); } else { rc = ENOMSG; } return rc; } int pcmk_pacemakerd_api_ping(pcmk_ipc_api_t *api, const char *ipc_name) { return do_pacemakerd_api_call(api, ipc_name, CRM_OP_PING); } int pcmk_pacemakerd_api_shutdown(pcmk_ipc_api_t *api, const char *ipc_name) { return do_pacemakerd_api_call(api, ipc_name, CRM_OP_QUIT); }