diff --git a/daemons/pacemakerd/pcmkd_messages.c b/daemons/pacemakerd/pcmkd_messages.c
index 4e6f8229ea..35c339d276 100644
--- a/daemons/pacemakerd/pcmkd_messages.c
+++ b/daemons/pacemakerd/pcmkd_messages.c
@@ -1,278 +1,278 @@
 /*
- * Copyright 2010-2022 the Pacemaker project contributors
+ * Copyright 2010-2024 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 <crm_internal.h>
 #include "pacemakerd.h"
 
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 
 #include <errno.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 #include <time.h>
 #include <sys/types.h>
 
 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,
                        "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, F_CRM_SYS_FROM);
 
     /* Pinged for status */
     crm_trace("Pinged from " F_CRM_SYS_FROM "='%s' " F_CRM_ORIGIN "='%s'",
               pcmk__s(from, ""),
               pcmk__s(crm_element_value(msg, F_CRM_ORIGIN), ""));
 
     pcmk__ipc_send_ack(request->ipc_client, request->ipc_id, request->ipc_flags,
                        "ack", NULL, CRM_EX_INDETERMINATE);
 
     ping = create_xml_node(NULL, XML_CRM_TAG_PING);
     value = crm_element_value(msg, F_CRM_SYS_TO);
     crm_xml_add(ping, XML_PING_ATTR_SYSFROM, value);
     crm_xml_add(ping, XML_PING_ATTR_PACEMAKERDSTATE, pacemakerd_state);
