summaryrefslogtreecommitdiffstats
path: root/include/pcmki
diff options
context:
space:
mode:
Diffstat (limited to 'include/pcmki')
-rw-r--r--include/pcmki/Makefile.am26
-rw-r--r--include/pcmki/pcmki_acl.h59
-rw-r--r--include/pcmki/pcmki_cluster_queries.h69
-rw-r--r--include/pcmki/pcmki_fence.h250
-rw-r--r--include/pcmki/pcmki_output.h32
-rw-r--r--include/pcmki/pcmki_resource.h20
-rw-r--r--include/pcmki/pcmki_result_code.h23
-rw-r--r--include/pcmki/pcmki_rule.h40
-rw-r--r--include/pcmki/pcmki_sched_allocate.h50
-rw-r--r--include/pcmki/pcmki_sched_utils.h33
-rw-r--r--include/pcmki/pcmki_scheduler.h43
-rw-r--r--include/pcmki/pcmki_simulate.h97
-rw-r--r--include/pcmki/pcmki_status.h63
-rw-r--r--include/pcmki/pcmki_transition.h176
14 files changed, 981 insertions, 0 deletions
diff --git a/include/pcmki/Makefile.am b/include/pcmki/Makefile.am
new file mode 100644
index 0000000..b379fdb
--- /dev/null
+++ b/include/pcmki/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Copyright 2019-2022 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
+#
+# This source code is licensed under the GNU General Public License version 2
+# or later (GPLv2+) WITHOUT ANY WARRANTY.
+#
+
+MAINTAINERCLEANFILES = Makefile.in
+
+noinst_HEADERS = pcmki_acl.h \
+ pcmki_cluster_queries.h \
+ pcmki_fence.h \
+ pcmki_output.h \
+ pcmki_resource.h \
+ pcmki_result_code.h \
+ pcmki_rule.h \
+ pcmki_sched_allocate.h \
+ pcmki_sched_utils.h \
+ pcmki_scheduler.h \
+ pcmki_simulate.h \
+ pcmki_status.h \
+ pcmki_transition.h
+
+.PHONY: $(ARCHIVE_VERSION)
diff --git a/include/pcmki/pcmki_acl.h b/include/pcmki/pcmki_acl.h
new file mode 100644
index 0000000..890336e
--- /dev/null
+++ b/include/pcmki/pcmki_acl.h
@@ -0,0 +1,59 @@
+/*
+ * 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__PCMKI_PCMKI_ACL__H
+#define PCMK__PCMKI_PCMKI_ACL__H
+
+#include <crm/common/xml.h>
+
+// How ACLs can be displayed (for cibadmin --show-access)
+enum pcmk__acl_render_how {
+ pcmk__acl_render_none = 0,
+ pcmk__acl_render_namespace,
+ pcmk__acl_render_text,
+ pcmk__acl_render_color,
+ pcmk__acl_render_default,
+};
+
+// Minimum CIB schema version that can be used to annotate and display ACLs
+#define PCMK__COMPAT_ACL_2_MIN_INCL "pacemaker-2.0"
+
+/*!
+ * \brief Annotate CIB with XML namespaces indicating ACL evaluation results
+ *
+ * \param[in] cred Credential whose ACL perspective to switch to
+ * \param[in] cib_doc CIB XML to annotate
+ * \param[out] acl_evaled_doc Where to store annotated CIB XML
+ *
+ * \return A standard Pacemaker return code (pcmk_rc_ok on success,
+ * pcmk_rc_already if ACLs were not applicable,
+ * pcmk_rc_schema_validation if the validation schema version
+ * is unsupported, or EINVAL or ENOMEM when appropriate.
+ * \note This supports CIBs validated with the pacemaker-2.0 schema or newer.
+ */
+int pcmk__acl_annotate_permissions(const char *cred, const xmlDoc *cib_doc,
+ xmlDoc **acl_evaled_doc);
+
+/*!
+ * \internal
+ * \brief Create a string representation of a CIB showing ACL evaluation results
+ *
+ * \param[in,out] annotated_doc XML annotated by pcmk__acl_annotate_permissions
+ * \param[in] how Desired rendering
+ * \param[out] doc_txt_ptr Where to put the final outcome string
+ *
+ * \return A standard Pacemaker return code
+ *
+ * \note This function will free \p annotated_doc, which should not be used
+ * after calling this function.
+ * \todo This function could use more extensive testing for resource leaks.
+ */
+int pcmk__acl_evaled_render(xmlDoc *annotated_doc, enum pcmk__acl_render_how,
+ xmlChar **doc_txt_ptr);
+
+#endif
diff --git a/include/pcmki/pcmki_cluster_queries.h b/include/pcmki/pcmki_cluster_queries.h
new file mode 100644
index 0000000..776aa27
--- /dev/null
+++ b/include/pcmki/pcmki_cluster_queries.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2020-2022 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__PCMKI_PCMKI_CLUSTER_QUERIES__H
+# define PCMK__PCMKI_PCMKI_CLUSTER_QUERIES__H
+
+#include <glib.h> // gboolean, GMainLoop, etc.
+
+#include <crm/crm.h>
+#include <crm/common/output_internal.h>
+#include <crm/common/ipc_controld.h>
+#include <crm/common/ipc_pacemakerd.h>
+
+// CIB queries
+int pcmk__list_nodes(pcmk__output_t *out, const char *node_types,
+ gboolean bash_export);
+
+// Controller queries
+int pcmk__controller_status(pcmk__output_t *out, const char *node_name,
+ unsigned int message_timeout_ms);
+int pcmk__designated_controller(pcmk__output_t *out,
+ unsigned int message_timeout_ms);
+int pcmk__pacemakerd_status(pcmk__output_t *out, const char *ipc_name,
+ unsigned int message_timeout_ms, bool show_output,
+ enum pcmk_pacemakerd_state *state);
+int pcmk__query_node_info(pcmk__output_t *out, uint32_t *node_id,
+ char **node_name, char **uuid, char **state,
+ bool *have_quorum, bool *is_remote, bool show_output,
+ unsigned int message_timeout_ms);
+
+/*!
+ * \internal
+ * \brief Get the node name corresponding to a node ID from the controller
+ *
+ * \param[in,out] out Output object
+ * \param[in] node_id ID of node whose name to get (or 0 for
+ * the local node)
+ * \param[out] node_name If not \p NULL, where to store the node
+ * name
+ * \param[in] message_timeout_ms How long to wait for a reply from the
+ * \p pacemaker-controld API. If 0,
+ * \p pcmk_ipc_dispatch_sync will be used.
+ * Otherwise, \p pcmk_ipc_dispatch_poll will
+ * be used.
+ *
+ * \return Standard Pacemaker return code
+ *
+ * \note The caller is responsible for freeing \p *node_name using \p free().
+ */
+static inline int
+pcmk__query_node_name(pcmk__output_t *out, uint32_t nodeid, char **node_name,
+ unsigned int message_timeout_ms)
+{
+ return pcmk__query_node_info(out, &nodeid, node_name, NULL, NULL, NULL,
+ NULL, false, message_timeout_ms);
+}
+
+// pacemakerd queries
+int pcmk__pacemakerd_status(pcmk__output_t *out, const char *ipc_name,
+ unsigned int message_timeout_ms, bool show_output,
+ enum pcmk_pacemakerd_state *state);
+
+#endif
diff --git a/include/pcmki/pcmki_fence.h b/include/pcmki/pcmki_fence.h
new file mode 100644
index 0000000..e96edf4
--- /dev/null
+++ b/include/pcmki/pcmki_fence.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2019-2022 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__PCMKI_PCMKI_FENCE__H
+# define PCMK__PCMKI_PCMKI_FENCE__H
+
+# include <crm/stonith-ng.h>
+# include <crm/common/output_internal.h>
+
+/*!
+ * \brief Control how much of the fencing history is output.
+ */
+enum pcmk__fence_history {
+ pcmk__fence_history_none,
+ pcmk__fence_history_reduced,
+ pcmk__fence_history_full
+};
+
+/*!
+ * \brief Ask the cluster to perform fencing
+ *
+ * \note This is the internal version of pcmk_request_fencing(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] target The node that should be fenced
+ * \param[in] action The fencing action (on, off, reboot) to perform
+ * \param[in] name Who requested the fence action?
+ * \param[in] timeout How long to wait for operation to complete (in ms)
+ * \param[in] tolerance If a successful action for \p target happened within
+ * this many milliseconds, return success without
+ * performing the action again
+ * \param[in] delay Apply this delay (in milliseconds) before initiating
+ * fencing action (a value of -1 applies no delay and
+ * disables any fencing delay from pcmk_delay_base and
+ * pcmk_delay_max)
+ * \param[out] reason If not NULL, where to put descriptive failure reason
+ *
+ * \return Standard Pacemaker return code
+ * \note If \p reason is not NULL, the caller is responsible for freeing its
+ * returned value.
+ * \todo delay is eventually used with g_timeout_add() and should be guint
+ */
+int pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
+ const char *name, unsigned int timeout,
+ unsigned int tolerance, int delay, char **reason);
+
+/*!
+ * \brief List the fencing operations that have occurred for a specific node
+ *
+ * \note This is the internal version of pcmk_fence_history(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] target The node to get history for
+ * \param[in] timeout How long to wait for operation to complete (in ms)
+ * \param[in] verbose Include additional output
+ * \param[in] broadcast Gather fencing history from all nodes
+ * \param[in] cleanup Clean up fencing history after listing
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_history(pcmk__output_t *out, stonith_t *st, const char *target,
+ unsigned int timeout, int verbose, bool broadcast,
+ bool cleanup);
+
+/*!
+ * \brief List all installed fence agents
+ *
+ * \note This is the internal version of pcmk_fence_installed(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] timeout How long to wait for the operation to complete (in ms)
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_installed(pcmk__output_t *out, stonith_t *st, unsigned int timeout);
+
+/*!
+ * \brief When was a device last fenced?
+ *
+ * \note This is the internal version of pcmk_fence_last(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure.
+ * \param[in] target The node that was fenced.
+ * \param[in] as_nodeid
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_last(pcmk__output_t *out, const char *target, bool as_nodeid);
+
+/*!
+ * \brief List nodes that can be fenced
+ *
+ * \note This is the internal version of pcmk_fence_list_targets(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] device_id Resource ID of fence device to check
+ * \param[in] timeout How long to wait for operation to complete (in ms)
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_list_targets(pcmk__output_t *out, stonith_t *st,
+ const char *device_id, unsigned int timeout);
+
+/*!
+ * \brief Get metadata for a fence agent
+ *
+ * \note This is the internal version of pcmk_fence_metadata(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] agent The fence agent to get metadata for
+ * \param[in] timeout How long to wait for the operation to complete (in ms)
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_metadata(pcmk__output_t *out, stonith_t *st, const char *agent,
+ unsigned int timeout);
+
+/*!
+ * \brief List registered fence devices
+ *
+ * \note This is the internal version of pcmk_fence_metadata(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] target If not NULL, return only devices that can fence this
+ * \param[in] timeout How long to wait for the operation to complete (in ms)
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_registered(pcmk__output_t *out, stonith_t *st,
+ const char *target, unsigned int timeout);
+
+/*!
+ * \brief Register a fencing level for a specific node, node regex, or attribute
+ *
+ * \note This is the internal version of pcmk_fence_register_level(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \p target can take three different forms:
+ * - name=value, in which case \p target is an attribute.
+ * - @pattern, in which case \p target is a node regex.
+ * - Otherwise, \p target is a node name.
+ *
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] target The object to register a fencing level for
+ * \param[in] fence_level Index number of level to add
+ * \param[in] devices Devices to use in level
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_register_level(stonith_t *st, const char *target,
+ int fence_level,
+ const stonith_key_value_t *devices);
+
+/*!
+ * \brief Unregister a fencing level for specific node, node regex, or attribute
+ *
+ * \note This is the internal version of pcmk_fence_unregister_level(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \p target can take three different forms:
+ * - name=value, in which case \p target is an attribute.
+ * - @pattern, in which case \p target is a node regex.
+ * - Otherwise, \p target is a node name.
+ *
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] target The object to unregister a fencing level for
+ * \param[in] fence_level Index number of level to remove
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_unregister_level(stonith_t *st, const char *target,
+ int fence_level);
+
+/*!
+ * \brief Validate a fence device configuration
+ *
+ * \note This is the internal version of pcmk_stonith_validate(). External users
+ * of the pacemaker API should use that function instead.
+ *
+ * \note \p out should be initialized with pcmk__output_new() before calling this
+ * function and destroyed with out->finish and pcmk__output_free() before
+ * reusing it with any other functions in this library.
+ *
+ * \param[in,out] out The output functions structure
+ * \param[in,out] st A connection to the fencer API
+ * \param[in] agent The agent to validate (for example, "fence_xvm")
+ * \param[in] id Fence device ID (may be NULL)
+ * \param[in] params Fence device configuration parameters
+ * \param[in] timeout How long to wait for the operation to complete (in ms)
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__fence_validate(pcmk__output_t *out, stonith_t *st, const char *agent,
+ const char *id, const stonith_key_value_t *params,
+ unsigned int timeout);
+
+/*!
+ * \brief Fetch fencing history, optionally reducing it
+ *
+ * \param[in,out] st A connection to the fencer API
+ * \param[out] stonith_history Destination for storing the history
+ * \param[in] fence_history How much of the fencing history to display
+ *
+ * \return Standard Pacemaker return code
+ */
+int
+pcmk__get_fencing_history(stonith_t *st, stonith_history_t **stonith_history,
+ enum pcmk__fence_history fence_history);
+#endif
diff --git a/include/pcmki/pcmki_output.h b/include/pcmki/pcmki_output.h
new file mode 100644
index 0000000..a2a8085
--- /dev/null
+++ b/include/pcmki/pcmki_output.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019-2022 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__PCMKI_PCMKI_OUTPUT__H
+# define PCMK__PCMKI_PCMKI_OUTPUT__H
+
+# include <libxml/tree.h>
+# include <crm/common/output_internal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This function registers only the formatted output messages that are a part
+ * of libpacemaker. It is not to be confused with pcmk__register_messages,
+ * which is a part of formatted output support and registers a whole table of
+ * messages at a time.
+ */
+void pcmk__register_lib_messages(pcmk__output_t *out);
+
+int pcmk__cluster_status_text(pcmk__output_t *out, va_list args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/pcmki/pcmki_resource.h b/include/pcmki/pcmki_resource.h
new file mode 100644
index 0000000..dc8ac69
--- /dev/null
+++ b/include/pcmki/pcmki_resource.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2021-2022 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__PCMKI_PCMKI_RESOURCE__H
+#define PCMK__PCMKI_PCMKI_RESOURCE__H
+
+#include <glib.h>
+
+#include <crm/common/output_internal.h>
+#include <crm/pengine/pe_types.h>
+
+int pcmk__resource_digests(pcmk__output_t *out, pe_resource_t *rsc,
+ const pe_node_t *node, GHashTable *overrides);
+
+#endif /* PCMK__PCMKI_PCMKI_RESOURCE__H */
diff --git a/include/pcmki/pcmki_result_code.h b/include/pcmki/pcmki_result_code.h
new file mode 100644
index 0000000..479e9c7
--- /dev/null
+++ b/include/pcmki/pcmki_result_code.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 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__PCMKI_PCMKI_RESULT_CODE__H
+# define PCMK__PCMKI_PCMKI_RESULT_CODE__H
+
+#include <stdint.h>
+
+#include <crm/crm.h>
+#include <crm/common/output_internal.h>
+
+int pcmk__show_result_code(pcmk__output_t *out, int code,
+ enum pcmk_result_type type, uint32_t flags);
+int pcmk__list_result_codes(pcmk__output_t *out, enum pcmk_result_type type,
+ uint32_t flags);
+
+#endif // PCMK__PCMKI_PCMKI_RESULT_CODE__H
diff --git a/include/pcmki/pcmki_rule.h b/include/pcmki/pcmki_rule.h
new file mode 100644
index 0000000..356278c
--- /dev/null
+++ b/include/pcmki/pcmki_rule.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 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__PCMKI_PCMKI_RULE__H
+# define PCMK__PCMKI_PCMKI_RULE__H
+
+#include <crm/crm.h>
+#include <crm/common/iso8601.h>
+#include <crm/common/output_internal.h>
+
+int pcmk__check_rules(pcmk__output_t *out, xmlNodePtr input,
+ const crm_time_t *date_time, const char **rule_ids);
+
+/*!
+ * \internal
+ * \brief Check whether a given rule is in effect
+ *
+ * \param[in,out] out Output object
+ * \param[in] input The CIB XML to check (if \c NULL, use current CIB)
+ * \param[in] date Check whether the rule is in effect at this date and
+ * time (if \c NULL, use current date and time)
+ * \param[in] rule_ids The ID of the rule to check
+ *
+ * \return Standard Pacemaker return code
+ */
+static inline int
+pcmk__check_rule(pcmk__output_t *out, xmlNodePtr input, const crm_time_t *date,
+ const char *rule_id)
+{
+ const char *rule_ids[] = {rule_id, NULL};
+ return pcmk__check_rules(out, input, date, rule_ids);
+}
+
+#endif // PCMK__PCMKI_PCMKI_RULE__H
diff --git a/include/pcmki/pcmki_sched_allocate.h b/include/pcmki/pcmki_sched_allocate.h
new file mode 100644
index 0000000..32044ea
--- /dev/null
+++ b/include/pcmki/pcmki_sched_allocate.h
@@ -0,0 +1,50 @@
+/*
+ * 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__PCMKI_PCMKI_SCHED_ALLOCATE__H
+# define PCMK__PCMKI_PCMKI_SCHED_ALLOCATE__H
+
+# include <glib.h>
+# include <crm/common/xml.h>
+# include <crm/pengine/status.h>
+# include <crm/pengine/complex.h>
+# include <crm/common/xml_internal.h>
+# include <crm/pengine/internal.h>
+# include <crm/common/xml.h>
+# include <pcmki/pcmki_scheduler.h>
+
+pe_node_t *pcmk__bundle_allocate(pe_resource_t *rsc, const pe_node_t *prefer);
+void pcmk__bundle_create_actions(pe_resource_t *rsc);
+bool pcmk__bundle_create_probe(pe_resource_t *rsc, pe_node_t *node);
+void pcmk__bundle_internal_constraints(pe_resource_t *rsc);
+void pcmk__bundle_rsc_location(pe_resource_t *rsc, pe__location_t *constraint);
+enum pe_action_flags pcmk__bundle_action_flags(pe_action_t *action,
+ const pe_node_t *node);
+void pcmk__bundle_expand(pe_resource_t *rsc);
+void pcmk__bundle_add_utilization(const pe_resource_t *rsc,
+ const pe_resource_t *orig_rsc,
+ GList *all_rscs, GHashTable *utilization);
+void pcmk__bundle_shutdown_lock(pe_resource_t *rsc);
+
+void clone_create_actions(pe_resource_t *rsc);
+void clone_internal_constraints(pe_resource_t *rsc);
+void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint);
+enum pe_action_flags clone_action_flags(pe_action_t *action,
+ const pe_node_t *node);
+void clone_expand(pe_resource_t *rsc);
+bool clone_create_probe(pe_resource_t *rsc, pe_node_t *node);
+void clone_append_meta(const pe_resource_t *rsc, xmlNode *xml);
+void pcmk__clone_add_utilization(const pe_resource_t *rsc,
+ const pe_resource_t *orig_rsc,
+ GList *all_rscs, GHashTable *utilization);
+void pcmk__clone_shutdown_lock(pe_resource_t *rsc);
+
+void pcmk__log_transition_summary(const char *filename);
+
+#endif
diff --git a/include/pcmki/pcmki_sched_utils.h b/include/pcmki/pcmki_sched_utils.h
new file mode 100644
index 0000000..3e6d52f
--- /dev/null
+++ b/include/pcmki/pcmki_sched_utils.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__PCMKI_PCMKI_SCHED_UTILS__H
+# define PCMK__PCMKI_PCMKI_SCHED_UTILS__H
+
+#include <stdbool.h> // bool
+#include <glib.h> // GList, GHashTable, gboolean, guint
+#include <crm/lrmd.h> // lrmd_event_data_t
+#include <crm/cib.h> // cib_t
+#include <crm/pengine/pe_types.h>
+#include <crm/common/xml_internal.h>
+#include <crm/pengine/internal.h>
+#include <pcmki/pcmki_scheduler.h>
+#include <pcmki/pcmki_transition.h>
+#include <pacemaker.h>
+
+/* Constraint helper functions */
+GList *pcmk__copy_node_list(const GList *list, bool reset);
+
+int copies_per_node(pe_resource_t * rsc);
+
+xmlNode *pcmk__create_history_xml(xmlNode *parent, lrmd_event_data_t *event,
+ const char *caller_version, int target_rc,
+ const char *node, const char *origin);
+
+#endif
diff --git a/include/pcmki/pcmki_scheduler.h b/include/pcmki/pcmki_scheduler.h
new file mode 100644
index 0000000..dde50a5
--- /dev/null
+++ b/include/pcmki/pcmki_scheduler.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014-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__PCMKI_PCMKI_SCHEDULER__H
+# define PCMK__PCMKI_PCMKI_SCHEDULER__H
+
+# include <glib.h>
+# include <crm/crm.h>
+# include <crm/common/iso8601.h>
+# include <crm/pengine/rules.h>
+# include <crm/pengine/common.h>
+# include <crm/pengine/status.h>
+
+# include <crm/pengine/complex.h>
+
+typedef struct {
+ const char *id;
+ const char *node_attribute;
+ pe_resource_t *dependent; // The resource being colocated
+ pe_resource_t *primary; // The resource the dependent is colocated with
+
+ int dependent_role; // Colocation applies only if dependent has this role
+ int primary_role; // Colocation applies only if primary has this role
+
+ int score;
+ bool influence; // Whether dependent influences active primary placement
+} pcmk__colocation_t;
+
+void pcmk__unpack_constraints(pe_working_set_t *data_set);
+
+void pcmk__schedule_actions(xmlNode *cib, unsigned long long flags,
+ pe_working_set_t *data_set);
+
+GList *pcmk__with_this_colocations(const pe_resource_t *rsc);
+GList *pcmk__this_with_colocations(const pe_resource_t *rsc);
+
+#endif
diff --git a/include/pcmki/pcmki_simulate.h b/include/pcmki/pcmki_simulate.h
new file mode 100644
index 0000000..0b09903
--- /dev/null
+++ b/include/pcmki/pcmki_simulate.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2021-2022 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__PCMKI_PCMKI_SIMULATE__H
+# define PCMK__PCMKI_PCMKI_SIMULATE__H
+
+#include <crm/common/output_internal.h>
+#include <crm/pengine/pe_types.h>
+#include <pcmki/pcmki_transition.h>
+#include <crm/cib.h> // cib_t
+#include <pacemaker.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/*!
+ * \internal
+ * \brief Profile the configuration updates and scheduler actions in every
+ * CIB file in a given directory, printing the profiling timings for
+ * each.
+ *
+ * \note \p data_set->priv must have been set to a valid \p pcmk__output_t
+ * object before this function is called.
+ *
+ * \param[in] dir A directory full of CIB files to be profiled
+ * \param[in] repeat Number of times to run on each input file
+ * \param[in,out] data_set Working set for the cluster
+ * \param[in] use_date The date to set the cluster's time to (may be NULL)
+ */
+void pcmk__profile_dir(const char *dir, long long repeat, pe_working_set_t *data_set,
+ const char *use_date);
+
+/*!
+ * \internal
+ * \brief Simulate executing a transition
+ *
+ * \param[in,out] data_set Cluster working set
+ * \param[in,out] cib CIB object for scheduler input
+ * \param[in] op_fail_list List of actions to simulate as failing
+ *
+ * \return Transition status after simulated execution
+ */
+enum pcmk__graph_status pcmk__simulate_transition(pe_working_set_t *data_set,
+ cib_t *cib,
+ const GList *op_fail_list);
+
+/*!
+ * \internal
+ * \brief Simulate a cluster's response to events
+ *
+ * This high-level function essentially implements crm_simulate(8). It operates
+ * on an input CIB file and various lists of events that can be simulated. It
+ * optionally writes out a variety of artifacts to show the results of the
+ * simulation. Output can be modified with various flags.
+ *
+ * \param[in,out] data_set Working set for the cluster
+ * \param[in,out] out The output functions structure
+ * \param[in] injections A structure containing cluster events
+ * (node up/down, tickets, injected operations)
+ * and related data
+ * \param[in] flags A bitfield of \p pcmk_sim_flags to modify
+ * operation of the simulation
+ * \param[in] section_opts Which portions of the cluster status output
+ * should be displayed?
+ * \param[in] use_date The date to set the cluster's time to
+ * (may be NULL)
+ * \param[in] input_file The source CIB file, which may be overwritten by
+ * this function (may be NULL)
+ * \param[in] graph_file Where to write the XML-formatted transition graph
+ * (may be NULL, in which case no file will be
+ * written)
+ * \param[in] dot_file Where to write the dot(1) formatted transition
+ * graph (may be NULL, in which case no file will
+ * be written; see \p pcmk__write_sim_dotfile())
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk__simulate(pe_working_set_t *data_set, pcmk__output_t *out,
+ const pcmk_injections_t *injections, unsigned int flags,
+ uint32_t section_opts, const char *use_date,
+ const char *input_file, const char *graph_file,
+ const char *dot_file);
+
+/*!
+ * \internal
+ *
+ * If this global is set to true, simulations will add nodes to the
+ * CIB configuration section, as well as the status section.
+ */
+extern bool pcmk__simulate_node_config;
+
+#endif
diff --git a/include/pcmki/pcmki_status.h b/include/pcmki/pcmki_status.h
new file mode 100644
index 0000000..6b48069
--- /dev/null
+++ b/include/pcmki/pcmki_status.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022-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__PCMKI_PCMKI_STATUS__H
+#define PCMK__PCMKI_PCMKI_STATUS__H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <crm/cib/cib_types.h>
+#include <crm/pengine/pe_types.h>
+#include <crm/common/ipc_pacemakerd.h>
+#include <crm/common/output_internal.h>
+#include <pcmki/pcmki_fence.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \internal
+ * \brief Print one-line status suitable for use with monitoring software
+ *
+ * \param[in,out] out Output object
+ * \param[in] data_set Cluster working set
+ *
+ * \return Standard Pacemaker return code
+ *
+ * \note This function's output should conform to
+ * https://www.monitoring-plugins.org/doc/guidelines.html
+ *
+ * \note This function is planned to be deprecated and then removed in the
+ * future. It should only be called from crm_mon, and no additional
+ * callers should be added.
+ */
+int pcmk__output_simple_status(pcmk__output_t *out,
+ const pe_working_set_t *data_set);
+
+int pcmk__output_cluster_status(pcmk__output_t *out, stonith_t *stonith,
+ cib_t *cib, xmlNode *current_cib,
+ enum pcmk_pacemakerd_state pcmkd_state,
+ enum pcmk__fence_history fence_history,
+ uint32_t show, uint32_t show_opts,
+ const char *only_node, const char *only_rsc,
+ const char *neg_location_prefix,
+ bool simple_output);
+
+int pcmk__status(pcmk__output_t *out, cib_t *cib,
+ enum pcmk__fence_history fence_history, uint32_t show,
+ uint32_t show_opts, const char *only_node,
+ const char *only_rsc, const char *neg_location_prefix,
+ bool simple_output, unsigned int timeout_ms);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/pcmki/pcmki_transition.h b/include/pcmki/pcmki_transition.h
new file mode 100644
index 0000000..5dc3101
--- /dev/null
+++ b/include/pcmki/pcmki_transition.h
@@ -0,0 +1,176 @@
+/*
+ * 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__PCMKI_PCMKI_TRANSITION__H
+# define PCMK__PCMKI_PCMKI_TRANSITION__H
+
+# include <glib.h>
+# include <crm/crm.h>
+# include <crm/msg_xml.h>
+# include <crm/common/xml.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum pcmk__graph_action_type {
+ pcmk__pseudo_graph_action,
+ pcmk__rsc_graph_action,
+ pcmk__cluster_graph_action,
+};
+
+enum pcmk__synapse_flags {
+ pcmk__synapse_ready = (1 << 0),
+ pcmk__synapse_failed = (1 << 1),
+ pcmk__synapse_executed = (1 << 2),
+ pcmk__synapse_confirmed = (1 << 3),
+};
+
+typedef struct {
+ int id;
+ int priority;
+
+ uint32_t flags; // Group of pcmk__synapse_flags
+
+ GList *actions; /* pcmk__graph_action_t* */
+ GList *inputs; /* pcmk__graph_action_t* */
+} pcmk__graph_synapse_t;
+
+#define pcmk__set_synapse_flags(synapse, flags_to_set) do { \
+ (synapse)->flags = pcmk__set_flags_as(__func__, __LINE__, \
+ LOG_TRACE, \
+ "Synapse", "synapse", \
+ (synapse)->flags, (flags_to_set), #flags_to_set); \
+ } while (0)
+
+#define pcmk__clear_synapse_flags(synapse, flags_to_clear) do { \
+ (synapse)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
+ LOG_TRACE, \
+ "Synapse", "synapse", \
+ (synapse)->flags, (flags_to_clear), #flags_to_clear); \
+ } while (0)
+
+enum pcmk__graph_action_flags {
+ pcmk__graph_action_sent_update = (1 << 0), /* sent to the CIB */
+ pcmk__graph_action_executed = (1 << 1), /* sent to the CRM */
+ pcmk__graph_action_confirmed = (1 << 2),
+ pcmk__graph_action_failed = (1 << 3),
+ pcmk__graph_action_can_fail = (1 << 4), //! \deprecated Will be removed in a future release
+};
+
+typedef struct {
+ int id;
+ int timeout;
+ int timer;
+ guint interval_ms;
+ GHashTable *params;
+ enum pcmk__graph_action_type type;
+ pcmk__graph_synapse_t *synapse;
+
+ uint32_t flags; // Group of pcmk__graph_action_flags
+
+ xmlNode *xml;
+
+} pcmk__graph_action_t;
+
+#define pcmk__set_graph_action_flags(action, flags_to_set) do { \
+ (action)->flags = pcmk__set_flags_as(__func__, __LINE__, \
+ LOG_TRACE, \
+ "Action", "action", \
+ (action)->flags, (flags_to_set), #flags_to_set); \
+ } while (0)
+
+#define pcmk__clear_graph_action_flags(action, flags_to_clear) do { \
+ (action)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
+ LOG_TRACE, \
+ "Action", "action", \
+ (action)->flags, (flags_to_clear), #flags_to_clear); \
+ } while (0)
+
+// What to do after finished processing a transition graph
+enum pcmk__graph_next {
+ // Order matters: lowest priority to highest
+ pcmk__graph_done, // Transition complete, nothing further needed
+ pcmk__graph_wait, // Transition interrupted, wait for further changes
+ pcmk__graph_restart, // Transition interrupted, start a new one
+ pcmk__graph_shutdown, // Transition interrupted, local shutdown needed
+};
+
+typedef struct {
+ int id;
+ char *source;
+ int abort_priority;
+
+ bool complete;
+ const char *abort_reason;
+ enum pcmk__graph_next completion_action;
+
+ int num_actions;
+ int num_synapses;
+
+ int batch_limit;
+ guint network_delay;
+ guint stonith_timeout;
+
+ int fired;
+ int pending;
+ int skipped;
+ int completed;
+ int incomplete;
+
+ GList *synapses; /* pcmk__graph_synapse_t* */
+
+ int migration_limit;
+
+ //! Failcount after one failed stop action
+ char *failed_stop_offset;
+
+ //! Failcount after one failed start action
+ char *failed_start_offset;
+
+ //! Time (from epoch) by which the controller should re-run the scheduler
+ time_t recheck_by;
+} pcmk__graph_t;
+
+
+typedef struct {
+ int (*pseudo) (pcmk__graph_t *graph, pcmk__graph_action_t *action);
+ int (*rsc) (pcmk__graph_t *graph, pcmk__graph_action_t *action);
+ int (*cluster) (pcmk__graph_t *graph, pcmk__graph_action_t *action);
+ int (*fence) (pcmk__graph_t *graph, pcmk__graph_action_t *action);
+ bool (*allowed) (pcmk__graph_t *graph, pcmk__graph_action_t *action);
+} pcmk__graph_functions_t;
+
+enum pcmk__graph_status {
+ pcmk__graph_active, // Some actions have been performed
+ pcmk__graph_pending, // No actions performed yet
+ pcmk__graph_complete,
+ pcmk__graph_terminated,
+};
+
+void pcmk__set_graph_functions(pcmk__graph_functions_t *fns);
+pcmk__graph_t *pcmk__unpack_graph(const xmlNode *xml_graph,
+ const char *reference);
+enum pcmk__graph_status pcmk__execute_graph(pcmk__graph_t *graph);
+void pcmk__update_graph(pcmk__graph_t *graph,
+ const pcmk__graph_action_t *action);
+void pcmk__free_graph(pcmk__graph_t *graph);
+const char *pcmk__graph_status2text(enum pcmk__graph_status state);
+void pcmk__log_graph(unsigned int log_level, pcmk__graph_t *graph);
+void pcmk__log_graph_action(int log_level, pcmk__graph_action_t *action);
+lrmd_event_data_t *pcmk__event_from_graph_action(const xmlNode *resource,
+ const pcmk__graph_action_t *action,
+ int status, int rc,
+ const char *exit_reason);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif