summaryrefslogtreecommitdiffstats
path: root/include/crm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 07:46:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 07:46:09 +0000
commit043aa641ad4373e96fd748deb1e7fab3cb579a07 (patch)
treef8fde8a97ab5db152043f6c01043672114c0a4df /include/crm
parentReleasing progress-linux version 2.1.6-5~progress7.99u1. (diff)
downloadpacemaker-043aa641ad4373e96fd748deb1e7fab3cb579a07.tar.xz
pacemaker-043aa641ad4373e96fd748deb1e7fab3cb579a07.zip
Merging upstream version 2.1.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/crm')
-rw-r--r--include/crm/Makefile.am23
-rw-r--r--include/crm/cib/cib_types.h139
-rw-r--r--include/crm/cib/internal.h124
-rw-r--r--include/crm/cluster.h8
-rw-r--r--include/crm/cluster/Makefile.am5
-rw-r--r--include/crm/cluster/compat.h8
-rw-r--r--include/crm/cluster/internal.h8
-rw-r--r--include/crm/common/Makefile.am73
-rw-r--r--include/crm/common/action_relation_internal.h132
-rw-r--r--include/crm/common/actions.h467
-rw-r--r--include/crm/common/actions_internal.h57
-rw-r--r--include/crm/common/alerts_internal.h3
-rw-r--r--include/crm/common/cib_internal.h23
-rw-r--r--include/crm/common/clone_internal.h33
-rw-r--r--include/crm/common/digests_internal.h33
-rw-r--r--include/crm/common/failcounts_internal.h41
-rw-r--r--include/crm/common/group_internal.h27
-rw-r--r--include/crm/common/health_internal.h2
-rw-r--r--include/crm/common/internal.h23
-rw-r--r--include/crm/common/ipc.h6
-rw-r--r--include/crm/common/ipc_internal.h11
-rw-r--r--include/crm/common/logging.h8
-rw-r--r--include/crm/common/logging_compat.h4
-rw-r--r--include/crm/common/logging_internal.h102
-rw-r--r--include/crm/common/nodes.h144
-rw-r--r--include/crm/common/nvpair.h1
-rw-r--r--include/crm/common/options_internal.h42
-rw-r--r--include/crm/common/output_internal.h5
-rw-r--r--include/crm/common/remote_internal.h4
-rw-r--r--include/crm/common/resources.h502
-rw-r--r--include/crm/common/results.h4
-rw-r--r--include/crm/common/results_compat.h5
-rw-r--r--include/crm/common/results_internal.h3
-rw-r--r--include/crm/common/roles.h62
-rw-r--r--include/crm/common/roles_internal.h30
-rw-r--r--include/crm/common/scheduler.h238
-rw-r--r--include/crm/common/scheduler_internal.h67
-rw-r--r--include/crm/common/scheduler_types.h39
-rw-r--r--include/crm/common/tags.h35
-rw-r--r--include/crm/common/tickets.h39
-rw-r--r--include/crm/common/unittest_internal.h40
-rw-r--r--include/crm/common/util.h24
-rw-r--r--include/crm/common/util_compat.h9
-rw-r--r--include/crm/common/xml.h36
-rw-r--r--include/crm/common/xml_compat.h15
-rw-r--r--include/crm/common/xml_internal.h42
-rw-r--r--include/crm/compatibility.h24
-rw-r--r--include/crm/crm.h78
-rw-r--r--include/crm/crm_compat.h129
-rw-r--r--include/crm/lrmd.h69
-rw-r--r--include/crm/lrmd_events.h108
-rw-r--r--include/crm/lrmd_internal.h1
-rw-r--r--include/crm/msg_xml.h33
-rw-r--r--include/crm/msg_xml_compat.h53
-rw-r--r--include/crm/pengine/Makefile.am11
-rw-r--r--include/crm/pengine/common.h123
-rw-r--r--include/crm/pengine/common_compat.h35
-rw-r--r--include/crm/pengine/complex.h22
-rw-r--r--include/crm/pengine/internal.h615
-rw-r--r--include/crm/pengine/pe_types.h530
-rw-r--r--include/crm/pengine/pe_types_compat.h221
-rw-r--r--include/crm/pengine/remote_internal.h23
-rw-r--r--include/crm/pengine/status.h47
-rw-r--r--include/crm/services_compat.h7
64 files changed, 3494 insertions, 1381 deletions
diff --git a/include/crm/Makefile.am b/include/crm/Makefile.am
index 6dd52fd..95564b8 100644
--- a/include/crm/Makefile.am
+++ b/include/crm/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2004-2021 the Pacemaker project contributors
+# Copyright 2004-2023 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
@@ -11,12 +11,23 @@ MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm
-header_HEADERS = cib.h cluster.h compatibility.h crm.h \
- lrmd.h msg_xml.h services.h stonith-ng.h \
+header_HEADERS = cib.h \
+ cluster.h \
+ compatibility.h \
+ crm.h \
crm_compat.h \
+ lrmd.h \
+ lrmd_events.h \
+ msg_xml.h \
msg_xml_compat.h \
- services_compat.h
+ services.h \
+ services_compat.h \
+ stonith-ng.h
-noinst_HEADERS = lrmd_internal.h services_internal.h
+noinst_HEADERS = $(wildcard *_internal.h)
-SUBDIRS = common pengine cib fencing cluster
+SUBDIRS = common \
+ pengine \
+ cib \
+ fencing \
+ cluster
diff --git a/include/crm/cib/cib_types.h b/include/crm/cib/cib_types.h
index 5bd10e4..a803311 100644
--- a/include/crm/cib/cib_types.h
+++ b/include/crm/cib/cib_types.h
@@ -59,12 +59,54 @@ enum cib_call_options {
cib_discard_reply = (1 << 4),
cib_no_children = (1 << 5),
cib_xpath_address = (1 << 6),
+
+ //! \deprecated This value will be removed in a future release
cib_mixed_update = (1 << 7),
+
+ /* @COMPAT: cib_scope_local is processed only in the legacy function
+ * parse_local_options_v1().
+ *
+ * If (host == NULL):
+ * * In legacy mode, the CIB manager forwards a request to the primary
+ * instance unless cib_scope_local is set or the local node is primary.
+ * * Outside of legacy mode:
+ * * If a request modifies the CIB, the CIB manager forwards it to all
+ * nodes.
+ * * Otherwise, the CIB manager processes the request locally.
+ *
+ * There is no current use case for this implementing this flag in
+ * non-legacy mode.
+ */
+
+ //! \deprecated This value will be removed in a future release
cib_scope_local = (1 << 8),
+
cib_dryrun = (1 << 9),
+
+ /*!
+ * \brief Process request when the client commits the active transaction
+ *
+ * Add the request to the client's active transaction instead of processing
+ * it immediately. If the client has no active transaction, or if the
+ * request is not supported in transactions, the call will fail.
+ *
+ * The request is added to the transaction synchronously, and the return
+ * value indicates whether it was added successfully.
+ *
+ * Refer to \p cib_api_operations_t:init_transaction() and
+ * \p cib_api_operations_t:end_transaction() for more details on CIB
+ * transactions.
+ */
+ cib_transaction = (1 << 10),
+
cib_sync_call = (1 << 12),
cib_no_mtime = (1 << 13),
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated This value will be removed in a future release
cib_zero_copy = (1 << 14),
+#endif // !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+
cib_inhibit_notify = (1 << 16),
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
@@ -82,13 +124,19 @@ typedef struct cib_s cib_t;
typedef struct cib_api_operations_s {
int (*signon) (cib_t *cib, const char *name, enum cib_conn_type type);
+
+ //! \deprecated This method will be removed and should not be used
int (*signon_raw) (cib_t *cib, const char *name, enum cib_conn_type type,
int *event_fd);
+
int (*signoff) (cib_t *cib);
int (*free) (cib_t *cib);
+
+ //! \deprecated This method will be removed and should not be used
int (*set_op_callback) (cib_t *cib, void (*callback) (const xmlNode *msg,
int callid, int rc,
xmlNode *output));
+
int (*add_notify_callback) (cib_t *cib, const char *event,
void (*callback) (const char *event,
xmlNode *msg));
@@ -97,8 +145,13 @@ typedef struct cib_api_operations_s {
xmlNode *msg));
int (*set_connection_dnotify) (cib_t *cib,
void (*dnotify) (gpointer user_data));
+
+ //! \deprecated This method will be removed and should not be used
int (*inputfd) (cib_t *cib);
+
+ //! \deprecated This method will be removed and should not be used
int (*noop) (cib_t *cib, int call_options);
+
int (*ping) (cib_t *cib, xmlNode **output_data, int call_options);
int (*query) (cib_t *cib, const char *section, xmlNode **output_data,
int call_options);
@@ -141,7 +194,9 @@ typedef struct cib_api_operations_s {
int (*delete_absolute) (cib_t *cib, const char *section, xmlNode *data,
int call_options);
+ //! \deprecated This method is not implemented and should not be used
int (*quit) (cib_t *cib, int call_options);
+
int (*register_notification) (cib_t *cib, const char *callback,
int enabled);
gboolean (*register_callback) (cib_t *cib, int call_id, int timeout,
@@ -190,14 +245,85 @@ typedef struct cib_api_operations_s {
*
* \return Legacy Pacemaker return code
*
- * \note The client IDs are assigned by \p pacemaker-based when the client
- * connects. \p cib_t variants that don't connect to
- * \p pacemaker-based may never be assigned a client ID.
* \note Some variants may have only one client for both asynchronous and
* synchronous requests.
*/
int (*client_id)(const cib_t *cib, const char **async_id,
const char **sync_id);
+
+ /*!
+ * \brief Initiate an atomic CIB transaction for this client
+ *
+ * If the client has initiated a transaction and a new request's call
+ * options contain \p cib_transaction, the new request is appended to the
+ * transaction for later processing.
+ *
+ * Supported requests are those that meet the following conditions:
+ * * can be processed synchronously (with any changes applied to a working
+ * CIB copy)
+ * * are not queries
+ * * do not involve other nodes
+ * * do not affect the state of pacemaker-based itself
+ *
+ * Currently supported CIB API functions include:
+ * * \p bump_epoch()
+ * * \p create()
+ * * \p erase()
+ * * \p modify()
+ * * \p remove()
+ * * \p replace()
+ * * \p upgrade()
+ *
+ * Because the transaction is atomic, individual requests do not trigger
+ * callbacks or notifications when they are processed, and they do not
+ * receive output XML. The commit request itself can trigger callbacks and
+ * notifications if any are registered.
+ *
+ * An \c init_transaction() call is always synchronous.
+ *
+ * \param[in,out] cib CIB connection
+ *
+ * \return Legacy Pacemaker return code
+ */
+ int (*init_transaction)(cib_t *cib);
+
+ /*!
+ * \brief End and optionally commit this client's CIB transaction
+ *
+ * When a client commits a transaction, all requests in the transaction are
+ * processed in a FIFO manner until either a request fails or all requests
+ * have been processed. Changes are applied to a working copy of the CIB.
+ * If a request fails, the transaction and working CIB copy are discarded,
+ * and an error is returned. If all requests succeed, the working CIB copy
+ * replaces the initial CIB copy.
+ *
+ * Callbacks and notifications can be triggered by the commit request itself
+ * but not by the individual requests in a transaction.
+ *
+ * An \c end_transaction() call with \p commit set to \c false is always
+ * synchronous.
+ *
+ * \param[in,out] cib CIB connection
+ * \param[in] commit If \p true, commit transaction; otherwise,
+ * discard it
+ * \param[in] call_options Group of <tt>enum cib_call_options</tt>
+ * flags
+ *
+ * \return Legacy Pacemaker return code
+ */
+ int (*end_transaction)(cib_t *cib, bool commit, int call_options);
+
+ /*!
+ * \brief Set the user as whom all CIB requests via methods will be executed
+ *
+ * By default, the value of the \c CIB_user environment variable is used if
+ * set. Otherwise, \c root is used.
+ *
+ * \param[in,out] cib CIB connection
+ * \param[in] user Name of user whose permissions to use when
+ * processing requests
+ */
+ void (*set_user)(cib_t *cib, const char *user);
} cib_api_operations_t;
struct cib_s {
@@ -211,9 +337,16 @@ struct cib_s {
void *delegate_fn;
GList *notify_list;
+
+ //! \deprecated This method will be removed in a future release
void (*op_callback) (const xmlNode *msg, int call_id, int rc,
xmlNode *output);
+
cib_api_operations_t *cmds;
+
+ xmlNode *transaction;
+
+ char *user;
};
#ifdef __cplusplus
diff --git a/include/crm/cib/internal.h b/include/crm/cib/internal.h
index 374902b..20059ec 100644
--- a/include/crm/cib/internal.h
+++ b/include/crm/cib/internal.h
@@ -15,7 +15,6 @@
// Request types for CIB manager IPC/CPG
#define PCMK__CIB_REQUEST_SECONDARY "cib_slave"
-#define PCMK__CIB_REQUEST_ALL_SECONDARY "cib_slave_all"
#define PCMK__CIB_REQUEST_PRIMARY "cib_master"
#define PCMK__CIB_REQUEST_SYNC_TO_ALL "cib_sync"
#define PCMK__CIB_REQUEST_SYNC_TO_ONE "cib_sync_one"
@@ -32,6 +31,7 @@
#define PCMK__CIB_REQUEST_ABS_DELETE "cib_delete_alt"
#define PCMK__CIB_REQUEST_NOOP "noop"
#define PCMK__CIB_REQUEST_SHUTDOWN "cib_shutdown_req"
+#define PCMK__CIB_REQUEST_COMMIT_TRANSACT "cib_commit_transact"
# define F_CIB_CLIENTID "cib_clientid"
# define F_CIB_CALLOPTS "cib_callopt"
@@ -60,34 +60,72 @@
# define F_CIB_LOCAL_NOTIFY_ID "cib_local_notify_id"
# define F_CIB_PING_ID "cib_ping_id"
# define F_CIB_SCHEMA_MAX "cib_schema_max"
-# define F_CIB_CHANGE_SECTION "cib_change_section"
# define T_CIB "cib"
+# define T_CIB_COMMAND "cib_command"
# define T_CIB_NOTIFY "cib_notify"
/* notify sub-types */
# define T_CIB_PRE_NOTIFY "cib_pre_notify"
# define T_CIB_POST_NOTIFY "cib_post_notify"
+# define T_CIB_TRANSACTION "cib_transaction"
# define T_CIB_UPDATE_CONFIRM "cib_update_confirmation"
-# define T_CIB_REPLACE_NOTIFY "cib_refresh_notify"
/*!
* \internal
- * \enum cib_change_section_info
- * \brief Flags to indicate which sections of the CIB have changed
+ * \enum cib__op_attr
+ * \brief Flags for CIB operation attributes
*/
-enum cib_change_section_info {
- cib_change_section_none = 0, //!< No sections have changed
- cib_change_section_nodes = (1 << 0), //!< The nodes section has changed
- cib_change_section_alerts = (1 << 1), //!< The alerts section has changed
- cib_change_section_status = (1 << 2), //!< The status section has changed
+enum cib__op_attr {
+ cib__op_attr_none = 0, //!< No special attributes
+ cib__op_attr_modifies = (1 << 1), //!< Modifies CIB
+ cib__op_attr_privileged = (1 << 2), //!< Requires privileges
+ cib__op_attr_local = (1 << 3), //!< Must only be processed locally
+ cib__op_attr_replaces = (1 << 4), //!< Replaces CIB
+ cib__op_attr_writes_through = (1 << 5), //!< Writes to disk on success
+ cib__op_attr_transaction = (1 << 6), //!< Supported in a transaction
};
+/*!
+ * \internal
+ * \enum cib__op_type
+ * \brief Types of CIB operations
+ */
+enum cib__op_type {
+ cib__op_abs_delete,
+ cib__op_apply_patch,
+ cib__op_bump,
+ cib__op_commit_transact,
+ cib__op_create,
+ cib__op_delete,
+ cib__op_erase,
+ cib__op_is_primary,
+ cib__op_modify,
+ cib__op_noop,
+ cib__op_ping,
+ cib__op_primary,
+ cib__op_query,
+ cib__op_replace,
+ cib__op_secondary,
+ cib__op_shutdown,
+ cib__op_sync_all,
+ cib__op_sync_one,
+ cib__op_upgrade,
+};
gboolean cib_diff_version_details(xmlNode * diff, int *admin_epoch, int *epoch, int *updates,
int *_admin_epoch, int *_epoch, int *_updates);
gboolean cib_read_config(GHashTable * options, xmlNode * current_cib);
+typedef int (*cib__op_fn_t)(const char *, int, const char *, xmlNode *,
+ xmlNode *, xmlNode *, xmlNode **, xmlNode **);
+
+typedef struct cib__operation_s {
+ const char *name;
+ enum cib__op_type type;
+ uint32_t flags; //!< Group of <tt>enum cib__op_attr</tt> flags
+} cib__operation_t;
+
typedef struct cib_notify_client_s {
const char *event;
const char *obj_id; /* implement one day */
@@ -124,24 +162,66 @@ struct timer_rec_s {
(flags_to_clear), #flags_to_clear); \
} while (0)
-typedef int (*cib_op_t) (const char *, int, const char *, xmlNode *,
- xmlNode *, xmlNode *, xmlNode **, xmlNode **);
-
cib_t *cib_new_variant(void);
-int cib_perform_op(const char *op, int call_options, cib_op_t * fn, gboolean is_query,
- const char *section, xmlNode * req, xmlNode * input,
- gboolean manage_counters, gboolean * config_changed,
- xmlNode * current_cib, xmlNode ** result_cib, xmlNode ** diff,
- xmlNode ** output);
-
-xmlNode *cib_create_op(int call_id, const char *op, const char *host,
- const char *section, xmlNode * data, int call_options,
- const char *user_name);
+/*!
+ * \internal
+ * \brief Check whether a given CIB client's update should trigger a refresh
+ *
+ * Here, "refresh" means that Pacemaker daemons write out their current state.
+ *
+ * If a Pacemaker daemon or one of certain Pacemaker CLI tools modifies the CIB,
+ * we can assume that the CIB hasn't diverged from the true cluster state. A
+ * "safe" CLI tool requests that all relevant daemons update their state before
+ * the tool requests any CIB modifications directly.
+ *
+ * In contrast, other "unsafe" tools (for example, \c cibadmin and external
+ * tools) may request arbitrary CIB changes.
+ *
+ * A Pacemaker daemon can write out its current state to the CIB when it's
+ * notified of an update from an unsafe client, to ensure the CIB still contains
+ * the daemon's correct state.
+ *
+ * \param[in] name CIB client name
+ *
+ * \return \c true if the CIB client should trigger a refresh, or \c false
+ * otherwise
+ */
+static inline bool
+cib__client_triggers_refresh(const char *name)
+{
+ return !crm_is_daemon_name(name)
+ && !pcmk__str_any_of(name,
+ "attrd_updater",
+ "crm_attribute",
+ "crm_node",
+ "crm_resource",
+ "crm_ticket",
+ NULL);
+}
+
+int cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset);
+
+bool cib__element_in_patchset(const xmlNode *patchset, const char *element);
+
+int cib_perform_op(const char *op, int call_options, cib__op_fn_t fn,
+ bool is_query, const char *section, xmlNode *req,
+ xmlNode *input, bool manage_counters, bool *config_changed,
+ xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff,
+ xmlNode **output);
+
+int cib__create_op(cib_t *cib, const char *op, const char *host,
+ const char *section, xmlNode *data, int call_options,
+ const char *user_name, const char *client_name,
+ xmlNode **op_msg);
+
+int cib__extend_transaction(cib_t *cib, xmlNode *request);
void cib_native_callback(cib_t * cib, xmlNode * msg, int call_id, int rc);
void cib_native_notify(gpointer data, gpointer user_data);
+int cib__get_operation(const char *op, const cib__operation_t **operation);
+
int cib_process_query(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
diff --git a/include/crm/cluster.h b/include/crm/cluster.h
index bceb9c2..b61fd70 100644
--- a/include/crm/cluster.h
+++ b/include/crm/cluster.h
@@ -78,6 +78,9 @@ typedef struct crm_peer_node_s {
time_t peer_lost;
char *conn_host;
+
+ time_t when_member; // Since when node has been a cluster member
+ time_t when_online; // Since when peer has been online in CPG
} crm_node_t;
void crm_peer_init(void);
@@ -133,8 +136,8 @@ enum crm_get_peer_flags {
};
gboolean send_cluster_message(const crm_node_t *node,
- enum crm_ais_msg_types service, xmlNode *data,
- gboolean ordered);
+ enum crm_ais_msg_types service,
+ const xmlNode *data, gboolean ordered);
int crm_remote_peer_cache_size(void);
@@ -174,7 +177,6 @@ char *pcmk_message_common_cs(cpg_handle_t handle, uint32_t nodeid, uint32_t pid,
const char *crm_peer_uuid(crm_node_t *node);
const char *crm_peer_uname(const char *uuid);
-void set_uuid(xmlNode *xml, const char *attr, crm_node_t *node);
enum crm_status_type {
crm_status_uname,
diff --git a/include/crm/cluster/Makefile.am b/include/crm/cluster/Makefile.am
index 96f2bd0..2500a87 100644
--- a/include/crm/cluster/Makefile.am
+++ b/include/crm/cluster/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2012-2021 the Pacemaker project contributors
+# Copyright 2012-2023 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
@@ -10,5 +10,6 @@ MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm/cluster
-noinst_HEADERS = internal.h election_internal.h
+noinst_HEADERS = internal.h \
+ $(wildcard *_internal.h)
header_HEADERS = compat.h
diff --git a/include/crm/cluster/compat.h b/include/crm/cluster/compat.h
index 9bf14ee..89a03fd 100644
--- a/include/crm/cluster/compat.h
+++ b/include/crm/cluster/compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2021 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -10,6 +10,9 @@
#ifndef PCMK__CRM_CLUSTER_COMPAT__H
# define PCMK__CRM_CLUSTER_COMPAT__H
+#include <libxml/tree.h> // xmlNode
+#include <crm/cluster.h> // crm_node_t
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -30,6 +33,9 @@ int crm_terminate_member(int nodeid, const char *uname, void *unused);
int crm_terminate_member_no_mainloop(int nodeid, const char *uname,
int *connection);
+// \deprecated Use crm_xml_add(xml, attr, crm_peer_uuid(node)) instead
+void set_uuid(xmlNode *xml, const char *attr, crm_node_t *node);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h
index 9bc57c6..e20ee4c 100644
--- a/include/crm/cluster/internal.h
+++ b/include/crm/cluster/internal.h
@@ -124,10 +124,16 @@ void pcmk__corosync_quorum_connect(gboolean (*dispatch)(unsigned long long,
void (*destroy) (gpointer));
crm_node_t *pcmk__search_node_caches(unsigned int id, const char *uname,
uint32_t flags);
-crm_node_t *pcmk__search_cluster_node_cache(unsigned int id, const char *uname);
+crm_node_t *pcmk__search_cluster_node_cache(unsigned int id, const char *uname,
+ const char *uuid);
void pcmk__refresh_node_caches_from_cib(xmlNode *cib);
crm_node_t *pcmk__search_known_node_cache(unsigned int id, const char *uname,
uint32_t flags);
+crm_node_t *pcmk__get_peer(unsigned int id, const char *uname,
+ const char *uuid);
+crm_node_t *pcmk__get_peer_full(unsigned int id, const char *uname,
+ const char *uuid, int flags);
+
#endif
diff --git a/include/crm/common/Makefile.am b/include/crm/common/Makefile.am
index 7d417e4..83a4197 100644
--- a/include/crm/common/Makefile.am
+++ b/include/crm/common/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2004-2022 the Pacemaker project contributors
+# Copyright 2004-2023 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
@@ -11,45 +11,34 @@ MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm/common
-header_HEADERS = acl.h \
- agents.h \
- agents_compat.h \
- cib.h \
- ipc.h \
- ipc_attrd_internal.h \
- ipc_controld.h \
- ipc_pacemakerd.h \
- ipc_schedulerd.h \
- iso8601.h \
- logging.h \
- logging_compat.h \
- mainloop.h \
- mainloop_compat.h \
- nvpair.h \
- output.h \
- results.h \
- results_compat.h \
- util.h \
- util_compat.h \
- xml.h \
- xml_compat.h
+header_HEADERS = acl.h \
+ actions.h \
+ agents.h \
+ agents_compat.h \
+ cib.h \
+ ipc.h \
+ ipc_controld.h \
+ ipc_pacemakerd.h \
+ ipc_schedulerd.h \
+ iso8601.h \
+ logging.h \
+ logging_compat.h \
+ mainloop.h \
+ mainloop_compat.h \
+ nodes.h \
+ nvpair.h \
+ output.h \
+ resources.h \
+ results.h \
+ results_compat.h \
+ roles.h \
+ scheduler.h \
+ scheduler_types.h \
+ tags.h \
+ tickets.h \
+ util.h \
+ util_compat.h \
+ xml.h \
+ xml_compat.h
-noinst_HEADERS = acl_internal.h \
- alerts_internal.h \
- attrd_internal.h \
- cmdline_internal.h \
- health_internal.h \
- internal.h \
- io_internal.h \
- ipc_internal.h \
- iso8601_internal.h \
- lists_internal.h \
- logging_internal.h \
- messages_internal.h \
- options_internal.h \
- output_internal.h \
- remote_internal.h \
- results_internal.h \
- strings_internal.h \
- unittest_internal.h \
- xml_internal.h
+noinst_HEADERS = $(wildcard *internal.h)
diff --git a/include/crm/common/action_relation_internal.h b/include/crm/common/action_relation_internal.h
new file mode 100644
index 0000000..e789131
--- /dev/null
+++ b/include/crm/common/action_relation_internal.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2023 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_ACTION_RELATION_INTERNAL__H
+# define PCMK__CRM_COMMON_ACTION_RELATION_INTERNAL__H
+
+/*!
+ * Flags to indicate the relationship between two actions
+ *
+ * @COMPAT The values and semantics of these flags should not be changed until
+ * the deprecated enum pe_ordering is dropped from the public API.
+ */
+enum pcmk__action_relation_flags {
+ //! No relation (compare with equality rather than bit set)
+ pcmk__ar_none = 0U,
+
+ //! Actions are ordered (optionally, if no other flags are set)
+ pcmk__ar_ordered = (1U << 0),
+
+ //! Relation applies only if 'first' cannot be part of a live migration
+ pcmk__ar_if_first_unmigratable = (1U << 1),
+
+ /*!
+ * If 'then' is required, 'first' becomes required (and becomes unmigratable
+ * if 'then' is); also, if 'first' is a stop of a blocked resource, 'then'
+ * becomes unrunnable
+ */
+ pcmk__ar_then_implies_first = (1U << 4),
+
+ /*!
+ * If 'first' is required, 'then' becomes required; if 'first' is a stop of
+ * a blocked resource, 'then' becomes unrunnable
+ */
+ pcmk__ar_first_implies_then = (1U << 5),
+
+ /*!
+ * If 'then' is required and for a promoted instance, 'first' becomes
+ * required (and becomes unmigratable if 'then' is)
+ */
+ pcmk__ar_promoted_then_implies_first = (1U << 6),
+
+ /*!
+ * 'first' is runnable only if 'then' is both runnable and migratable,
+ * and 'first' becomes required if 'then' is
+ */
+ pcmk__ar_unmigratable_then_blocks = (1U << 7),
+
+ //! 'then' is runnable (and migratable) only if 'first' is runnable
+ pcmk__ar_unrunnable_first_blocks = (1U << 8),
+
+ //! If 'first' is unrunnable, 'then' becomes a real, unmigratable action
+ pcmk__ar_first_else_then = (1U << 9),
+
+ //! If 'first' is required, 'then' action for instance on same node is
+ pcmk__ar_first_implies_same_node_then = (1U << 10),
+
+ /*!
+ * Disable relation if 'first' is unrunnable and for an active resource,
+ * otherwise order actions and make 'then' unrunnable if 'first' is.
+ *
+ * This is used to order a bundle replica's start of its container before a
+ * probe of its remote connection resource, in case the connection uses the
+ * REMOTE_CONTAINER_HACK to replace the connection address with where the
+ * container is running.
+ */
+ pcmk__ar_nested_remote_probe = (1U << 11),
+
+ /*!
+ * If 'first' is for a blocked resource, make 'then' unrunnable.
+ *
+ * If 'then' is required, make 'first' required, make 'first' unmigratable
+ * if 'then' is unmigratable, and make 'then' unrunnable if 'first' is
+ * unrunnable.
+ *
+ * If 'then' is unrunnable and for the same resource as 'first', make
+ * 'first' required if it is runnable, and make 'first' unmigratable if
+ * 'then' is unmigratable.
+ *
+ * This is used for "stop then start primitive" (restarts) and
+ * "stop group member then stop previous member".
+ */
+ pcmk__ar_intermediate_stop = (1U << 12),
+
+ /*!
+ * The actions must be serialized if in the same transition but can be in
+ * either order. (In practice, we always arrange them as 'first' then
+ * 'then', so they end up being essentially the same as optional orderings.)
+ *
+ * @TODO Handle more intelligently -- for example, we could schedule the
+ * action with the fewest inputs first, so we're more likely to execute at
+ * least one if there is a failure during the transition. Or, we could
+ * prefer certain action types over others, or base it on resource priority.
+ */
+ pcmk__ar_serialize = (1U << 14),
+
+ //! Relation applies only if actions are on same node
+ pcmk__ar_if_on_same_node = (1U << 15),
+
+ //! If 'then' is required, 'first' must be added to the transition graph
+ pcmk__ar_then_implies_first_graphed = (1U << 16),
+
+ //! If 'first' is required and runnable, 'then' must be in graph
+ pcmk__ar_first_implies_then_graphed = (1U << 17),
+
+ //! User-configured asymmetric ordering
+ pcmk__ar_asymmetric = (1U << 20),
+
+ //! Actions are ordered if on same node (or migration target for migrate_to)
+ pcmk__ar_if_on_same_node_or_target = (1U << 21),
+
+ //! 'then' action is runnable if certain number of 'first' instances are
+ pcmk__ar_min_runnable = (1U << 22),
+
+ //! Ordering applies only if 'first' is required and on same node as 'then'
+ pcmk__ar_if_required_on_same_node = (1U << 23),
+
+ //! Ordering applies even if 'first' runs on guest node created by 'then'
+ pcmk__ar_guest_allowed = (1U << 24),
+
+ //! If 'then' action becomes required, 'first' becomes optional
+ pcmk__ar_then_cancels_first = (1U << 25),
+};
+
+typedef struct pe_action_wrapper_s pcmk__related_action_t;
+
+#endif // PCMK__CRM_COMMON_ACTION_RELATION_INTERNAL__H
diff --git a/include/crm/common/actions.h b/include/crm/common/actions.h
new file mode 100644
index 0000000..5d2784d
--- /dev/null
+++ b/include/crm/common/actions.h
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2004-2023 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_ACTIONS__H
+#define PCMK__CRM_COMMON_ACTIONS__H
+
+#include <stdbool.h> // bool
+#include <strings.h> // strcasecmp()
+#include <glib.h> // gboolean, guint
+#include <libxml/tree.h> // xmlNode
+
+#include <crm/lrmd_events.h> // lrmd_event_data_t
+
+#include <glib.h> // GList, GHashTable
+#include <libxml/tree.h> // xmlNode
+
+#include <crm/common/nodes.h>
+#include <crm/common/resources.h> // enum rsc_start_requirement, etc.
+#include <crm/common/scheduler_types.h> // pcmk_resource_t, pcmk_node_t
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief APIs related to actions
+ * \ingroup core
+ */
+
+//! Default timeout (in milliseconds) for non-metadata actions
+#define PCMK_DEFAULT_ACTION_TIMEOUT_MS 20000
+
+// @COMPAT We don't need a separate timeout for metadata, much less a longer one
+//! \deprecated Default timeout (in milliseconds) for metadata actions
+#define PCMK_DEFAULT_METADATA_TIMEOUT_MS 30000
+
+// Action names as strings
+#define PCMK_ACTION_CANCEL "cancel"
+#define PCMK_ACTION_CLEAR_FAILCOUNT "clear_failcount"
+#define PCMK_ACTION_CLONE_ONE_OR_MORE "clone-one-or-more"
+#define PCMK_ACTION_DELETE "delete"
+#define PCMK_ACTION_DEMOTE "demote"
+#define PCMK_ACTION_DEMOTED "demoted"
+#define PCMK_ACTION_DO_SHUTDOWN "do_shutdown"
+#define PCMK_ACTION_LIST "list"
+#define PCMK_ACTION_LRM_DELETE "lrm_delete"
+#define PCMK_ACTION_LOAD_STOPPED "load_stopped"
+#define PCMK_ACTION_MAINTENANCE_NODES "maintenance_nodes"
+#define PCMK_ACTION_META_DATA "meta-data"
+#define PCMK_ACTION_MIGRATE_FROM "migrate_from"
+#define PCMK_ACTION_MIGRATE_TO "migrate_to"
+#define PCMK_ACTION_MONITOR "monitor"
+#define PCMK_ACTION_NOTIFIED "notified"
+#define PCMK_ACTION_NOTIFY "notify"
+#define PCMK_ACTION_OFF "off"
+#define PCMK_ACTION_ON "on"
+#define PCMK_ACTION_ONE_OR_MORE "one-or-more"
+#define PCMK_ACTION_PROMOTE "promote"
+#define PCMK_ACTION_PROMOTED "promoted"
+#define PCMK_ACTION_REBOOT "reboot"
+#define PCMK_ACTION_RELOAD "reload"
+#define PCMK_ACTION_RELOAD_AGENT "reload-agent"
+#define PCMK_ACTION_RUNNING "running"
+#define PCMK_ACTION_START "start"
+#define PCMK_ACTION_STATUS "status"
+#define PCMK_ACTION_STONITH "stonith"
+#define PCMK_ACTION_STOP "stop"
+#define PCMK_ACTION_STOPPED "stopped"
+#define PCMK_ACTION_VALIDATE_ALL "validate-all"
+
+//! Possible actions (including some pseudo-actions)
+enum action_tasks {
+ pcmk_action_unspecified = 0, //!< Unspecified or unknown action
+ pcmk_action_monitor, //!< Monitor
+
+ // Each "completed" action must be the regular action plus 1
+
+ pcmk_action_stop, //!< Stop
+ pcmk_action_stopped, //!< Stop completed
+
+ pcmk_action_start, //!< Start
+ pcmk_action_started, //!< Start completed
+
+ pcmk_action_notify, //!< Notify
+ pcmk_action_notified, //!< Notify completed
+
+ pcmk_action_promote, //!< Promote
+ pcmk_action_promoted, //!< Promoted
+
+ pcmk_action_demote, //!< Demote
+ pcmk_action_demoted, //!< Demoted
+
+ pcmk_action_shutdown, //!< Shut down node
+ pcmk_action_fence, //!< Fence node
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_action_unspecified instead
+ no_action = pcmk_action_unspecified,
+
+ //! \deprecated Use pcmk_action_monitor instead
+ monitor_rsc = pcmk_action_monitor,
+
+ //! \deprecated Use pcmk_action_stop instead
+ stop_rsc = pcmk_action_stop,
+
+ //! \deprecated Use pcmk_action_stopped instead
+ stopped_rsc = pcmk_action_stopped,
+
+ //! \deprecated Use pcmk_action_start instead
+ start_rsc = pcmk_action_start,
+
+ //! \deprecated Use pcmk_action_started instead
+ started_rsc = pcmk_action_started,
+
+ //! \deprecated Use pcmk_action_notify instead
+ action_notify = pcmk_action_notify,
+
+ //! \deprecated Use pcmk_action_notified instead
+ action_notified = pcmk_action_notified,
+
+ //! \deprecated Use pcmk_action_promote instead
+ action_promote = pcmk_action_promote,
+
+ //! \deprecated Use pcmk_action_promoted instead
+ action_promoted = pcmk_action_promoted,
+
+ //! \deprecated Use pcmk_action_demote instead
+ action_demote = pcmk_action_demote,
+
+ //! \deprecated Use pcmk_action_demoted instead
+ action_demoted = pcmk_action_demoted,
+
+ //! \deprecated Use pcmk_action_shutdown instead
+ shutdown_crm = pcmk_action_shutdown,
+
+ //! \deprecated Use pcmk_action_fence instead
+ stonith_node = pcmk_action_fence,
+#endif
+};
+
+//! Possible responses to a resource action failure
+enum action_fail_response {
+ /* The order is (partially) significant here; the values from
+ * pcmk_on_fail_ignore through pcmk_on_fail_fence_node are in order of
+ * increasing severity.
+ *
+ * @COMPAT The values should be ordered and numbered per the "TODO" comments
+ * below, so all values are in order of severity and there is room for
+ * future additions, but that would break API compatibility.
+ * @TODO For now, we just use a function to compare the values specially, but
+ * at the next compatibility break, we should arrange things
+ * properly so we can compare with less than and greater than.
+ */
+
+ // @TODO Define as 10
+ pcmk_on_fail_ignore = 0, //!< Act as if failure didn't happen
+
+ // @TODO Define as 30
+ pcmk_on_fail_restart = 1, //!< Restart resource
+
+ // @TODO Define as 60
+ pcmk_on_fail_ban = 2, //!< Ban resource from current node
+
+ // @TODO Define as 70
+ pcmk_on_fail_block = 3, //!< Treat resource as unmanaged
+
+ // @TODO Define as 80
+ pcmk_on_fail_stop = 4, //!< Stop resource and leave stopped
+
+ // @TODO Define as 90
+ pcmk_on_fail_standby_node = 5, //!< Put resource's node in standby
+
+ // @TODO Define as 100
+ pcmk_on_fail_fence_node = 6, //!< Fence resource's node
+
+ // @COMPAT Values below here are out of desired order for API compatibility
+
+ // @TODO Define as 50
+ pcmk_on_fail_restart_container = 7, //!< Restart resource's container
+
+ // @TODO Define as 40
+ /*!
+ * Fence the remote node created by the resource if fencing is enabled,
+ * otherwise attempt to restart the resource (used internally for some
+ * remote connection failures).
+ */
+ pcmk_on_fail_reset_remote = 8,
+
+ // @TODO Define as 20
+ pcmk_on_fail_demote = 9, //!< Demote if promotable, else stop
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_on_fail_ignore instead
+ action_fail_ignore = pcmk_on_fail_ignore,
+
+ //! \deprecated Use pcmk_on_fail_restart instead
+ action_fail_recover = pcmk_on_fail_restart,
+
+ //! \deprecated Use pcmk_on_fail_ban instead
+ action_fail_migrate = pcmk_on_fail_ban,
+
+ //! \deprecated Use pcmk_on_fail_block instead
+ action_fail_block = pcmk_on_fail_block,
+
+ //! \deprecated Use pcmk_on_fail_stop instead
+ action_fail_stop = pcmk_on_fail_stop,
+
+ //! \deprecated Use pcmk_on_fail_standby_node instead
+ action_fail_standby = pcmk_on_fail_standby_node,
+
+ //! \deprecated Use pcmk_on_fail_fence_node instead
+ action_fail_fence = pcmk_on_fail_fence_node,
+
+ //! \deprecated Use pcmk_on_fail_restart_container instead
+ action_fail_restart_container = pcmk_on_fail_restart_container,
+
+ //! \deprecated Use pcmk_on_fail_reset_remote instead
+ action_fail_reset_remote = pcmk_on_fail_reset_remote,
+
+ //! \deprecated Use pcmk_on_fail_demote instead
+ action_fail_demote = pcmk_on_fail_demote,
+#endif
+};
+
+//! Action scheduling flags
+enum pe_action_flags {
+ //! No action flags set (compare with equality rather than bit set)
+ pcmk_no_action_flags = 0,
+
+ //! Whether action does not require invoking an agent
+ pcmk_action_pseudo = (1 << 0),
+
+ //! Whether action is runnable
+ pcmk_action_runnable = (1 << 1),
+
+ //! Whether action should not be executed
+ pcmk_action_optional = (1 << 2),
+
+ //! Whether action should be added to transition graph even if optional
+ pcmk_action_always_in_graph = (1 << 3),
+
+ //! Whether operation-specific instance attributes have been unpacked yet
+ pcmk_action_attrs_evaluated = (1 << 4),
+
+ //! Whether action is allowed to be part of a live migration
+ pcmk_action_migratable = (1 << 7),
+
+ //! Whether action has been added to transition graph
+ pcmk_action_added_to_graph = (1 << 8),
+
+ //! Whether action is a stop to abort a dangling migration
+ pcmk_action_migration_abort = (1 << 11),
+
+ /*!
+ * Whether action is an ordering point for minimum required instances
+ * (used to implement ordering after clones with clone-min configured,
+ * and ordered sets with require-all=false)
+ */
+ pcmk_action_min_runnable = (1 << 12),
+
+ //! Whether action is recurring monitor that must be rescheduled if active
+ pcmk_action_reschedule = (1 << 13),
+
+ //! Whether action has already been processed by a recursive procedure
+ pcmk_action_detect_loop = (1 << 14),
+
+ //! Whether action's inputs have been de-duplicated yet
+ pcmk_action_inputs_deduplicated = (1 << 15),
+
+ //! Whether action can be executed on DC rather than own node
+ pcmk_action_on_dc = (1 << 16),
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_action_pseudo instead
+ pe_action_pseudo = pcmk_action_pseudo,
+
+ //! \deprecated Use pcmk_action_runnable instead
+ pe_action_runnable = pcmk_action_runnable,
+
+ //! \deprecated Use pcmk_action_optional instead
+ pe_action_optional = pcmk_action_optional,
+
+ //! \deprecated Use pcmk_action_always_in_graph instead
+ pe_action_print_always = pcmk_action_always_in_graph,
+
+ //! \deprecated Use pcmk_action_attrs_evaluated instead
+ pe_action_have_node_attrs = pcmk_action_attrs_evaluated,
+
+ //! \deprecated Do not use
+ pe_action_implied_by_stonith = (1 << 6),
+
+ //! \deprecated Use pcmk_action_migratable instead
+ pe_action_migrate_runnable = pcmk_action_migratable,
+
+ //! \deprecated Use pcmk_action_added_to_graph instead
+ pe_action_dumped = pcmk_action_added_to_graph,
+
+ //! \deprecated Do not use
+ pe_action_processed = (1 << 9),
+
+ //! \deprecated Do not use
+ pe_action_clear = (1 << 10),
+
+ //! \deprecated Use pcmk_action_migration_abort instead
+ pe_action_dangle = pcmk_action_migration_abort,
+
+ //! \deprecated Use pcmk_action_min_runnable instead
+ pe_action_requires_any = pcmk_action_min_runnable,
+
+ //! \deprecated Use pcmk_action_reschedule instead
+ pe_action_reschedule = pcmk_action_reschedule,
+
+ //! \deprecated Use pcmk_action_detect_loop instead
+ pe_action_tracking = pcmk_action_detect_loop,
+
+ //! \deprecated Use pcmk_action_inputs_deduplicated instead
+ pe_action_dedup = pcmk_action_inputs_deduplicated,
+
+ //! \deprecated Use pcmk_action_on_dc instead
+ pe_action_dc = pcmk_action_on_dc,
+#endif
+};
+
+/* @COMPAT enum pe_link_state and enum pe_ordering are currently needed for
+ * struct pe_action_wrapper_s (which is public) but should be removed at an
+ * API compatibility break when that can be refactored and made internal
+ */
+
+//!@{
+//! \deprecated Do not use
+enum pe_link_state {
+ pe_link_not_dumped = 0,
+ pe_link_dumped = 1,
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ pe_link_dup = 2,
+#endif
+};
+
+enum pe_ordering {
+ pe_order_none = 0x0,
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ pe_order_optional = 0x1,
+ pe_order_apply_first_non_migratable = 0x2,
+ pe_order_implies_first = 0x10,
+ pe_order_implies_then = 0x20,
+ pe_order_promoted_implies_first = 0x40,
+ pe_order_implies_first_migratable = 0x80,
+ pe_order_runnable_left = 0x100,
+ pe_order_pseudo_left = 0x200,
+ pe_order_implies_then_on_node = 0x400,
+ pe_order_probe = 0x800,
+ pe_order_restart = 0x1000,
+ pe_order_stonith_stop = 0x2000,
+ pe_order_serialize_only = 0x4000,
+ pe_order_same_node = 0x8000,
+ pe_order_implies_first_printed = 0x10000,
+ pe_order_implies_then_printed = 0x20000,
+ pe_order_asymmetrical = 0x100000,
+ pe_order_load = 0x200000,
+ pe_order_one_or_more = 0x400000,
+ pe_order_anti_colocation = 0x800000,
+ pe_order_preserve = 0x1000000,
+ pe_order_then_cancels_first = 0x2000000,
+ pe_order_trace = 0x4000000,
+ pe_order_implies_first_master = pe_order_promoted_implies_first,
+#endif
+};
+
+// Action sequenced relative to another action
+// @COMPAT This should be internal
+struct pe_action_wrapper_s {
+ // @COMPAT This should be uint32_t
+ enum pe_ordering type; // Group of enum pcmk__action_relation_flags
+
+ // @COMPAT This should be a bool
+ enum pe_link_state state; // Whether action has been added to graph yet
+
+ pcmk_action_t *action; // Action to be sequenced
+};
+//!@}
+
+//! Implementation of pcmk_action_t
+struct pe_action_s {
+ int id; //!< Counter to identify action
+
+ /*!
+ * When the controller aborts a transition graph, it sets an abort priority.
+ * If this priority is higher, the action will still be executed anyway.
+ * Pseudo-actions are always allowed, so this is irrelevant for them.
+ */
+ int priority;
+
+ pcmk_resource_t *rsc; //!< Resource to apply action to, if any
+ pcmk_node_t *node; //!< Node to execute action on, if any
+ xmlNode *op_entry; //!< Action XML configuration, if any
+ char *task; //!< Action name
+ char *uuid; //!< Action key
+ char *cancel_task; //!< If task is "cancel", the action being cancelled
+ char *reason; //!< Readable description of why action is needed
+
+ //@ COMPAT Change to uint32_t at a compatibility break
+ enum pe_action_flags flags; //!< Group of enum pe_action_flags
+
+ enum rsc_start_requirement needs; //!< Prerequisite for recovery
+ enum action_fail_response on_fail; //!< Response to failure
+ enum rsc_role_e fail_role; //!< Resource role if action fails
+ GHashTable *meta; //!< Meta-attributes relevant to action
+ GHashTable *extra; //!< Action-specific instance attributes
+
+ /* Current count of runnable instance actions for "first" action in an
+ * ordering dependency with pcmk__ar_min_runnable set.
+ */
+ int runnable_before; //!< For Pacemaker use only
+
+ /*!
+ * Number of instance actions for "first" action in an ordering dependency
+ * with pcmk__ar_min_runnable set that must be runnable before this action
+ * can be runnable.
+ */
+ int required_runnable_before;
+
+ // Actions in a relation with this one (as pcmk__related_action_t *)
+ GList *actions_before; //!< For Pacemaker use only
+ GList *actions_after; //!< For Pacemaker use only
+
+ /* This is intended to hold data that varies by the type of action, but is
+ * not currently used. Some of the above fields could be moved here except
+ * for API backward compatibility.
+ */
+ void *action_details; //!< For Pacemaker use only
+};
+
+// For parsing various action-related string specifications
+gboolean parse_op_key(const char *key, char **rsc_id, char **op_type,
+ guint *interval_ms);
+gboolean decode_transition_key(const char *key, char **uuid, int *transition_id,
+ int *action_id, int *target_rc);
+gboolean decode_transition_magic(const char *magic, char **uuid,
+ int *transition_id, int *action_id,
+ int *op_status, int *op_rc, int *target_rc);
+
+// @COMPAT Either these shouldn't be in libcrmcommon or lrmd_event_data_t should
+int rsc_op_expected_rc(const lrmd_event_data_t *event);
+gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc);
+
+bool crm_op_needs_metadata(const char *rsc_class, const char *op);
+
+xmlNode *crm_create_op_xml(xmlNode *parent, const char *prefix,
+ const char *task, const char *interval_spec,
+ const char *timeout);
+
+bool pcmk_is_probe(const char *task, guint interval);
+bool pcmk_xe_is_probe(const xmlNode *xml_op);
+bool pcmk_xe_mask_probe_failure(const xmlNode *xml_op);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_ACTIONS__H
diff --git a/include/crm/common/actions_internal.h b/include/crm/common/actions_internal.h
new file mode 100644
index 0000000..7e794e6
--- /dev/null
+++ b/include/crm/common/actions_internal.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2004-2023 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_ACTIONS_INTERNAL__H
+#define PCMK__CRM_COMMON_ACTIONS_INTERNAL__H
+
+#include <stdbool.h> // bool
+#include <glib.h> // guint
+#include <libxml/tree.h> // xmlNode
+
+#include <crm/common/actions.h> // PCMK_ACTION_MONITOR
+#include <crm/common/strings_internal.h> // pcmk__str_eq()
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//! printf-style format to create operation key from resource, action, interval
+#define PCMK__OP_FMT "%s_%s_%u"
+
+char *pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms);
+char *pcmk__notify_key(const char *rsc_id, const char *notify_type,
+ const char *op_type);
+char *pcmk__transition_key(int transition_id, int action_id, int target_rc,
+ const char *node);
+void pcmk__filter_op_for_digest(xmlNode *param_set);
+bool pcmk__is_fencing_action(const char *action);
+
+/*!
+ * \internal
+ * \brief Get a human-friendly action name
+ *
+ * \param[in] action_name Actual action name
+ * \param[in] interval_ms Action interval (in milliseconds)
+ *
+ * \return Action name suitable for display
+ */
+static inline const char *
+pcmk__readable_action(const char *action_name, guint interval_ms) {
+ if ((interval_ms == 0)
+ && pcmk__str_eq(action_name, PCMK_ACTION_MONITOR, pcmk__str_none)) {
+ return "probe";
+ }
+ return action_name;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_ACTIONS_INTERNAL__H
diff --git a/include/crm/common/alerts_internal.h b/include/crm/common/alerts_internal.h
index ef64fab..dc67427 100644
--- a/include/crm/common/alerts_internal.h
+++ b/include/crm/common/alerts_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2022 the Pacemaker project contributors
+ * Copyright 2015-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -76,7 +76,6 @@ void pcmk__add_alert_key(GHashTable *table, enum pcmk__alert_keys_e name,
const char *value);
void pcmk__add_alert_key_int(GHashTable *table, enum pcmk__alert_keys_e name,
int value);
-bool pcmk__alert_in_patchset(xmlNode *msg, bool config);
static inline const char *
pcmk__alert_flag2text(enum pcmk__alert_flags flag)
diff --git a/include/crm/common/cib_internal.h b/include/crm/common/cib_internal.h
new file mode 100644
index 0000000..c41c12e
--- /dev/null
+++ b/include/crm/common/cib_internal.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023 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_CIB_INTERNAL__H
+#define PCMK__CRM_COMMON_CIB_INTERNAL__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *pcmk__cib_abs_xpath_for(const char *element);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__COMMON_CIB_INTERNAL__H
diff --git a/include/crm/common/clone_internal.h b/include/crm/common/clone_internal.h
new file mode 100644
index 0000000..494ee74
--- /dev/null
+++ b/include/crm/common/clone_internal.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004-2023 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_CLONE_INTERNAL__H
+# define PCMK__CRM_COMMON_CLONE_INTERNAL__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Clone resource flags (used in variant data)
+enum pcmk__clone_flags {
+ // Whether instances should be started sequentially
+ pcmk__clone_ordered = (1 << 0),
+
+ // Whether promotion scores have been added
+ pcmk__clone_promotion_added = (1 << 1),
+
+ // Whether promotion constraints have been added
+ pcmk__clone_promotion_constrained = (1 << 2),
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_CLONE_INTERNAL__H
diff --git a/include/crm/common/digests_internal.h b/include/crm/common/digests_internal.h
new file mode 100644
index 0000000..7598de2
--- /dev/null
+++ b/include/crm/common/digests_internal.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004-2023 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_DIGESTS_INTERNAL__H
+# define PCMK__CRM_COMMON_DIGESTS_INTERNAL__H
+
+#include <libxml/tree.h> // xmlNode
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Digest comparison results
+enum pcmk__digest_result {
+ pcmk__digest_unknown, // No digest available for comparison
+ pcmk__digest_match, // Digests match
+ pcmk__digest_mismatch, // Any parameter changed (potentially reloadable)
+ pcmk__digest_restart, // Parameters that require a restart changed
+};
+
+bool pcmk__verify_digest(xmlNode *input, const char *expected);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_DIGESTS_INTERNAL__H
diff --git a/include/crm/common/failcounts_internal.h b/include/crm/common/failcounts_internal.h
new file mode 100644
index 0000000..4ad01bf
--- /dev/null
+++ b/include/crm/common/failcounts_internal.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004-2023 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_FAILCOUNTS_INTERNAL__H
+# define PCMK__CRM_COMMON_FAILCOUNTS_INTERNAL__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Options when getting resource fail counts
+enum pcmk__fc_flags {
+ pcmk__fc_default = (1 << 0),
+ pcmk__fc_effective = (1 << 1), // Don't count expired failures
+ pcmk__fc_fillers = (1 << 2), // If container, include filler failures
+};
+
+/*!
+ * \internal
+ * \enum pcmk__rsc_node
+ * \brief Type of resource location lookup to perform
+ */
+enum pcmk__rsc_node {
+ pcmk__rsc_node_assigned = 0, //!< Where resource is assigned
+ pcmk__rsc_node_current = 1, //!< Where resource is running
+
+ // @COMPAT: Use in native_location() at a compatibility break
+ pcmk__rsc_node_pending = 2, //!< Where resource is pending
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_FAILCOUNTS_INTERNAL__H
diff --git a/include/crm/common/group_internal.h b/include/crm/common/group_internal.h
new file mode 100644
index 0000000..9e1424d
--- /dev/null
+++ b/include/crm/common/group_internal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-2023 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_GROUP_INTERNAL__H
+# define PCMK__CRM_COMMON_GROUP_INTERNAL__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Group resource flags (used in variant data)
+enum pcmk__group_flags {
+ pcmk__group_ordered = (1 << 0), // Members start sequentially
+ pcmk__group_colocated = (1 << 1), // Members must be on same node
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_GROUP_INTERNAL__H
diff --git a/include/crm/common/health_internal.h b/include/crm/common/health_internal.h
index 277a4c9..f98529c 100644
--- a/include/crm/common/health_internal.h
+++ b/include/crm/common/health_internal.h
@@ -18,7 +18,7 @@ extern "C" {
* \internal
* \brief Possible node health strategies
*
- * \note It would be nice to use this in pe_working_set_t but that will have to
+ * \note It would be nice to use this in pcmk_scheduler_t but that will have to
* wait for an API backward compatibility break.
*/
enum pcmk__health_strategy {
diff --git a/include/crm/common/internal.h b/include/crm/common/internal.h
index bd98780..3078606 100644
--- a/include/crm/common/internal.h
+++ b/include/crm/common/internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2022 the Pacemaker project contributors
+ * Copyright 2015-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -20,6 +20,8 @@
#include <crm/common/util.h> // crm_strdup_printf()
#include <crm/common/logging.h> // do_crm_log_unlikely(), etc.
#include <crm/common/mainloop.h> // mainloop_io_t, struct ipc_client_callbacks
+#include <crm/common/actions_internal.h>
+#include <crm/common/digests_internal.h>
#include <crm/common/health_internal.h>
#include <crm/common/io_internal.h>
#include <crm/common/iso8601_internal.h>
@@ -50,11 +52,6 @@ int pcmk__substitute_secrets(const char *rsc_id, GHashTable *params);
#endif
-/* internal digest-related utilities (from digest.c) */
-
-bool pcmk__verify_digest(xmlNode *input, const char *expected);
-
-
/* internal main loop utilities (from mainloop.c) */
int pcmk__add_mainloop_ipc(crm_ipc_t *ipc, int priority, void *userdata,
@@ -164,20 +161,6 @@ int pcmk__pidfile_matches(const char *filename, pid_t expected_pid,
int pcmk__lock_pidfile(const char *filename, const char *name);
-/* internal functions related to resource operations (from operations.c) */
-
-// printf-style format to create operation ID from resource, action, interval
-#define PCMK__OP_FMT "%s_%s_%u"
-
-char *pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms);
-char *pcmk__notify_key(const char *rsc_id, const char *notify_type,
- const char *op_type);
-char *pcmk__transition_key(int transition_id, int action_id, int target_rc,
- const char *node);
-void pcmk__filter_op_for_digest(xmlNode *param_set);
-bool pcmk__is_fencing_action(const char *action);
-
-
// bitwise arithmetic utilities
/*!
diff --git a/include/crm/common/ipc.h b/include/crm/common/ipc.h
index 3d4ee10..397c8b1 100644
--- a/include/crm/common/ipc.h
+++ b/include/crm/common/ipc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2022 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -170,8 +170,8 @@ void crm_ipc_close(crm_ipc_t * client);
void crm_ipc_destroy(crm_ipc_t * client);
void pcmk_free_ipc_event(struct iovec *event);
-int crm_ipc_send(crm_ipc_t * client, xmlNode * message, enum crm_ipc_flags flags,
- int32_t ms_timeout, xmlNode ** reply);
+int crm_ipc_send(crm_ipc_t *client, const xmlNode *message,
+ enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply);
int crm_ipc_get_fd(crm_ipc_t * client);
bool crm_ipc_connected(crm_ipc_t * client);
diff --git a/include/crm/common/ipc_internal.h b/include/crm/common/ipc_internal.h
index 5099dda..b391e83 100644
--- a/include/crm/common/ipc_internal.h
+++ b/include/crm/common/ipc_internal.h
@@ -96,6 +96,10 @@ extern "C" {
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
gid_t refgid, pid_t *gotpid);
+int pcmk__connect_generic_ipc(crm_ipc_t *ipc);
+int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd);
+int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type,
+ int attempts);
/*
* Server-related
@@ -112,6 +116,7 @@ struct pcmk__remote_s {
int tcp_socket;
mainloop_io_t *source;
time_t uptime;
+ char *start_state;
/* CIB-only */
char *token;
@@ -245,11 +250,11 @@ int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
#define pcmk__ipc_send_ack(c, req, flags, tag, ver, st) \
pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (ver), (st))
-int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message,
+int pcmk__ipc_prepare_iov(uint32_t request, const xmlNode *message,
uint32_t max_send_size,
struct iovec **result, ssize_t *bytes);
-int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message,
- uint32_t flags);
+int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request,
+ const xmlNode *message, uint32_t flags);
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
uint32_t *id, uint32_t *flags);
diff --git a/include/crm/common/logging.h b/include/crm/common/logging.h
index 2878fba..eea4cec 100644
--- a/include/crm/common/logging.h
+++ b/include/crm/common/logging.h
@@ -11,6 +11,7 @@
# define PCMK__CRM_COMMON_LOGGING__H
# include <stdio.h>
+# include <stdint.h> // uint8_t, uint32_t
# include <glib.h>
# include <qb/qblog.h>
# include <libxml/tree.h>
@@ -120,7 +121,9 @@ unsigned int set_crm_log_level(unsigned int level);
unsigned int get_crm_log_level(void);
-void pcmk_log_xml_impl(uint8_t level, const char *text, const xmlNode *xml);
+void pcmk_log_xml_as(const char *file, const char *function, uint32_t line,
+ uint32_t tags, uint8_t level, const char *text,
+ const xmlNode *xml);
/*
* Throughout the macros below, note the leading, pre-comma, space in the
@@ -270,7 +273,8 @@ pcmk__clip_log_level(int level)
__LINE__, 0); \
} \
if (crm_is_callsite_active(xml_cs, _level, 0)) { \
- pcmk_log_xml_impl(_level, text, xml); \
+ pcmk_log_xml_as(__FILE__, __func__, __LINE__, 0, \
+ _level, text, (xml)); \
} \
break; \
} \
diff --git a/include/crm/common/logging_compat.h b/include/crm/common/logging_compat.h
index cfdb562..b57a802 100644
--- a/include/crm/common/logging_compat.h
+++ b/include/crm/common/logging_compat.h
@@ -10,6 +10,7 @@
#ifndef PCMK__CRM_COMMON_LOGGING_COMPAT__H
# define PCMK__CRM_COMMON_LOGGING_COMPAT__H
+#include <stdint.h> // uint8_t
#include <glib.h>
#include <libxml/tree.h>
@@ -78,6 +79,9 @@ void log_data_element(int log_level, const char *file, const char *function,
int line, const char *prefix, const xmlNode *data,
int depth, int legacy_options);
+//! \deprecated Do not use Pacemaker for general-purpose logging
+void pcmk_log_xml_impl(uint8_t level, const char *text, const xmlNode *xml);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/crm/common/logging_internal.h b/include/crm/common/logging_internal.h
index 479dcab..981ddf3 100644
--- a/include/crm/common/logging_internal.h
+++ b/include/crm/common/logging_internal.h
@@ -19,6 +19,18 @@ extern "C" {
# include <crm/common/logging.h>
# include <crm/common/output_internal.h>
+typedef void (*pcmk__config_error_func) (void *ctx, const char *msg, ...);
+typedef void (*pcmk__config_warning_func) (void *ctx, const char *msg, ...);
+
+extern pcmk__config_error_func pcmk__config_error_handler;
+extern pcmk__config_warning_func pcmk__config_warning_handler;
+
+extern void *pcmk__config_error_context;
+extern void *pcmk__config_warning_context;
+
+void pcmk__set_config_error_handler(pcmk__config_error_func error_handler, void *error_context);
+void pcmk__set_config_warning_handler(pcmk__config_warning_func warning_handler, void *warning_context);
+
/*!
* \internal
* \brief Log a configuration error
@@ -26,9 +38,13 @@ extern "C" {
* \param[in] fmt printf(3)-style format string
* \param[in] ... Arguments for format string
*/
-# define pcmk__config_err(fmt...) do { \
- crm_config_error = TRUE; \
- crm_err(fmt); \
+# define pcmk__config_err(fmt...) do { \
+ crm_config_error = TRUE; \
+ if (pcmk__config_error_handler == NULL) { \
+ crm_err(fmt); \
+ } else { \
+ pcmk__config_error_handler(pcmk__config_error_context, fmt); \
+ } \
} while (0)
/*!
@@ -38,9 +54,13 @@ extern "C" {
* \param[in] fmt printf(3)-style format string
* \param[in] ... Arguments for format string
*/
-# define pcmk__config_warn(fmt...) do { \
- crm_config_warning = TRUE; \
- crm_warn(fmt); \
+# define pcmk__config_warn(fmt...) do { \
+ crm_config_warning = TRUE; \
+ if (pcmk__config_warning_handler == NULL) { \
+ crm_warn(fmt); \
+ } else { \
+ pcmk__config_warning_handler(pcmk__config_warning_context, fmt); \
+ } \
} while (0)
/*!
@@ -74,6 +94,76 @@ extern "C" {
/*!
* \internal
+ * \brief Log XML changes line-by-line in a formatted fashion
+ *
+ * \param[in] level Priority at which to log the messages
+ * \param[in] xml XML to log
+ *
+ * \note This does nothing when \p level is \c LOG_STDOUT.
+ */
+#define pcmk__log_xml_changes(level, xml) do { \
+ uint8_t _level = pcmk__clip_log_level(level); \
+ static struct qb_log_callsite *xml_cs = NULL; \
+ \
+ switch (_level) { \
+ case LOG_STDOUT: \
+ case LOG_NEVER: \
+ break; \
+ default: \
+ if (xml_cs == NULL) { \
+ xml_cs = qb_log_callsite_get(__func__, __FILE__, \
+ "xml-changes", _level, \
+ __LINE__, 0); \
+ } \
+ if (crm_is_callsite_active(xml_cs, _level, 0)) { \
+ pcmk__log_xml_changes_as(__FILE__, __func__, __LINE__, \
+ 0, _level, xml); \
+ } \
+ break; \
+ } \
+ } while(0)
+
+/*!
+ * \internal
+ * \brief Log an XML patchset line-by-line in a formatted fashion
+ *
+ * \param[in] level Priority at which to log the messages
+ * \param[in] patchset XML patchset to log
+ *
+ * \note This does nothing when \p level is \c LOG_STDOUT.
+ */
+#define pcmk__log_xml_patchset(level, patchset) do { \
+ uint8_t _level = pcmk__clip_log_level(level); \
+ static struct qb_log_callsite *xml_cs = NULL; \
+ \
+ switch (_level) { \
+ case LOG_STDOUT: \
+ case LOG_NEVER: \
+ break; \
+ default: \
+ if (xml_cs == NULL) { \
+ xml_cs = qb_log_callsite_get(__func__, __FILE__, \
+ "xml-patchset", _level, \
+ __LINE__, 0); \
+ } \
+ if (crm_is_callsite_active(xml_cs, _level, 0)) { \
+ pcmk__log_xml_patchset_as(__FILE__, __func__, __LINE__, \
+ 0, _level, patchset); \
+ } \
+ break; \
+ } \
+ } while(0)
+
+void pcmk__log_xml_changes_as(const char *file, const char *function,
+ uint32_t line, uint32_t tags, uint8_t level,
+ const xmlNode *xml);
+
+void pcmk__log_xml_patchset_as(const char *file, const char *function,
+ uint32_t line, uint32_t tags, uint8_t level,
+ const xmlNode *patchset);
+
+/*!
+ * \internal
* \brief Initialize logging for command line tools
*
* \param[in] name The name of the program
diff --git a/include/crm/common/nodes.h b/include/crm/common/nodes.h
new file mode 100644
index 0000000..fbc3758
--- /dev/null
+++ b/include/crm/common/nodes.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2004-2023 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_NODES__H
+# define PCMK__CRM_COMMON_NODES__H
+
+#include <glib.h> // gboolean, GList, GHashTable
+
+#include <crm/common/scheduler_types.h> // pcmk_resource_t, pcmk_scheduler_t
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Scheduler API for nodes
+ * \ingroup core
+ */
+
+// Special node attributes
+
+#define PCMK_NODE_ATTR_TERMINATE "terminate"
+
+
+//! Possible node types
+enum node_type {
+ pcmk_node_variant_cluster = 1, //!< Cluster layer node
+ pcmk_node_variant_remote = 2, //!< Pacemaker Remote node
+
+ node_ping = 0, //!< \deprecated Do not use
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_node_variant_cluster instead
+ node_member = pcmk_node_variant_cluster,
+
+ //! \deprecated Use pcmk_node_variant_remote instead
+ node_remote = pcmk_node_variant_remote,
+#endif
+};
+
+//! When to probe a resource on a node (as specified in location constraints)
+enum pe_discover_e {
+ pcmk_probe_always = 0, //! Always probe resource on node
+ pcmk_probe_never = 1, //! Never probe resource on node
+ pcmk_probe_exclusive = 2, //! Probe only on designated nodes
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_probe_always instead
+ pe_discover_always = pcmk_probe_always,
+
+ //! \deprecated Use pcmk_probe_never instead
+ pe_discover_never = pcmk_probe_never,
+
+ //! \deprecated Use pcmk_probe_exclusive instead
+ pe_discover_exclusive = pcmk_probe_exclusive,
+#endif
+};
+
+//! Basic node information (all node objects for the same node share this)
+struct pe_node_shared_s {
+ const char *id; //!< Node ID at the cluster layer
+ const char *uname; //!< Node name in cluster
+ enum node_type type; //!< Node variant
+
+ // @TODO Convert these into a flag group
+ gboolean online; //!< Whether online
+ gboolean standby; //!< Whether in standby mode
+ gboolean standby_onfail; //!< Whether in standby mode due to on-fail
+ gboolean pending; //!< Whether controller membership is pending
+ gboolean unclean; //!< Whether node requires fencing
+ gboolean unseen; //!< Whether node has never joined cluster
+ gboolean shutdown; //!< Whether shutting down
+ gboolean expected_up; //!< Whether expected join state is member
+ gboolean is_dc; //!< Whether node is cluster's DC
+ gboolean maintenance; //!< Whether in maintenance mode
+ gboolean rsc_discovery_enabled; //!< Whether probes are allowed on node
+
+ /*!
+ * Whether this is a guest node whose guest resource must be recovered or a
+ * remote node that must be fenced
+ */
+ gboolean remote_requires_reset;
+
+ /*!
+ * Whether this is a Pacemaker Remote node that was fenced since it was last
+ * connected by the cluster
+ */
+ gboolean remote_was_fenced;
+
+ /*!
+ * Whether this is a Pacemaker Remote node previously marked in its
+ * node state as being in maintenance mode
+ */
+ gboolean remote_maintenance;
+
+ gboolean unpacked; //!< Whether node history has been unpacked
+
+ /*!
+ * Number of resources active on this node (valid after CIB status section
+ * has been unpacked, as long as pcmk_sched_no_counts was not set)
+ */
+ int num_resources;
+
+ //! Remote connection resource for node, if it is a Pacemaker Remote node
+ pcmk_resource_t *remote_rsc;
+
+ GList *running_rsc; //!< List of resources active on node
+ GList *allocated_rsc; //!< List of resources assigned to node
+ GHashTable *attrs; //!< Node attributes
+ GHashTable *utilization; //!< Node utilization attributes
+ GHashTable *digest_cache; //!< Cache of calculated resource digests
+
+ /*!
+ * Sum of priorities of all resources active on node and on any guest nodes
+ * connected to this node, with +1 for promoted instances (used to compare
+ * nodes for priority-fencing-delay)
+ */
+ int priority;
+
+ pcmk_scheduler_t *data_set; //!< Cluster that node is part of
+};
+
+//! Implementation of pcmk_node_t
+struct pe_node_s {
+ int weight; //!< Node score for a given resource
+ gboolean fixed; //!< \deprecated Do not use
+ int count; //!< Counter reused by assignment and promotion code
+ struct pe_node_shared_s *details; //!< Basic node information
+
+ // @COMPAT This should be enum pe_discover_e
+ int rsc_discover_mode; //!< Probe mode (enum pe_discover_e)
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_NODES__H
diff --git a/include/crm/common/nvpair.h b/include/crm/common/nvpair.h
index aebc199..185bdc3 100644
--- a/include/crm/common/nvpair.h
+++ b/include/crm/common/nvpair.h
@@ -46,7 +46,6 @@ void hash2smartfield(gpointer key, gpointer value, gpointer user_data);
GHashTable *xml2list(const xmlNode *parent);
const char *crm_xml_add(xmlNode *node, const char *name, const char *value);
-const char *crm_xml_replace(xmlNode *node, const char *name, const char *value);
const char *crm_xml_add_int(xmlNode *node, const char *name, int value);
const char *crm_xml_add_ll(xmlNode *node, const char *name, long long value);
const char *crm_xml_add_ms(xmlNode *node, const char *name, guint ms);
diff --git a/include/crm/common/options_internal.h b/include/crm/common/options_internal.h
index 4157b58..5c561fd 100644
--- a/include/crm/common/options_internal.h
+++ b/include/crm/common/options_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2022 the Pacemaker project contributors
+ * Copyright 2006-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -26,7 +26,7 @@ _Noreturn void pcmk__cli_help(char cmd);
*/
const char *pcmk__env_option(const char *option);
-void pcmk__set_env_option(const char *option, const char *value);
+void pcmk__set_env_option(const char *option, const char *value, bool compat);
bool pcmk__env_option_enabled(const char *daemon, const char *option);
@@ -76,18 +76,52 @@ long pcmk__auto_watchdog_timeout(void);
bool pcmk__valid_sbd_timeout(const char *value);
// Constants for environment variable names
+#define PCMK__ENV_AUTHKEY_LOCATION "authkey_location"
#define PCMK__ENV_BLACKBOX "blackbox"
+#define PCMK__ENV_CALLGRIND_ENABLED "callgrind_enabled"
#define PCMK__ENV_CLUSTER_TYPE "cluster_type"
#define PCMK__ENV_DEBUG "debug"
+#define PCMK__ENV_DH_MAX_BITS "dh_max_bits"
+#define PCMK__ENV_DH_MIN_BITS "dh_min_bits"
+#define PCMK__ENV_FAIL_FAST "fail_fast"
+#define PCMK__ENV_IPC_BUFFER "ipc_buffer"
+#define PCMK__ENV_IPC_TYPE "ipc_type"
#define PCMK__ENV_LOGFACILITY "logfacility"
#define PCMK__ENV_LOGFILE "logfile"
+#define PCMK__ENV_LOGFILE_MODE "logfile_mode"
#define PCMK__ENV_LOGPRIORITY "logpriority"
-#define PCMK__ENV_MCP "mcp"
+#define PCMK__ENV_NODE_ACTION_LIMIT "node_action_limit"
#define PCMK__ENV_NODE_START_STATE "node_start_state"
+#define PCMK__ENV_PANIC_ACTION "panic_action"
#define PCMK__ENV_PHYSICAL_HOST "physical_host"
+#define PCMK__ENV_REMOTE_ADDRESS "remote_address"
+#define PCMK__ENV_REMOTE_PID1 "remote_pid1"
+#define PCMK__ENV_REMOTE_PORT "remote_port"
+#define PCMK__ENV_RESPAWNED "respawned"
+#define PCMK__ENV_SCHEMA_DIRECTORY "schema_directory"
+#define PCMK__ENV_SERVICE "service"
+#define PCMK__ENV_STDERR "stderr"
+#define PCMK__ENV_TLS_PRIORITIES "tls_priorities"
+#define PCMK__ENV_TRACE_BLACKBOX "trace_blackbox"
+#define PCMK__ENV_TRACE_FILES "trace_files"
+#define PCMK__ENV_TRACE_FORMATS "trace_formats"
+#define PCMK__ENV_TRACE_FUNCTIONS "trace_functions"
+#define PCMK__ENV_TRACE_TAGS "trace_tags"
+#define PCMK__ENV_VALGRIND_ENABLED "valgrind_enabled"
+
+// @COMPAT Drop at 3.0.0; default is plenty
+#define PCMK__ENV_CIB_TIMEOUT "cib_timeout"
+
+// @COMPAT Drop at 3.0.0; likely last used in 1.1.24
+#define PCMK__ENV_MCP "mcp"
+
+// @COMPAT Drop at 3.0.0; added unused in 1.1.9
#define PCMK__ENV_QUORUM_TYPE "quorum_type"
+
+/* @COMPAT Drop at 3.0.0; added to debug shutdown issues when Pacemaker is
+ * managed by systemd, but no longer useful.
+ */
#define PCMK__ENV_SHUTDOWN_DELAY "shutdown_delay"
-#define PCMK__ENV_STDERR "stderr"
// Constants for cluster option names
#define PCMK__OPT_NODE_HEALTH_BASE "node-health-base"
diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h
index e7b631e..274bd85 100644
--- a/include/crm/common/output_internal.h
+++ b/include/crm/common/output_internal.h
@@ -763,6 +763,11 @@ pcmk__output_get_log_level(const pcmk__output_t *out);
void
pcmk__output_set_log_level(pcmk__output_t *out, uint8_t log_level);
+void pcmk__output_set_log_filter(pcmk__output_t *out, const char *file,
+ const char *function, uint32_t line,
+ uint32_t tags);
+
+
/*!
* \internal
* \brief Create and return a new XML node with the given name, as a child of the
diff --git a/include/crm/common/remote_internal.h b/include/crm/common/remote_internal.h
index 8473668..030c7a4 100644
--- a/include/crm/common/remote_internal.h
+++ b/include/crm/common/remote_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2022 the Pacemaker project contributors
+ * Copyright 2008-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -14,7 +14,7 @@
typedef struct pcmk__remote_s pcmk__remote_t;
-int pcmk__remote_send_xml(pcmk__remote_t *remote, xmlNode *msg);
+int pcmk__remote_send_xml(pcmk__remote_t *remote, const xmlNode *msg);
int pcmk__remote_ready(const pcmk__remote_t *remote, int timeout_ms);
int pcmk__read_remote_message(pcmk__remote_t *remote, int timeout_ms);
xmlNode *pcmk__remote_message_xml(pcmk__remote_t *remote);
diff --git a/include/crm/common/resources.h b/include/crm/common/resources.h
new file mode 100644
index 0000000..043dc1c
--- /dev/null
+++ b/include/crm/common/resources.h
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2004-2023 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_RESOURCES__H
+# define PCMK__CRM_COMMON_RESOURCES__H
+
+#include <sys/types.h> // time_t
+#include <libxml/tree.h> // xmlNode
+#include <glib.h> // gboolean, guint, GList, GHashTable
+
+#include <crm/common/roles.h> // enum rsc_role_e
+#include <crm/common/scheduler_types.h> // pcmk_resource_t, etc.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Scheduler API for resources
+ * \ingroup core
+ */
+
+//! Resource variants supported by Pacemaker
+enum pe_obj_types {
+ // Order matters: some code compares greater or lesser than
+ pcmk_rsc_variant_unknown = -1, //!< Unknown resource variant
+ pcmk_rsc_variant_primitive = 0, //!< Primitive resource
+ pcmk_rsc_variant_group = 1, //!< Group resource
+ pcmk_rsc_variant_clone = 2, //!< Clone resource
+ pcmk_rsc_variant_bundle = 3, //!< Bundle resource
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_rsc_variant_unknown instead
+ pe_unknown = pcmk_rsc_variant_unknown,
+
+ //! \deprecated Use pcmk_rsc_variant_primitive instead
+ pe_native = pcmk_rsc_variant_primitive,
+
+ //! \deprecated Use pcmk_rsc_variant_group instead
+ pe_group = pcmk_rsc_variant_group,
+
+ //! \deprecated Use pcmk_rsc_variant_clone instead
+ pe_clone = pcmk_rsc_variant_clone,
+
+ //! \deprecated Use pcmk_rsc_variant_bundle instead
+ pe_container = pcmk_rsc_variant_bundle,
+#endif
+};
+
+//! What resource needs before it can be recovered from a failed node
+enum rsc_start_requirement {
+ pcmk_requires_nothing = 0, //!< Resource can be recovered immediately
+ pcmk_requires_quorum = 1, //!< Resource can be recovered if quorate
+ pcmk_requires_fencing = 2, //!< Resource can be recovered after fencing
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_requires_nothing instead
+ rsc_req_nothing = pcmk_requires_nothing,
+
+ //! \deprecated Use pcmk_requires_quorum instead
+ rsc_req_quorum = pcmk_requires_quorum,
+
+ //! \deprecated Use pcmk_requires_fencing instead
+ rsc_req_stonith = pcmk_requires_fencing,
+#endif
+};
+
+//! How to recover a resource that is incorrectly active on multiple nodes
+enum rsc_recovery_type {
+ pcmk_multiply_active_restart = 0, //!< Stop on all, start on desired
+ pcmk_multiply_active_stop = 1, //!< Stop on all and leave stopped
+ pcmk_multiply_active_block = 2, //!< Do nothing to resource
+ pcmk_multiply_active_unexpected = 3, //!< Stop unexpected instances
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_multiply_active_restart instead
+ recovery_stop_start = pcmk_multiply_active_restart,
+
+ //! \deprecated Use pcmk_multiply_active_stop instead
+ recovery_stop_only = pcmk_multiply_active_stop,
+
+ //! \deprecated Use pcmk_multiply_active_block instead
+ recovery_block = pcmk_multiply_active_block,
+
+ //! \deprecated Use pcmk_multiply_active_unexpected instead
+ recovery_stop_unexpected = pcmk_multiply_active_unexpected,
+#endif
+};
+
+//! Resource scheduling flags
+enum pcmk_rsc_flags {
+ //! No resource flags set (compare with equality rather than bit set)
+ pcmk_no_rsc_flags = 0ULL,
+
+ //! Whether resource has been removed from the configuration
+ pcmk_rsc_removed = (1ULL << 0),
+
+ //! Whether resource is managed
+ pcmk_rsc_managed = (1ULL << 1),
+
+ //! Whether resource is blocked from further action
+ pcmk_rsc_blocked = (1ULL << 2),
+
+ //! Whether resource has been removed but has a container
+ pcmk_rsc_removed_filler = (1ULL << 3),
+
+ //! Whether resource has clone notifications enabled
+ pcmk_rsc_notify = (1ULL << 4),
+
+ //! Whether resource is not an anonymous clone instance
+ pcmk_rsc_unique = (1ULL << 5),
+
+ //! Whether resource's class is "stonith"
+ pcmk_rsc_fence_device = (1ULL << 6),
+
+ //! Whether resource can be promoted and demoted
+ pcmk_rsc_promotable = (1ULL << 7),
+
+ //! Whether resource has not yet been assigned to a node
+ pcmk_rsc_unassigned = (1ULL << 8),
+
+ //! Whether resource is in the process of being assigned to a node
+ pcmk_rsc_assigning = (1ULL << 9),
+
+ //! Whether resource is in the process of modifying allowed node scores
+ pcmk_rsc_updating_nodes = (1ULL << 10),
+
+ //! Whether resource is in the process of scheduling actions to restart
+ pcmk_rsc_restarting = (1ULL << 11),
+
+ //! Whether resource must be stopped (instead of demoted) if it is failed
+ pcmk_rsc_stop_if_failed = (1ULL << 12),
+
+ //! Whether a reload action has been scheduled for resource
+ pcmk_rsc_reload = (1ULL << 13),
+
+ //! Whether resource is a remote connection allowed to run on a remote node
+ pcmk_rsc_remote_nesting_allowed = (1ULL << 14),
+
+ //! Whether resource has "critical" meta-attribute enabled
+ pcmk_rsc_critical = (1ULL << 15),
+
+ //! Whether resource is considered failed
+ pcmk_rsc_failed = (1ULL << 16),
+
+ //! Flag for non-scheduler code to use to detect recursion loops
+ pcmk_rsc_detect_loop = (1ULL << 17),
+
+ //! \deprecated Do not use
+ pcmk_rsc_runnable = (1ULL << 18),
+
+ //! Whether resource has pending start action in history
+ pcmk_rsc_start_pending = (1ULL << 19),
+
+ //! \deprecated Do not use
+ pcmk_rsc_starting = (1ULL << 20),
+
+ //! \deprecated Do not use
+ pcmk_rsc_stopping = (1ULL << 21),
+
+ //! Whether resource is multiply active with recovery set to stop_unexpected
+ pcmk_rsc_stop_unexpected = (1ULL << 22),
+
+ //! Whether resource is allowed to live-migrate
+ pcmk_rsc_migratable = (1ULL << 23),
+
+ //! Whether resource has an ignorable failure
+ pcmk_rsc_ignore_failure = (1ULL << 24),
+
+ //! Whether resource is an implicit container resource for a bundle replica
+ pcmk_rsc_replica_container = (1ULL << 25),
+
+ //! Whether resource, its node, or entire cluster is in maintenance mode
+ pcmk_rsc_maintenance = (1ULL << 26),
+
+ //! \deprecated Do not use
+ pcmk_rsc_has_filler = (1ULL << 27),
+
+ //! Whether resource can be started or promoted only on quorate nodes
+ pcmk_rsc_needs_quorum = (1ULL << 28),
+
+ //! Whether resource requires fencing before recovery if on unclean node
+ pcmk_rsc_needs_fencing = (1ULL << 29),
+
+ //! Whether resource can be started or promoted only on unfenced nodes
+ pcmk_rsc_needs_unfencing = (1ULL << 30),
+};
+
+//! Search options for resources (exact resource ID always matches)
+enum pe_find {
+ //! Also match clone instance ID from resource history
+ pcmk_rsc_match_history = (1 << 0),
+
+ //! Also match anonymous clone instances by base name
+ pcmk_rsc_match_anon_basename = (1 << 1),
+
+ //! Match only clones and their instances, by either clone or instance ID
+ pcmk_rsc_match_clone_only = (1 << 2),
+
+ //! If matching by node, compare current node instead of assigned node
+ pcmk_rsc_match_current_node = (1 << 3),
+
+ //! \deprecated Do not use
+ pe_find_inactive = (1 << 4),
+
+ //! Match clone instances (even unique) by base name as well as exact ID
+ pcmk_rsc_match_basename = (1 << 5),
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_rsc_match_history instead
+ pe_find_renamed = pcmk_rsc_match_history,
+
+ //! \deprecated Use pcmk_rsc_match_anon_basename instead
+ pe_find_anon = pcmk_rsc_match_anon_basename,
+
+ //! \deprecated Use pcmk_rsc_match_clone_only instead
+ pe_find_clone = pcmk_rsc_match_clone_only,
+
+ //! \deprecated Use pcmk_rsc_match_current_node instead
+ pe_find_current = pcmk_rsc_match_current_node,
+
+ //! \deprecated Use pcmk_rsc_match_basename instead
+ pe_find_any = pcmk_rsc_match_basename,
+#endif
+};
+
+//!@{
+//! \deprecated Do not use
+enum pe_restart {
+ pe_restart_restart,
+ pe_restart_ignore,
+};
+
+enum pe_print_options {
+ pe_print_log = (1 << 0),
+ pe_print_html = (1 << 1),
+ pe_print_ncurses = (1 << 2),
+ pe_print_printf = (1 << 3),
+ pe_print_dev = (1 << 4), // Ignored
+ pe_print_details = (1 << 5), // Ignored
+ pe_print_max_details = (1 << 6), // Ignored
+ pe_print_rsconly = (1 << 7),
+ pe_print_ops = (1 << 8),
+ pe_print_suppres_nl = (1 << 9),
+ pe_print_xml = (1 << 10),
+ pe_print_brief = (1 << 11),
+ pe_print_pending = (1 << 12),
+ pe_print_clone_details = (1 << 13),
+ pe_print_clone_active = (1 << 14), // Print clone instances only if active
+ pe_print_implicit = (1 << 15) // Print implicitly created resources
+};
+//!@}
+
+// Resource assignment methods (implementation defined by libpacemaker)
+//! This type should be considered internal to Pacemaker
+typedef struct resource_alloc_functions_s pcmk_assignment_methods_t;
+
+//! Resource object methods
+typedef struct resource_object_functions_s {
+ /*!
+ * \brief Parse variant-specific resource XML from CIB into struct members
+ *
+ * \param[in,out] rsc Partially unpacked resource
+ * \param[in,out] scheduler Scheduler data
+ *
+ * \return TRUE if resource was unpacked successfully, otherwise FALSE
+ */
+ gboolean (*unpack)(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler);
+
+ /*!
+ * \brief Search for a resource ID in a resource and its children
+ *
+ * \param[in] rsc Search this resource and its children
+ * \param[in] id Search for this resource ID
+ * \param[in] on_node If not NULL, limit search to resources on this node
+ * \param[in] flags Group of enum pe_find flags
+ *
+ * \return Resource that matches search criteria if any, otherwise NULL
+ */
+ pcmk_resource_t *(*find_rsc)(pcmk_resource_t *rsc, const char *search,
+ const pcmk_node_t *node, int flags);
+
+ /*!
+ * \brief Get value of a resource instance attribute
+ *
+ * \param[in,out] rsc Resource to check
+ * \param[in] node Node to use to evaluate rules
+ * \param[in] create Ignored
+ * \param[in] name Name of instance attribute to check
+ * \param[in,out] scheduler Scheduler data
+ *
+ * \return Value of requested attribute if available, otherwise NULL
+ * \note The caller is responsible for freeing the result using free().
+ */
+ char *(*parameter)(pcmk_resource_t *rsc, pcmk_node_t *node, gboolean create,
+ const char *name, pcmk_scheduler_t *scheduler);
+
+ //! \deprecated Do not use
+ void (*print)(pcmk_resource_t *rsc, const char *pre_text, long options,
+ void *print_data);
+
+ /*!
+ * \brief Check whether a resource is active
+ *
+ * \param[in] rsc Resource to check
+ * \param[in] all If \p rsc is collective, all instances must be active
+ *
+ * \return TRUE if \p rsc is active, otherwise FALSE
+ */
+ gboolean (*active)(pcmk_resource_t *rsc, gboolean all);
+
+ /*!
+ * \brief Get resource's current or assigned role
+ *
+ * \param[in] rsc Resource to check
+ * \param[in] current If TRUE, check current role, otherwise assigned role
+ *
+ * \return Current or assigned role of \p rsc
+ */
+ enum rsc_role_e (*state)(const pcmk_resource_t *rsc, gboolean current);
+
+ /*!
+ * \brief List nodes where a resource (or any of its children) is
+ *
+ * \param[in] rsc Resource to check
+ * \param[out] list List to add result to
+ * \param[in] current If 0, list nodes where \p rsc is assigned;
+ * if 1, where active; if 2, where active or pending
+ *
+ * \return If list contains only one node, that node, otherwise NULL
+ */
+ pcmk_node_t *(*location)(const pcmk_resource_t *rsc, GList **list,
+ int current);
+
+ /*!
+ * \brief Free all memory used by a resource
+ *
+ * \param[in,out] rsc Resource to free
+ */
+ void (*free)(pcmk_resource_t *rsc);
+
+ /*!
+ * \brief Increment cluster's instance counts for a resource
+ *
+ * Given a resource, increment its cluster's ninstances, disabled_resources,
+ * and blocked_resources counts for the resource and its descendants.
+ *
+ * \param[in,out] rsc Resource to count
+ */
+ void (*count)(pcmk_resource_t *rsc);
+
+ /*!
+ * \brief Check whether a given resource is in a list of resources
+ *
+ * \param[in] rsc Resource ID to check for
+ * \param[in] only_rsc List of resource IDs to check
+ * \param[in] check_parent If TRUE, check top ancestor as well
+ *
+ * \return TRUE if \p rsc, its top parent if requested, or '*' is in
+ * \p only_rsc, otherwise FALSE
+ */
+ gboolean (*is_filtered)(const pcmk_resource_t *rsc, GList *only_rsc,
+ gboolean check_parent);
+
+ /*!
+ * \brief Find a node (and optionally count all) where resource is active
+ *
+ * \param[in] rsc Resource to check
+ * \param[out] count_all If not NULL, set this to count of active nodes
+ * \param[out] count_clean If not NULL, set this to count of clean nodes
+ *
+ * \return A node where the resource is active, preferring the source node
+ * if the resource is involved in a partial migration, or a clean,
+ * online node if the resource's "requires" is "quorum" or
+ * "nothing", otherwise NULL.
+ */
+ pcmk_node_t *(*active_node)(const pcmk_resource_t *rsc,
+ unsigned int *count_all,
+ unsigned int *count_clean);
+
+ /*!
+ * \brief Get maximum resource instances per node
+ *
+ * \param[in] rsc Resource to check
+ *
+ * \return Maximum number of \p rsc instances that can be active on one node
+ */
+ unsigned int (*max_per_node)(const pcmk_resource_t *rsc);
+} pcmk_rsc_methods_t;
+
+//! Implementation of pcmk_resource_t
+struct pe_resource_s {
+ char *id; //!< Resource ID in configuration
+ char *clone_name; //!< Resource instance ID in history
+
+ //! Resource configuration (possibly expanded from template)
+ xmlNode *xml;
+
+ //! Original resource configuration, if using template
+ xmlNode *orig_xml;
+
+ //! Configuration of resource operations (possibly expanded from template)
+ xmlNode *ops_xml;
+
+ pcmk_scheduler_t *cluster; //!< Cluster that resource is part of
+ pcmk_resource_t *parent; //!< Resource's parent resource, if any
+ enum pe_obj_types variant; //!< Resource variant
+ void *variant_opaque; //!< Variant-specific (and private) data
+ pcmk_rsc_methods_t *fns; //!< Resource object methods
+ pcmk_assignment_methods_t *cmds; //!< Resource assignment methods
+
+ enum rsc_recovery_type recovery_type; //!< How to recover if failed
+
+ enum pe_restart restart_type; //!< \deprecated Do not use
+ int priority; //!< Configured priority
+ int stickiness; //!< Extra preference for current node
+ int sort_index; //!< Promotion score on assigned node
+ int failure_timeout; //!< Failure timeout
+ int migration_threshold; //!< Migration threshold
+ guint remote_reconnect_ms; //!< Retry interval for remote connections
+ char *pending_task; //!< Pending action in history, if any
+ unsigned long long flags; //!< Group of enum pcmk_rsc_flags
+
+ // @TODO Merge these into flags
+ gboolean is_remote_node; //!< Whether this is a remote connection
+ gboolean exclusive_discover; //!< Whether exclusive probing is enabled
+
+ /* Pay special attention to whether you want to use rsc_cons_lhs and
+ * rsc_cons directly, which include only colocations explicitly involving
+ * this resource, or call libpacemaker's pcmk__with_this_colocations() and
+ * pcmk__this_with_colocations() functions, which may return relevant
+ * colocations involving the resource's ancestors as well.
+ */
+
+ //!@{
+ //! This field should be treated as internal to Pacemaker
+ GList *rsc_cons_lhs; // Colocations of other resources with this one
+ GList *rsc_cons; // Colocations of this resource with others
+ GList *rsc_location; // Location constraints for resource
+ GList *actions; // Actions scheduled for resource
+ GList *rsc_tickets; // Ticket constraints for resource
+ //!@}
+
+ pcmk_node_t *allocated_to; //!< Node resource is assigned to
+
+ //! The destination node, if migrate_to completed but migrate_from has not
+ pcmk_node_t *partial_migration_target;
+
+ //! The source node, if migrate_to completed but migrate_from has not
+ pcmk_node_t *partial_migration_source;
+
+ //! Nodes where resource may be active
+ GList *running_on;
+
+ //! Nodes where resource has been probed (key is node ID, not name)
+ GHashTable *known_on;
+
+ //! Nodes where resource may run (key is node ID, not name)
+ GHashTable *allowed_nodes;
+
+ enum rsc_role_e role; //!< Resource's current role
+ enum rsc_role_e next_role; //!< Resource's scheduled next role
+
+ GHashTable *meta; //!< Resource's meta-attributes
+ GHashTable *parameters; //!< \deprecated Use pe_rsc_params() instead
+ GHashTable *utilization; //!< Resource's utilization attributes
+
+ GList *children; //!< Resource's child resources, if any
+
+ // Source nodes where stop is needed after migrate_from and migrate_to
+ GList *dangling_migrations;
+
+ pcmk_resource_t *container; //!< Resource containing this one, if any
+ GList *fillers; //!< Resources contained by this one, if any
+
+ // @COMPAT These should be made const at next API compatibility break
+ pcmk_node_t *pending_node; //!< Node on which pending_task is happening
+ pcmk_node_t *lock_node; //!< Resource shutdown-locked to this node
+
+ time_t lock_time; //!< When shutdown lock started
+
+ /*!
+ * Resource parameters may have node-attribute-based rules, which means the
+ * values can vary by node. This table has node names as keys and parameter
+ * name/value tables as values. Use pe_rsc_params() to get the table for a
+ * given node rather than use this directly.
+ */
+ GHashTable *parameter_cache;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_RESOURCES__H
diff --git a/include/crm/common/results.h b/include/crm/common/results.h
index 224bcbe..87d00d2 100644
--- a/include/crm/common/results.h
+++ b/include/crm/common/results.h
@@ -108,6 +108,9 @@ enum pcmk_rc_e {
/* When adding new values, use consecutively lower numbers, update the array
* in lib/common/results.c, and test with crm_error.
*/
+ pcmk_rc_compression = -1039,
+ pcmk_rc_ns_resolution = -1038,
+ pcmk_rc_no_transaction = -1037,
pcmk_rc_bad_xml_patch = -1036,
pcmk_rc_bad_input = -1035,
pcmk_rc_disabled = -1034,
@@ -360,7 +363,6 @@ int pcmk_rc2legacy(int rc);
int pcmk_legacy2rc(int legacy_rc);
const char *pcmk_strerror(int rc);
const char *pcmk_errorname(int rc);
-const char *bz2_strerror(int rc);
const char *crm_exit_name(crm_exit_t exit_code);
const char *crm_exit_str(crm_exit_t exit_code);
_Noreturn crm_exit_t crm_exit(crm_exit_t rc);
diff --git a/include/crm/common/results_compat.h b/include/crm/common/results_compat.h
index 00ac6b2..278e48e 100644
--- a/include/crm/common/results_compat.h
+++ b/include/crm/common/results_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 the Pacemaker project contributors
+ * Copyright 2022-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -25,6 +25,9 @@ extern "C" {
* release.
*/
+//! \deprecated Do not use
+const char *bz2_strerror(int rc);
+
//! \deprecated Use pcmk_rc2exitc(pcmk_legacy2rc(rc)) instead
crm_exit_t crm_errno2exit(int rc);
diff --git a/include/crm/common/results_internal.h b/include/crm/common/results_internal.h
index be62780..09907e9 100644
--- a/include/crm/common/results_internal.h
+++ b/include/crm/common/results_internal.h
@@ -69,6 +69,9 @@ void pcmk__reset_result(pcmk__action_result_t *result);
void pcmk__copy_result(const pcmk__action_result_t *src,
pcmk__action_result_t *dst);
+int pcmk__gaierror2rc(int gai);
+int pcmk__bzlib2rc(int bz2);
+
/*!
* \internal
* \brief Check whether a result is OK
diff --git a/include/crm/common/roles.h b/include/crm/common/roles.h
new file mode 100644
index 0000000..1498097
--- /dev/null
+++ b/include/crm/common/roles.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2004-2023 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_ROLES__H
+# define PCMK__CRM_COMMON_ROLES__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Scheduler API for resource roles
+ * \ingroup core
+ */
+
+/*!
+ * Possible roles that a resource can be in
+ * (order matters; values can be compared with less than and greater than)
+ */
+enum rsc_role_e {
+ pcmk_role_unknown = 0, //!< Resource role is unknown
+ pcmk_role_stopped = 1, //!< Stopped
+ pcmk_role_started = 2, //!< Started
+ pcmk_role_unpromoted = 3, //!< Unpromoted
+ pcmk_role_promoted = 4, //!< Promoted
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_role_unknown instead
+ RSC_ROLE_UNKNOWN = pcmk_role_unknown,
+
+ //! \deprecated Use pcmk_role_stopped instead
+ RSC_ROLE_STOPPED = pcmk_role_stopped,
+
+ //! \deprecated Use pcmk_role_started instead
+ RSC_ROLE_STARTED = pcmk_role_started,
+
+ //! \deprecated Use pcmk_role_unpromoted instead
+ RSC_ROLE_UNPROMOTED = pcmk_role_unpromoted,
+
+ //! \deprecated Use pcmk_role_unpromoted instead
+ RSC_ROLE_SLAVE = pcmk_role_unpromoted,
+
+ //! \deprecated Use pcmk_role_promoted instead
+ RSC_ROLE_PROMOTED = pcmk_role_promoted,
+
+ //! \deprecated Use pcmk_role_promoted instead
+ RSC_ROLE_MASTER = pcmk_role_promoted,
+#endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_ROLES__H
diff --git a/include/crm/common/roles_internal.h b/include/crm/common/roles_internal.h
new file mode 100644
index 0000000..e304f13
--- /dev/null
+++ b/include/crm/common/roles_internal.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004-2023 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_ROLES_INTERNAL__H
+# define PCMK__CRM_COMMON_ROLES_INTERNAL__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// String equivalents of enum rsc_role_e
+#define PCMK__ROLE_UNKNOWN "Unknown"
+#define PCMK__ROLE_STOPPED "Stopped"
+#define PCMK__ROLE_STARTED "Started"
+#define PCMK__ROLE_UNPROMOTED "Unpromoted"
+#define PCMK__ROLE_PROMOTED "Promoted"
+#define PCMK__ROLE_UNPROMOTED_LEGACY "Slave"
+#define PCMK__ROLE_PROMOTED_LEGACY "Master"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_ROLES_INTERNAL__H
diff --git a/include/crm/common/scheduler.h b/include/crm/common/scheduler.h
new file mode 100644
index 0000000..96f9a62
--- /dev/null
+++ b/include/crm/common/scheduler.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2004-2023 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_SCHEDULER__H
+# define PCMK__CRM_COMMON_SCHEDULER__H
+
+#include <sys/types.h> // time_t
+#include <libxml/tree.h> // xmlNode
+#include <glib.h> // guint, GList, GHashTable
+
+#include <crm/common/iso8601.h> // crm_time_t
+
+#include <crm/common/actions.h>
+#include <crm/common/nodes.h>
+#include <crm/common/resources.h>
+#include <crm/common/roles.h>
+#include <crm/common/scheduler_types.h>
+#include <crm/common/tags.h>
+#include <crm/common/tickets.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Scheduler API
+ * \ingroup core
+ */
+
+//! Possible responses to loss of quorum
+enum pe_quorum_policy {
+ pcmk_no_quorum_freeze, //<! Do not recover resources from outside partition
+ pcmk_no_quorum_stop, //<! Stop all resources in partition
+ pcmk_no_quorum_ignore, //<! Act as if partition still holds quorum
+ pcmk_no_quorum_fence, //<! Fence all nodes in partition
+ pcmk_no_quorum_demote, //<! Demote promotable resources and stop all others
+
+#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
+ //! \deprecated Use pcmk_no_quorum_freeze instead
+ no_quorum_freeze = pcmk_no_quorum_freeze,
+
+ //! \deprecated Use pcmk_no_quorum_stop instead
+ no_quorum_stop = pcmk_no_quorum_stop,
+
+ //! \deprecated Use pcmk_no_quorum_ignore instead
+ no_quorum_ignore = pcmk_no_quorum_ignore,
+
+ //! \deprecated Use pcmk_no_quorum_fence instead
+ no_quorum_suicide = pcmk_no_quorum_fence,
+
+ //! \deprecated Use pcmk_no_quorum_demote instead
+ no_quorum_demote = pcmk_no_quorum_demote,
+#endif
+};
+
+//! Scheduling options and conditions
+enum pcmk_scheduler_flags {
+ //! No scheduler flags set (compare with equality rather than bit set)
+ pcmk_sched_none = 0ULL,
+
+ // These flags are dynamically determined conditions
+
+ //! Whether partition has quorum (via have-quorum property)
+ pcmk_sched_quorate = (1ULL << 0),
+
+ //! Whether cluster is symmetric (via symmetric-cluster property)
+ pcmk_sched_symmetric_cluster = (1ULL << 1),
+
+ //! Whether cluster is in maintenance mode (via maintenance-mode property)
+ pcmk_sched_in_maintenance = (1ULL << 3),
+
+ //! Whether fencing is enabled (via stonith-enabled property)
+ pcmk_sched_fencing_enabled = (1ULL << 4),
+
+ //! Whether cluster has a fencing resource (via CIB resources)
+ pcmk_sched_have_fencing = (1ULL << 5),
+
+ //! Whether any resource provides or requires unfencing (via CIB resources)
+ pcmk_sched_enable_unfencing = (1ULL << 6),
+
+ //! Whether concurrent fencing is allowed (via concurrent-fencing property)
+ pcmk_sched_concurrent_fencing = (1ULL << 7),
+
+ /*!
+ * Whether resources removed from the configuration should be stopped (via
+ * stop-orphan-resources property)
+ */
+ pcmk_sched_stop_removed_resources = (1ULL << 8),
+
+ /*!
+ * Whether recurring actions removed from the configuration should be
+ * cancelled (via stop-orphan-actions property)
+ */
+ pcmk_sched_cancel_removed_actions = (1ULL << 9),
+
+ //! Whether to stop all resources (via stop-all-resources property)
+ pcmk_sched_stop_all = (1ULL << 10),
+
+ /*!
+ * Whether start failure should be treated as if migration-threshold is 1
+ * (via start-failure-is-fatal property)
+ */
+ pcmk_sched_start_failure_fatal = (1ULL << 12),
+
+ //! \deprecated Do not use
+ pcmk_sched_remove_after_stop = (1ULL << 13),
+
+ //! Whether unseen nodes should be fenced (via startup-fencing property)
+ pcmk_sched_startup_fencing = (1ULL << 14),
+
+ /*!
+ * Whether resources should be left stopped when their node shuts down
+ * cleanly (via shutdown-lock property)
+ */
+ pcmk_sched_shutdown_lock = (1ULL << 15),
+
+ /*!
+ * Whether resources' current state should be probed (when unknown) before
+ * scheduling any other actions (via the enable-startup-probes property)
+ */
+ pcmk_sched_probe_resources = (1ULL << 16),
+
+ //! Whether the CIB status section has been parsed yet
+ pcmk_sched_have_status = (1ULL << 17),
+
+ //! Whether the cluster includes any Pacemaker Remote nodes (via CIB)
+ pcmk_sched_have_remote_nodes = (1ULL << 18),
+
+ // The remaining flags are scheduling options that must be set explicitly
+
+ /*!
+ * Whether to skip unpacking the CIB status section and stop the scheduling
+ * sequence after applying node-specific location criteria (skipping
+ * assignment, ordering, actions, etc.).
+ */
+ pcmk_sched_location_only = (1ULL << 20),
+
+ //! Whether sensitive resource attributes have been masked
+ pcmk_sched_sanitized = (1ULL << 21),
+
+ //! Skip counting of total, disabled, and blocked resource instances
+ pcmk_sched_no_counts = (1ULL << 23),
+
+ /*!
+ * Skip deprecated code kept solely for backward API compatibility
+ * (internal code should always set this)
+ */
+ pcmk_sched_no_compat = (1ULL << 24),
+
+ //! Whether node scores should be output instead of logged
+ pcmk_sched_output_scores = (1ULL << 25),
+
+ //! Whether to show node and resource utilization (in log or output)
+ pcmk_sched_show_utilization = (1ULL << 26),
+
+ /*!
+ * Whether to stop the scheduling sequence after unpacking the CIB,
+ * calculating cluster status, and applying node health (skipping
+ * applying node-specific location criteria, assignment, etc.)
+ */
+ pcmk_sched_validate_only = (1ULL << 27),
+};
+
+//! Implementation of pcmk_scheduler_t
+struct pe_working_set_s {
+ // Be careful about when each piece of information is available and final
+
+ xmlNode *input; //!< CIB XML
+ crm_time_t *now; //!< Current time for evaluation purposes
+ char *dc_uuid; //!< Node ID of designated controller
+ pcmk_node_t *dc_node; //!< Node object for DC
+ const char *stonith_action; //!< Default fencing action
+ const char *placement_strategy; //!< Value of placement-strategy property
+
+ // @COMPAT Change to uint64_t at a compatibility break
+ unsigned long long flags; //!< Group of enum pcmk_scheduler_flags
+
+ int stonith_timeout; //!< Value of stonith-timeout property
+ enum pe_quorum_policy no_quorum_policy; //!< Response to loss of quorum
+ GHashTable *config_hash; //!< Cluster properties
+
+ //!< Ticket constraints unpacked from ticket state
+ GHashTable *tickets;
+
+ //! Actions for which there can be only one (such as "fence node X")
+ GHashTable *singletons;
+
+ GList *nodes; //!< Nodes in cluster
+ GList *resources; //!< Resources in cluster
+ GList *placement_constraints; //!< Location constraints
+ GList *ordering_constraints; //!< Ordering constraints
+ GList *colocation_constraints; //!< Colocation constraints
+
+ //!< Ticket constraints unpacked by libpacemaker
+ GList *ticket_constraints;
+
+ GList *actions; //!< Scheduled actions
+ xmlNode *failed; //!< History entries of failed actions
+ xmlNode *op_defaults; //!< Configured operation defaults
+ xmlNode *rsc_defaults; //!< Configured resource defaults
+ int num_synapse; //!< Number of transition graph synapses
+ int max_valid_nodes; //!< \deprecated Do not use
+ int order_id; //!< ID to use for next created ordering
+ int action_id; //!< ID to use for next created action
+ xmlNode *graph; //!< Transition graph
+ GHashTable *template_rsc_sets; //!< Mappings of template ID to resource ID
+
+ // @COMPAT Replace this with a fencer variable (only place it's used)
+ const char *localhost; //!< \deprecated Do not use
+
+ GHashTable *tags; //!< Configuration tags (ID -> pcmk_tag_t *)
+ int blocked_resources; //!< Number of blocked resources in cluster
+ int disabled_resources; //!< Number of disabled resources in cluster
+ GList *param_check; //!< History entries that need to be checked
+ GList *stop_needed; //!< Containers that need stop actions
+ time_t recheck_by; //!< Hint to controller when to reschedule
+ int ninstances; //!< Total number of resource instances
+ guint shutdown_lock; //!< How long to lock resources (seconds)
+ int priority_fencing_delay; //!< Priority fencing delay
+
+ // pcmk__output_t *
+ void *priv; //!< For Pacemaker use only
+
+ guint node_pending_timeout; //!< Pending join times out after this (ms)
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_SCHEDULER__H
diff --git a/include/crm/common/scheduler_internal.h b/include/crm/common/scheduler_internal.h
new file mode 100644
index 0000000..1f1da9f
--- /dev/null
+++ b/include/crm/common/scheduler_internal.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2004-2023 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_SCHEDULER_INTERNAL__H
+# define PCMK__CRM_COMMON_SCHEDULER_INTERNAL__H
+
+#include <crm/common/action_relation_internal.h>
+#include <crm/common/clone_internal.h>
+#include <crm/common/digests_internal.h>
+#include <crm/common/failcounts_internal.h>
+#include <crm/common/group_internal.h>
+#include <crm/common/roles_internal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Some warnings are too noisy when logged every time a give function is called
+ * (for example, using a deprecated feature). As an alternative, we allow
+ * warnings to be logged once per scheduler sequence (transition). Each of those
+ * warnings needs a flag defined here.
+ */
+enum pcmk__sched_warnings {
+ pcmk__wo_blind = (1 << 0),
+ pcmk__wo_restart_type = (1 << 1),
+ pcmk__wo_role_after = (1 << 2),
+ pcmk__wo_poweroff = (1 << 3),
+ pcmk__wo_require_all = (1 << 4),
+ pcmk__wo_order_score = (1 << 5),
+ pcmk__wo_neg_threshold = (1 << 6),
+ pcmk__wo_remove_after = (1 << 7),
+ pcmk__wo_ping_node = (1 << 8),
+ pcmk__wo_order_inst = (1 << 9),
+ pcmk__wo_coloc_inst = (1 << 10),
+ pcmk__wo_group_order = (1 << 11),
+ pcmk__wo_group_coloc = (1 << 12),
+ pcmk__wo_upstart = (1 << 13),
+ pcmk__wo_nagios = (1 << 14),
+ pcmk__wo_set_ordering = (1 << 15),
+};
+
+enum pcmk__check_parameters {
+ /* Clear fail count if parameters changed for un-expired start or monitor
+ * last_failure.
+ */
+ pcmk__check_last_failure,
+
+ /* Clear fail count if parameters changed for start, monitor, promote, or
+ * migrate_from actions for active resources.
+ */
+ pcmk__check_active,
+};
+
+// Group of enum pcmk__sched_warnings flags for warnings we want to log once
+extern uint32_t pcmk__warnings;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_SCHEDULER_INTERNAL__H
diff --git a/include/crm/common/scheduler_types.h b/include/crm/common/scheduler_types.h
new file mode 100644
index 0000000..5c4a193
--- /dev/null
+++ b/include/crm/common/scheduler_types.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 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_SCHEDULER_TYPES__H
+# define PCMK__CRM_COMMON_SCHEDULER_TYPES__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Type aliases needed to define scheduler objects
+ * \ingroup core
+ */
+
+//! Node object (including information that may vary depending on resource)
+typedef struct pe_node_s pcmk_node_t;
+
+//! Resource object
+typedef struct pe_resource_s pcmk_resource_t;
+
+//! Action object
+typedef struct pe_action_s pcmk_action_t;
+
+//! Scheduler object
+typedef struct pe_working_set_s pcmk_scheduler_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_SCHEDULER_TYPES__H
diff --git a/include/crm/common/tags.h b/include/crm/common/tags.h
new file mode 100644
index 0000000..3f4861d
--- /dev/null
+++ b/include/crm/common/tags.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2004-2023 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_TAGS__H
+# define PCMK__CRM_COMMON_TAGS__H
+
+#include <glib.h> // GList
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Scheduler API for configuration tags
+ * \ingroup core
+ */
+
+//! Configuration tag object
+typedef struct pe_tag_s {
+ char *id; //!< XML ID of tag
+ GList *refs; //!< XML IDs of objects that reference the tag
+} pcmk_tag_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_TAGS__H
diff --git a/include/crm/common/tickets.h b/include/crm/common/tickets.h
new file mode 100644
index 0000000..40079e9
--- /dev/null
+++ b/include/crm/common/tickets.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004-2023 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_TICKETS__H
+# define PCMK__CRM_COMMON_TICKETS__H
+
+#include <sys/types.h> // time_t
+#include <glib.h> // gboolean, GHashTable
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \brief Scheduler API for tickets
+ * \ingroup core
+ */
+
+//! Ticket constraint object
+typedef struct pe_ticket_s {
+ char *id; //!< XML ID of ticket constraint or state
+ gboolean granted; //!< Whether cluster has been granted the ticket
+ time_t last_granted; //!< When cluster was last granted the ticket
+ gboolean standby; //!< Whether ticket is temporarily suspended
+ GHashTable *state; //!< XML attributes from ticket state
+} pcmk_ticket_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_COMMON_TICKETS__H
diff --git a/include/crm/common/unittest_internal.h b/include/crm/common/unittest_internal.h
index b8f78cf..1fc8501 100644
--- a/include/crm/common/unittest_internal.h
+++ b/include/crm/common/unittest_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 the Pacemaker project contributors
+ * Copyright 2022-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -65,6 +65,44 @@
} \
} while (0);
+/*!
+ * \internal
+ * \brief Assert that a statement exits with the expected exit status.
+ *
+ * \param[in] stmt Statement to execute; can be an expression.
+ * \param[in] rc The expected exit status.
+ *
+ * This functions just like \c pcmk__assert_asserts, except that it tests for
+ * an expected exit status. Abnormal termination or incorrect exit status is
+ * treated as a failure of the test.
+ *
+ * In the event that stmt does not exit at all, the special code \c CRM_EX_NONE
+ * will be returned. It is expected that this code is not used anywhere, thus
+ * always causing an error.
+ */
+#define pcmk__assert_exits(rc, stmt) \
+ do { \
+ pid_t p = fork(); \
+ if (p == 0) { \
+ struct rlimit cores = { 0, 0 }; \
+ setrlimit(RLIMIT_CORE, &cores); \
+ stmt; \
+ _exit(CRM_EX_NONE); \
+ } else if (p > 0) { \
+ int wstatus = 0; \
+ if (waitpid(p, &wstatus, 0) == -1) { \
+ fail_msg("waitpid failed"); \
+ } \
+ if (!WIFEXITED(wstatus)) { \
+ fail_msg("statement terminated abnormally"); \
+ } else if (WEXITSTATUS(wstatus) != rc) { \
+ fail_msg("statement exited with %d, not expected %d", WEXITSTATUS(wstatus), rc); \
+ } \
+ } else { \
+ fail_msg("unable to fork for assert test"); \
+ } \
+ } while (0);
+
/* Generate the main function of most unit test files. Typically, group_setup
* and group_teardown will be NULL. The rest of the arguments are a list of
* calls to cmocka_unit_test or cmocka_unit_test_setup_teardown to run the
diff --git a/include/crm/common/util.h b/include/crm/common/util.h
index 8acdff9..c75a55e 100644
--- a/include/crm/common/util.h
+++ b/include/crm/common/util.h
@@ -18,10 +18,8 @@
# include <signal.h>
# include <glib.h>
-# include <libxml/tree.h>
-
-# include <crm/lrmd.h>
# include <crm/common/acl.h>
+# include <crm/common/actions.h>
# include <crm/common/agents.h>
# include <crm/common/results.h>
@@ -59,26 +57,6 @@ char *crm_strdup_printf(char const *format, ...) G_GNUC_PRINTF(1, 2);
guint crm_parse_interval_spec(const char *input);
-/* public operation functions (from operations.c) */
-gboolean parse_op_key(const char *key, char **rsc_id, char **op_type,
- guint *interval_ms);
-gboolean decode_transition_key(const char *key, char **uuid, int *transition_id,
- int *action_id, int *target_rc);
-gboolean decode_transition_magic(const char *magic, char **uuid,
- int *transition_id, int *action_id,
- int *op_status, int *op_rc, int *target_rc);
-int rsc_op_expected_rc(const lrmd_event_data_t *event);
-gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc);
-bool crm_op_needs_metadata(const char *rsc_class, const char *op);
-xmlNode *crm_create_op_xml(xmlNode *parent, const char *prefix,
- const char *task, const char *interval_spec,
- const char *timeout);
-#define CRM_DEFAULT_OP_TIMEOUT_S "20s"
-
-bool pcmk_is_probe(const char *task, guint interval);
-bool pcmk_xe_is_probe(const xmlNode *xml_op);
-bool pcmk_xe_mask_probe_failure(const xmlNode *xml_op);
-
int compare_version(const char *version1, const char *version2);
/* coverity[+kill] */
diff --git a/include/crm/common/util_compat.h b/include/crm/common/util_compat.h
index 9e02e12..7a60208 100644
--- a/include/crm/common/util_compat.h
+++ b/include/crm/common/util_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2021 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -11,6 +11,7 @@
# define PCMK__CRM_COMMON_UTIL_COMPAT__H
# include <glib.h>
+# include <libxml/tree.h>
# include <crm/common/util.h>
#ifdef __cplusplus
@@ -29,6 +30,9 @@ extern "C" {
//! \deprecated Use crm_parse_interval_spec() instead
#define crm_get_interval crm_parse_interval_spec
+//! \deprecated Do not use
+#define CRM_DEFAULT_OP_TIMEOUT_S "20s"
+
//! \deprecated Use !pcmk_is_set() or !pcmk_all_flags_set() instead
static inline gboolean
is_not_set(long long word, long long bit)
@@ -69,6 +73,9 @@ int pcmk_scan_nvpair(const char *input, char **name, char **value);
char *pcmk_format_nvpair(const char *name, const char *value,
const char *units);
+//! \deprecated Use \c crm_xml_add() or \c xml_remove_prop() instead
+const char *crm_xml_replace(xmlNode *node, const char *name, const char *value);
+
//! \deprecated Use a standard printf()-style function instead
char *pcmk_format_named_time(const char *name, time_t epoch_time);
diff --git a/include/crm/common/xml.h b/include/crm/common/xml.h
index 682b31c..ac839d3 100644
--- a/include/crm/common/xml.h
+++ b/include/crm/common/xml.h
@@ -52,8 +52,6 @@ typedef const xmlChar *pcmkXmlStr;
gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
xmlNode *get_message_xml(const xmlNode *msg, const char *field);
-xmlDoc *getDocPtr(xmlNode * node);
-
/*
* \brief xmlCopyPropList ACLs-sensitive replacement expading i++ notation
*
@@ -132,12 +130,13 @@ xmlNode *stdin2xml(void);
xmlNode *string2xml(const char *input);
-int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
-int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
+int write_xml_fd(const xmlNode *xml, const char *filename, int fd,
+ gboolean compress);
+int write_xml_file(const xmlNode *xml, const char *filename, gboolean compress);
-char *dump_xml_formatted(xmlNode * msg);
-char *dump_xml_formatted_with_text(xmlNode * msg);
-char *dump_xml_unformatted(xmlNode * msg);
+char *dump_xml_formatted(const xmlNode *xml);
+char *dump_xml_formatted_with_text(const xmlNode *xml);
+char *dump_xml_unformatted(const xmlNode *xml);
/*
* Diff related Functions
@@ -170,25 +169,17 @@ xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level)
xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
static inline const char *
-crm_element_name(const xmlNode *xml)
-{
- return xml? (const char *)(xml->name) : NULL;
-}
-
-static inline const char *
crm_map_element_name(const xmlNode *xml)
{
- const char *name = crm_element_name(xml);
-
- if (strcmp(name, "master") == 0) {
+ if (xml == NULL) {
+ return NULL;
+ } else if (strcmp((const char *) xml->name, "master") == 0) {
return "clone";
} else {
- return name;
+ return (const char *) xml->name;
}
}
-gboolean xml_has_children(const xmlNode * root);
-
char *calculate_on_disk_digest(xmlNode * local_cib);
char *calculate_operation_digest(xmlNode * local_cib, const char *version);
char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
@@ -196,7 +187,7 @@ char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do
/* schema-related functions (from schemas.c) */
gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
-gboolean validate_xml_verbose(xmlNode * xml_blob);
+gboolean validate_xml_verbose(const xmlNode *xml_blob);
/*!
* \brief Update CIB XML to most recent schema version
@@ -258,7 +249,7 @@ xmlNode *first_named_child(const xmlNode *parent, const char *name);
xmlNode *crm_next_same_xml(const xmlNode *sibling);
xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
-xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
+xmlXPathObjectPtr xpath_search(const xmlNode *xml_top, const char *path);
void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
void (*helper)(xmlNode*, void*), void *user_data);
xmlNode *expand_idref(xmlNode * input, xmlNode * top);
@@ -289,7 +280,8 @@ int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
-void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
+void save_xml_to_file(const xmlNode *xml, const char *desc,
+ const char *filename);
char * crm_xml_escape(const char *text);
void crm_xml_sanitize_id(char *id);
diff --git a/include/crm/common/xml_compat.h b/include/crm/common/xml_compat.h
index bb49b68..85e39ff 100644
--- a/include/crm/common/xml_compat.h
+++ b/include/crm/common/xml_compat.h
@@ -31,6 +31,9 @@ extern "C" {
#define XML_PARANOIA_CHECKS 0
//! \deprecated This function will be removed in a future release
+xmlDoc *getDocPtr(xmlNode *node);
+
+//! \deprecated This function will be removed in a future release
int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
//! \deprecated This function will be removed in a future release
@@ -51,13 +54,23 @@ gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml);
//! \deprecated Do not use (will be removed in a future release)
void crm_destroy_xml(gpointer data);
-//! \deprecated Use crm_xml_add() with "true" or "false" instead
+//! \deprecated Check children member directly
+gboolean xml_has_children(const xmlNode *root);
+
+//! \deprecated Use crm_xml_add() with "true" or "false" instead
static inline const char *
crm_xml_add_boolean(xmlNode *node, const char *name, gboolean value)
{
return crm_xml_add(node, name, (value? "true" : "false"));
}
+//! \deprecated Use name member directly
+static inline const char *
+crm_element_name(const xmlNode *xml)
+{
+ return (xml == NULL)? NULL : (const char *) xml->name;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/include/crm/common/xml_internal.h b/include/crm/common/xml_internal.h
index 43b3b8c..ddb4384 100644
--- a/include/crm/common/xml_internal.h
+++ b/include/crm/common/xml_internal.h
@@ -21,6 +21,7 @@
# include <crm/crm.h> /* transitively imports qblog.h */
# include <crm/common/output_internal.h>
+# include <libxml/relaxng.h>
/*!
* \brief Base for directing lib{xml2,xslt} log into standard libqb backend
@@ -135,9 +136,6 @@ enum pcmk__xml_fmt_options {
//! Include indentation and newlines
pcmk__xml_fmt_pretty = (1 << 1),
- //! Include full XML subtree (with any text), using libxml serialization
- pcmk__xml_fmt_full = (1 << 2),
-
//! Include the opening tag of an XML element, and include XML comments
pcmk__xml_fmt_open = (1 << 3),
@@ -147,7 +145,6 @@ enum pcmk__xml_fmt_options {
//! Include the closing tag of an XML element
pcmk__xml_fmt_close = (1 << 5),
- // @COMPAT Remove when log_data_element() is removed
//! Include XML text nodes
pcmk__xml_fmt_text = (1 << 6),
@@ -190,6 +187,16 @@ int pcmk__xml_show_changes(pcmk__output_t *out, const xmlNode *xml);
#define PCMK__XP_REMOTE_NODE_STATUS \
"//" XML_TAG_CIB "//" XML_CIB_TAG_STATUS "//" XML_CIB_TAG_STATE \
"[@" XML_NODE_IS_REMOTE "='true']"
+/*!
+ * \internal
+ * \brief Serialize XML (using libxml) into provided descriptor
+ *
+ * \param[in] fd File descriptor to (piece-wise) write to
+ * \param[in] cur XML subtree to proceed
+ *
+ * \return a standard Pacemaker return code
+ */
+int pcmk__xml2fd(int fd, xmlNode *cur);
enum pcmk__xml_artefact_ns {
pcmk__xml_artefact_ns_legacy_rng = 1,
@@ -235,6 +242,22 @@ char *pcmk__xml_artefact_path(enum pcmk__xml_artefact_ns ns,
/*!
* \internal
+ * \brief Check whether an XML element is of a particular type
+ *
+ * \param[in] xml XML element to compare
+ * \param[in] name XML element name to compare
+ *
+ * \return \c true if \p xml is of type \p name, otherwise \c false
+ */
+static inline bool
+pcmk__xe_is(const xmlNode *xml, const char *name)
+{
+ return (xml != NULL) && (xml->name != NULL) && (name != NULL)
+ && (strcmp((const char *) xml->name, name) == 0);
+}
+
+/*!
+ * \internal
* \brief Return first non-text child node of an XML node
*
* \param[in] parent XML node to check
@@ -411,4 +434,15 @@ pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name,
int (*handler)(xmlNode *xml, void *userdata),
void *userdata);
+static inline const char *
+pcmk__xml_attr_value(const xmlAttr *attr)
+{
+ return ((attr == NULL) || (attr->children == NULL))? NULL
+ : (const char *) attr->children->content;
+}
+
+gboolean pcmk__validate_xml(xmlNode *xml_blob, const char *validation,
+ xmlRelaxNGValidityErrorFunc error_handler,
+ void *error_handler_context);
+
#endif // PCMK__XML_INTERNAL__H
diff --git a/include/crm/compatibility.h b/include/crm/compatibility.h
index 1281a3c..f8502cc 100644
--- a/include/crm/compatibility.h
+++ b/include/crm/compatibility.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2021 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -196,41 +196,41 @@ extern "C" {
/* Clone terminology definitions */
// These can no longer be used in a switch together
-#define pe_master pe_clone
+#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 pe_native;
+ return pcmk_rsc_variant_primitive;
} else if (safe_str_eq(name, XML_CIB_TAG_GROUP)) {
- return pe_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 pe_clone;
+ return pcmk_rsc_variant_clone;
} else if (safe_str_eq(name, XML_CIB_TAG_CONTAINER)) {
- return pe_container;
+ return pcmk_rsc_variant_bundle;
}
- return pe_unknown;
+ return pcmk_rsc_variant_unknown;
}
static inline const char *
get_resource_typename(enum pe_obj_types type)
{
switch (type) {
- case pe_native:
+ case pcmk_rsc_variant_primitive:
return XML_CIB_TAG_RESOURCE;
- case pe_group:
+ case pcmk_rsc_variant_group:
return XML_CIB_TAG_GROUP;
- case pe_clone:
+ case pcmk_rsc_variant_clone:
return XML_CIB_TAG_INCARNATION;
- case pe_container:
+ case pcmk_rsc_variant_bundle:
return XML_CIB_TAG_CONTAINER;
- case pe_unknown:
+ case pcmk_rsc_variant_unknown:
return "unknown";
}
return "<unknown>";
diff --git a/include/crm/crm.h b/include/crm/crm.h
index e824825..aecfcc8 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -65,8 +65,9 @@ extern "C" {
* XML v2 patchsets are created by default
* >=3.0.13: Fail counts include operation name and interval
* >=3.2.0: DC supports PCMK_EXEC_INVALID and PCMK_EXEC_NOT_CONNECTED
+ * >=3.19.0: DC supports PCMK__CIB_REQUEST_COMMIT_TRANSACT
*/
-# define CRM_FEATURE_SET "3.17.4"
+# define CRM_FEATURE_SET "3.19.0"
/* Pacemaker's CPG protocols use fixed-width binary fields for the sender and
* recipient of a CPG message. This imposes an arbitrary limit on cluster node
@@ -79,8 +80,6 @@ extern "C" {
extern char *crm_system_name;
-/* *INDENT-OFF* */
-
// How we represent "infinite" scores
# define CRM_SCORE_INFINITY 1000000
# define CRM_INFINITY_S "INFINITY"
@@ -110,6 +109,7 @@ extern char *crm_system_name;
# define CRM_SYSTEM_MCP "pacemakerd"
// Names of internally generated node attributes
+// @TODO Replace these with PCMK_NODE_ATTR_*
# define CRM_ATTR_UNAME "#uname"
# define CRM_ATTR_ID "#id"
# define CRM_ATTR_KIND "#kind"
@@ -140,22 +140,19 @@ extern char *crm_system_name;
# define CRM_OP_QUIT "quit"
# define CRM_OP_LOCAL_SHUTDOWN "start_shutdown"
# define CRM_OP_SHUTDOWN_REQ "req_shutdown"
-# define CRM_OP_SHUTDOWN "do_shutdown"
-# define CRM_OP_FENCE "stonith"
+# define CRM_OP_SHUTDOWN PCMK_ACTION_DO_SHUTDOWN
# define CRM_OP_REGISTER "register"
# define CRM_OP_IPC_FWD "ipc_fwd"
# define CRM_OP_INVOKE_LRM "lrm_invoke"
# define CRM_OP_LRM_REFRESH "lrm_refresh" //!< Deprecated since 1.1.10
-# define CRM_OP_LRM_DELETE "lrm_delete"
+# define CRM_OP_LRM_DELETE PCMK_ACTION_LRM_DELETE
# define CRM_OP_LRM_FAIL "lrm_fail"
# define CRM_OP_PROBED "probe_complete"
# define CRM_OP_REPROBE "probe_again"
-# define CRM_OP_CLEAR_FAILCOUNT "clear_failcount"
+# define CRM_OP_CLEAR_FAILCOUNT PCMK_ACTION_CLEAR_FAILCOUNT
# define CRM_OP_REMOTE_STATE "remote_state"
-# define CRM_OP_RELAXED_SET "one-or-more"
-# define CRM_OP_RELAXED_CLONE "clone-one-or-more"
# define CRM_OP_RM_NODE_CACHE "rm_node_cache"
-# define CRM_OP_MAINTENANCE_NODES "maintenance_nodes"
+# define CRM_OP_MAINTENANCE_NODES PCMK_ACTION_MAINTENANCE_NODES
/* Possible cluster membership states */
# define CRMD_JOINSTATE_DOWN "down"
@@ -163,70 +160,11 @@ extern char *crm_system_name;
# define CRMD_JOINSTATE_MEMBER "member"
# define CRMD_JOINSTATE_NACK "banned"
-# define CRMD_ACTION_DELETE "delete"
-# define CRMD_ACTION_CANCEL "cancel"
-
-# define CRMD_ACTION_RELOAD "reload"
-# define CRMD_ACTION_RELOAD_AGENT "reload-agent"
-# define CRMD_ACTION_MIGRATE "migrate_to"
-# define CRMD_ACTION_MIGRATED "migrate_from"
-
-# define CRMD_ACTION_START "start"
-# define CRMD_ACTION_STARTED "running"
-
-# define CRMD_ACTION_STOP "stop"
-# define CRMD_ACTION_STOPPED "stopped"
-
-# define CRMD_ACTION_PROMOTE "promote"
-# define CRMD_ACTION_PROMOTED "promoted"
-# define CRMD_ACTION_DEMOTE "demote"
-# define CRMD_ACTION_DEMOTED "demoted"
-
-# define CRMD_ACTION_NOTIFY "notify"
-# define CRMD_ACTION_NOTIFIED "notified"
-
-# define CRMD_ACTION_STATUS "monitor"
-# define CRMD_ACTION_METADATA "meta-data"
-# define CRMD_METADATA_CALL_TIMEOUT 30000
-
-/* short names */
-# define RSC_DELETE CRMD_ACTION_DELETE
-# define RSC_CANCEL CRMD_ACTION_CANCEL
-
-# define RSC_MIGRATE CRMD_ACTION_MIGRATE
-# define RSC_MIGRATED CRMD_ACTION_MIGRATED
-
-# define RSC_START CRMD_ACTION_START
-# define RSC_STARTED CRMD_ACTION_STARTED
-
-# define RSC_STOP CRMD_ACTION_STOP
-# define RSC_STOPPED CRMD_ACTION_STOPPED
-
-# define RSC_PROMOTE CRMD_ACTION_PROMOTE
-# define RSC_PROMOTED CRMD_ACTION_PROMOTED
-# define RSC_DEMOTE CRMD_ACTION_DEMOTE
-# define RSC_DEMOTED CRMD_ACTION_DEMOTED
-
-# define RSC_NOTIFY CRMD_ACTION_NOTIFY
-# define RSC_NOTIFIED CRMD_ACTION_NOTIFIED
-
-# define RSC_STATUS CRMD_ACTION_STATUS
-# define RSC_METADATA CRMD_ACTION_METADATA
-/* *INDENT-ON* */
-
+# include <crm/common/actions.h>
# include <crm/common/cib.h>
# include <crm/common/logging.h>
# include <crm/common/util.h>
-static inline const char *
-crm_action_str(const char *task, guint interval_ms) {
- if ((task != NULL) && (interval_ms == 0)
- && (strcasecmp(task, RSC_STATUS) == 0)) {
- return "probe";
- }
- return task;
-}
-
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
#include <crm/crm_compat.h>
#endif
diff --git a/include/crm/crm_compat.h b/include/crm/crm_compat.h
index 2c0a3dd..bfe1098 100644
--- a/include/crm/crm_compat.h
+++ b/include/crm/crm_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2022 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -10,8 +10,11 @@
#ifndef PCMK__CRM_CRM_COMPAT__H
# define PCMK__CRM_CRM_COMPAT__H
+#include <strings.h>
#include <glib.h>
+#include <crm/common/actions.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -31,12 +34,126 @@ extern "C" {
//! \deprecated This defined constant will be removed in a future release
#define MAX_IPC_DELAY 120
+//! \deprecated Use PCMK_ACTION_STONITH instead
+#define CRM_OP_FENCE PCMK_ACTION_STONITH
+
//! \deprecated This defined constant will be removed in a future release
#define CRM_OP_LRM_QUERY "lrm_query"
+//! \deprecated Use PCMK_ACTION_CLONE_ONE_OR_MORE instead
+#define CRM_OP_RELAXED_CLONE PCMK_ACTION_CLONE_ONE_OR_MORE
+
+//! \deprecated Use PCMK_ACTION_ONE_OR_MORE instead
+#define CRM_OP_RELAXED_SET PCMK_ACTION_ONE_OR_MORE
+
//! \deprecated This defined constant will be removed in a future release
#define CRM_ATTR_RA_VERSION "#ra-version"
+//! \deprecated Use PCMK_ACTION_CANCEL instead
+#define CRMD_ACTION_CANCEL PCMK_ACTION_CANCEL
+
+//! \deprecated Use PCMK_ACTION_DELETE instead
+#define CRMD_ACTION_DELETE PCMK_ACTION_DELETE
+
+//! \deprecated Use PCMK_ACTION_DEMOTE instead
+#define CRMD_ACTION_DEMOTE PCMK_ACTION_DEMOTE
+
+//! \deprecated Use PCMK_ACTION_DEMOTED instead
+#define CRMD_ACTION_DEMOTED PCMK_ACTION_DEMOTED
+
+//! \deprecated Use PCMK_ACTION_META_DATA instead
+#define CRMD_ACTION_METADATA PCMK_ACTION_META_DATA
+
+//! \deprecated Use PCMK_ACTION_MIGRATE_TO instead
+#define CRMD_ACTION_MIGRATE PCMK_ACTION_MIGRATE_TO
+
+//! \deprecated Use PCMK_ACTION_MIGRATE_FROM instead
+#define CRMD_ACTION_MIGRATED PCMK_ACTION_MIGRATE_FROM
+
+//! \deprecated Use PCMK_ACTION_NOTIFIED instead
+#define CRMD_ACTION_NOTIFIED PCMK_ACTION_NOTIFIED
+
+//! \deprecated Use PCMK_ACTION_NOTIFY instead
+#define CRMD_ACTION_NOTIFY PCMK_ACTION_NOTIFY
+
+//! \deprecated Use PCMK_ACTION_PROMOTE instead
+#define CRMD_ACTION_PROMOTE PCMK_ACTION_PROMOTE
+
+//! \deprecated Use PCMK_ACTION_PROMOTED instead
+#define CRMD_ACTION_PROMOTED PCMK_ACTION_PROMOTED
+
+//! \deprecated Use PCMK_ACTION_RELOAD instead
+#define CRMD_ACTION_RELOAD PCMK_ACTION_RELOAD
+
+//! \deprecated Use PCMK_ACTION_RELOAD_AGENT instead
+#define CRMD_ACTION_RELOAD_AGENT PCMK_ACTION_RELOAD_AGENT
+
+//! \deprecated Use PCMK_ACTION_START instead
+#define CRMD_ACTION_START PCMK_ACTION_START
+
+//! \deprecated Use PCMK_ACTION_RUNNING instead
+#define CRMD_ACTION_STARTED PCMK_ACTION_RUNNING
+
+//! \deprecated Use PCMK_ACTION_MONITOR instead
+#define CRMD_ACTION_STATUS PCMK_ACTION_MONITOR
+
+//! \deprecated Use PCMK_ACTION_STOP instead
+#define CRMD_ACTION_STOP PCMK_ACTION_STOP
+
+//! \deprecated Use PCMK_ACTION_STOPPED instead
+#define CRMD_ACTION_STOPPED PCMK_ACTION_STOPPED
+
+//! \deprecated Do not use
+#define CRMD_METADATA_CALL_TIMEOUT PCMK_DEFAULT_METADATA_TIMEOUT_MS
+
+//! \deprecated Use PCMK_ACTION_CANCEL instead
+#define RSC_CANCEL PCMK_ACTION_CANCEL
+
+//! \deprecated Use PCMK_ACTION_DELETE instead
+#define RSC_DELETE PCMK_ACTION_DELETE
+
+//! \deprecated Use PCMK_ACTION_DEMOTE instead
+#define RSC_DEMOTE PCMK_ACTION_DEMOTE
+
+//! \deprecated Use PCMK_ACTION_DEMOTED instead
+#define RSC_DEMOTED PCMK_ACTION_DEMOTED
+
+//! \deprecated Use PCMK_ACTION_META_DATA instead
+#define RSC_METADATA PCMK_ACTION_META_DATA
+
+//! \deprecated Use PCMK_ACTION_MIGRATE_TO instead
+#define RSC_MIGRATE PCMK_ACTION_MIGRATE_TO
+
+//! \deprecated Use PCMK_ACTION_MIGRATE_FROM instead
+#define RSC_MIGRATED PCMK_ACTION_MIGRATE_FROM
+
+//! \deprecated Use PCMK_ACTION_NOTIFIED instead
+#define RSC_NOTIFIED PCMK_ACTION_NOTIFIED
+
+//! \deprecated Use PCMK_ACTION_NOTIFY instead
+#define RSC_NOTIFY PCMK_ACTION_NOTIFY
+
+//! \deprecated Use PCMK_ACTION_PROMOTE instead
+#define RSC_PROMOTE PCMK_ACTION_PROMOTE
+
+//! \deprecated Use PCMK_ACTION_PROMOTED instead
+#define RSC_PROMOTED PCMK_ACTION_PROMOTED
+
+//! \deprecated Use PCMK_ACTION_START instead
+#define RSC_START PCMK_ACTION_START
+
+//! \deprecated Use PCMK_ACTION_RUNNING instead
+#define RSC_STARTED PCMK_ACTION_RUNNING
+
+//! \deprecated Use PCMK_ACTION_MONITOR instead
+#define RSC_STATUS PCMK_ACTION_MONITOR
+
+//! \deprecated Use PCMK_ACTION_STOP instead
+#define RSC_STOP PCMK_ACTION_STOP
+
+//! \deprecated Use PCMK_ACTION_STOPPED instead
+#define RSC_STOPPED PCMK_ACTION_STOPPED
+
//!@{
//! \deprecated This macro will be removed in a future release
@@ -54,6 +171,16 @@ extern "C" {
//! \deprecated Use GList * instead
typedef GList *GListPtr;
+//! \deprecated Do not use
+static inline const char *
+crm_action_str(const char *task, guint interval_ms) {
+ if ((task != NULL) && (interval_ms == 0)
+ && (strcasecmp(task, PCMK_ACTION_MONITOR) == 0)) {
+ return "probe";
+ }
+ return task;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/include/crm/lrmd.h b/include/crm/lrmd.h
index dfc2f25..0c5a40b 100644
--- a/include/crm/lrmd.h
+++ b/include/crm/lrmd.h
@@ -13,6 +13,7 @@
#include <stdbool.h> // bool
#include <glib.h> // guint, GList
#include <crm_config.h>
+#include <crm/lrmd_events.h>
#include <crm/services.h>
#ifdef __cplusplus
@@ -203,74 +204,6 @@ enum lrmd_call_options {
lrmd_opt_notify_changes_only = (1 << 2),
};
-enum lrmd_callback_event {
- lrmd_event_register,
- lrmd_event_unregister,
- lrmd_event_exec_complete,
- lrmd_event_disconnect,
- lrmd_event_connect,
- lrmd_event_poke,
- lrmd_event_new_client,
-};
-
-typedef struct lrmd_event_data_s {
- /*! Type of event, register, unregister, call_completed... */
- enum lrmd_callback_event type;
-
- /*! The resource this event occurred on. */
- const char *rsc_id;
- /*! The action performed, start, stop, monitor... */
- const char *op_type;
- /*! The user data passed by caller of exec() API function */
- const char *user_data;
-
- /*! The client api call id associated with this event */
- int call_id;
- /*! The operation's timeout period in ms. */
- int timeout;
- /*! The operation's recurring interval in ms. */
- guint interval_ms;
- /*! The operation's start delay value in ms. */
- int start_delay;
- /*! This operation that just completed is on a deleted rsc. */
- int rsc_deleted;
-
- /*! The executed ra return code mapped to OCF */
- enum ocf_exitcode rc;
- /*! The executor status returned for exec_complete events */
- int op_status;
- /*! stdout from resource agent operation */
- const char *output;
- /*! Timestamp of when op ran */
- unsigned int t_run;
- /*! Timestamp of last rc change */
- unsigned int t_rcchange;
- /*! Time in length op took to execute */
- unsigned int exec_time;
- /*! Time in length spent in queue */
- unsigned int queue_time;
-
- /*! int connection result. Used for connection and poke events */
- int connection_rc;
-
- /* This is a GHashTable containing the
- * parameters given to the operation */
- void *params;
-
- /*! client node name associated with this connection
- * (used to match actions to the proper client when there are multiple)
- */
- const char *remote_nodename;
-
- /*! exit failure reason string from resource agent operation */
- const char *exit_reason;
-} lrmd_event_data_t;
-
-lrmd_event_data_t *lrmd_new_event(const char *rsc_id, const char *task,
- guint interval_ms);
-lrmd_event_data_t *lrmd_copy_event(lrmd_event_data_t * event);
-void lrmd_free_event(lrmd_event_data_t * event);
-
typedef struct lrmd_rsc_info_s {
char *id;
char *type;
diff --git a/include/crm/lrmd_events.h b/include/crm/lrmd_events.h
new file mode 100644
index 0000000..3a1c500
--- /dev/null
+++ b/include/crm/lrmd_events.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2012-2023 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_LRMD_EVENTS__H
+# define PCMK__CRM_LRMD_EVENTS__H
+
+#include <glib.h> // guint
+#include <crm/common/results.h> // enum ocf_exitcode
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file
+ * \brief Resource agent executor events
+ * \ingroup lrmd
+ */
+
+enum lrmd_callback_event {
+ lrmd_event_register,
+ lrmd_event_unregister,
+ lrmd_event_exec_complete,
+ lrmd_event_disconnect,
+ lrmd_event_connect,
+ lrmd_event_poke,
+ lrmd_event_new_client,
+};
+
+typedef struct lrmd_event_data_s {
+ /*! Type of event, register, unregister, call_completed... */
+ enum lrmd_callback_event type;
+
+ /*! The resource this event occurred on. */
+ const char *rsc_id;
+ /*! The action performed, start, stop, monitor... */
+ const char *op_type;
+ /*! The user data passed by caller of exec() API function */
+ const char *user_data;
+
+ /*! The client api call id associated with this event */
+ int call_id;
+
+ /*! The operation's timeout period in ms. */
+ int timeout;
+
+ /*! The operation's recurring interval in ms. */
+ guint interval_ms;
+
+ /*! The operation's start delay value in ms. */
+ int start_delay;
+
+ /*! This operation that just completed is on a deleted rsc. */
+ int rsc_deleted;
+
+ /*! The executed ra return code mapped to OCF */
+ enum ocf_exitcode rc;
+
+ /*! The executor status returned for exec_complete events */
+ int op_status;
+
+ /*! stdout from resource agent operation */
+ const char *output;
+
+ /*! Timestamp of when op ran */
+ unsigned int t_run;
+
+ /*! Timestamp of last rc change */
+ unsigned int t_rcchange;
+
+ /*! Time in length op took to execute */
+ unsigned int exec_time;
+
+ /*! Time in length spent in queue */
+ unsigned int queue_time;
+
+ /*! int connection result. Used for connection and poke events */
+ int connection_rc;
+
+ /* This is a GHashTable containing the
+ * parameters given to the operation */
+ void *params;
+
+ /*! client node name associated with this connection
+ * (used to match actions to the proper client when there are multiple)
+ */
+ const char *remote_nodename;
+
+ /*! exit failure reason string from resource agent operation */
+ const char *exit_reason;
+} lrmd_event_data_t;
+
+lrmd_event_data_t *lrmd_new_event(const char *rsc_id, const char *task,
+ guint interval_ms);
+lrmd_event_data_t *lrmd_copy_event(lrmd_event_data_t *event);
+void lrmd_free_event(lrmd_event_data_t *event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCMK__CRM_LRMD_EVENTS__H
diff --git a/include/crm/lrmd_internal.h b/include/crm/lrmd_internal.h
index 5810554..d1cd25d 100644
--- a/include/crm/lrmd_internal.h
+++ b/include/crm/lrmd_internal.h
@@ -47,6 +47,7 @@ void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc,
void lrmd__reset_result(lrmd_event_data_t *event);
time_t lrmd__uptime(lrmd_t *lrmd);
+const char *lrmd__node_start_state(lrmd_t *lrmd);
/* Shared functions for IPC proxy back end */
diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h
index 2e50adb..c616182 100644
--- a/include/crm/msg_xml.h
+++ b/include/crm/msg_xml.h
@@ -48,6 +48,8 @@ extern "C" {
* XML attributes
*/
+#define PCMK_XA_FORMAT "format"
+
/* These have been deprecated as CIB <clone> element attributes (aliases for
* "promoted-max" and "promoted-node-max") since 2.0.0.
*/
@@ -59,7 +61,14 @@ extern "C" {
* 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"
/*
@@ -149,7 +158,6 @@ extern "C" {
# define XML_ATTR_IDREF "id-ref"
# define XML_ATTR_ID_LONG "long-id"
# define XML_ATTR_TYPE "type"
-# define XML_ATTR_VERBOSE "verbose"
# define XML_ATTR_OP "op"
# define XML_ATTR_DC_UUID "dc-uuid"
# define XML_ATTR_UPDATE_ORIG "update-origin"
@@ -183,8 +191,6 @@ extern "C" {
# define XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE "shutdown_complete"
# define XML_PING_ATTR_PACEMAKERDSTATE_REMOTE "remote"
-# define XML_TAG_FRAGMENT "cib_fragment"
-
# define XML_FAIL_TAG_CIB "failed_update"
# define XML_FAILCIB_ATTR_ID "id"
@@ -198,7 +204,6 @@ extern "C" {
# define XML_CIB_TAG_STATUS "status"
# define XML_CIB_TAG_RESOURCES "resources"
# define XML_CIB_TAG_NODES "nodes"
-# define XML_CIB_TAG_DOMAINS "domains"
# define XML_CIB_TAG_CONSTRAINTS "constraints"
# define XML_CIB_TAG_CRMCONFIG "crm_config"
# define XML_CIB_TAG_OPCONFIG "op_defaults"
@@ -239,19 +244,12 @@ extern "C" {
# define XML_RSC_ATTR_ORDERED "ordered"
# define XML_RSC_ATTR_INTERLEAVE "interleave"
# define XML_RSC_ATTR_INCARNATION "clone"
-# define XML_RSC_ATTR_INCARNATION_MAX "clone-max"
-# define XML_RSC_ATTR_INCARNATION_MIN "clone-min"
-# define XML_RSC_ATTR_INCARNATION_NODEMAX "clone-node-max"
# define XML_RSC_ATTR_PROMOTABLE "promotable"
-# define XML_RSC_ATTR_PROMOTED_MAX "promoted-max"
-# define XML_RSC_ATTR_PROMOTED_NODEMAX "promoted-node-max"
# 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_FAIL_STICKINESS "migration-threshold"
-# define XML_RSC_ATTR_FAIL_TIMEOUT "failure-timeout"
# define XML_RSC_ATTR_MULTIPLE "multiple-active"
# define XML_RSC_ATTR_REQUIRES "requires"
# define XML_RSC_ATTR_CONTAINER "container"
@@ -285,15 +283,8 @@ extern "C" {
//! \deprecated Do not use (will be removed in a future release)
# define XML_CIB_ATTR_REPLACE "replace"
-# define XML_CIB_ATTR_SOURCE "source"
-
# define XML_CIB_ATTR_PRIORITY "priority"
-# define XML_CIB_ATTR_SOURCE "source"
-# define XML_NODE_JOIN_STATE "join"
-# define XML_NODE_EXPECTED "expected"
-# define XML_NODE_IN_CLUSTER "in_ccm"
-# define XML_NODE_IS_PEER "crmd"
# define XML_NODE_IS_REMOTE "remote_node"
# define XML_NODE_IS_FENCED "node_fenced"
# define XML_NODE_IS_MAINTENANCE "node_in_maintenance"
@@ -333,7 +324,6 @@ extern "C" {
# define XML_LRM_ATTR_EXIT_REASON "exit-reason"
# define XML_RSC_OP_LAST_CHANGE "last-rc-change"
-# define XML_RSC_OP_LAST_RUN "last-run" // deprecated since 2.0.3
# define XML_RSC_OP_T_EXEC "exec-time"
# define XML_RSC_OP_T_QUEUE "queue-time"
@@ -413,6 +403,7 @@ extern "C" {
# define XML_CONFIG_ATTR_SHUTDOWN_LOCK "shutdown-lock"
# define XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT "shutdown-lock-limit"
# define XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY "priority-fencing-delay"
+# define XML_CONFIG_ATTR_NODE_PENDING_TIMEOUT "node-pending-timeout"
# define XML_ALERT_ATTR_PATH "path"
# define XML_ALERT_ATTR_TIMEOUT "timeout"
@@ -428,7 +419,10 @@ extern "C" {
# 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"
@@ -478,7 +472,6 @@ extern "C" {
# define XML_DIFF_POSITION "position"
# define ID(x) crm_element_value(x, XML_ATTR_ID)
-# define TYPE(x) crm_element_name(x)
#ifdef __cplusplus
}
diff --git a/include/crm/msg_xml_compat.h b/include/crm/msg_xml_compat.h
index aad98e8..612eebf 100644
--- a/include/crm/msg_xml_compat.h
+++ b/include/crm/msg_xml_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2022 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -25,6 +25,21 @@ extern "C" {
* release.
*/
+//! \deprecated Use PCMK_META_CLONE_MAX instead
+#define XML_RSC_ATTR_INCARNATION_MAX PCMK_META_CLONE_MAX
+
+//! \deprecated Use PCMK_META_CLONE_MIN instead
+#define XML_RSC_ATTR_INCARNATION_MIN PCMK_META_CLONE_MIN
+
+//! \deprecated Use PCMK_META_CLONE_NODE_MAX instead
+#define XML_RSC_ATTR_INCARNATION_NODEMAX PCMK_META_CLONE_NODE_MAX
+
+//! \deprecated Use PCMK_META_PROMOTED_MAX instead
+#define XML_RSC_ATTR_PROMOTED_MAX PCMK_META_PROMOTED_MAX
+
+//! \deprecated Use PCMK_META_PROMOTED_NODE_MAX instead
+#define XML_RSC_ATTR_PROMOTED_NODEMAX PCMK_META_PROMOTED_NODE_MAX
+
//! \deprecated Use PCMK_STONITH_PROVIDES instead
#define XML_RSC_ATTR_PROVIDES PCMK_STONITH_PROVIDES
@@ -40,6 +55,12 @@ extern "C" {
//! \deprecated Use PCMK_XA_PROMOTED_NODE_MAX_LEGACY instead
#define PCMK_XE_PROMOTED_NODE_MAX_LEGACY PCMK_XA_PROMOTED_NODE_MAX_LEGACY
+//! \deprecated Use PCMK_META_MIGRATION_THRESHOLD instead
+#define XML_RSC_ATTR_FAIL_STICKINESS PCMK_META_MIGRATION_THRESHOLD
+
+//! \deprecated Use PCMK_META_FAILURE_TIMEOUT instead
+#define XML_RSC_ATTR_FAIL_TIMEOUT PCMK_META_FAILURE_TIMEOUT
+
//! \deprecated Use PCMK_XA_PROMOTED_NODE_MAX_LEGACY instead
#define XML_RSC_ATTR_MASTER_NODEMAX PCMK_XA_PROMOTED_NODE_MAX_LEGACY
@@ -47,6 +68,9 @@ extern "C" {
#define XML_ATTR_RA_VERSION "ra-version"
//! \deprecated Do not use (will be removed in a future release)
+#define XML_TAG_FRAGMENT "cib_fragment"
+
+//! \deprecated Do not use (will be removed in a future release)
#define XML_TAG_RSC_VER_ATTRS "rsc_versioned_attrs"
//! \deprecated Do not use (will be removed in a future release)
@@ -58,6 +82,33 @@ extern "C" {
//! \deprecated Use \p XML_ATTR_ID instead
#define XML_ATTR_UUID "id"
+//! \deprecated Do not use (will be removed in a future release)
+#define XML_ATTR_VERBOSE "verbose"
+
+//! \deprecated Do not use (will be removed in a future release)
+#define XML_CIB_TAG_DOMAINS "domains"
+
+//! \deprecated Do not use (will be removed in a future release)
+#define XML_CIB_ATTR_SOURCE "source"
+
+//! \deprecated Do not use
+#define XML_NODE_EXPECTED "expected"
+
+//! \deprecated Do not use
+#define XML_NODE_IN_CLUSTER "in_ccm"
+
+//! \deprecated Do not use
+#define XML_NODE_IS_PEER "crmd"
+
+//! \deprecated Do not use
+#define XML_NODE_JOIN_STATE "join"
+
+//! \deprecated Do not use (will be removed in a future release)
+#define XML_RSC_OP_LAST_RUN "last-run"
+
+//! \deprecated Use name member directly
+#define TYPE(x) (((x) == NULL)? NULL : (const char *) ((x)->name))
+
#ifdef __cplusplus
}
#endif
diff --git a/include/crm/pengine/Makefile.am b/include/crm/pengine/Makefile.am
index fac6031..3560d24 100644
--- a/include/crm/pengine/Makefile.am
+++ b/include/crm/pengine/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2006-2021 the Pacemaker project contributors
+# Copyright 2006-2023 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
@@ -10,8 +10,13 @@ MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm/pengine
-noinst_HEADERS = internal.h remote_internal.h rules_internal.h
-header_HEADERS = common.h complex.h pe_types.h rules.h status.h \
+noinst_HEADERS = internal.h \
+ $(wildcard *_internal.h)
+header_HEADERS = common.h \
+ complex.h \
+ pe_types.h \
+ rules.h \
+ status.h \
common_compat.h \
pe_types_compat.h \
rules_compat.h
diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h
index 9fe05bd..2feac8a 100644
--- a/include/crm/pengine/common.h
+++ b/include/crm/pengine/common.h
@@ -13,6 +13,7 @@
# include <glib.h>
# include <regex.h>
# include <crm/common/iso8601.h>
+# include <crm/common/scheduler.h>
#ifdef __cplusplus
extern "C" {
@@ -21,120 +22,6 @@ extern "C" {
extern gboolean was_processing_error;
extern gboolean was_processing_warning;
-/* The order is (partially) significant here; the values from action_fail_ignore
- * through action_fail_fence are in order of increasing severity.
- *
- * @COMPAT The values should be ordered and numbered per the "TODO" comments
- * below, so all values are in order of severity and there is room for
- * future additions, but that would break API compatibility.
- * @TODO For now, we just use a function to compare the values specially, but
- * at the next compatibility break, we should arrange things properly.
- */
-enum action_fail_response {
- action_fail_ignore, // @TODO = 10
- // @TODO action_fail_demote = 20,
- action_fail_recover, // @TODO = 30
- // @TODO action_fail_reset_remote = 40,
- // @TODO action_fail_restart_container = 50,
- action_fail_migrate, // @TODO = 60
- action_fail_block, // @TODO = 70
- action_fail_stop, // @TODO = 80
- action_fail_standby, // @TODO = 90
- action_fail_fence, // @TODO = 100
-
- // @COMPAT Values below here are out of order for API compatibility
-
- action_fail_restart_container,
-
- /* This is reserved for internal use for remote node connection resources.
- * Fence the remote node if stonith is enabled, otherwise attempt to recover
- * the connection resource. This allows us to specify types of connection
- * resource failures that should result in fencing the remote node
- * (for example, recurring monitor failures).
- */
- action_fail_reset_remote,
-
- action_fail_demote,
-};
-
-/* the "done" action must be the "pre" action +1 */
-enum action_tasks {
- no_action,
- monitor_rsc,
- stop_rsc,
- stopped_rsc,
- start_rsc,
- started_rsc,
- action_notify,
- action_notified,
- action_promote,
- action_promoted,
- action_demote,
- action_demoted,
- shutdown_crm,
- stonith_node
-};
-
-enum rsc_recovery_type {
- recovery_stop_start,
- recovery_stop_only,
- recovery_block,
- recovery_stop_unexpected,
-};
-
-enum rsc_start_requirement {
- rsc_req_nothing, /* Allowed by custom_action() */
- rsc_req_quorum, /* Enforced by custom_action() */
- rsc_req_stonith /* Enforced by native_start_constraints() */
-};
-
-//! Possible roles that a resource can be in
-enum rsc_role_e {
- RSC_ROLE_UNKNOWN = 0,
- RSC_ROLE_STOPPED = 1,
- RSC_ROLE_STARTED = 2,
- RSC_ROLE_UNPROMOTED = 3,
- RSC_ROLE_PROMOTED = 4,
-
-#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
- //! \deprecated Use RSC_ROLE_UNPROMOTED instead
- RSC_ROLE_SLAVE = RSC_ROLE_UNPROMOTED,
-
- //! \deprecated Use RSC_ROLE_PROMOTED instead
- RSC_ROLE_MASTER = RSC_ROLE_PROMOTED,
-#endif
-};
-
-# define RSC_ROLE_MAX (RSC_ROLE_PROMOTED + 1)
-
-# define RSC_ROLE_UNKNOWN_S "Unknown"
-# define RSC_ROLE_STOPPED_S "Stopped"
-# define RSC_ROLE_STARTED_S "Started"
-# define RSC_ROLE_UNPROMOTED_S "Unpromoted"
-# define RSC_ROLE_PROMOTED_S "Promoted"
-# define RSC_ROLE_UNPROMOTED_LEGACY_S "Slave"
-# define RSC_ROLE_PROMOTED_LEGACY_S "Master"
-
-//! Deprecated
-enum pe_print_options {
- pe_print_log = (1 << 0),
- pe_print_html = (1 << 1),
- pe_print_ncurses = (1 << 2),
- pe_print_printf = (1 << 3),
- pe_print_dev = (1 << 4), //! Ignored
- pe_print_details = (1 << 5), //! Ignored
- pe_print_max_details = (1 << 6), //! Ignored
- pe_print_rsconly = (1 << 7),
- pe_print_ops = (1 << 8),
- pe_print_suppres_nl = (1 << 9),
- pe_print_xml = (1 << 10),
- pe_print_brief = (1 << 11),
- pe_print_pending = (1 << 12),
- pe_print_clone_details = (1 << 13),
- pe_print_clone_active = (1 << 14), // Print clone instances only if active
- pe_print_implicit = (1 << 15) // Print implicitly created resources
-};
-
const char *task2text(enum action_tasks task);
enum action_tasks text2task(const char *task);
enum rsc_role_e text2role(const char *role);
@@ -154,13 +41,13 @@ static inline const char *
recovery2text(enum rsc_recovery_type type)
{
switch (type) {
- case recovery_stop_only:
+ case pcmk_multiply_active_stop:
return "shutting it down";
- case recovery_stop_start:
+ case pcmk_multiply_active_restart:
return "attempting recovery";
- case recovery_block:
+ case pcmk_multiply_active_block:
return "waiting for an administrator";
- case recovery_stop_unexpected:
+ case pcmk_multiply_active_unexpected:
return "stopping unexpected instances";
}
return "Unknown";
diff --git a/include/crm/pengine/common_compat.h b/include/crm/pengine/common_compat.h
index 773bb3d..4330ccf 100644
--- a/include/crm/pengine/common_compat.h
+++ b/include/crm/pengine/common_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2021 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -10,6 +10,8 @@
#ifndef PCMK__CRM_PENGINE_COMMON_COMPAT__H
# define PCMK__CRM_PENGINE_COMMON_COMPAT__H
+#include <crm/common/scheduler.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -23,12 +25,35 @@ extern "C" {
* release.
*/
-//! \deprecated Use RSC_ROLE_UNPROMOTED_LEGACY_S instead
-# define RSC_ROLE_SLAVE_S RSC_ROLE_UNPROMOTED_LEGACY_S
+//! \deprecated Use (pcmk_role_promoted + 1) instead
+#define RSC_ROLE_MAX (pcmk_role_promoted + 1)
+
+//! \deprecated Use role2text(pcmk_role_unknown) instead
+#define RSC_ROLE_UNKNOWN_S role2text(pcmk_role_unknown)
+
+//! \deprecated Use role2text(pcmk_role_stopped) instead
+#define RSC_ROLE_STOPPED_S role2text(pcmk_role_stopped)
+
+//! \deprecated Use role2text(pcmk_role_started) instead
+#define RSC_ROLE_STARTED_S role2text(pcmk_role_started)
+
+//! \deprecated Use role2text(pcmk_role_unpromoted) instead
+#define RSC_ROLE_UNPROMOTED_S role2text(pcmk_role_unpromoted)
+
+//! \deprecated Use role2text(pcmk_role_promoted) instead
+#define RSC_ROLE_PROMOTED_S role2text(pcmk_role_promoted)
+
+//! \deprecated Do not use
+#define RSC_ROLE_UNPROMOTED_LEGACY_S "Slave"
+
+//! \deprecated Do not use
+#define RSC_ROLE_SLAVE_S RSC_ROLE_UNPROMOTED_LEGACY_S
-//! \deprecated Use RSC_ROLE_PROMOTED_LEGACY_S instead
-# define RSC_ROLE_MASTER_S RSC_ROLE_PROMOTED_LEGACY_S
+//! \deprecated Do not use
+#define RSC_ROLE_PROMOTED_LEGACY_S "Master"
+//! \deprecated Do not use
+#define RSC_ROLE_MASTER_S RSC_ROLE_PROMOTED_LEGACY_S
#ifdef __cplusplus
}
diff --git a/include/crm/pengine/complex.h b/include/crm/pengine/complex.h
index 929e4da..9b6ad1b 100644
--- a/include/crm/pengine/complex.h
+++ b/include/crm/pengine/complex.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2022 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -12,23 +12,23 @@
#include <glib.h> // gboolean, GHashTable
#include <libxml/tree.h> // xmlNode
-#include <crm/pengine/pe_types.h> // pe_node_t, pe_resource_t, etc.
+#include <crm/pengine/pe_types.h> // pcmk_node_t, pcmk_resource_t, etc.
#ifdef __cplusplus
extern "C" {
#endif
-extern resource_object_functions_t resource_class_functions[];
+extern pcmk_rsc_methods_t resource_class_functions[];
-GHashTable *pe_rsc_params(pe_resource_t *rsc, const pe_node_t *node,
- pe_working_set_t *data_set);
-void get_meta_attributes(GHashTable * meta_hash, pe_resource_t *rsc,
- pe_node_t *node, pe_working_set_t *data_set);
-void get_rsc_attributes(GHashTable *meta_hash, const pe_resource_t *rsc,
- const pe_node_t *node, pe_working_set_t *data_set);
+GHashTable *pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node,
+ pcmk_scheduler_t *scheduler);
+void get_meta_attributes(GHashTable * meta_hash, pcmk_resource_t *rsc,
+ pcmk_node_t *node, pcmk_scheduler_t *scheduler);
+void get_rsc_attributes(GHashTable *meta_hash, const pcmk_resource_t *rsc,
+ const pcmk_node_t *node, pcmk_scheduler_t *scheduler);
-gboolean is_parent(pe_resource_t *child, pe_resource_t *rsc);
-pe_resource_t *uber_parent(pe_resource_t *rsc);
+gboolean is_parent(pcmk_resource_t *child, pcmk_resource_t *rsc);
+pcmk_resource_t *uber_parent(pcmk_resource_t *rsc);
#ifdef __cplusplus
}
diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h
index 1b5f6f1..9c8068f 100644
--- a/include/crm/pengine/internal.h
+++ b/include/crm/pengine/internal.h
@@ -10,6 +10,7 @@
#ifndef PE_INTERNAL__H
# define PE_INTERNAL__H
+# include <stdbool.h>
# include <stdint.h>
# include <string.h>
# include <crm/msg_xml.h>
@@ -18,31 +19,17 @@
# include <crm/common/internal.h>
# include <crm/common/options_internal.h>
# include <crm/common/output_internal.h>
+# include <crm/common/scheduler_internal.h>
-const char *pe__resource_description(const pe_resource_t *rsc, uint32_t show_opts);
+const char *pe__resource_description(const pcmk_resource_t *rsc,
+ uint32_t show_opts);
-enum pe__clone_flags {
- // Whether instances should be started sequentially
- pe__clone_ordered = (1 << 0),
+bool pe__clone_is_ordered(const pcmk_resource_t *clone);
+int pe__set_clone_flag(pcmk_resource_t *clone, enum pcmk__clone_flags flag);
+bool pe__clone_flag_is_set(const pcmk_resource_t *clone, uint32_t flags);
- // Whether promotion scores have been added
- pe__clone_promotion_added = (1 << 1),
-
- // Whether promotion constraints have been added
- pe__clone_promotion_constrained = (1 << 2),
-};
-
-bool pe__clone_is_ordered(const pe_resource_t *clone);
-int pe__set_clone_flag(pe_resource_t *clone, enum pe__clone_flags flag);
-
-
-enum pe__group_flags {
- pe__group_ordered = (1 << 0), // Members start sequentially
- pe__group_colocated = (1 << 1), // Members must be on same node
-};
-
-bool pe__group_flag_is_set(const pe_resource_t *group, uint32_t flags);
-pe_resource_t *pe__last_group_member(const pe_resource_t *group);
+bool pe__group_flag_is_set(const pcmk_resource_t *group, uint32_t flags);
+pcmk_resource_t *pe__last_group_member(const pcmk_resource_t *group);
# define pe_rsc_info(rsc, fmt, args...) crm_log_tag(LOG_INFO, rsc ? rsc->id : "<NULL>", fmt, ##args)
@@ -62,16 +49,16 @@ pe_resource_t *pe__last_group_member(const pe_resource_t *group);
# define pe_proc_err(fmt...) { was_processing_error = TRUE; crm_err(fmt); }
# define pe_proc_warn(fmt...) { was_processing_warning = TRUE; crm_warn(fmt); }
-#define pe__set_working_set_flags(working_set, flags_to_set) do { \
- (working_set)->flags = pcmk__set_flags_as(__func__, __LINE__, \
- LOG_TRACE, "Working set", crm_system_name, \
- (working_set)->flags, (flags_to_set), #flags_to_set); \
+#define pe__set_working_set_flags(scheduler, flags_to_set) do { \
+ (scheduler)->flags = pcmk__set_flags_as(__func__, __LINE__, \
+ LOG_TRACE, "Scheduler", crm_system_name, \
+ (scheduler)->flags, (flags_to_set), #flags_to_set); \
} while (0)
-#define pe__clear_working_set_flags(working_set, flags_to_clear) do { \
- (working_set)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
- LOG_TRACE, "Working set", crm_system_name, \
- (working_set)->flags, (flags_to_clear), #flags_to_clear); \
+#define pe__clear_working_set_flags(scheduler, flags_to_clear) do { \
+ (scheduler)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
+ LOG_TRACE, "Scheduler", crm_system_name, \
+ (scheduler)->flags, (flags_to_clear), #flags_to_clear); \
} while (0)
#define pe__set_resource_flags(resource, flags_to_set) do { \
@@ -152,144 +139,127 @@ pe_resource_t *pe__last_group_member(const pe_resource_t *group);
#flags_to_clear); \
} while (0)
-// Some warnings we don't want to print every transition
-
-enum pe_warn_once_e {
- pe_wo_blind = (1 << 0),
- pe_wo_restart_type = (1 << 1),
- pe_wo_role_after = (1 << 2),
- pe_wo_poweroff = (1 << 3),
- pe_wo_require_all = (1 << 4),
- pe_wo_order_score = (1 << 5),
- pe_wo_neg_threshold = (1 << 6),
- pe_wo_remove_after = (1 << 7),
- pe_wo_ping_node = (1 << 8),
- pe_wo_order_inst = (1 << 9),
- pe_wo_coloc_inst = (1 << 10),
- pe_wo_group_order = (1 << 11),
- pe_wo_group_coloc = (1 << 12),
- pe_wo_upstart = (1 << 13),
- pe_wo_nagios = (1 << 14),
-};
-
-extern uint32_t pe_wo;
-
#define pe_warn_once(pe_wo_bit, fmt...) do { \
- if (!pcmk_is_set(pe_wo, pe_wo_bit)) { \
- if (pe_wo_bit == pe_wo_blind) { \
+ if (!pcmk_is_set(pcmk__warnings, pe_wo_bit)) { \
+ if (pe_wo_bit == pcmk__wo_blind) { \
crm_warn(fmt); \
} else { \
pe_warn(fmt); \
} \
- pe_wo = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
- "Warn-once", "logging", pe_wo, \
- (pe_wo_bit), #pe_wo_bit); \
- } \
+ pcmk__warnings = pcmk__set_flags_as(__func__, __LINE__, \
+ LOG_TRACE, \
+ "Warn-once", "logging", \
+ pcmk__warnings, \
+ (pe_wo_bit), #pe_wo_bit); \
+ } \
} while (0);
typedef struct pe__location_constraint_s {
char *id; // Constraint XML ID
- pe_resource_t *rsc_lh; // Resource being located
+ pcmk_resource_t *rsc_lh; // Resource being located
enum rsc_role_e role_filter; // Role to locate
enum pe_discover_e discover_mode; // Resource discovery
- GList *node_list_rh; // List of pe_node_t*
+ GList *node_list_rh; // List of pcmk_node_t*
} pe__location_t;
typedef struct pe__order_constraint_s {
int id;
- uint32_t flags; // Group of enum pe_ordering flags
+ uint32_t flags; // Group of enum pcmk__action_relation_flags
void *lh_opaque;
- pe_resource_t *lh_rsc;
- pe_action_t *lh_action;
+ pcmk_resource_t *lh_rsc;
+ pcmk_action_t *lh_action;
char *lh_action_task;
void *rh_opaque;
- pe_resource_t *rh_rsc;
- pe_action_t *rh_action;
+ pcmk_resource_t *rh_rsc;
+ pcmk_action_t *rh_action;
char *rh_action_task;
} pe__ordering_t;
-const pe_resource_t *pe__const_top_resource(const pe_resource_t *rsc,
- bool include_bundle);
+const pcmk_resource_t *pe__const_top_resource(const pcmk_resource_t *rsc,
+ bool include_bundle);
-int pe__clone_max(const pe_resource_t *clone);
-int pe__clone_node_max(const pe_resource_t *clone);
-int pe__clone_promoted_max(const pe_resource_t *clone);
-int pe__clone_promoted_node_max(const pe_resource_t *clone);
-void pe__create_clone_notifications(pe_resource_t *clone);
-void pe__free_clone_notification_data(pe_resource_t *clone);
-void pe__create_clone_notif_pseudo_ops(pe_resource_t *clone,
- pe_action_t *start, pe_action_t *started,
- pe_action_t *stop, pe_action_t *stopped);
+int pe__clone_max(const pcmk_resource_t *clone);
+int pe__clone_node_max(const pcmk_resource_t *clone);
+int pe__clone_promoted_max(const pcmk_resource_t *clone);
+int pe__clone_promoted_node_max(const pcmk_resource_t *clone);
+void pe__create_clone_notifications(pcmk_resource_t *clone);
+void pe__free_clone_notification_data(pcmk_resource_t *clone);
+void pe__create_clone_notif_pseudo_ops(pcmk_resource_t *clone,
+ pcmk_action_t *start,
+ pcmk_action_t *started,
+ pcmk_action_t *stop,
+ pcmk_action_t *stopped);
+pcmk_action_t *pe__new_rsc_pseudo_action(pcmk_resource_t *rsc, const char *task,
+ bool optional, bool runnable);
-pe_action_t *pe__new_rsc_pseudo_action(pe_resource_t *rsc, const char *task,
- bool optional, bool runnable);
+void pe__create_promotable_pseudo_ops(pcmk_resource_t *clone,
+ bool any_promoting, bool any_demoting);
-void pe__create_promotable_pseudo_ops(pe_resource_t *clone, bool any_promoting,
- bool any_demoting);
-
-bool pe_can_fence(const pe_working_set_t *data_set, const pe_node_t *node);
+bool pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node);
void add_hash_param(GHashTable * hash, const char *name, const char *value);
-char *native_parameter(pe_resource_t * rsc, pe_node_t * node, gboolean create, const char *name,
- pe_working_set_t * data_set);
-pe_node_t *native_location(const pe_resource_t *rsc, GList **list, int current);
+char *native_parameter(pcmk_resource_t *rsc, pcmk_node_t *node, gboolean create,
+ const char *name, pcmk_scheduler_t *scheduler);
+pcmk_node_t *native_location(const pcmk_resource_t *rsc, GList **list,
+ int current);
void pe_metadata(pcmk__output_t *out);
void verify_pe_options(GHashTable * options);
-void native_add_running(pe_resource_t * rsc, pe_node_t * node, pe_working_set_t * data_set, gboolean failed);
+void native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node,
+ pcmk_scheduler_t *scheduler, gboolean failed);
-gboolean native_unpack(pe_resource_t * rsc, pe_working_set_t * data_set);
-gboolean group_unpack(pe_resource_t * rsc, pe_working_set_t * data_set);
-gboolean clone_unpack(pe_resource_t * rsc, pe_working_set_t * data_set);
-gboolean pe__unpack_bundle(pe_resource_t *rsc, pe_working_set_t *data_set);
+gboolean native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler);
+gboolean group_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler);
+gboolean clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler);
+gboolean pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler);
-pe_resource_t *native_find_rsc(pe_resource_t *rsc, const char *id, const pe_node_t *node,
- int flags);
+pcmk_resource_t *native_find_rsc(pcmk_resource_t *rsc, const char *id,
+ const pcmk_node_t *node, int flags);
-gboolean native_active(pe_resource_t * rsc, gboolean all);
-gboolean group_active(pe_resource_t * rsc, gboolean all);
-gboolean clone_active(pe_resource_t * rsc, gboolean all);
-gboolean pe__bundle_active(pe_resource_t *rsc, gboolean all);
+gboolean native_active(pcmk_resource_t *rsc, gboolean all);
+gboolean group_active(pcmk_resource_t *rsc, gboolean all);
+gboolean clone_active(pcmk_resource_t *rsc, gboolean all);
+gboolean pe__bundle_active(pcmk_resource_t *rsc, gboolean all);
//! \deprecated This function will be removed in a future release
-void native_print(pe_resource_t *rsc, const char *pre_text, long options,
+void native_print(pcmk_resource_t *rsc, const char *pre_text, long options,
void *print_data);
//! \deprecated This function will be removed in a future release
-void group_print(pe_resource_t *rsc, const char *pre_text, long options,
+void group_print(pcmk_resource_t *rsc, const char *pre_text, long options,
void *print_data);
//! \deprecated This function will be removed in a future release
-void clone_print(pe_resource_t *rsc, const char *pre_text, long options,
+void clone_print(pcmk_resource_t *rsc, const char *pre_text, long options,
void *print_data);
//! \deprecated This function will be removed in a future release
-void pe__print_bundle(pe_resource_t *rsc, const char *pre_text, long options,
+void pe__print_bundle(pcmk_resource_t *rsc, const char *pre_text, long options,
void *print_data);
-gchar *pcmk__native_output_string(const pe_resource_t *rsc, const char *name,
- const pe_node_t *node, uint32_t show_opts,
+gchar *pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name,
+ const pcmk_node_t *node, uint32_t show_opts,
const char *target_role, bool show_nodes);
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name
, size_t pairs_count, ...);
-char *pe__node_display_name(pe_node_t *node, bool print_detail);
+char *pe__node_display_name(pcmk_node_t *node, bool print_detail);
// Clone notifications (pe_notif.c)
-void pe__order_notifs_after_fencing(const pe_action_t *action,
- pe_resource_t *rsc,
- pe_action_t *stonith_op);
+void pe__order_notifs_after_fencing(const pcmk_action_t *action,
+ pcmk_resource_t *rsc,
+ pcmk_action_t *stonith_op);
static inline const char *
-pe__rsc_bool_str(const pe_resource_t *rsc, uint64_t rsc_flag)
+pe__rsc_bool_str(const pcmk_resource_t *rsc, uint64_t rsc_flag)
{
return pcmk__btoa(pcmk_is_set(rsc->flags, rsc_flag));
}
@@ -308,167 +278,156 @@ int pe__resource_xml(pcmk__output_t *out, va_list args);
int pe__resource_html(pcmk__output_t *out, va_list args);
int pe__resource_text(pcmk__output_t *out, va_list args);
-void native_free(pe_resource_t * rsc);
-void group_free(pe_resource_t * rsc);
-void clone_free(pe_resource_t * rsc);
-void pe__free_bundle(pe_resource_t *rsc);
-
-enum rsc_role_e native_resource_state(const pe_resource_t * rsc, gboolean current);
-enum rsc_role_e group_resource_state(const pe_resource_t * rsc, gboolean current);
-enum rsc_role_e clone_resource_state(const pe_resource_t * rsc, gboolean current);
-enum rsc_role_e pe__bundle_resource_state(const pe_resource_t *rsc,
+void native_free(pcmk_resource_t *rsc);
+void group_free(pcmk_resource_t *rsc);
+void clone_free(pcmk_resource_t *rsc);
+void pe__free_bundle(pcmk_resource_t *rsc);
+
+enum rsc_role_e native_resource_state(const pcmk_resource_t *rsc,
+ gboolean current);
+enum rsc_role_e group_resource_state(const pcmk_resource_t *rsc,
+ gboolean current);
+enum rsc_role_e clone_resource_state(const pcmk_resource_t *rsc,
+ gboolean current);
+enum rsc_role_e pe__bundle_resource_state(const pcmk_resource_t *rsc,
gboolean current);
-void pe__count_common(pe_resource_t *rsc);
-void pe__count_bundle(pe_resource_t *rsc);
+void pe__count_common(pcmk_resource_t *rsc);
+void pe__count_bundle(pcmk_resource_t *rsc);
-void common_free(pe_resource_t * rsc);
+void common_free(pcmk_resource_t *rsc);
-pe_node_t *pe__copy_node(const pe_node_t *this_node);
-extern time_t get_effective_time(pe_working_set_t * data_set);
+pcmk_node_t *pe__copy_node(const pcmk_node_t *this_node);
+time_t get_effective_time(pcmk_scheduler_t *scheduler);
/* Failure handling utilities (from failcounts.c) */
-// bit flags for fail count handling options
-enum pe_fc_flags_e {
- pe_fc_default = (1 << 0),
- pe_fc_effective = (1 << 1), // don't count expired failures
- pe_fc_fillers = (1 << 2), // if container, include filler failures in count
-};
-
-int pe_get_failcount(const pe_node_t *node, pe_resource_t *rsc,
+int pe_get_failcount(const pcmk_node_t *node, pcmk_resource_t *rsc,
time_t *last_failure, uint32_t flags,
const xmlNode *xml_op);
-pe_action_t *pe__clear_failcount(pe_resource_t *rsc, const pe_node_t *node,
- const char *reason,
- pe_working_set_t *data_set);
+pcmk_action_t *pe__clear_failcount(pcmk_resource_t *rsc,
+ const pcmk_node_t *node, const char *reason,
+ pcmk_scheduler_t *scheduler);
/* Functions for finding/counting a resource's active nodes */
-bool pe__count_active_node(const pe_resource_t *rsc, pe_node_t *node,
- pe_node_t **active, unsigned int *count_all,
+bool pe__count_active_node(const pcmk_resource_t *rsc, pcmk_node_t *node,
+ pcmk_node_t **active, unsigned int *count_all,
unsigned int *count_clean);
-pe_node_t *pe__find_active_requires(const pe_resource_t *rsc,
+pcmk_node_t *pe__find_active_requires(const pcmk_resource_t *rsc,
unsigned int *count);
-static inline pe_node_t *
-pe__current_node(const pe_resource_t *rsc)
+static inline pcmk_node_t *
+pe__current_node(const pcmk_resource_t *rsc)
{
return (rsc == NULL)? NULL : rsc->fns->active_node(rsc, NULL, NULL);
}
/* Binary like operators for lists of nodes */
-extern void node_list_exclude(GHashTable * list, GList *list2, gboolean merge_scores);
-
GHashTable *pe__node_list2table(const GList *list);
-static inline gpointer
-pe_hash_table_lookup(GHashTable * hash, gconstpointer key)
-{
- if (hash) {
- return g_hash_table_lookup(hash, key);
- }
- return NULL;
-}
-
-extern pe_action_t *get_pseudo_op(const char *name, pe_working_set_t * data_set);
-extern gboolean order_actions(pe_action_t * lh_action, pe_action_t * rh_action, enum pe_ordering order);
-
-void pe__show_node_weights_as(const char *file, const char *function,
- int line, bool to_log, const pe_resource_t *rsc,
- const char *comment, GHashTable *nodes,
- pe_working_set_t *data_set);
-
-#define pe__show_node_weights(level, rsc, text, nodes, data_set) \
- pe__show_node_weights_as(__FILE__, __func__, __LINE__, \
- (level), (rsc), (text), (nodes), (data_set))
-
-xmlNode *find_rsc_op_entry(const pe_resource_t *rsc, const char *key);
-
-pe_action_t *custom_action(pe_resource_t *rsc, char *key, const char *task,
- const pe_node_t *on_node, gboolean optional,
- gboolean foo, pe_working_set_t *data_set);
-
-# define delete_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_DELETE, 0)
+pcmk_action_t *get_pseudo_op(const char *name, pcmk_scheduler_t *scheduler);
+gboolean order_actions(pcmk_action_t *lh_action, pcmk_action_t *rh_action,
+ uint32_t flags);
+
+void pe__show_node_scores_as(const char *file, const char *function,
+ int line, bool to_log, const pcmk_resource_t *rsc,
+ const char *comment, GHashTable *nodes,
+ pcmk_scheduler_t *scheduler);
+
+#define pe__show_node_scores(level, rsc, text, nodes, scheduler) \
+ pe__show_node_scores_as(__FILE__, __func__, __LINE__, \
+ (level), (rsc), (text), (nodes), (scheduler))
+
+GHashTable *pcmk__unpack_action_meta(pcmk_resource_t *rsc,
+ const pcmk_node_t *node,
+ const char *action_name, guint interval_ms,
+ const xmlNode *action_config);
+GHashTable *pcmk__unpack_action_rsc_params(const xmlNode *action_xml,
+ GHashTable *node_attrs,
+ pcmk_scheduler_t *data_set);
+xmlNode *pcmk__find_action_config(const pcmk_resource_t *rsc,
+ const char *action_name, guint interval_ms,
+ bool include_disabled);
+
+enum rsc_start_requirement pcmk__action_requires(const pcmk_resource_t *rsc,
+ const char *action_name);
+
+enum action_fail_response pcmk__parse_on_fail(const pcmk_resource_t *rsc,
+ const char *action_name,
+ guint interval_ms,
+ const char *value);
+
+enum rsc_role_e pcmk__role_after_failure(const pcmk_resource_t *rsc,
+ const char *action_name,
+ enum action_fail_response on_fail,
+ GHashTable *meta);
+
+pcmk_action_t *custom_action(pcmk_resource_t *rsc, char *key, const char *task,
+ const pcmk_node_t *on_node, gboolean optional,
+ pcmk_scheduler_t *scheduler);
+
+# define delete_key(rsc) pcmk__op_key(rsc->id, PCMK_ACTION_DELETE, 0)
# define delete_action(rsc, node, optional) custom_action( \
- rsc, delete_key(rsc), CRMD_ACTION_DELETE, node, \
- optional, TRUE, rsc->cluster);
-
-# define stopped_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_STOPPED, 0)
-# define stopped_action(rsc, node, optional) custom_action( \
- rsc, stopped_key(rsc), CRMD_ACTION_STOPPED, node, \
- optional, TRUE, rsc->cluster);
+ rsc, delete_key(rsc), PCMK_ACTION_DELETE, node, \
+ optional, rsc->cluster);
-# define stop_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_STOP, 0)
+# define stop_key(rsc) pcmk__op_key(rsc->id, PCMK_ACTION_STOP, 0)
# define stop_action(rsc, node, optional) custom_action( \
- rsc, stop_key(rsc), CRMD_ACTION_STOP, node, \
- optional, TRUE, rsc->cluster);
+ rsc, stop_key(rsc), PCMK_ACTION_STOP, node, \
+ optional, rsc->cluster);
-# define reload_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_RELOAD_AGENT, 0)
-# define start_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_START, 0)
+# define reload_key(rsc) pcmk__op_key(rsc->id, PCMK_ACTION_RELOAD_AGENT, 0)
+# define start_key(rsc) pcmk__op_key(rsc->id, PCMK_ACTION_START, 0)
# define start_action(rsc, node, optional) custom_action( \
- rsc, start_key(rsc), CRMD_ACTION_START, node, \
- optional, TRUE, rsc->cluster)
+ rsc, start_key(rsc), PCMK_ACTION_START, node, \
+ optional, rsc->cluster)
-# define started_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_STARTED, 0)
-# define started_action(rsc, node, optional) custom_action( \
- rsc, started_key(rsc), CRMD_ACTION_STARTED, node, \
- optional, TRUE, rsc->cluster)
-
-# define promote_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_PROMOTE, 0)
+# define promote_key(rsc) pcmk__op_key(rsc->id, PCMK_ACTION_PROMOTE, 0)
# define promote_action(rsc, node, optional) custom_action( \
- rsc, promote_key(rsc), CRMD_ACTION_PROMOTE, node, \
- optional, TRUE, rsc->cluster)
-
-# define promoted_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_PROMOTED, 0)
-# define promoted_action(rsc, node, optional) custom_action( \
- rsc, promoted_key(rsc), CRMD_ACTION_PROMOTED, node, \
- optional, TRUE, rsc->cluster)
+ rsc, promote_key(rsc), PCMK_ACTION_PROMOTE, node, \
+ optional, rsc->cluster)
-# define demote_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_DEMOTE, 0)
+# define demote_key(rsc) pcmk__op_key(rsc->id, PCMK_ACTION_DEMOTE, 0)
# define demote_action(rsc, node, optional) custom_action( \
- rsc, demote_key(rsc), CRMD_ACTION_DEMOTE, node, \
- optional, TRUE, rsc->cluster)
+ rsc, demote_key(rsc), PCMK_ACTION_DEMOTE, node, \
+ optional, rsc->cluster)
-# define demoted_key(rsc) pcmk__op_key(rsc->id, CRMD_ACTION_DEMOTED, 0)
-# define demoted_action(rsc, node, optional) custom_action( \
- rsc, demoted_key(rsc), CRMD_ACTION_DEMOTED, node, \
- optional, TRUE, rsc->cluster)
+extern int pe_get_configured_timeout(pcmk_resource_t *rsc, const char *action,
+ pcmk_scheduler_t *scheduler);
-extern int pe_get_configured_timeout(pe_resource_t *rsc, const char *action,
- pe_working_set_t *data_set);
+pcmk_action_t *find_first_action(const GList *input, const char *uuid,
+ const char *task, const pcmk_node_t *on_node);
-pe_action_t *find_first_action(const GList *input, const char *uuid,
- const char *task, const pe_node_t *on_node);
+enum action_tasks get_complex_task(const pcmk_resource_t *rsc,
+ const char *name);
-enum action_tasks get_complex_task(const pe_resource_t *rsc, const char *name);
-
-extern GList *find_actions(GList *input, const char *key, const pe_node_t *on_node);
+GList *find_actions(GList *input, const char *key, const pcmk_node_t *on_node);
GList *find_actions_exact(GList *input, const char *key,
- const pe_node_t *on_node);
-GList *pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node,
+ const pcmk_node_t *on_node);
+GList *pe__resource_actions(const pcmk_resource_t *rsc, const pcmk_node_t *node,
const char *task, bool require_node);
-extern void pe_free_action(pe_action_t * action);
+extern void pe_free_action(pcmk_action_t *action);
-void resource_location(pe_resource_t *rsc, const pe_node_t *node, int score,
- const char *tag, pe_working_set_t *data_set);
+void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score,
+ const char *tag, pcmk_scheduler_t *scheduler);
extern int pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b,
bool same_node_default);
extern gint sort_op_by_callid(gconstpointer a, gconstpointer b);
-gboolean get_target_role(const pe_resource_t *rsc, enum rsc_role_e *role);
-void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role,
+gboolean get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role);
+void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role,
const char *why);
-pe_resource_t *find_clone_instance(const pe_resource_t *rsc,
- const char *sub_id);
+pcmk_resource_t *find_clone_instance(const pcmk_resource_t *rsc,
+ const char *sub_id);
extern void destroy_ticket(gpointer data);
-extern pe_ticket_t *ticket_new(const char *ticket_id, pe_working_set_t * data_set);
+pcmk_ticket_t *ticket_new(const char *ticket_id, pcmk_scheduler_t *scheduler);
// Resources for manipulating resource names
const char *pe_base_name_end(const char *id);
@@ -476,7 +435,7 @@ char *clone_strip(const char *last_rsc_id);
char *clone_zero(const char *last_rsc_id);
static inline bool
-pe_base_name_eq(const pe_resource_t *rsc, const char *id)
+pe_base_name_eq(const pcmk_resource_t *rsc, const char *id)
{
if (id && rsc && rsc->id) {
// Number of characters in rsc->id before any clone suffix
@@ -490,22 +449,10 @@ pe_base_name_eq(const pe_resource_t *rsc, const char *id)
int pe__target_rc_from_xml(const xmlNode *xml_op);
gint pe__cmp_node_name(gconstpointer a, gconstpointer b);
-bool is_set_recursive(const pe_resource_t *rsc, long long flag, bool any);
-
-enum rsc_digest_cmp_val {
- /*! Digests are the same */
- RSC_DIGEST_MATCH = 0,
- /*! Params that require a restart changed */
- RSC_DIGEST_RESTART,
- /*! Some parameter changed. */
- RSC_DIGEST_ALL,
- /*! rsc op didn't have a digest associated with it, so
- * it is unknown if parameters changed or not. */
- RSC_DIGEST_UNKNOWN,
-};
+bool is_set_recursive(const pcmk_resource_t *rsc, long long flag, bool any);
typedef struct op_digest_cache_s {
- enum rsc_digest_cmp_val rc;
+ enum pcmk__digest_result rc;
xmlNode *params_all;
xmlNode *params_secure;
xmlNode *params_restart;
@@ -514,35 +461,37 @@ typedef struct op_digest_cache_s {
char *digest_restart_calc;
} op_digest_cache_t;
-op_digest_cache_t *pe__calculate_digests(pe_resource_t *rsc, const char *task,
+op_digest_cache_t *pe__calculate_digests(pcmk_resource_t *rsc, const char *task,
guint *interval_ms,
- const pe_node_t *node,
+ const pcmk_node_t *node,
const xmlNode *xml_op,
GHashTable *overrides,
bool calc_secure,
- pe_working_set_t *data_set);
+ pcmk_scheduler_t *scheduler);
void pe__free_digests(gpointer ptr);
-op_digest_cache_t *rsc_action_digest_cmp(pe_resource_t *rsc,
+op_digest_cache_t *rsc_action_digest_cmp(pcmk_resource_t *rsc,
const xmlNode *xml_op,
- pe_node_t *node,
- pe_working_set_t *data_set);
-
-pe_action_t *pe_fence_op(pe_node_t *node, const char *op, bool optional,
- const char *reason, bool priority_delay,
- pe_working_set_t *data_set);
-void trigger_unfencing(pe_resource_t *rsc, pe_node_t *node,
- const char *reason, pe_action_t *dependency,
- pe_working_set_t *data_set);
-
-char *pe__action2reason(const pe_action_t *action, enum pe_action_flags flag);
-void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite);
-void pe__add_action_expected_result(pe_action_t *action, int expected_result);
-
-void pe__set_resource_flags_recursive(pe_resource_t *rsc, uint64_t flags);
-void pe__clear_resource_flags_recursive(pe_resource_t *rsc, uint64_t flags);
-void pe__clear_resource_flags_on_all(pe_working_set_t *data_set, uint64_t flag);
+ pcmk_node_t *node,
+ pcmk_scheduler_t *scheduler);
+
+pcmk_action_t *pe_fence_op(pcmk_node_t *node, const char *op, bool optional,
+ const char *reason, bool priority_delay,
+ pcmk_scheduler_t *scheduler);
+void trigger_unfencing(pcmk_resource_t *rsc, pcmk_node_t *node,
+ const char *reason, pcmk_action_t *dependency,
+ pcmk_scheduler_t *scheduler);
+
+char *pe__action2reason(const pcmk_action_t *action, enum pe_action_flags flag);
+void pe_action_set_reason(pcmk_action_t *action, const char *reason,
+ bool overwrite);
+void pe__add_action_expected_result(pcmk_action_t *action, int expected_result);
+
+void pe__set_resource_flags_recursive(pcmk_resource_t *rsc, uint64_t flags);
+void pe__clear_resource_flags_recursive(pcmk_resource_t *rsc, uint64_t flags);
+void pe__clear_resource_flags_on_all(pcmk_scheduler_t *scheduler,
+ uint64_t flag);
gboolean add_tag_ref(GHashTable * tags, const char * tag_name, const char * obj_ref);
@@ -550,49 +499,75 @@ gboolean add_tag_ref(GHashTable * tags, const char * tag_name, const char * obj
void print_rscs_brief(GList *rsc_list, const char * pre_text, long options,
void * print_data, gboolean print_all);
int pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, unsigned int options);
-void pe_fence_node(pe_working_set_t * data_set, pe_node_t * node, const char *reason, bool priority_delay);
+void pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node,
+ const char *reason, bool priority_delay);
-pe_node_t *pe_create_node(const char *id, const char *uname, const char *type,
- const char *score, pe_working_set_t * data_set);
+pcmk_node_t *pe_create_node(const char *id, const char *uname, const char *type,
+ const char *score, pcmk_scheduler_t *scheduler);
//! \deprecated This function will be removed in a future release
-void common_print(pe_resource_t *rsc, const char *pre_text, const char *name,
- const pe_node_t *node, long options, void *print_data);
-int pe__common_output_text(pcmk__output_t *out, const pe_resource_t *rsc,
- const char *name, const pe_node_t *node,
+void common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name,
+ const pcmk_node_t *node, long options, void *print_data);
+int pe__common_output_text(pcmk__output_t *out, const pcmk_resource_t *rsc,
+ const char *name, const pcmk_node_t *node,
unsigned int options);
-int pe__common_output_html(pcmk__output_t *out, const pe_resource_t *rsc,
- const char *name, const pe_node_t *node,
+int pe__common_output_html(pcmk__output_t *out, const pcmk_resource_t *rsc,
+ const char *name, const pcmk_node_t *node,
unsigned int options);
-GList *pe__bundle_containers(const pe_resource_t *bundle);
-
-int pe__bundle_max(const pe_resource_t *rsc);
-int pe__bundle_max_per_node(const pe_resource_t *rsc);
-
-pe_resource_t *pe__find_bundle_replica(const pe_resource_t *bundle,
- const pe_node_t *node);
-bool pe__bundle_needs_remote_name(pe_resource_t *rsc);
-const char *pe__add_bundle_remote_name(pe_resource_t *rsc,
- pe_working_set_t *data_set,
+//! A single instance of a bundle
+typedef struct {
+ int offset; //!< 0-origin index of this instance in bundle
+ char *ipaddr; //!< IP address associated with this instance
+ pcmk_node_t *node; //!< Node created for this instance
+ pcmk_resource_t *ip; //!< IP address resource for ipaddr
+ pcmk_resource_t *child; //!< Instance of bundled resource
+ pcmk_resource_t *container; //!< Container associated with this instance
+ pcmk_resource_t *remote; //!< Pacemaker Remote connection into container
+} pe__bundle_replica_t;
+
+GList *pe__bundle_containers(const pcmk_resource_t *bundle);
+
+int pe__bundle_max(const pcmk_resource_t *rsc);
+bool pe__node_is_bundle_instance(const pcmk_resource_t *bundle,
+ const pcmk_node_t *node);
+pcmk_resource_t *pe__bundled_resource(const pcmk_resource_t *rsc);
+const pcmk_resource_t *pe__get_rsc_in_container(const pcmk_resource_t *instance);
+pcmk_resource_t *pe__first_container(const pcmk_resource_t *bundle);
+void pe__foreach_bundle_replica(pcmk_resource_t *bundle,
+ bool (*fn)(pe__bundle_replica_t *, void *),
+ void *user_data);
+void pe__foreach_const_bundle_replica(const pcmk_resource_t *bundle,
+ bool (*fn)(const pe__bundle_replica_t *,
+ void *),
+ void *user_data);
+pcmk_resource_t *pe__find_bundle_replica(const pcmk_resource_t *bundle,
+ const pcmk_node_t *node);
+bool pe__bundle_needs_remote_name(pcmk_resource_t *rsc);
+const char *pe__add_bundle_remote_name(pcmk_resource_t *rsc,
+ pcmk_scheduler_t *scheduler,
xmlNode *xml, const char *field);
-const char *pe_node_attribute_calculated(const pe_node_t *node,
- const char *name,
- const pe_resource_t *rsc);
-const char *pe_node_attribute_raw(const pe_node_t *node, const char *name);
-bool pe__is_universal_clone(const pe_resource_t *rsc,
- const pe_working_set_t *data_set);
-void pe__add_param_check(const xmlNode *rsc_op, pe_resource_t *rsc,
- pe_node_t *node, enum pe_check_parameters,
- pe_working_set_t *data_set);
-void pe__foreach_param_check(pe_working_set_t *data_set,
- void (*cb)(pe_resource_t*, pe_node_t*,
+
+const char *pe__node_attribute_calculated(const pcmk_node_t *node,
+ const char *name,
+ const pcmk_resource_t *rsc,
+ enum pcmk__rsc_node node_type,
+ bool force_host);
+const char *pe_node_attribute_raw(const pcmk_node_t *node, const char *name);
+bool pe__is_universal_clone(const pcmk_resource_t *rsc,
+ const pcmk_scheduler_t *scheduler);
+void pe__add_param_check(const xmlNode *rsc_op, pcmk_resource_t *rsc,
+ pcmk_node_t *node, enum pcmk__check_parameters,
+ pcmk_scheduler_t *scheduler);
+void pe__foreach_param_check(pcmk_scheduler_t *scheduler,
+ void (*cb)(pcmk_resource_t*, pcmk_node_t*,
const xmlNode*,
- enum pe_check_parameters));
-void pe__free_param_checks(pe_working_set_t *data_set);
+ enum pcmk__check_parameters));
+void pe__free_param_checks(pcmk_scheduler_t *scheduler);
-bool pe__shutdown_requested(const pe_node_t *node);
-void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set);
+bool pe__shutdown_requested(const pcmk_node_t *node);
+void pe__update_recheck_time(time_t recheck, pcmk_scheduler_t *scheduler,
+ const char *reason);
/*!
* \internal
@@ -605,53 +580,55 @@ void pe__register_messages(pcmk__output_t *out);
void pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name,
const pe_rule_eval_data_t *rule_data,
GHashTable *hash, const char *always_first,
- gboolean overwrite, pe_working_set_t *data_set);
-
-bool pe__resource_is_disabled(const pe_resource_t *rsc);
-pe_action_t *pe__clear_resource_history(pe_resource_t *rsc,
- const pe_node_t *node,
- pe_working_set_t *data_set);
-
-GList *pe__rscs_with_tag(pe_working_set_t *data_set, const char *tag_name);
-GList *pe__unames_with_tag(pe_working_set_t *data_set, const char *tag_name);
-bool pe__rsc_has_tag(pe_working_set_t *data_set, const char *rsc, const char *tag);
-bool pe__uname_has_tag(pe_working_set_t *data_set, const char *node, const char *tag);
-
-bool pe__rsc_running_on_only(const pe_resource_t *rsc, const pe_node_t *node);
-bool pe__rsc_running_on_any(pe_resource_t *rsc, GList *node_list);
+ gboolean overwrite,
+ pcmk_scheduler_t *scheduler);
+
+bool pe__resource_is_disabled(const pcmk_resource_t *rsc);
+void pe__clear_resource_history(pcmk_resource_t *rsc, const pcmk_node_t *node);
+
+GList *pe__rscs_with_tag(pcmk_scheduler_t *scheduler, const char *tag_name);
+GList *pe__unames_with_tag(pcmk_scheduler_t *scheduler, const char *tag_name);
+bool pe__rsc_has_tag(pcmk_scheduler_t *scheduler, const char *rsc,
+ const char *tag);
+bool pe__uname_has_tag(pcmk_scheduler_t *scheduler, const char *node,
+ const char *tag);
+
+bool pe__rsc_running_on_only(const pcmk_resource_t *rsc,
+ const pcmk_node_t *node);
+bool pe__rsc_running_on_any(pcmk_resource_t *rsc, GList *node_list);
GList *pe__filter_rsc_list(GList *rscs, GList *filter);
-GList * pe__build_node_name_list(pe_working_set_t *data_set, const char *s);
-GList * pe__build_rsc_list(pe_working_set_t *data_set, const char *s);
+GList * pe__build_node_name_list(pcmk_scheduler_t *scheduler, const char *s);
+GList * pe__build_rsc_list(pcmk_scheduler_t *scheduler, const char *s);
-bool pcmk__rsc_filtered_by_node(pe_resource_t *rsc, GList *only_node);
+bool pcmk__rsc_filtered_by_node(pcmk_resource_t *rsc, GList *only_node);
-gboolean pe__bundle_is_filtered(const pe_resource_t *rsc, GList *only_rsc,
+gboolean pe__bundle_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc,
gboolean check_parent);
-gboolean pe__clone_is_filtered(const pe_resource_t *rsc, GList *only_rsc,
+gboolean pe__clone_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc,
gboolean check_parent);
-gboolean pe__group_is_filtered(const pe_resource_t *rsc, GList *only_rsc,
+gboolean pe__group_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc,
gboolean check_parent);
-gboolean pe__native_is_filtered(const pe_resource_t *rsc, GList *only_rsc,
+gboolean pe__native_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc,
gboolean check_parent);
-xmlNode *pe__failed_probe_for_rsc(const pe_resource_t *rsc, const char *name);
+xmlNode *pe__failed_probe_for_rsc(const pcmk_resource_t *rsc, const char *name);
-const char *pe__clone_child_id(const pe_resource_t *rsc);
+const char *pe__clone_child_id(const pcmk_resource_t *rsc);
-int pe__sum_node_health_scores(const pe_node_t *node, int base_health);
-int pe__node_health(pe_node_t *node);
+int pe__sum_node_health_scores(const pcmk_node_t *node, int base_health);
+int pe__node_health(pcmk_node_t *node);
static inline enum pcmk__health_strategy
-pe__health_strategy(pe_working_set_t *data_set)
+pe__health_strategy(pcmk_scheduler_t *scheduler)
{
- return pcmk__parse_health_strategy(pe_pref(data_set->config_hash,
+ return pcmk__parse_health_strategy(pe_pref(scheduler->config_hash,
PCMK__OPT_NODE_HEALTH_STRATEGY));
}
static inline int
-pe__health_score(const char *option, pe_working_set_t *data_set)
+pe__health_score(const char *option, pcmk_scheduler_t *scheduler)
{
- return char2score(pe_pref(data_set->config_hash, option));
+ return char2score(pe_pref(scheduler->config_hash, option));
}
/*!
@@ -665,7 +642,7 @@ pe__health_score(const char *option, pe_working_set_t *data_set)
* if node has neither a name nor ID.
*/
static inline const char *
-pe__node_name(const pe_node_t *node)
+pe__node_name(const pcmk_node_t *node)
{
if (node == NULL) {
return "unspecified node";
@@ -691,7 +668,7 @@ pe__node_name(const pe_node_t *node)
* \return true if \p node1 and \p node2 refer to the same node
*/
static inline bool
-pe__same_node(const pe_node_t *node1, const pe_node_t *node2)
+pe__same_node(const pcmk_node_t *node1, const pcmk_node_t *node2)
{
return (node1 != NULL) && (node2 != NULL)
&& (node1->details == node2->details);
diff --git a/include/crm/pengine/pe_types.h b/include/crm/pengine/pe_types.h
index cc626c8..24355f8 100644
--- a/include/crm/pengine/pe_types.h
+++ b/include/crm/pengine/pe_types.h
@@ -16,6 +16,7 @@
# include <libxml/tree.h> // xmlNode
# include <glib.h> // gboolean, guint, GList, GHashTable
# include <crm/common/iso8601.h>
+# include <crm/common/scheduler.h>
# include <crm/pengine/common.h>
#ifdef __cplusplus
@@ -28,535 +29,6 @@ extern "C" {
* \ingroup pengine
*/
-typedef struct pe_node_s pe_node_t;
-typedef struct pe_action_s pe_action_t;
-typedef struct pe_resource_s pe_resource_t;
-typedef struct pe_working_set_s pe_working_set_t;
-
-enum pe_obj_types {
- pe_unknown = -1,
- pe_native = 0,
- pe_group = 1,
- pe_clone = 2,
- pe_container = 3,
-};
-
-typedef struct resource_object_functions_s {
- gboolean (*unpack) (pe_resource_t*, pe_working_set_t*);
- pe_resource_t *(*find_rsc) (pe_resource_t *parent, const char *search,
- const pe_node_t *node, int flags);
- /* parameter result must be free'd */
- char *(*parameter) (pe_resource_t*, pe_node_t*, gboolean, const char*,
- pe_working_set_t*);
- //! \deprecated will be removed in a future release
- void (*print) (pe_resource_t*, const char*, long, void*);
- gboolean (*active) (pe_resource_t*, gboolean);
- enum rsc_role_e (*state) (const pe_resource_t*, gboolean);
- pe_node_t *(*location) (const pe_resource_t*, GList**, int);
- void (*free) (pe_resource_t*);
- void (*count) (pe_resource_t*);
- gboolean (*is_filtered) (const pe_resource_t*, GList *, gboolean);
-
- /*!
- * \brief
- * \internal Find a node (and optionally count all) where resource is active
- *
- * \param[in] rsc Resource to check
- * \param[out] count_all If not NULL, set this to count of active nodes
- * \param[out] count_clean If not NULL, set this to count of clean nodes
- *
- * \return A node where the resource is active, preferring the source node
- * if the resource is involved in a partial migration or a clean,
- * online node if the resource's "requires" is "quorum" or
- * "nothing", or NULL if the resource is inactive.
- */
- pe_node_t *(*active_node)(const pe_resource_t *rsc, unsigned int *count_all,
- unsigned int *count_clean);
-} resource_object_functions_t;
-
-typedef struct resource_alloc_functions_s resource_alloc_functions_t;
-
-enum pe_quorum_policy {
- no_quorum_freeze,
- no_quorum_stop,
- no_quorum_ignore,
- no_quorum_suicide,
- no_quorum_demote
-};
-
-enum node_type {
- node_ping, //! \deprecated Do not use
- node_member,
- node_remote
-};
-
-//! \deprecated will be removed in a future release
-enum pe_restart {
- pe_restart_restart, //! \deprecated will be removed in a future release
- pe_restart_ignore //! \deprecated will be removed in a future release
-};
-
-//! Determine behavior of pe_find_resource_with_flags()
-enum pe_find {
- pe_find_renamed = 0x001, //!< match resource ID or LRM history ID
- pe_find_anon = 0x002, //!< match base name of anonymous clone instances
- pe_find_clone = 0x004, //!< match only clone instances
- pe_find_current = 0x008, //!< match resource active on specified node
- pe_find_inactive = 0x010, //!< match resource not running anywhere
- pe_find_any = 0x020, //!< match base name of any clone instance
-};
-
-// @TODO Make these an enum
-
-# define pe_flag_have_quorum 0x00000001ULL
-# define pe_flag_symmetric_cluster 0x00000002ULL
-# define pe_flag_maintenance_mode 0x00000008ULL
-
-# define pe_flag_stonith_enabled 0x00000010ULL
-# define pe_flag_have_stonith_resource 0x00000020ULL
-# define pe_flag_enable_unfencing 0x00000040ULL
-# define pe_flag_concurrent_fencing 0x00000080ULL
-
-# define pe_flag_stop_rsc_orphans 0x00000100ULL
-# define pe_flag_stop_action_orphans 0x00000200ULL
-# define pe_flag_stop_everything 0x00000400ULL
-
-# define pe_flag_start_failure_fatal 0x00001000ULL
-
-//! \deprecated
-# define pe_flag_remove_after_stop 0x00002000ULL
-
-# define pe_flag_startup_fencing 0x00004000ULL
-# define pe_flag_shutdown_lock 0x00008000ULL
-
-# define pe_flag_startup_probes 0x00010000ULL
-# define pe_flag_have_status 0x00020000ULL
-# define pe_flag_have_remote_nodes 0x00040000ULL
-
-# define pe_flag_quick_location 0x00100000ULL
-# define pe_flag_sanitized 0x00200000ULL
-
-//! \deprecated
-# define pe_flag_stdout 0x00400000ULL
-
-//! Don't count total, disabled and blocked resource instances
-# define pe_flag_no_counts 0x00800000ULL
-
-/*! Skip deprecated code that is kept solely for backward API compatibility.
- * (Internal code should always set this.)
- */
-# define pe_flag_no_compat 0x01000000ULL
-
-# define pe_flag_show_scores 0x02000000ULL
-# define pe_flag_show_utilization 0x04000000ULL
-
-/*!
- * When scheduling, only unpack the CIB (including constraints), calculate
- * as much cluster status as possible, and apply node health.
- */
-# define pe_flag_check_config 0x08000000ULL
-
-struct pe_working_set_s {
- xmlNode *input;
- crm_time_t *now;
-
- /* options extracted from the input */
- char *dc_uuid;
- pe_node_t *dc_node;
- const char *stonith_action;
- const char *placement_strategy;
-
- unsigned long long flags;
-
- int stonith_timeout;
- enum pe_quorum_policy no_quorum_policy;
-
- GHashTable *config_hash;
- GHashTable *tickets;
-
- // Actions for which there can be only one (e.g. fence nodeX)
- GHashTable *singletons;
-
- GList *nodes;
- GList *resources;
- GList *placement_constraints;
- GList *ordering_constraints;
- GList *colocation_constraints;
- GList *ticket_constraints;
-
- GList *actions;
- xmlNode *failed;
- xmlNode *op_defaults;
- xmlNode *rsc_defaults;
-
- /* stats */
- int num_synapse;
- int max_valid_nodes; //! Deprecated (will be removed in a future release)
- int order_id;
- int action_id;
-
- /* final output */
- xmlNode *graph;
-
- GHashTable *template_rsc_sets;
- const char *localhost;
- GHashTable *tags;
-
- int blocked_resources;
- int disabled_resources;
-
- GList *param_check; // History entries that need to be checked
- GList *stop_needed; // Containers that need stop actions
- time_t recheck_by; // Hint to controller to re-run scheduler by this time
- int ninstances; // Total number of resource instances
- guint shutdown_lock;// How long (seconds) to lock resources to shutdown node
- int priority_fencing_delay; // Priority fencing delay
-
- void *priv;
-};
-
-enum pe_check_parameters {
- /* Clear fail count if parameters changed for un-expired start or monitor
- * last_failure.
- */
- pe_check_last_failure,
-
- /* Clear fail count if parameters changed for start, monitor, promote, or
- * migrate_from actions for active resources.
- */
- pe_check_active,
-};
-
-struct pe_node_shared_s {
- const char *id;
- const char *uname;
- enum node_type type;
-
- /* @TODO convert these flags into a bitfield */
- gboolean online;
- gboolean standby;
- gboolean standby_onfail;
- gboolean pending;
- gboolean unclean;
- gboolean unseen;
- gboolean shutdown;
- gboolean expected_up;
- gboolean is_dc;
- gboolean maintenance;
- gboolean rsc_discovery_enabled;
- gboolean remote_requires_reset;
- gboolean remote_was_fenced;
- gboolean remote_maintenance; /* what the remote-rsc is thinking */
- gboolean unpacked;
-
- int num_resources;
- pe_resource_t *remote_rsc;
- GList *running_rsc; /* pe_resource_t* */
- GList *allocated_rsc; /* pe_resource_t* */
-
- GHashTable *attrs; /* char* => char* */
- GHashTable *utilization;
- GHashTable *digest_cache; //!< cache of calculated resource digests
- int priority; // calculated based on the priority of resources running on the node
- pe_working_set_t *data_set; //!< Cluster that this node is part of
-};
-
-struct pe_node_s {
- int weight;
- gboolean fixed; //!< \deprecated Will be removed in a future release
- int count;
- struct pe_node_shared_s *details;
- int rsc_discover_mode;
-};
-
-# define pe_rsc_orphan 0x00000001ULL
-# define pe_rsc_managed 0x00000002ULL
-# define pe_rsc_block 0x00000004ULL
-# define pe_rsc_orphan_container_filler 0x00000008ULL
-
-# define pe_rsc_notify 0x00000010ULL
-# define pe_rsc_unique 0x00000020ULL
-# define pe_rsc_fence_device 0x00000040ULL
-# define pe_rsc_promotable 0x00000080ULL
-
-# define pe_rsc_provisional 0x00000100ULL
-# define pe_rsc_allocating 0x00000200ULL
-# define pe_rsc_merging 0x00000400ULL
-# define pe_rsc_restarting 0x00000800ULL
-
-# define pe_rsc_stop 0x00001000ULL
-# define pe_rsc_reload 0x00002000ULL
-# define pe_rsc_allow_remote_remotes 0x00004000ULL
-# define pe_rsc_critical 0x00008000ULL
-
-# define pe_rsc_failed 0x00010000ULL
-# define pe_rsc_detect_loop 0x00020000ULL
-# define pe_rsc_runnable 0x00040000ULL
-# define pe_rsc_start_pending 0x00080000ULL
-
-//!< \deprecated Do not use
-# define pe_rsc_starting 0x00100000ULL
-
-//!< \deprecated Do not use
-# define pe_rsc_stopping 0x00200000ULL
-
-# define pe_rsc_stop_unexpected 0x00400000ULL
-# define pe_rsc_allow_migrate 0x00800000ULL
-
-# define pe_rsc_failure_ignored 0x01000000ULL
-# define pe_rsc_replica_container 0x02000000ULL
-# define pe_rsc_maintenance 0x04000000ULL
-# define pe_rsc_is_container 0x08000000ULL
-
-# define pe_rsc_needs_quorum 0x10000000ULL
-# define pe_rsc_needs_fencing 0x20000000ULL
-# define pe_rsc_needs_unfencing 0x40000000ULL
-
-/* *INDENT-OFF* */
-enum pe_action_flags {
- pe_action_pseudo = 0x00001,
- pe_action_runnable = 0x00002,
- pe_action_optional = 0x00004,
- pe_action_print_always = 0x00008,
-
- pe_action_have_node_attrs = 0x00010,
- pe_action_implied_by_stonith = 0x00040,
- pe_action_migrate_runnable = 0x00080,
-
- pe_action_dumped = 0x00100,
- pe_action_processed = 0x00200,
-#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
- pe_action_clear = 0x00400, //! \deprecated Unused
-#endif
- pe_action_dangle = 0x00800,
-
- /* This action requires one or more of its dependencies to be runnable.
- * We use this to clear the runnable flag before checking dependencies.
- */
- pe_action_requires_any = 0x01000,
-
- pe_action_reschedule = 0x02000,
- pe_action_tracking = 0x04000,
- pe_action_dedup = 0x08000, //! Internal state tracking when creating graph
-
- pe_action_dc = 0x10000, //! Action may run on DC instead of target
-};
-/* *INDENT-ON* */
-
-struct pe_resource_s {
- char *id;
- char *clone_name;
- xmlNode *xml;
- xmlNode *orig_xml;
- xmlNode *ops_xml;
-
- pe_working_set_t *cluster;
- pe_resource_t *parent;
-
- enum pe_obj_types variant;
- void *variant_opaque;
- resource_object_functions_t *fns;
- resource_alloc_functions_t *cmds;
-
- enum rsc_recovery_type recovery_type;
-
- enum pe_restart restart_type; //!< \deprecated will be removed in future release
-
- int priority;
- int stickiness;
- int sort_index;
- int failure_timeout;
- int migration_threshold;
- guint remote_reconnect_ms;
- char *pending_task;
-
- unsigned long long flags;
-
- // @TODO merge these into flags
- gboolean is_remote_node;
- gboolean exclusive_discover;
-
- /* Pay special attention to whether you want to use rsc_cons_lhs and
- * rsc_cons directly, which include only colocations explicitly involving
- * this resource, or call libpacemaker's pcmk__with_this_colocations() and
- * pcmk__this_with_colocations() functions, which may return relevant
- * colocations involving the resource's ancestors as well.
- */
-
- //!@{
- //! This field should be treated as internal to Pacemaker
- GList *rsc_cons_lhs; // List of pcmk__colocation_t*
- GList *rsc_cons; // List of pcmk__colocation_t*
- GList *rsc_location; // List of pe__location_t*
- GList *actions; // List of pe_action_t*
- GList *rsc_tickets; // List of rsc_ticket*
- //!@}
-
- pe_node_t *allocated_to;
- pe_node_t *partial_migration_target;
- pe_node_t *partial_migration_source;
- GList *running_on; /* pe_node_t* */
- GHashTable *known_on; /* pe_node_t* */
- GHashTable *allowed_nodes; /* pe_node_t* */
-
- enum rsc_role_e role;
- enum rsc_role_e next_role;
-
- GHashTable *meta;
- GHashTable *parameters; //! \deprecated Use pe_rsc_params() instead
- GHashTable *utilization;
-
- GList *children; /* pe_resource_t* */
- GList *dangling_migrations; /* pe_node_t* */
-
- pe_resource_t *container;
- GList *fillers;
-
- // @COMPAT These should be made const at next API compatibility break
- pe_node_t *pending_node; // Node on which pending_task is happening
- pe_node_t *lock_node; // Resource is shutdown-locked to this node
-
- time_t lock_time; // When shutdown lock started
-
- /* Resource parameters may have node-attribute-based rules, which means the
- * values can vary by node. This table is a cache of parameter name/value
- * tables for each node (as needed). Use pe_rsc_params() to get the table
- * for a given node.
- */
- GHashTable *parameter_cache; // Key = node name, value = parameters table
-};
-
-struct pe_action_s {
- int id;
- int priority;
-
- pe_resource_t *rsc;
- pe_node_t *node;
- xmlNode *op_entry;
-
- char *task;
- char *uuid;
- char *cancel_task;
- char *reason;
-
- enum pe_action_flags flags;
- enum rsc_start_requirement needs;
- enum action_fail_response on_fail;
- enum rsc_role_e fail_role;
-
- GHashTable *meta;
- GHashTable *extra;
-
- /*
- * These two varables are associated with the constraint logic
- * that involves first having one or more actions runnable before
- * then allowing this action to execute.
- *
- * These varables are used with features such as 'clone-min' which
- * requires at minimum X number of cloned instances to be running
- * before an order dependency can run. Another option that uses
- * this is 'require-all=false' in ordering constrants. This option
- * says "only require one instance of a resource to start before
- * allowing dependencies to start" -- basically, require-all=false is
- * the same as clone-min=1.
- */
-
- /* current number of known runnable actions in the before list. */
- int runnable_before;
- /* the number of "before" runnable actions required for this action
- * to be considered runnable */
- int required_runnable_before;
-
- GList *actions_before; /* pe_action_wrapper_t* */
- GList *actions_after; /* pe_action_wrapper_t* */
-
- /* Some of the above fields could be moved to the details,
- * except for API backward compatibility.
- */
- void *action_details; // varies by type of action
-};
-
-typedef struct pe_ticket_s {
- char *id;
- gboolean granted;
- time_t last_granted;
- gboolean standby;
- GHashTable *state;
-} pe_ticket_t;
-
-typedef struct pe_tag_s {
- char *id;
- GList *refs;
-} pe_tag_t;
-
-//! Internal tracking for transition graph creation
-enum pe_link_state {
- pe_link_not_dumped, //! Internal tracking for transition graph creation
- pe_link_dumped, //! Internal tracking for transition graph creation
- pe_link_dup, //! \deprecated No longer used by Pacemaker
-};
-
-enum pe_discover_e {
- pe_discover_always = 0,
- pe_discover_never,
- pe_discover_exclusive,
-};
-
-/* *INDENT-OFF* */
-enum pe_ordering {
- pe_order_none = 0x0, /* deleted */
- pe_order_optional = 0x1, /* pure ordering, nothing implied */
- pe_order_apply_first_non_migratable = 0x2, /* Only apply this constraint's ordering if first is not migratable. */
-
- pe_order_implies_first = 0x10, /* If 'then' is required, ensure 'first' is too */
- pe_order_implies_then = 0x20, /* If 'first' is required, ensure 'then' is too */
- pe_order_promoted_implies_first = 0x40, /* If 'then' is required and then's rsc is promoted, ensure 'first' becomes required too */
-
- /* first requires then to be both runnable and migrate runnable. */
- pe_order_implies_first_migratable = 0x80,
-
- pe_order_runnable_left = 0x100, /* 'then' requires 'first' to be runnable */
-
- pe_order_pseudo_left = 0x200, /* 'then' can only be pseudo if 'first' is runnable */
- pe_order_implies_then_on_node = 0x400, /* If 'first' is required on 'nodeX',
- * ensure instances of 'then' on 'nodeX' are too.
- * Only really useful if 'then' is a clone and 'first' is not
- */
- pe_order_probe = 0x800, /* If 'first->rsc' is
- * - running but about to stop, ignore the constraint
- * - otherwise, behave as runnable_left
- */
-
- pe_order_restart = 0x1000, /* 'then' is runnable if 'first' is optional or runnable */
- pe_order_stonith_stop = 0x2000, //<! \deprecated Will be removed in future release
- pe_order_serialize_only = 0x4000, /* serialize */
- pe_order_same_node = 0x8000, /* applies only if 'first' and 'then' are on same node */
-
- pe_order_implies_first_printed = 0x10000, /* Like ..implies_first but only ensures 'first' is printed, not mandatory */
- pe_order_implies_then_printed = 0x20000, /* Like ..implies_then but only ensures 'then' is printed, not mandatory */
-
- pe_order_asymmetrical = 0x100000, /* Indicates asymmetrical one way ordering constraint. */
- pe_order_load = 0x200000, /* Only relevant if... */
- pe_order_one_or_more = 0x400000, /* 'then' is runnable only if one or more of its dependencies are too */
- pe_order_anti_colocation = 0x800000,
-
- pe_order_preserve = 0x1000000, /* Hack for breaking user ordering constraints with container resources */
- pe_order_then_cancels_first = 0x2000000, // if 'then' becomes required, 'first' becomes optional
- pe_order_trace = 0x4000000, /* test marker */
-
-#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
- // \deprecated Use pe_order_promoted_implies_first instead
- pe_order_implies_first_master = pe_order_promoted_implies_first,
-#endif
-};
-/* *INDENT-ON* */
-
-typedef struct pe_action_wrapper_s {
- enum pe_ordering type;
- enum pe_link_state state;
- pe_action_t *action;
-} pe_action_wrapper_t;
-
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
#include <crm/pengine/pe_types_compat.h>
#endif
diff --git a/include/crm/pengine/pe_types_compat.h b/include/crm/pengine/pe_types_compat.h
index 6f174c4..1becd12 100644
--- a/include/crm/pengine/pe_types_compat.h
+++ b/include/crm/pengine/pe_types_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2022 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -10,7 +10,7 @@
#ifndef PCMK__CRM_PENGINE_PE_TYPES_COMPAT__H
# define PCMK__CRM_PENGINE_PE_TYPES_COMPAT__H
-#include <crm/pengine/pe_types.h>
+#include <crm/common/scheduler.h>
#ifdef __cplusplus
extern "C" {
@@ -25,6 +25,174 @@ extern "C" {
* release.
*/
+//! \deprecated Use pcmk_rsc_removed instead
+#define pe_rsc_orphan pcmk_rsc_removed
+
+//! \deprecated Use pcmk_rsc_managed instead
+#define pe_rsc_managed pcmk_rsc_managed
+
+//! \deprecated Use pcmk_rsc_blocked instead
+#define pe_rsc_block pcmk_rsc_blocked
+
+//! \deprecated Use pcmk_rsc_removed_filler instead
+#define pe_rsc_orphan_container_filler pcmk_rsc_removed_filler
+
+//! \deprecated Use pcmk_rsc_notify instead
+#define pe_rsc_notify pcmk_rsc_notify
+
+//! \deprecated Use pcmk_rsc_unique instead
+#define pe_rsc_unique pcmk_rsc_unique
+
+//! \deprecated Use pcmk_rsc_fence_device instead
+#define pe_rsc_fence_device pcmk_rsc_fence_device
+
+//! \deprecated Use pcmk_rsc_promotable instead
+#define pe_rsc_promotable pcmk_rsc_promotable
+
+//! \deprecated Use pcmk_rsc_unassigned instead
+#define pe_rsc_provisional pcmk_rsc_unassigned
+
+//! \deprecated Use pcmk_rsc_assigning instead
+#define pe_rsc_allocating pcmk_rsc_assigning
+
+//! \deprecated Use pcmk_rsc_updating_nodes instead
+#define pe_rsc_merging pcmk_rsc_updating_nodes
+
+//! \deprecated Use pcmk_rsc_restarting instead
+#define pe_rsc_restarting pcmk_rsc_restarting
+
+//! \deprecated Use pcmk_rsc_stop_if_failed instead
+#define pe_rsc_stop pcmk_rsc_stop_if_failed
+
+//! \deprecated Use pcmk_rsc_reload instead
+#define pe_rsc_reload pcmk_rsc_reload
+
+//! \deprecated Use pcmk_rsc_remote_nesting_allowed instead
+#define pe_rsc_allow_remote_remotes pcmk_rsc_remote_nesting_allowed
+
+//! \deprecated Use pcmk_rsc_critical instead
+#define pe_rsc_critical pcmk_rsc_critical
+
+//! \deprecated Use pcmk_rsc_failed instead
+#define pe_rsc_failed pcmk_rsc_failed
+
+//! \deprecated Use pcmk_rsc_detect_loop instead
+#define pe_rsc_detect_loop pcmk_rsc_detect_loop
+
+//! \deprecated Do not use
+#define pe_rsc_runnable pcmk_rsc_runnable
+
+//! \deprecated Use pcmk_rsc_start_pending instead
+#define pe_rsc_start_pending pcmk_rsc_start_pending
+
+//!< \deprecated Do not use
+#define pe_rsc_starting pcmk_rsc_starting
+
+//!< \deprecated Do not use
+#define pe_rsc_stopping pcmk_rsc_stopping
+
+//! \deprecated Use pcmk_rsc_stop_unexpected instead
+#define pe_rsc_stop_unexpected pcmk_rsc_stop_unexpected
+
+//! \deprecated Use pcmk_rsc_migratable instead
+#define pe_rsc_allow_migrate pcmk_rsc_migratable
+
+//! \deprecated Use pcmk_rsc_ignore_failure instead
+#define pe_rsc_failure_ignored pcmk_rsc_ignore_failure
+
+//! \deprecated Use pcmk_rsc_replica_container instead
+#define pe_rsc_replica_container pcmk_rsc_replica_container
+
+//! \deprecated Use pcmk_rsc_maintenance instead
+#define pe_rsc_maintenance pcmk_rsc_maintenance
+
+//! \deprecated Do not use
+#define pe_rsc_is_container pcmk_rsc_has_filler
+
+//! \deprecated Use pcmk_rsc_needs_quorum instead
+#define pe_rsc_needs_quorum pcmk_rsc_needs_quorum
+
+//! \deprecated Use pcmk_rsc_needs_fencing instead
+#define pe_rsc_needs_fencing pcmk_rsc_needs_fencing
+
+//! \deprecated Use pcmk_rsc_needs_unfencing instead
+#define pe_rsc_needs_unfencing pcmk_rsc_needs_unfencing
+
+//! \deprecated Use pcmk_sched_quorate instead
+#define pe_flag_have_quorum pcmk_sched_quorate
+
+//! \deprecated Use pcmk_sched_symmetric_cluster instead
+#define pe_flag_symmetric_cluster pcmk_sched_symmetric_cluster
+
+//! \deprecated Use pcmk_sched_in_maintenance instead
+#define pe_flag_maintenance_mode pcmk_sched_in_maintenance
+
+//! \deprecated Use pcmk_sched_fencing_enabled instead
+#define pe_flag_stonith_enabled pcmk_sched_fencing_enabled
+
+//! \deprecated Use pcmk_sched_have_fencing instead
+#define pe_flag_have_stonith_resource pcmk_sched_have_fencing
+
+//! \deprecated Use pcmk_sched_enable_unfencing instead
+#define pe_flag_enable_unfencing pcmk_sched_enable_unfencing
+
+//! \deprecated Use pcmk_sched_concurrent_fencing instead
+#define pe_flag_concurrent_fencing pcmk_sched_concurrent_fencing
+
+//! \deprecated Use pcmk_sched_stop_removed_resources instead
+#define pe_flag_stop_rsc_orphans pcmk_sched_stop_removed_resources
+
+//! \deprecated Use pcmk_sched_cancel_removed_actions instead
+#define pe_flag_stop_action_orphans pcmk_sched_cancel_removed_actions
+
+//! \deprecated Use pcmk_sched_stop_all instead
+#define pe_flag_stop_everything pcmk_sched_stop_all
+
+//! \deprecated Use pcmk_sched_start_failure_fatal instead
+#define pe_flag_start_failure_fatal pcmk_sched_start_failure_fatal
+
+//! \deprecated Do not use
+#define pe_flag_remove_after_stop pcmk_sched_remove_after_stop
+
+//! \deprecated Use pcmk_sched_startup_fencing instead
+#define pe_flag_startup_fencing pcmk_sched_startup_fencing
+
+//! \deprecated Use pcmk_sched_shutdown_lock instead
+#define pe_flag_shutdown_lock pcmk_sched_shutdown_lock
+
+//! \deprecated Use pcmk_sched_probe_resources instead
+#define pe_flag_startup_probes pcmk_sched_probe_resources
+
+//! \deprecated Use pcmk_sched_have_status instead
+#define pe_flag_have_status pcmk_sched_have_status
+
+//! \deprecated Use pcmk_sched_have_remote_nodes instead
+#define pe_flag_have_remote_nodes pcmk_sched_have_remote_nodes
+
+//! \deprecated Use pcmk_sched_location_only instead
+#define pe_flag_quick_location pcmk_sched_location_only
+
+//! \deprecated Use pcmk_sched_sanitized instead
+#define pe_flag_sanitized pcmk_sched_sanitized
+
+//! \deprecated Do not use
+#define pe_flag_stdout (1ULL << 22)
+
+//! \deprecated Use pcmk_sched_no_counts instead
+#define pe_flag_no_counts pcmk_sched_no_counts
+
+//! \deprecated Use pcmk_sched_no_compat instead
+#define pe_flag_no_compat pcmk_sched_no_compat
+
+//! \deprecated Use pcmk_sched_output_scores instead
+#define pe_flag_show_scores pcmk_sched_output_scores
+
+//! \deprecated Use pcmk_sched_show_utilization instead
+#define pe_flag_show_utilization pcmk_sched_show_utilization
+
+//! \deprecated Use pcmk_sched_validate_only instead
+#define pe_flag_check_config pcmk_sched_validate_only
+
//!@{
//! \deprecated Do not use (unused by Pacemaker)
enum pe_graph_flags {
@@ -35,27 +203,62 @@ enum pe_graph_flags {
};
//!@}
-//!< \deprecated Use pe_action_t instead
+//!@{
+//! \deprecated Do not use
+enum pe_check_parameters {
+ pe_check_last_failure,
+ pe_check_active,
+};
+//!@}
+
+//! \deprecated Use pcmk_action_t instead
typedef struct pe_action_s action_t;
-//!< \deprecated Use pe_action_wrapper_t instead
+//! \deprecated Use pcmk_action_t instead
+typedef struct pe_action_s pe_action_t;
+
+//! \deprecated Do not use
typedef struct pe_action_wrapper_s action_wrapper_t;
-//!< \deprecated Use pe_node_t instead
+//! \deprecated Do not use
+typedef struct pe_action_wrapper_s pe_action_wrapper_t;
+
+//! \deprecated Use pcmk_node_t instead
typedef struct pe_node_s node_t;
-//!< \deprecated Use enum pe_quorum_policy instead
+//! \deprecated Use pcmk_node_t instead
+typedef struct pe_node_s pe_node_t;
+
+//! \deprecated Use enum pe_quorum_policy instead
typedef enum pe_quorum_policy no_quorum_policy_t;
-//!< \deprecated use pe_resource_t instead
+//! \deprecated use pcmk_resource_t instead
typedef struct pe_resource_s resource_t;
-//!< \deprecated Use pe_tag_t instead
+//! \deprecated use pcmk_resource_t instead
+typedef struct pe_resource_s pe_resource_t;
+
+//! \deprecated Use pcmk_tag_t instead
typedef struct pe_tag_s tag_t;
-//!< \deprecated Use pe_ticket_t instead
+//! \deprecated Use pcmk_tag_t instead
+typedef struct pe_tag_s pe_tag_t;
+
+//! \deprecated Use pcmk_ticket_t instead
typedef struct pe_ticket_s ticket_t;
+//! \deprecated Use pcmk_ticket_t instead
+typedef struct pe_ticket_s pe_ticket_t;
+
+//! \deprecated Use pcmk_scheduler_t instead
+typedef struct pe_working_set_s pe_working_set_t;
+
+//! \deprecated This type should be treated as internal to Pacemaker
+typedef struct resource_alloc_functions_s resource_alloc_functions_t;
+
+//! \deprecated Use pcmk_rsc_methods_t instead
+typedef struct resource_object_functions_s resource_object_functions_t;
+
#ifdef __cplusplus
}
#endif
diff --git a/include/crm/pengine/remote_internal.h b/include/crm/pengine/remote_internal.h
index 46d58fc..0e7c044 100644
--- a/include/crm/pengine/remote_internal.h
+++ b/include/crm/pengine/remote_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2019 the Pacemaker project contributors
+ * Copyright 2013-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -19,16 +19,17 @@ extern "C" {
#include <crm/pengine/status.h>
bool xml_contains_remote_node(xmlNode *xml);
-bool pe__is_remote_node(const pe_node_t *node);
-bool pe__is_guest_node(const pe_node_t *node);
-bool pe__is_guest_or_remote_node(const pe_node_t *node);
-bool pe__is_bundle_node(const pe_node_t *node);
-bool pe__resource_is_remote_conn(const pe_resource_t *rsc,
- const pe_working_set_t *data_set);
-pe_resource_t *pe__resource_contains_guest_node(const pe_working_set_t *data_set,
- const pe_resource_t *rsc);
-void pe_foreach_guest_node(const pe_working_set_t *data_set, const pe_node_t *host,
- void (*helper)(const pe_node_t*, void*), void *user_data);
+bool pe__is_remote_node(const pcmk_node_t *node);
+bool pe__is_guest_node(const pcmk_node_t *node);
+bool pe__is_guest_or_remote_node(const pcmk_node_t *node);
+bool pe__is_bundle_node(const pcmk_node_t *node);
+bool pe__resource_is_remote_conn(const pcmk_resource_t *rsc);
+pcmk_resource_t *pe__resource_contains_guest_node(const pcmk_scheduler_t *scheduler,
+ const pcmk_resource_t *rsc);
+void pe_foreach_guest_node(const pcmk_scheduler_t *scheduler,
+ const pcmk_node_t *host,
+ void (*helper)(const pcmk_node_t*, void*),
+ void *user_data);
xmlNode *pe_create_remote_xml(xmlNode *parent, const char *uname,
const char *container_id, const char *migrateable,
const char *is_managed, const char *start_timeout,
diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
index 145a166..9c85425 100644
--- a/include/crm/pengine/status.h
+++ b/include/crm/pengine/status.h
@@ -15,7 +15,7 @@
# include <crm/common/util.h> // pcmk_is_set()
# include <crm/common/iso8601.h>
# include <crm/pengine/common.h>
-# include <crm/pengine/pe_types.h> // pe_node_t, pe_resource_t, etc.
+# include <crm/pengine/pe_types.h> // pcmk_node_t, pcmk_resource_t, etc.
# include <crm/pengine/complex.h>
#ifdef __cplusplus
@@ -28,24 +28,25 @@ extern "C" {
* \ingroup pengine
*/
-const char *rsc_printable_id(const pe_resource_t *rsc);
-gboolean cluster_status(pe_working_set_t * data_set);
-pe_working_set_t *pe_new_working_set(void);
-void pe_free_working_set(pe_working_set_t *data_set);
-void set_working_set_defaults(pe_working_set_t * data_set);
-void cleanup_calculations(pe_working_set_t * data_set);
-void pe_reset_working_set(pe_working_set_t *data_set);
-pe_resource_t *pe_find_resource(GList *rsc_list, const char *id_rh);
-pe_resource_t *pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags);
-pe_node_t *pe_find_node(const GList *node_list, const char *node_name);
-pe_node_t *pe_find_node_id(const GList *node_list, const char *id);
-pe_node_t *pe_find_node_any(const GList *node_list, const char *id,
+const char *rsc_printable_id(const pcmk_resource_t *rsc);
+gboolean cluster_status(pcmk_scheduler_t *scheduler);
+pcmk_scheduler_t *pe_new_working_set(void);
+void pe_free_working_set(pcmk_scheduler_t *scheduler);
+void set_working_set_defaults(pcmk_scheduler_t *scheduler);
+void cleanup_calculations(pcmk_scheduler_t *scheduler);
+void pe_reset_working_set(pcmk_scheduler_t *scheduler);
+pcmk_resource_t *pe_find_resource(GList *rsc_list, const char *id_rh);
+pcmk_resource_t *pe_find_resource_with_flags(GList *rsc_list, const char *id,
+ enum pe_find flags);
+pcmk_node_t *pe_find_node(const GList *node_list, const char *node_name);
+pcmk_node_t *pe_find_node_id(const GList *node_list, const char *id);
+pcmk_node_t *pe_find_node_any(const GList *node_list, const char *id,
const char *node_name);
GList *find_operations(const char *rsc, const char *node, gboolean active_filter,
- pe_working_set_t * data_set);
+ pcmk_scheduler_t *scheduler);
void calculate_active_ops(const GList *sorted_op_list, int *start_index,
int *stop_index);
-int pe_bundle_replicas(const pe_resource_t *rsc);
+int pe_bundle_replicas(const pcmk_resource_t *rsc);
/*!
* \brief Check whether a resource is any clone type
@@ -55,9 +56,9 @@ int pe_bundle_replicas(const pe_resource_t *rsc);
* \return true if resource is clone, false otherwise
*/
static inline bool
-pe_rsc_is_clone(const pe_resource_t *rsc)
+pe_rsc_is_clone(const pcmk_resource_t *rsc)
{
- return rsc && (rsc->variant == pe_clone);
+ return (rsc != NULL) && (rsc->variant == pcmk_rsc_variant_clone);
}
/*!
@@ -68,9 +69,9 @@ pe_rsc_is_clone(const pe_resource_t *rsc)
* \return true if resource is unique clone, false otherwise
*/
static inline bool
-pe_rsc_is_unique_clone(const pe_resource_t *rsc)
+pe_rsc_is_unique_clone(const pcmk_resource_t *rsc)
{
- return pe_rsc_is_clone(rsc) && pcmk_is_set(rsc->flags, pe_rsc_unique);
+ return pe_rsc_is_clone(rsc) && pcmk_is_set(rsc->flags, pcmk_rsc_unique);
}
/*!
@@ -81,9 +82,9 @@ pe_rsc_is_unique_clone(const pe_resource_t *rsc)
* \return true if resource is anonymous clone, false otherwise
*/
static inline bool
-pe_rsc_is_anon_clone(const pe_resource_t *rsc)
+pe_rsc_is_anon_clone(const pcmk_resource_t *rsc)
{
- return pe_rsc_is_clone(rsc) && !pcmk_is_set(rsc->flags, pe_rsc_unique);
+ return pe_rsc_is_clone(rsc) && !pcmk_is_set(rsc->flags, pcmk_rsc_unique);
}
/*!
@@ -94,7 +95,7 @@ pe_rsc_is_anon_clone(const pe_resource_t *rsc)
* \return true if resource is part of a bundle, false otherwise
*/
static inline bool
-pe_rsc_is_bundled(const pe_resource_t *rsc)
+pe_rsc_is_bundled(const pcmk_resource_t *rsc)
{
if (rsc == NULL) {
return false;
@@ -102,7 +103,7 @@ pe_rsc_is_bundled(const pe_resource_t *rsc)
while (rsc->parent != NULL) {
rsc = rsc->parent;
}
- return rsc->variant == pe_container;
+ return rsc->variant == pcmk_rsc_variant_bundle;
}
#ifdef __cplusplus
diff --git a/include/crm/services_compat.h b/include/crm/services_compat.h
index 97310f4..456d351 100644
--- a/include/crm/services_compat.h
+++ b/include/crm/services_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2022 the Pacemaker project contributors
+ * Copyright 2010-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -10,7 +10,7 @@
#ifndef PCMK__CRM_SERVICES_COMPAT__H
# define PCMK__CRM_SERVICES_COMPAT__H
-
+#include <crm/common/actions.h>
#include <crm/common/results.h>
#include <crm/services.h>
#include <glib.h>
@@ -68,7 +68,8 @@ static inline enum ocf_exitcode
services_get_ocf_exitcode(const char *action, int lsb_exitcode)
{
/* For non-status actions, LSB and OCF share error code meaning <= 7 */
- if (action && strcmp(action, "status") && strcmp(action, "monitor")) {
+ if ((action != NULL) && (strcmp(action, PCMK_ACTION_STATUS) != 0)
+ && (strcmp(action, PCMK_ACTION_MONITOR) != 0)) {
if ((lsb_exitcode < 0) || (lsb_exitcode > PCMK_LSB_NOT_RUNNING)) {
return PCMK_OCF_UNKNOWN_ERROR;
}