pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
status.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2025 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <stdint.h> // uint32_t
13#include <sys/param.h>
14
15#include <glib.h>
16#include <libxml/tree.h> // xmlNode
17
18#include <crm/crm.h>
19#include <crm/common/xml.h>
21
23#include <pe_status_private.h>
24
25#define XPATH_DEPRECATED_RULES \
26 "//" PCMK_XE_OP_DEFAULTS "//" PCMK_XE_EXPRESSION \
27 "|//" PCMK_XE_OP "//" PCMK_XE_EXPRESSION
28
35static void
36check_for_deprecated_rules(pcmk_scheduler_t *scheduler)
37{
38 // @COMPAT Drop this function when support for the syntax is dropped
39 xmlNode *deprecated = pcmk__xpath_find_one(scheduler->input->doc,
41 LOG_NEVER);
42
43 if (deprecated != NULL) {
45 "Support for rules with node attribute expressions in "
46 PCMK_XE_OP " or " PCMK_XE_OP_DEFAULTS " is deprecated "
47 "and will be dropped in a future release");
48 }
49}
50
51/*
52 * Unpack everything
53 * At the end you'll have:
54 * - A list of nodes
55 * - A list of resources (each with any dependencies on other resources)
56 * - A list of constraints between resources and nodes
57 * - A list of constraints between start/stop actions
58 * - A list of nodes that need to be stonith'd
59 * - A list of nodes that need to be shutdown
60 * - A list of the possible stop/start actions (without dependencies)
61 *
62 * @TODO Currently this function can modify scheduler->input by creating
63 * primitive elements for guest nodes. Commit 5dbc819 aimed to make this
64 * function idempotent. It seems to be idempotent now, except that if
65 * scheduler->input is reused, it may gain duplicate primitive elements for
66 * guest nodes each time.
67 *
68 * Investigate whether we can leave scheduler->input unmodified without a lot of
69 * unnecessary XML copying. Otherwise, just document that scheduler->input may
70 * be modified.
71 */
72gboolean
74{
75 // @TODO Deprecate, replacing with a safer public alternative if necessary
76 const char *new_version = NULL;
77 xmlNode *section = NULL;
78
79 if ((scheduler == NULL) || (scheduler->input == NULL)) {
80 return FALSE;
81 }
82
84 /* cluster_status() has already been called since the last time the
85 * scheduler was reset. Unpacking the input CIB again would cause
86 * duplication within the scheduler object's data structures.
87 *
88 * The correct return code here is not obvious. Nothing internal checks
89 * the code, however.
90 */
91 return TRUE;
92 }
93
95
96 if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) {
97 pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'",
98 new_version, CRM_FEATURE_SET);
99 return FALSE;
100 }
101
102 crm_trace("Beginning unpack");
103
105 scheduler->priv->failed = pcmk__xe_create(NULL, "failed-ops");
106
107 if (scheduler->priv->now == NULL) {
108 scheduler->priv->now = crm_time_new(NULL);
109 }
110
113 } else {
115 }
116
119 LOG_NEVER);
120 check_for_deprecated_rules(scheduler);
121
124 LOG_NEVER);
125
126 section = pcmk__xpath_find_one(scheduler->input->doc,
128 unpack_config(section, scheduler);
129
130 if (!pcmk_any_flags_set(scheduler->flags,
134 "Fencing and resource management disabled "
135 "due to lack of quorum");
136 }
137
139 LOG_TRACE);
140 unpack_nodes(section, scheduler);
141
142 section = pcmk__xpath_find_one(scheduler->input->doc,
146 }
147 unpack_resources(section, scheduler);
148
149 section = pcmk__xpath_find_one(scheduler->input->doc,
152
153 section = pcmk__xpath_find_one(scheduler->input->doc, "//" PCMK_XE_TAGS,
154 LOG_NEVER);
155 unpack_tags(section, scheduler);
156
158 section = pcmk__xpath_find_one(scheduler->input->doc,
160 unpack_status(section, scheduler);
161 }
162
164 for (GList *item = scheduler->priv->resources;
165 item != NULL; item = item->next) {
166
167 pcmk_resource_t *rsc = item->data;
168
169 rsc->priv->fns->count(item->data);
170 }
171 crm_trace("Cluster resource count: %d (%d disabled, %d blocked)",
175 }
176
177 if ((scheduler->priv->local_node_name != NULL)
179 scheduler->priv->local_node_name) == NULL)) {
180 crm_info("Creating a fake local node for %s",
184 }
185
187 return TRUE;
188}
189
191pe_find_resource(GList *rsc_list, const char *id)
192{
194}
195
197pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
198{
199 GList *rIter = NULL;
200
201 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
202 pcmk_resource_t *parent = rIter->data;
203 pcmk_resource_t *match = parent->priv->fns->find_rsc(parent, id, NULL,
204 (uint32_t) flags);
205
206 if (match != NULL) {
207 return match;
208 }
209 }
210 crm_trace("No match for %s", id);
211 return NULL;
212}
213
226pe_find_node_any(const GList *nodes, const char *id, const char *uname)
227{
228 pcmk_node_t *match = NULL;
229
230 if (id != NULL) {
231 match = pe_find_node_id(nodes, id);
232 }
233 if ((match == NULL) && (uname != NULL)) {
234 match = pcmk__find_node_in_list(nodes, uname);
235 }
236 return match;
237}
238
248pe_find_node_id(const GList *nodes, const char *id)
249{
250 for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
251 pcmk_node_t *node = (pcmk_node_t *) iter->data;
252
253 /* @TODO Whether node IDs should be considered case-sensitive should
254 * probably depend on the node type, so functionizing the comparison
255 * would be worthwhile
256 */
257 if (pcmk__str_eq(node->priv->id, id, pcmk__str_casei)) {
258 return node;
259 }
260 }
261 return NULL;
262}
263
264// Deprecated functions kept only for backward API compatibility
265// LCOV_EXCL_START
266
268
271{
272 return pcmk_new_scheduler();
273}
274
275void
277{
278 if (scheduler == NULL) {
279 return;
280 }
282}
283
284void
286{
287 if (scheduler == NULL) {
288 return;
289 }
290
292 if (scheduler->priv->options != NULL) {
293 g_hash_table_destroy(scheduler->priv->options);
294 }
295
296 if (scheduler->priv->singletons != NULL) {
297 g_hash_table_destroy(scheduler->priv->singletons);
298 }
299
300 if (scheduler->priv->ticket_constraints != NULL) {
301 g_hash_table_destroy(scheduler->priv->ticket_constraints);
302 }
303
304 if (scheduler->priv->templates != NULL) {
305 g_hash_table_destroy(scheduler->priv->templates);
306 }
307
308 if (scheduler->priv->tags != NULL) {
309 g_hash_table_destroy(scheduler->priv->tags);
310 }
311
312 crm_trace("deleting resources");
313 g_list_free_full(scheduler->priv->resources, pcmk__free_resource);
314
315 crm_trace("deleting actions");
316 g_list_free_full(scheduler->priv->actions, pcmk__free_action);
317
318 crm_trace("deleting nodes");
319 g_list_free_full(scheduler->nodes, pcmk__free_node);
320 scheduler->nodes = NULL;
321
323 g_list_free(scheduler->priv->stop_needed);
328
330
332 && (scheduler->priv->ordering_constraints == NULL));
333}
334
335void
337{
338 // These members must be preserved
340 pcmk__output_t *out = priv->out;
341 char *local_node_name = scheduler->priv->local_node_name;
342
343 // Wipe the main structs (any other members must have previously been freed)
344 memset(scheduler, 0, sizeof(pcmk_scheduler_t));
345 memset(priv, 0, sizeof(pcmk__scheduler_private_t));
346
347 // Restore the members to preserve
348 scheduler->priv = priv;
349 scheduler->priv->out = out;
350 scheduler->priv->local_node_name = local_node_name;
351
352 // Set defaults for everything else
354}
355
356void
361
363pe_find_node(const GList *nodes, const char *node_name)
364{
365 return pcmk__find_node_in_list(nodes, node_name);
366}
367
368// LCOV_EXCL_STOP
369// End deprecated API
void pcmk__free_action(gpointer user_data)
Definition actions.c:189
const char * parent
Definition cib.c:27
int pcmk__check_feature_set(const char *cib_version)
Definition cib.c:185
uint64_t flags
Definition remote.c:3
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:80
char uname[MAX_NAME]
Definition cpg.c:5
A dumping ground.
#define CRM_FEATURE_SET
Definition crm.h:66
void crm_time_free(crm_time_t *dt)
Definition iso8601.c:150
crm_time_t * crm_time_new(const char *string)
Definition iso8601.c:112
#define crm_info(fmt, args...)
Definition logging.h:365
#define CRM_LOG_ASSERT(expr)
Definition logging.h:196
#define LOG_NEVER
Definition logging.h:48
#define crm_trace(fmt, args...)
Definition logging.h:370
#define LOG_TRACE
Definition logging.h:38
#define pcmk__config_err(fmt...)
@ pcmk__wo_op_attr_expr
#define pcmk__warn_once(wo_flag, fmt...)
pcmk_scheduler_t * scheduler
pcmk_node_t * pcmk__find_node_in_list(const GList *nodes, const char *node_name)
Definition nodes.c:198
void pcmk__free_node(gpointer user_data)
Definition nodes.c:22
G_GNUC_INTERNAL gboolean unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler)
Definition unpack.c:824
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pcmk_scheduler_t *scheduler)
Definition unpack.c:934
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler)
Definition unpack.c:692
G_GNUC_INTERNAL void pcmk__validate_fencing_topology(const xmlNode *xml)
Definition unpack.c:899
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler)
Definition unpack.c:1397
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pcmk_scheduler_t *scheduler)
Definition unpack.c:610
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler)
Definition unpack.c:219
pcmk_node_t * pe_create_node(const char *id, const char *uname, const char *type, int score, pcmk_scheduler_t *scheduler)
Definition unpack.c:452
pe_find
Search options for resources (exact resource ID always matches)
Definition resources.h:32
@ pcmk_rsc_match_history
Also match clone instance ID from resource history.
Definition resources.h:34
void pcmk__free_resource(gpointer user_data)
Definition resources.c:25
@ pcmk_rc_ok
Definition results.h:159
@ pcmk_no_quorum_ignore
Act as if partition still holds quorum.
Definition scheduler.h:41
void pcmk_free_scheduler(pcmk_scheduler_t *scheduler)
Free scheduler data.
Definition scheduler.c:193
pcmk_scheduler_t * pcmk_new_scheduler(void)
Create a new object to hold scheduler data.
Definition scheduler.c:32
pcmk_node_t * pcmk_find_node(const pcmk_scheduler_t *scheduler, const char *node_name)
Find a node by name in scheduler data.
Definition scheduler.c:282
void pcmk_reset_scheduler(pcmk_scheduler_t *scheduler)
Reset scheduler data to defaults.
Definition scheduler.c:87
void pcmk__set_scheduler_defaults(pcmk_scheduler_t *scheduler)
Definition scheduler.c:57
#define pcmk__clear_scheduler_flags(scheduler, flags_to_clear)
void pcmk__free_param_checks(pcmk_scheduler_t *scheduler)
Definition scheduler.c:410
#define pcmk__sched_warn(scheduler, fmt...)
#define pcmk__set_scheduler_flags(scheduler, flags_to_set)
@ pcmk__sched_quorate
@ pcmk__sched_no_counts
@ pcmk__sched_have_status
@ pcmk__sched_location_only
pcmk_node_t * pe_find_node_id(const GList *nodes, const char *id)
Find a node by ID in a list of nodes.
Definition status.c:248
pcmk_node_t * pe_find_node(const GList *nodes, const char *node_name)
Definition status.c:363
void pe_free_working_set(pcmk_scheduler_t *scheduler)
Definition status.c:357
void pe_reset_working_set(pcmk_scheduler_t *scheduler)
Definition status.c:276
pcmk_node_t * pe_find_node_any(const GList *nodes, const char *id, const char *uname)
Find a node by name or ID in a list of nodes.
Definition status.c:226
pcmk_resource_t * pe_find_resource(GList *rsc_list, const char *id)
Definition status.c:191
pcmk_scheduler_t * pe_new_working_set(void)
Definition status.c:270
gboolean cluster_status(pcmk_scheduler_t *scheduler)
Definition status.c:73
void cleanup_calculations(pcmk_scheduler_t *scheduler)
Definition status.c:285
void set_working_set_defaults(pcmk_scheduler_t *scheduler)
Definition status.c:336
#define XPATH_DEPRECATED_RULES
Definition status.c:25
pcmk_resource_t * pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
Definition status.c:197
Deprecated Pacemaker scheduler utilities.
@ pcmk__str_casei
This structure contains everything that makes up a single output formatter.
const pcmk__rsc_methods_t * fns
pcmk__resource_private_t * priv
Definition resources.h:61
pcmk_resource_t *(* find_rsc)(pcmk_resource_t *rsc, const char *search, const pcmk_node_t *node, uint32_t flags)
void(* count)(pcmk_resource_t *rsc)
pcmk__scheduler_private_t * priv
Definition scheduler.h:99
enum pe_quorum_policy no_quorum_policy
Definition scheduler.h:93
GList * nodes
Definition scheduler.h:97
xmlNode * input
Definition scheduler.h:81
uint64_t flags
Definition scheduler.h:89
pcmk__node_private_t * priv
Definition nodes.h:85
Wrappers for and extensions to libxml2.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
void pcmk__xml_free(xmlNode *xml)
Definition xml.c:816
#define PCMK_XE_STATUS
Definition xml_names.h:204
#define PCMK_XE_OP_DEFAULTS
Definition xml_names.h:147
#define PCMK_XE_CRM_CONFIG
Definition xml_names.h:91
#define PCMK_XE_RESOURCES
Definition xml_names.h:179
#define PCMK_XE_TAGS
Definition xml_names.h:209
#define PCMK_XA_HAVE_QUORUM
Definition xml_names.h:295
#define PCMK_XE_FENCING_TOPOLOGY
Definition xml_names.h:118
#define PCMK_XA_CRM_FEATURE_SET
Definition xml_names.h:254
#define PCMK_XE_NODES
Definition xml_names.h:142
#define PCMK_XE_OP
Definition xml_names.h:146
#define PCMK_XE_RSC_DEFAULTS
Definition xml_names.h:186
xmlNode * pcmk__xpath_find_one(xmlDoc *doc, const char *path, uint8_t level)
Definition xpath.c:206