-    crm_xml_add_ll(ping, XML_ATTR_TSTAMP,
+    crm_xml_add_ll(ping, PCMK_XA_CRM_TIMESTAMP,
                    (long long) subdaemon_check_progress);
     crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok");
     reply = create_reply(msg, ping);
 
     free_xml(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, XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE, 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, XML_PING_ATTR_PACEMAKERDSTATE_WAITPING, pcmk__str_none)) {
             crm_notice("Received startup-trigger from SBD.");
             pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS;
             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,
                        "ack", NULL, CRM_EX_INDETERMINATE);
 
     shutdown = create_xml_node(NULL, XML_CIB_ATTR_SHUTDOWN);
 
     if (allowed) {
         crm_notice("Shutting down in response to IPC request %s from %s",
                    crm_element_value(msg, F_CRM_REFERENCE),
                    crm_element_value(msg, F_CRM_ORIGIN));
         crm_xml_add_int(shutdown, XML_LRM_ATTR_OPSTATUS, CRM_EX_OK);
     } else {
         crm_warn("Ignoring shutdown request from unprivileged client %s",
                  pcmk__client_name(request->ipc_client));
         crm_xml_add_int(shutdown, XML_LRM_ATTR_OPSTATUS, CRM_EX_INSUFFICIENT_PRIV);
     }
 
     reply = create_reply(msg, shutdown);
     free_xml(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,
                        "ack", NULL, CRM_EX_INVALID_PARAM);
 
     pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID,
                         "Unknown IPC request type '%s' (bug?)",
                         pcmk__client_name(request->ipc_client));
     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 -EIO;
     }
     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)
 {
     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();
     }
 
     msg = pcmk__client_data2xml(c, data, &id, &flags);
     if (msg == NULL) {
         pcmk__ipc_send_ack(c, id, flags, "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, F_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);
             free_xml(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);
     }
 
     free_xml(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/compatibility.h b/include/crm/compatibility.h
index f8502cc17e..93035f016a 100644
--- a/include/crm/compatibility.h
+++ b/include/crm/compatibility.h
@@ -1,243 +1,243 @@
 /*
- * Copyright 2004-2023 the Pacemaker project contributors
+ * Copyright 2004-2024 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.
  */
 #ifndef PCMK__CRM_COMPATIBILITY__H
 #  define PCMK__CRM_COMPATIBILITY__H
 
 #include <crm/msg_xml.h>
 #include <crm/pengine/pe_types.h> // enum pe_obj_types
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* This file allows external code that uses Pacemaker libraries to transition
  * more easily from old APIs to current ones. Any code that compiled with an
  * earlier API but not with the current API can include this file and have a
  * good chance of compiling again.
  *
  * Everything here is deprecated and will be removed at the next major Pacemaker
  * release (i.e. 3.0), so it should only be used during a transitionary period
  * while the external code is being updated to the current API.
  */
 
 /* Heartbeat-specific definitions. Support for heartbeat has been removed
  * entirely, so any code branches relying on these should be deleted.
  */
 #define ACTIVESTATUS "active"
 #define DEADSTATUS "dead"
 #define PINGSTATUS "ping"
 #define JOINSTATUS "join"
 #define LEAVESTATUS "leave"
 #define NORMALNODE "normal"
 #define CRM_NODE_EVICTED "evicted"
 #define CRM_LEGACY_CONFIG_DIR "/var/lib/heartbeat/crm"
 #define HA_VARLIBHBDIR "/var/lib/heartbeat"
 #define pcmk_cluster_heartbeat 0x0004
 
 /* Corosync-version-1-specific definitions */
 
 /* Support for corosync version 1 has been removed entirely, so any code
  * branches relying on these should be deleted.
  */
 #define PCMK_SERVICE_ID 9
 #define CRM_SERVICE PCMK_SERVICE_ID
 #define XML_ATTR_EXPECTED_VOTES "expected-quorum-votes"
 #define crm_class_members 1
 #define crm_class_notify 2
 #define crm_class_nodeid 3
 #define crm_class_rmpeer 4
 #define crm_class_quorum 5
 #define pcmk_cluster_classic_ais 0x0010
 #define pcmk_cluster_cman 0x0040
 #define ais_fd_sync -1
 
 // These are always true now
 #define CS_USES_LIBQB 1
 #define HAVE_CMAP 1
 #define SUPPORT_CS_QUORUM 1
 #define SUPPORT_AIS 1
 #define AIS_COROSYNC 1
 
 // These are always false now
 #define HAVE_CONFDB 0
 #define SUPPORT_CMAN 0
 #define SUPPORT_PLUGIN 0
 #define SUPPORT_STONITH_CONFIG 0
 #define is_classic_ais_cluster() 0
 #define is_cman_cluster() 0
 
 // These have newer names
 #define is_openais_cluster() is_corosync_cluster()
 #if SUPPORT_COROSYNC
 #define SUPPORT_CS
 #endif
 
 /* Isolation-specific definitions. Support for the resource isolation feature
  * has been removed * entirely, so any code branches relying on these should be
  * deleted.
  */
 #define XML_RSC_ATTR_ISOLATION_INSTANCE "isolation-instance"
 #define XML_RSC_ATTR_ISOLATION_WRAPPER "isolation-wrapper"
 #define XML_RSC_ATTR_ISOLATION_HOST "isolation-host"
 #define XML_RSC_ATTR_ISOLATION "isolation"
 
 /* Schema-related definitions */
 
 // This has been renamed
 #define CRM_DTD_DIRECTORY CRM_SCHEMA_DIRECTORY
 
 /* Exit-code-related definitions */
 
 #define DAEMON_RESPAWN_STOP CRM_EX_FATAL
 #define pcmk_err_panic      CRM_EX_PANIC
 
 // Deprecated symbols that were removed
 #define APPNAME_LEN         256
 #define CRM_NODE_ACTIVE             CRM_NODE_MEMBER
 #define CRM_OP_DIE          "die_no_respawn"
 #define CRM_OP_RETRIVE_CIB  "retrieve_cib"
 #define CRM_OP_HBEAT        "dc_beat"
 #define CRM_OP_ABORT        "abort"
 #define CRM_OP_DEBUG_UP     "debug_inc"
 #define CRM_OP_DEBUG_DOWN   "debug_dec"
 #define CRM_OP_EVENTCC      "event_cc"
 #define CRM_OP_TEABORT      "te_abort"
 #define CRM_OP_TEABORTED    "te_abort_confirmed"
 #define CRM_OP_TE_HALT      "te_halt"
 #define CRM_OP_TECOMPLETE   "te_complete"
 #define CRM_OP_TETIMEOUT    "te_timeout"
 #define CRM_OP_TRANSITION   "transition"
 #define CRM_OP_NODES_PROBED "probe_nodes_complete"
 #define DOT_ALL_FSA_INPUTS  1
 #define DOT_FSA_ACTIONS     1
 #define F_LRMD_CANCEL_CALLID        "lrmd_cancel_callid"
 #define F_LRMD_RSC_METADATA         "lrmd_rsc_metadata_res"
 #define F_LRMD_IPC_PROXY_NODE       "lrmd_ipc_proxy_node"
 #define INSTANCE(x)                 crm_element_value(x, XML_CIB_ATTR_INSTANCE)
 #define LOG_DEBUG_2  LOG_TRACE
 #define LOG_DEBUG_3  LOG_TRACE
 #define LOG_DEBUG_4  LOG_TRACE
 #define LOG_DEBUG_5  LOG_TRACE
 #define LOG_DEBUG_6  LOG_TRACE
 #define LRMD_OP_RSC_CHK_REG         "lrmd_rsc_check_register"
 #define MAX_IPC_FAIL                5
 #define NAME(x)                     crm_element_value(x, XML_NVPAIR_ATTR_NAME)
 #define MSG_LOG                     1
 #define PE_OBJ_T_NATIVE             "native"
 #define PE_OBJ_T_GROUP              "group"
 #define PE_OBJ_T_INCARNATION        "clone"
 #define PE_OBJ_T_MASTER             "master"
 #define SERVICE_SCRIPT              "/sbin/service"
 #define SOCKET_LEN                  1024
-#define TSTAMP(x)                   crm_element_value(x, XML_ATTR_TSTAMP)
+#define TSTAMP(x)                   crm_element_value(x, PCMK_XA_CRM_TIMESTAMP)
 #define XML_ATTR_TAGNAME            F_XML_TAGNAME
 #define XML_ATTR_FILTER_TYPE        "type-filter"
 #define XML_ATTR_FILTER_ID          "id-filter"
 #define XML_ATTR_FILTER_PRIORITY    "priority-filter"
 #define XML_ATTR_DC                 "is_dc"
 #define XML_MSG_TAG                 "crm_message"
 #define XML_MSG_TAG_DATA            "msg_data"
 #define XML_FAIL_TAG_RESOURCE       "failed_resource"
 #define XML_FAILRES_ATTR_RESID      "resource_id"
 #define XML_FAILRES_ATTR_REASON     "reason"
 #define XML_FAILRES_ATTR_RESSTATUS  "resource_status"
 #define XML_ATTR_RESULT             "result"
 #define XML_ATTR_SECTION            "section"
 #define XML_CIB_TAG_DOMAIN          "domain"
 #define XML_CIB_TAG_CONSTRAINT      "constraint"
 #define XML_RSC_ATTR_STATE          "clone-state"
 #define XML_RSC_ATTR_PRIORITY       "priority"
 #define XML_OP_ATTR_DEPENDENT       "dependent-on"
 #define XML_LRM_TAG_AGENTS          "lrm_agents"
 #define XML_LRM_TAG_AGENT           "lrm_agent"
 #define XML_LRM_TAG_ATTRIBUTES      "attributes"
 #define XML_CIB_ATTR_HEALTH         "health"
 #define XML_CIB_ATTR_WEIGHT         "weight"
 #define XML_CIB_ATTR_CLEAR          "clear_on"
 #define XML_CIB_ATTR_STONITH        "stonith"
 #define XML_CIB_ATTR_STANDBY        "standby"
 #define XML_RULE_ATTR_SCORE_MANGLED "score-attribute-mangled"
 #define XML_RULE_ATTR_RESULT        "result"
 #define XML_NODE_ATTR_STATE         "state"
 #define XML_ATTR_LRM_PROBE          "lrm-is-probe"
 #define XML_ATTR_TE_ALLOWFAIL       "op_allow_fail"
 #define VALUE(x)                    crm_element_value(x, XML_NVPAIR_ATTR_VALUE)
 #define action_wrapper_s            pe_action_wrapper_s
 #define add_cib_op_callback(cib, id, flag, data, fn) do {                \
         cib->cmds->register_callback(cib, id, 120, flag, data, #fn, fn); \
     } while(0)
 #define cib_default_options = cib_none
 #define crm_remote_baremetal              0x0004
 #define crm_remote_container              0x0002
 #define crm_element_value_const           crm_element_value
 #define crm_element_value_const_int       crm_element_value_int
 #define n_object_classes                  3
 #define no_quorum_policy_e                pe_quorum_policy
 #define node_s                            pe_node_s
 #define node_shared_s                     pe_node_shared_s
 #define pe_action_failure_is_fatal        0x00020
 #define pe_rsc_munging                    0x00000800ULL
 #define pe_rsc_try_reload                 0x00001000ULL
 #define pe_rsc_shutdown                   0x00020000ULL
 #define pe_rsc_migrating                  0x00400000ULL
 #define pe_rsc_unexpectedly_running       0x02000000ULL
 #define pe_rsc_have_unfencing             0x80000000ULL
 #define resource_s                        pe_resource_s
 #define ticket_s                          pe_ticket_s
 
 #define node_score_infinity 1000000
 
 /* Clone terminology definitions */
 
 // These can no longer be used in a switch together
 #define pe_master pcmk_rsc_variant_clone
 
 static inline enum pe_obj_types
 get_resource_type(const char *name)
 {
     if (safe_str_eq(name, XML_CIB_TAG_RESOURCE)) {
         return pcmk_rsc_variant_primitive;
 
     } else if (safe_str_eq(name, XML_CIB_TAG_GROUP)) {
         return pcmk_rsc_variant_group;
 
     } else if (safe_str_eq(name, XML_CIB_TAG_INCARNATION)
                 || safe_str_eq(name, PCMK_XE_PROMOTABLE_LEGACY)) {
         return pcmk_rsc_variant_clone;
 
     } else if (safe_str_eq(name, XML_CIB_TAG_CONTAINER)) {
         return pcmk_rsc_variant_bundle;
     }
 
     return pcmk_rsc_variant_unknown;
 }
 
 static inline const char *
 get_resource_typename(enum pe_obj_types type)
 {
     switch (type) {
         case pcmk_rsc_variant_primitive:
             return XML_CIB_TAG_RESOURCE;
         case pcmk_rsc_variant_group:
             return XML_CIB_TAG_GROUP;
         case pcmk_rsc_variant_clone:
             return XML_CIB_TAG_INCARNATION;
         case pcmk_rsc_variant_bundle:
             return XML_CIB_TAG_CONTAINER;
         case pcmk_rsc_variant_unknown:
             return "unknown";
     }
     return "<unknown>";
 }
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif
diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h
index 06a33f3036..ad02d20990 100644
--- a/include/crm/msg_xml.h
+++ b/include/crm/msg_xml.h
@@ -1,467 +1,468 @@
 /*
  * Copyright 2004-2024 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_MSG_XML__H
 #  define PCMK__CRM_MSG_XML__H
 
 #  include <crm/common/xml.h>
 
 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
 #include <crm/msg_xml_compat.h>
 #endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* This file defines constants for various XML syntax (mainly element and
  * attribute names).
  *
  * For consistency, new constants should start with "PCMK_", followed by "XE"
  * for XML element names, "XA" for XML attribute names, and "META" for meta
  * attribute names. Old names that don't follow this policy should eventually be
  * deprecated and replaced with names that do.
  */
 
 /*
  * XML elements
  */
 
 #define PCMK_XE_DATE_EXPRESSION             "date_expression"
 #define PCMK_XE_OP_EXPRESSION               "op_expression"
 
 /* This has been deprecated as a CIB element (an alias for <clone> with
  * "promotable" set to "true") since 2.0.0.
  */
 #define PCMK_XE_PROMOTABLE_LEGACY           "master"
 
 #define PCMK_XE_RSC_EXPRESSION              "rsc_expression"
 
 
 /*
  * XML attributes
  */
 
 #define PCMK_XA_ADMIN_EPOCH                 "admin_epoch"
 #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_EPOCH                       "epoch"
 #define PCMK_XA_FORMAT                      "format"
 #define PCMK_XA_HAVE_QUORUM                 "have-quorum"
 #define PCMK_XA_NO_QUORUM_PANIC             "no-quorum-panic"
 #define PCMK_XA_NUM_UPDATES                 "num_updates"
 #define PCMK_XA_VALIDATE_WITH               "validate-with"
 
 /* These have been deprecated as CIB <clone> element attributes (aliases for
  * "promoted-max" and "promoted-node-max") since 2.0.0.
  */
 #define PCMK_XA_PROMOTED_MAX_LEGACY         "master-max"
 #define PCMK_XA_PROMOTED_NODE_MAX_LEGACY    "master-node-max"
 
 
 /*
  * Meta attributes
  */
 
 #define PCMK_META_CLONE_MAX                 "clone-max"
 #define PCMK_META_CLONE_MIN                 "clone-min"
 #define PCMK_META_CLONE_NODE_MAX            "clone-node-max"
 #define PCMK_META_ENABLED                   "enabled"
 #define PCMK_META_FAILURE_TIMEOUT           "failure-timeout"
 #define PCMK_META_MIGRATION_THRESHOLD       "migration-threshold"
 #define PCMK_META_PROMOTED_MAX              "promoted-max"
 #define PCMK_META_PROMOTED_NODE_MAX         "promoted-node-max"
 
 
 /*
  * Older constants that don't follow current naming
  */
 
 #  ifndef F_ORIG
 #    define F_ORIG    "src"
 #  endif
 
 #  ifndef F_SEQ
 #    define F_SEQ		"seq"
 #  endif
 
 #  ifndef F_SUBTYPE
 #    define F_SUBTYPE "subt"
 #  endif
 
 #  ifndef F_TYPE
 #    define F_TYPE    "t"
 #  endif
 
 #  ifndef F_CLIENTNAME
 #    define	F_CLIENTNAME	"cn"
 #  endif
 
 #  ifndef F_XML_TAGNAME
 #    define F_XML_TAGNAME	"__name__"
 #  endif
 
 #  ifndef T_CRM
 #    define T_CRM     "crmd"
 #  endif
 
 #  ifndef T_ATTRD
 #    define T_ATTRD     "attrd"
 #  endif
 
 #  define CIB_OPTIONS_FIRST "cib-bootstrap-options"
 
 #  define F_CRM_DATA			"crm_xml"
 #  define F_CRM_TASK			"crm_task"
 #  define F_CRM_HOST_TO			"crm_host_to"
 #  define F_CRM_MSG_TYPE		F_SUBTYPE
 #  define F_CRM_SYS_TO			"crm_sys_to"
 #  define F_CRM_SYS_FROM		"crm_sys_from"
 #  define F_CRM_HOST_FROM		F_ORIG
 #  define F_CRM_REFERENCE		XML_ATTR_REFERENCE
 #  define F_CRM_VERSION			XML_ATTR_VERSION
 #  define F_CRM_ORIGIN			"origin"
 #  define F_CRM_USER			"crm_user"
 #  define F_CRM_JOIN_ID			"join_id"
 #  define F_CRM_DC_LEAVING      "dc-leaving"
 #  define F_CRM_ELECTION_ID		"election-id"
 #  define F_CRM_ELECTION_AGE_S		"election-age-sec"
 #  define F_CRM_ELECTION_AGE_US		"election-age-nano-sec"
 #  define F_CRM_ELECTION_OWNER		"election-owner"
 #  define F_CRM_TGRAPH			"crm-tgraph-file"
 #  define F_CRM_TGRAPH_INPUT		"crm-tgraph-in"
 
 #  define F_CRM_THROTTLE_MODE		"crm-limit-mode"
 #  define F_CRM_THROTTLE_MAX		"crm-limit-max"
 
 /*---- Common tags/attrs */
 #  define XML_DIFF_MARKER		"__crm_diff_marker__"
 #  define XML_TAG_CIB			"cib"
 #  define XML_TAG_FAILED		"failed"
 
 #  define XML_ATTR_TIMEOUT		"timeout"
 #  define XML_ATTR_TSTAMP		"crm-timestamp"
 #  define XML_CIB_ATTR_WRITTEN		"cib-last-written"
 #  define XML_ATTR_VERSION		"version"
 #  define XML_ATTR_DESC			"description"
 #  define XML_ATTR_ID			"id"
 #  define XML_ATTR_NAME			"name"
 #  define XML_ATTR_IDREF			"id-ref"
 #  define XML_ATTR_ID_LONG		"long-id"
 #  define XML_ATTR_TYPE			"type"
 #  define XML_ATTR_OP			"op"
 #  define XML_ATTR_DC_UUID		"dc-uuid"
 #  define XML_ATTR_UPDATE_ORIG		"update-origin"
 #  define XML_ATTR_UPDATE_CLIENT	"update-client"
 #  define XML_ATTR_UPDATE_USER		"update-user"
 
 #  define XML_BOOLEAN_TRUE		"true"
 #  define XML_BOOLEAN_FALSE		"false"
 #  define XML_BOOLEAN_YES		XML_BOOLEAN_TRUE
 #  define XML_BOOLEAN_NO		XML_BOOLEAN_FALSE
 
 #  define XML_TAG_OPTIONS		"options"
 
 /*---- top level tags/attrs */
 #  define XML_ATTR_REQUEST		"request"
 #  define XML_ATTR_RESPONSE		"response"
 
 #  define XML_ATTR_UNAME		"uname"
 #  define XML_ATTR_REFERENCE		"reference"
 
 #  define XML_CRM_TAG_PING		"ping_response"
 #  define XML_PING_ATTR_STATUS		"result"
 #  define XML_PING_ATTR_SYSFROM		"crm_subsystem"
 #  define XML_PING_ATTR_CRMDSTATE   "crmd_state"
 #  define XML_PING_ATTR_PACEMAKERDSTATE "pacemakerd_state"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_INIT "init"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS "starting_daemons"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_WAITPING "wait_for_ping"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_RUNNING "running"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_SHUTTINGDOWN "shutting_down"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE "shutdown_complete"
 #  define XML_PING_ATTR_PACEMAKERDSTATE_REMOTE "remote"
 
 #  define XML_FAIL_TAG_CIB		"failed_update"
 
 #  define XML_FAILCIB_ATTR_ID		"id"
 #  define XML_FAILCIB_ATTR_OBJTYPE	"object_type"
 #  define XML_FAILCIB_ATTR_OP		"operation"
 #  define XML_FAILCIB_ATTR_REASON	"reason"
 
 /*---- CIB specific tags/attrs */
 #  define XML_CIB_TAG_SECTION_ALL	"all"
 #  define XML_CIB_TAG_CONFIGURATION	"configuration"
 #  define XML_CIB_TAG_STATUS       	"status"
 #  define XML_CIB_TAG_RESOURCES		"resources"
 #  define XML_CIB_TAG_NODES         	"nodes"
 #  define XML_CIB_TAG_CONSTRAINTS   	"constraints"
 #  define XML_CIB_TAG_CRMCONFIG   	"crm_config"
 #  define XML_CIB_TAG_OPCONFIG		"op_defaults"
 #  define XML_CIB_TAG_RSCCONFIG   	"rsc_defaults"
 #  define XML_CIB_TAG_ACLS   		"acls"
 #  define XML_CIB_TAG_ALERTS    	"alerts"
 #  define XML_CIB_TAG_ALERT   		"alert"
 #  define XML_CIB_TAG_ALERT_RECIPIENT	"recipient"
 #  define XML_CIB_TAG_ALERT_SELECT      "select"
 #  define XML_CIB_TAG_ALERT_ATTRIBUTES  "select_attributes"
 #  define XML_CIB_TAG_ALERT_FENCING     "select_fencing"
 #  define XML_CIB_TAG_ALERT_NODES       "select_nodes"
 #  define XML_CIB_TAG_ALERT_RESOURCES   "select_resources"
 #  define XML_CIB_TAG_ALERT_ATTR        "attribute"
 
 #  define XML_CIB_TAG_STATE         	"node_state"
 #  define XML_CIB_TAG_NODE          	"node"
 #  define XML_CIB_TAG_NVPAIR        	"nvpair"
 
 #  define XML_CIB_TAG_PROPSET	   	"cluster_property_set"
 #  define XML_TAG_ATTR_SETS	   	"instance_attributes"
 #  define XML_TAG_META_SETS	   	"meta_attributes"
 #  define XML_TAG_ATTRS			"attributes"
 #  define XML_TAG_PARAMS		"parameters"
 #  define XML_TAG_PARAM			"param"
 #  define XML_TAG_UTILIZATION		"utilization"
 
 #  define XML_TAG_RESOURCE_REF		"resource_ref"
 #  define XML_CIB_TAG_RESOURCE	  	"primitive"
 #  define XML_CIB_TAG_GROUP	  	"group"
 #  define XML_CIB_TAG_INCARNATION	"clone"
 #  define XML_CIB_TAG_CONTAINER		"bundle"
 
 #  define XML_CIB_TAG_RSC_TEMPLATE	"template"
 
 #  define XML_RSC_ATTR_TARGET           "container-attribute-target"
 #  define XML_RSC_ATTR_RESTART	  	"restart-type"
 #  define XML_RSC_ATTR_ORDERED		"ordered"
 #  define XML_RSC_ATTR_INTERLEAVE	"interleave"
 #  define XML_RSC_ATTR_INCARNATION	"clone"
 #  define XML_RSC_ATTR_PROMOTABLE       "promotable"
 #  define XML_RSC_ATTR_MANAGED		"is-managed"
 #  define XML_RSC_ATTR_TARGET_ROLE	"target-role"
 #  define XML_RSC_ATTR_UNIQUE		"globally-unique"
 #  define XML_RSC_ATTR_NOTIFY		"notify"
 #  define XML_RSC_ATTR_STICKINESS	"resource-stickiness"
 #  define XML_RSC_ATTR_MULTIPLE		"multiple-active"
 #  define XML_RSC_ATTR_REQUIRES		"requires"
 #  define XML_RSC_ATTR_CONTAINER	"container"
 #  define XML_RSC_ATTR_INTERNAL_RSC	"internal_rsc"
 #  define XML_RSC_ATTR_MAINTENANCE	"maintenance"
 #  define XML_RSC_ATTR_REMOTE_NODE  	"remote-node"
 #  define XML_RSC_ATTR_CLEAR_OP         "clear_failure_op"
 #  define XML_RSC_ATTR_CLEAR_INTERVAL   "clear_failure_interval"
 #  define XML_RSC_ATTR_REMOTE_RA_ADDR   "addr"
 #  define XML_RSC_ATTR_REMOTE_RA_SERVER "server"
 #  define XML_RSC_ATTR_REMOTE_RA_PORT   "port"
 #  define XML_RSC_ATTR_CRITICAL         "critical"
 
 #  define XML_REMOTE_ATTR_RECONNECT_INTERVAL "reconnect_interval"
 
 #  define XML_OP_ATTR_ON_FAIL		"on-fail"
 #  define XML_OP_ATTR_START_DELAY	"start-delay"
 #  define XML_OP_ATTR_ALLOW_MIGRATE	"allow-migrate"
 #  define XML_OP_ATTR_ORIGIN		"interval-origin"
 #  define XML_OP_ATTR_PENDING		"record-pending"
 #  define XML_OP_ATTR_DIGESTS_ALL       "digests-all"
 #  define XML_OP_ATTR_DIGESTS_SECURE    "digests-secure"
 
 #  define XML_CIB_TAG_LRM		"lrm"
 #  define XML_LRM_TAG_RESOURCES     	"lrm_resources"
 #  define XML_LRM_TAG_RESOURCE     	"lrm_resource"
 #  define XML_LRM_TAG_RSC_OP		"lrm_rsc_op"
 #  define XML_AGENT_ATTR_CLASS		"class"
 #  define XML_AGENT_ATTR_PROVIDER	"provider"
 
 //! \deprecated Do not use (will be removed in a future release)
 #  define XML_CIB_ATTR_REPLACE       	"replace"
 
 #  define XML_CIB_ATTR_PRIORITY     	"priority"
 
 #  define XML_NODE_IS_REMOTE    	"remote_node"
 #  define XML_NODE_IS_FENCED		"node_fenced"
 #  define XML_NODE_IS_MAINTENANCE   "node_in_maintenance"
 
 #  define XML_CIB_ATTR_SHUTDOWN       	"shutdown"
 
 /* Aside from being an old name for the executor, LRM is a misnomer here because
  * the controller and scheduler use these to track actions, which are not always
  * executor operations.
  */
 
 // XML attribute that takes interval specification (user-facing configuration)
 #  define XML_LRM_ATTR_INTERVAL		"interval"
 
 // XML attribute that takes interval in milliseconds (daemon APIs)
 // (identical value as above, but different constant allows clearer code intent)
 #  define XML_LRM_ATTR_INTERVAL_MS  XML_LRM_ATTR_INTERVAL
 
 #  define XML_LRM_ATTR_TASK		"operation"
 #  define XML_LRM_ATTR_TASK_KEY		"operation_key"
 #  define XML_LRM_ATTR_TARGET		"on_node"
 #  define XML_LRM_ATTR_TARGET_UUID	"on_node_uuid"
 /*! 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 XML_LRM_ATTR_ROUTER_NODE  "router_node"
 #  define XML_LRM_ATTR_RSCID		"rsc-id"
 #  define XML_LRM_ATTR_OPSTATUS		"op-status"
 #  define XML_LRM_ATTR_RC		"rc-code"
 #  define XML_LRM_ATTR_CALLID		"call-id"
 #  define XML_LRM_ATTR_OP_DIGEST	"op-digest"
 #  define XML_LRM_ATTR_OP_RESTART	"op-force-restart"
 #  define XML_LRM_ATTR_OP_SECURE	"op-secure-params"
 #  define XML_LRM_ATTR_RESTART_DIGEST	"op-restart-digest"
 #  define XML_LRM_ATTR_SECURE_DIGEST	"op-secure-digest"
 #  define XML_LRM_ATTR_EXIT_REASON	"exit-reason"
 
 #  define XML_RSC_OP_LAST_CHANGE        "last-rc-change"
 #  define XML_RSC_OP_T_EXEC             "exec-time"
 #  define XML_RSC_OP_T_QUEUE            "queue-time"
 
 #  define XML_LRM_ATTR_MIGRATE_SOURCE	"migrate_source"
 #  define XML_LRM_ATTR_MIGRATE_TARGET	"migrate_target"
 
 #  define XML_TAG_GRAPH			"transition_graph"
 #  define XML_GRAPH_TAG_RSC_OP		"rsc_op"
 #  define XML_GRAPH_TAG_PSEUDO_EVENT	"pseudo_event"
 #  define XML_GRAPH_TAG_CRM_EVENT	"crm_event"
 #  define XML_GRAPH_TAG_DOWNED            "downed"
 #  define XML_GRAPH_TAG_MAINTENANCE       "maintenance"
 
 #  define XML_TAG_RULE			"rule"
 #  define XML_RULE_ATTR_SCORE		"score"
 #  define XML_RULE_ATTR_SCORE_ATTRIBUTE	"score-attribute"
 #  define XML_RULE_ATTR_ROLE		"role"
 #  define XML_RULE_ATTR_BOOLEAN_OP	"boolean-op"
 
 #  define XML_TAG_EXPRESSION		"expression"
 #  define XML_EXPR_ATTR_ATTRIBUTE	"attribute"
 #  define XML_EXPR_ATTR_OPERATION	"operation"
 #  define XML_EXPR_ATTR_VALUE		"value"
 #  define XML_EXPR_ATTR_TYPE		"type"
 #  define XML_EXPR_ATTR_VALUE_SOURCE	"value-source"
 
 #  define XML_CONS_TAG_RSC_DEPEND	"rsc_colocation"
 #  define XML_CONS_TAG_RSC_ORDER	"rsc_order"
 #  define XML_CONS_TAG_RSC_LOCATION	"rsc_location"
 #  define XML_CONS_TAG_RSC_TICKET	"rsc_ticket"
 #  define XML_CONS_TAG_RSC_SET		"resource_set"
 #  define XML_CONS_ATTR_SYMMETRICAL	"symmetrical"
 
 #  define XML_LOCATION_ATTR_DISCOVERY	"resource-discovery"
 
 #  define XML_COLOC_ATTR_SOURCE		"rsc"
 #  define XML_COLOC_ATTR_SOURCE_ROLE	"rsc-role"
 #  define XML_COLOC_ATTR_TARGET		"with-rsc"
 #  define XML_COLOC_ATTR_TARGET_ROLE	"with-rsc-role"
 #  define XML_COLOC_ATTR_NODE_ATTR	"node-attribute"
 #  define XML_COLOC_ATTR_INFLUENCE          "influence"
 
 //! \deprecated Deprecated since 2.1.5
 #  define XML_COLOC_ATTR_SOURCE_INSTANCE	"rsc-instance"
 
 //! \deprecated Deprecated since 2.1.5
 #  define XML_COLOC_ATTR_TARGET_INSTANCE	"with-rsc-instance"
 
 #  define XML_LOC_ATTR_SOURCE           "rsc"
 #  define XML_LOC_ATTR_SOURCE_PATTERN   "rsc-pattern"
 
 #  define XML_ORDER_ATTR_FIRST		"first"
 #  define XML_ORDER_ATTR_THEN		"then"
 #  define XML_ORDER_ATTR_FIRST_ACTION	"first-action"
 #  define XML_ORDER_ATTR_THEN_ACTION	"then-action"
 #  define XML_ORDER_ATTR_KIND		"kind"
 
 //! \deprecated Deprecated since 2.1.5
 #  define XML_ORDER_ATTR_FIRST_INSTANCE	"first-instance"
 
 //! \deprecated Deprecated since 2.1.5
 #  define XML_ORDER_ATTR_THEN_INSTANCE	"then-instance"
 
 #  define XML_TICKET_ATTR_TICKET	"ticket"
 #  define XML_TICKET_ATTR_LOSS_POLICY	"loss-policy"
 
 #  define XML_NVPAIR_ATTR_NAME        	"name"
 #  define XML_NVPAIR_ATTR_VALUE        	"value"
 
 #  define XML_NODE_ATTR_RSC_DISCOVERY   "resource-discovery-enabled"
 
 #  define XML_ALERT_ATTR_PATH		"path"
 #  define XML_ALERT_ATTR_TIMEOUT	"timeout"
 #  define XML_ALERT_ATTR_TSTAMP_FORMAT	"timestamp-format"
 #  define XML_ALERT_ATTR_REC_VALUE	"value"
 
 #  define XML_CIB_TAG_GENERATION_TUPPLE	"generation_tuple"
 
 #  define XML_ATTR_TRANSITION_MAGIC	"transition-magic"
 #  define XML_ATTR_TRANSITION_KEY	"transition-key"
 
 #  define XML_ATTR_TE_NOWAIT		"op_no_wait"
 #  define XML_ATTR_TE_TARGET_RC		"op_target_rc"
 #  define XML_TAG_TRANSIENT_NODEATTRS	"transient_attributes"
 
 //! \deprecated Do not use (will be removed in a future release)
 #  define XML_TAG_DIFF_ADDED		"diff-added"
 
 //! \deprecated Do not use (will be removed in a future release)
 #  define XML_TAG_DIFF_REMOVED		"diff-removed"
 
 #  define XML_ACL_TAG_USER		"acl_target"
 #  define XML_ACL_TAG_USERv1		"acl_user"
 #  define XML_ACL_TAG_GROUP		"acl_group"
 #  define XML_ACL_TAG_ROLE		"acl_role"
 #  define XML_ACL_TAG_PERMISSION	"acl_permission"
 #  define XML_ACL_TAG_ROLE_REF 		"role"
 #  define XML_ACL_TAG_ROLE_REFv1	"role_ref"
 #  define XML_ACL_ATTR_KIND		"kind"
 #  define XML_ACL_TAG_READ		"read"
 #  define XML_ACL_TAG_WRITE		"write"
 #  define XML_ACL_TAG_DENY		"deny"
 #  define XML_ACL_ATTR_REF		"reference"
 #  define XML_ACL_ATTR_REFv1		"ref"
 #  define XML_ACL_ATTR_TAG		"object-type"
 #  define XML_ACL_ATTR_TAGv1		"tag"
 #  define XML_ACL_ATTR_XPATH		"xpath"
 #  define XML_ACL_ATTR_ATTRIBUTE	"attribute"
 
 #  define XML_CIB_TAG_TICKETS		"tickets"
 #  define XML_CIB_TAG_TICKET_STATE	"ticket_state"
 
 #  define XML_CIB_TAG_TAGS   		"tags"
 #  define XML_CIB_TAG_TAG   		"tag"
 #  define XML_CIB_TAG_OBJ_REF 		"obj_ref"
 
 #  define XML_TAG_FENCING_TOPOLOGY      "fencing-topology"
 #  define XML_TAG_FENCING_LEVEL         "fencing-level"
 #  define XML_ATTR_STONITH_INDEX        "index"
 #  define XML_ATTR_STONITH_TARGET       "target"
 #  define XML_ATTR_STONITH_TARGET_VALUE     "target-value"
 #  define XML_ATTR_STONITH_TARGET_PATTERN   "target-pattern"
 #  define XML_ATTR_STONITH_TARGET_ATTRIBUTE "target-attribute"
 #  define XML_ATTR_STONITH_DEVICES      "devices"
 
 #  define XML_TAG_DIFF                  "diff"
 #  define XML_DIFF_VERSION              "version"
 #  define XML_DIFF_VSOURCE              "source"
 #  define XML_DIFF_VTARGET              "target"
 #  define XML_DIFF_CHANGE               "change"
 #  define XML_DIFF_LIST                 "change-list"
 #  define XML_DIFF_ATTR                 "change-attr"
 #  define XML_DIFF_RESULT               "change-result"
 #  define XML_DIFF_OP                   "operation"
 #  define XML_DIFF_PATH                 "path"
 #  define XML_DIFF_POSITION             "position"
 
 #  define ID(x) crm_element_value(x, XML_ATTR_ID)
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif
diff --git a/lib/common/ipc_pacemakerd.c b/lib/common/ipc_pacemakerd.c
index 6d6f6d6bff..e13fa0a6e3 100644
--- a/lib/common/ipc_pacemakerd.c
+++ b/lib/common/ipc_pacemakerd.c
@@ -1,317 +1,317 @@
 /*
- * Copyright 2020-2023 the Pacemaker project contributors
+ * Copyright 2020-2024 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 <crm_internal.h>
 
 #include <stdlib.h>
 #include <time.h>
 
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 #include <crm/common/xml.h>
 #include <crm/common/ipc.h>
 #include <crm/common/ipc_internal.h>
 #include <crm/common/ipc_pacemakerd.h>
 #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[] = {
     XML_PING_ATTR_PACEMAKERDSTATE_INIT,
     XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS,
     XML_PING_ATTR_PACEMAKERDSTATE_WAITPING,
     XML_PING_ATTR_PACEMAKERDSTATE_RUNNING,
     XML_PING_ATTR_PACEMAKERDSTATE_SHUTTINGDOWN,
     XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE,
     XML_PING_ATTR_PACEMAKERDSTATE_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
  *         <tt>"Invalid pacemakerd state"</tt>
  */
 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 "pacemaker-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, F_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 *msg_data = NULL;
     pcmk_pacemakerd_api_reply_t reply_data = {
         pcmk_pacemakerd_reply_unknown
     };
     const char *value = NULL;
     long long value_ll = 0;
 
     if (pcmk__str_eq((const char *) reply->name, "ack", pcmk__str_none)) {
         long long int ack_status = 0;
         pcmk__scan_ll(crm_element_value(reply, "status"), &ack_status, CRM_EX_OK);
         return ack_status == CRM_EX_INDETERMINATE;
     }
 
     value = crm_element_value(reply, F_CRM_MSG_TYPE);
     if (pcmk__str_empty(value)
         || !pcmk__str_eq(value, XML_ATTR_RESPONSE, pcmk__str_none)) {
         crm_info("Unrecognizable message from %s: "
                  "message type '%s' not '" XML_ATTR_RESPONSE "'",
                  pcmk_ipc_name(api, true), pcmk__s(value, ""));
         status = CRM_EX_PROTOCOL;
         goto done;
     }
 
     if (pcmk__str_empty(crm_element_value(reply, XML_ATTR_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, F_CRM_TASK);
 
     // Parse useful info from reply
     msg_data = get_message_xml(reply, F_CRM_DATA);
-    crm_element_value_ll(msg_data, XML_ATTR_TSTAMP, &value_ll);
+    crm_element_value_ll(msg_data, PCMK_XA_CRM_TIMESTAMP, &value_ll);
 
     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, XML_PING_ATTR_PACEMAKERDSTATE));
         reply_data.data.ping.status =
             pcmk__str_eq(crm_element_value(msg_data, XML_PING_ATTR_STATUS), "ok",
                          pcmk__str_casei)?pcmk_rc_ok:pcmk_rc_error;
         reply_data.data.ping.last_good = (value_ll < 0)? 0 : (time_t) value_ll;
         reply_data.data.ping.sys_from = crm_element_value(msg_data,
                                             XML_PING_ATTR_SYSFROM);
     } else if (pcmk__str_eq(value, CRM_OP_QUIT, pcmk__str_none)) {
         reply_data.reply_type = pcmk_pacemakerd_reply_shutdown;
         reply_data.data.shutdown.status = atoi(crm_element_value(msg_data, XML_LRM_ATTR_OPSTATUS));
     } 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;
     xmlNode *cmd;
     int rc;
 
     if (api == NULL) {
         return EINVAL;
     }
 
     private = api->api_data;
     CRM_ASSERT(private != NULL);
 
     cmd = create_request(task, NULL, NULL, CRM_SYSTEM_MCP,
                          pcmk__ipc_sys_name(ipc_name, "client"),
                          private->client_uuid);
 
     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);
         }
         free_xml(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);
 }