pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
status.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2024 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 <sys/param.h>
13
14#include <crm/crm.h>
15#include <crm/common/xml.h>
17
18#include <glib.h>
19
21#include <pe_status_private.h>
22
35{
36 pcmk_scheduler_t *scheduler = calloc(1, sizeof(pcmk_scheduler_t));
37
38 if (scheduler != NULL) {
40 }
41 return scheduler;
42}
43
49void
58
59#define XPATH_DEPRECATED_RULES \
60 "//" PCMK_XE_OP_DEFAULTS "//" PCMK_XE_EXPRESSION \
61 "|//" PCMK_XE_OP "//" PCMK_XE_EXPRESSION
62
69static void
70check_for_deprecated_rules(pcmk_scheduler_t *scheduler)
71{
72 // @COMPAT Drop this function when support for the syntax is dropped
73 xmlNode *deprecated = get_xpath_object(XPATH_DEPRECATED_RULES,
75
76 if (deprecated != NULL) {
78 "Support for rules with node attribute expressions in "
79 PCMK_XE_OP " or " PCMK_XE_OP_DEFAULTS " is deprecated "
80 "and will be dropped in a future release");
81 }
82}
83
84/*
85 * Unpack everything
86 * At the end you'll have:
87 * - A list of nodes
88 * - A list of resources (each with any dependencies on other resources)
89 * - A list of constraints between resources and nodes
90 * - A list of constraints between start/stop actions
91 * - A list of nodes that need to be stonith'd
92 * - A list of nodes that need to be shutdown
93 * - A list of the possible stop/start actions (without dependencies)
94 */
95gboolean
97{
98 const char *new_version = NULL;
99 xmlNode *section = NULL;
100
101 if ((scheduler == NULL) || (scheduler->input == NULL)) {
102 return FALSE;
103 }
104
106
107 if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) {
108 pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'",
109 new_version, CRM_FEATURE_SET);
110 return FALSE;
111 }
112
113 crm_trace("Beginning unpack");
114
115 if (scheduler->failed != NULL) {
117 }
118 scheduler->failed = pcmk__xe_create(NULL, "failed-ops");
119
120 if (scheduler->now == NULL) {
121 scheduler->now = crm_time_new(NULL);
122 }
123
124 if (scheduler->dc_uuid == NULL) {
127 }
128
131 } else {
133 }
134
137 check_for_deprecated_rules(scheduler);
138
141
143 LOG_TRACE);
144 unpack_config(section, scheduler);
145
146 if (!pcmk_any_flags_set(scheduler->flags,
149 pcmk__sched_warn("Fencing and resource management disabled "
150 "due to lack of quorum");
151 }
152
154 unpack_nodes(section, scheduler);
155
157 LOG_TRACE);
160 }
161 unpack_resources(section, scheduler);
162
164 LOG_TRACE);
166
168 unpack_tags(section, scheduler);
169
172 LOG_TRACE);
173 unpack_status(section, scheduler);
174 }
175
177 for (GList *item = scheduler->resources; item != NULL;
178 item = item->next) {
179 ((pcmk_resource_t *) (item->data))->fns->count(item->data);
180 }
181 crm_trace("Cluster resource count: %d (%d disabled, %d blocked)",
184 }
185
187 return TRUE;
188}
189
201static void
202pe_free_resources(GList *resources)
203{
204 pcmk_resource_t *rsc = NULL;
205 GList *iterator = resources;
206
207 while (iterator != NULL) {
208 rsc = (pcmk_resource_t *) iterator->data;
209 iterator = iterator->next;
210 rsc->fns->free(rsc);
211 }
212 if (resources != NULL) {
213 g_list_free(resources);
214 }
215}
216
217static void
218pe_free_actions(GList *actions)
219{
220 GList *iterator = actions;
221
222 while (iterator != NULL) {
223 pe_free_action(iterator->data);
224 iterator = iterator->next;
225 }
226 if (actions != NULL) {
227 g_list_free(actions);
228 }
229}
230
231static void
232pe_free_nodes(GList *nodes)
233{
234 for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
235 pcmk_node_t *node = (pcmk_node_t *) iterator->data;
236
237 // Shouldn't be possible, but to be safe ...
238 if (node == NULL) {
239 continue;
240 }
241 if (node->details == NULL) {
242 free(node);
243 continue;
244 }
245
246 /* This is called after pe_free_resources(), which means that we can't
247 * use node->details->uname for Pacemaker Remote nodes.
248 */
249 crm_trace("Freeing node %s", (pcmk__is_pacemaker_remote_node(node)?
250 "(guest or remote)" : pcmk__node_name(node)));
251
252 if (node->details->attrs != NULL) {
253 g_hash_table_destroy(node->details->attrs);
254 }
255 if (node->details->utilization != NULL) {
256 g_hash_table_destroy(node->details->utilization);
257 }
258 if (node->details->digest_cache != NULL) {
259 g_hash_table_destroy(node->details->digest_cache);
260 }
261 g_list_free(node->details->running_rsc);
262 g_list_free(node->details->allocated_rsc);
263 free(node->details);
264 free(node);
265 }
266 if (nodes != NULL) {
267 g_list_free(nodes);
268 }
269}
270
271static void
272pe__free_ordering(GList *constraints)
273{
274 GList *iterator = constraints;
275
276 while (iterator != NULL) {
277 pcmk__action_relation_t *order = iterator->data;
278
279 iterator = iterator->next;
280
281 free(order->task1);
282 free(order->task2);
283 free(order);
284 }
285 if (constraints != NULL) {
286 g_list_free(constraints);
287 }
288}
289
290static void
291pe__free_location(GList *constraints)
292{
293 GList *iterator = constraints;
294
295 while (iterator != NULL) {
296 pcmk__location_t *cons = iterator->data;
297
298 iterator = iterator->next;
299
300 g_list_free_full(cons->nodes, free);
301 free(cons->id);
302 free(cons);
303 }
304 if (constraints != NULL) {
305 g_list_free(constraints);
306 }
307}
308
317void
319{
320 if (scheduler == NULL) {
321 return;
322 }
323
325 if (scheduler->config_hash != NULL) {
326 g_hash_table_destroy(scheduler->config_hash);
327 }
328
329 if (scheduler->singletons != NULL) {
330 g_hash_table_destroy(scheduler->singletons);
331 }
332
333 if (scheduler->tickets) {
334 g_hash_table_destroy(scheduler->tickets);
335 }
336
338 g_hash_table_destroy(scheduler->template_rsc_sets);
339 }
340
341 if (scheduler->tags) {
342 g_hash_table_destroy(scheduler->tags);
343 }
344
345 free(scheduler->dc_uuid);
346
347 crm_trace("deleting resources");
348 pe_free_resources(scheduler->resources);
349
350 crm_trace("deleting actions");
351 pe_free_actions(scheduler->actions);
352
353 crm_trace("deleting nodes");
354 pe_free_nodes(scheduler->nodes);
355
357 g_list_free(scheduler->stop_needed);
362
364
366 );
368 );
369}
370
376void
378{
379 if (scheduler == NULL) {
380 return;
381 }
382
383 crm_trace("Deleting %d ordering constraints",
384 g_list_length(scheduler->ordering_constraints));
385 pe__free_ordering(scheduler->ordering_constraints);
387
388 crm_trace("Deleting %d location constraints",
389 g_list_length(scheduler->placement_constraints));
390 pe__free_location(scheduler->placement_constraints);
392
393 crm_trace("Deleting %d colocation constraints",
394 g_list_length(scheduler->colocation_constraints));
395 g_list_free_full(scheduler->colocation_constraints, free);
397
398 crm_trace("Deleting %d ticket constraints",
399 g_list_length(scheduler->ticket_constraints));
400 g_list_free_full(scheduler->ticket_constraints, free);
402
404}
405
406void
428
430pe_find_resource(GList *rsc_list, const char *id)
431{
433}
434
436pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
437{
438 GList *rIter = NULL;
439
440 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
441 pcmk_resource_t *parent = rIter->data;
442
443 pcmk_resource_t *match =
444 parent->fns->find_rsc(parent, id, NULL, flags);
445 if (match != NULL) {
446 return match;
447 }
448 }
449 crm_trace("No match for %s", id);
450 return NULL;
451}
452
465pe_find_node_any(const GList *nodes, const char *id, const char *uname)
466{
467 pcmk_node_t *match = NULL;
468
469 if (id != NULL) {
470 match = pe_find_node_id(nodes, id);
471 }
472 if ((match == NULL) && (uname != NULL)) {
473 match = pcmk__find_node_in_list(nodes, uname);
474 }
475 return match;
476}
477
487pe_find_node_id(const GList *nodes, const char *id)
488{
489 for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
490 pcmk_node_t *node = (pcmk_node_t *) iter->data;
491
492 /* @TODO Whether node IDs should be considered case-sensitive should
493 * probably depend on the node type, so functionizing the comparison
494 * would be worthwhile
495 */
496 if (pcmk__str_eq(node->details->id, id, pcmk__str_casei)) {
497 return node;
498 }
499 }
500 return NULL;
501}
502
503// Deprecated functions kept only for backward API compatibility
504// LCOV_EXCL_START
505
507
517pe_find_node(const GList *nodes, const char *node_name)
518{
519 return pcmk__find_node_in_list(nodes, node_name);
520}
521
522// LCOV_EXCL_STOP
523// End deprecated API
const char * parent
Definition cib.c:27
int pcmk__check_feature_set(const char *cib_version)
Definition cib.c:184
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
Definition nvpair.c:936
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:98
#define PCMK__CONCURRENT_FENCING_DEFAULT
Definition config.h:553
char uname[MAX_NAME]
Definition cpg.c:5
A dumping ground.
#define CRM_FEATURE_SET
Definition crm.h:72
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_CHECK(expr, failure_action)
Definition logging.h:245
#define LOG_NEVER
Definition logging.h:48
#define crm_trace(fmt, args...)
Definition logging.h:402
#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:150
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition nvpair.c:446
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition nvpair.c:674
#define PCMK_VALUE_TRUE
Definition options.h:215
G_GNUC_INTERNAL gboolean unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler)
Definition unpack.c:847
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pcmk_scheduler_t *scheduler)
Definition unpack.c:949
G_GNUC_INTERNAL void pcmk__unpack_fencing_topology(const xmlNode *xml_fencing_topology, pcmk_scheduler_t *scheduler)
Definition unpack.c:922
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler)
Definition unpack.c:703
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler)
Definition unpack.c:1407
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pcmk_scheduler_t *scheduler)
Definition unpack.c:623
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler)
Definition unpack.c:214
void pe__free_param_checks(pcmk_scheduler_t *scheduler)
Definition remote.c:232
void pe_free_action(pcmk_action_t *action)
pe_find
Search options for resources (exact resource ID always matches)
Definition resources.h:183
@ pcmk_rsc_match_history
Also match clone instance ID from resource history.
Definition resources.h:185
@ pcmk_rc_ok
Definition results.h:162
@ pcmk_no_quorum_stop
Definition scheduler.h:42
@ pcmk_no_quorum_ignore
Definition scheduler.h:43
@ pcmk_sched_stop_removed_resources
Definition scheduler.h:108
@ pcmk_sched_symmetric_cluster
Definition scheduler.h:83
@ pcmk_sched_no_counts
Definition scheduler.h:164
@ pcmk_sched_location_only
Definition scheduler.h:158
@ pcmk_sched_quorate
Definition scheduler.h:80
@ pcmk_sched_concurrent_fencing
Definition scheduler.h:102
@ pcmk_sched_have_status
Definition scheduler.h:145
@ pcmk_sched_cancel_removed_actions
Definition scheduler.h:114
#define pcmk__clear_scheduler_flags(scheduler, flags_to_clear)
#define pcmk__sched_warn(fmt...)
#define pcmk__set_scheduler_flags(scheduler, flags_to_set)
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:487
pcmk_node_t * pe_find_node(const GList *nodes, const char *node_name)
Find a node by name in a list of nodes.
Definition status.c:517
void pe_free_working_set(pcmk_scheduler_t *scheduler)
Free scheduler data.
Definition status.c:50
void pe_reset_working_set(pcmk_scheduler_t *scheduler)
Reset scheduler data to default state without freeing it.
Definition status.c:377
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:465
pcmk_resource_t * pe_find_resource(GList *rsc_list, const char *id)
Definition status.c:430
pcmk_scheduler_t * pe_new_working_set(void)
Create a new object to hold scheduler data.
Definition status.c:34
gboolean cluster_status(pcmk_scheduler_t *scheduler)
Definition status.c:96
void cleanup_calculations(pcmk_scheduler_t *scheduler)
Reset scheduler data to defaults without freeing it or constraints.
Definition status.c:318
void set_working_set_defaults(pcmk_scheduler_t *scheduler)
Definition status.c:407
#define XPATH_DEPRECATED_RULES
Definition status.c:59
pcmk_resource_t * pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
Definition status.c:436
Deprecated Pacemaker scheduler utilities.
@ pcmk__str_casei
Location constraint object.
struct pe_node_shared_s * details
Definition nodes.h:167
const char * id
Definition nodes.h:72
pcmk_rsc_methods_t * fns
Definition resources.h:412
GHashTable * singletons
Definition scheduler.h:225
GList * colocation_constraints
Definition scheduler.h:234
GList * ticket_constraints
Definition scheduler.h:237
GHashTable * tags
Definition scheduler.h:253
GHashTable * config_hash
Definition scheduler.h:219
GHashTable * template_rsc_sets
Definition scheduler.h:248
xmlNode * input
Definition scheduler.h:196
GList * resources
Definition scheduler.h:231
xmlNode * failed
Definition scheduler.h:240
xmlNode * graph
Definition scheduler.h:247
unsigned long long flags
Definition scheduler.h:211
xmlNode * rsc_defaults
Definition scheduler.h:242
xmlNode * op_defaults
Definition scheduler.h:241
enum pe_quorum_policy no_quorum_policy
Definition scheduler.h:217
GList * stop_needed
Definition scheduler.h:257
GHashTable * tickets
Definition scheduler.h:222
GList * placement_constraints
Definition scheduler.h:232
GList * ordering_constraints
Definition scheduler.h:233
crm_time_t * now
Definition scheduler.h:198
void(* free)(pcmk_resource_t *rsc)
Definition resources.h:336
pcmk_resource_t *(* find_rsc)(pcmk_resource_t *rsc, const char *search, const pcmk_node_t *node, int flags)
Definition resources.h:276
Wrappers for and extensions to libxml2.
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition xpath.c:189
void free_xml(xmlNode *child)
Definition xml.c:867
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition xml.c:720
#define PCMK_XA_DC_UUID
Definition xml_names.h:253
#define PCMK_XE_STATUS
Definition xml_names.h:199
#define PCMK_XE_OP_DEFAULTS
Definition xml_names.h:144
#define PCMK_XE_CRM_CONFIG
Definition xml_names.h:91
#define PCMK_XE_RESOURCES
Definition xml_names.h:175
#define PCMK_XE_TAGS
Definition xml_names.h:204
#define PCMK_XA_HAVE_QUORUM
Definition xml_names.h:290
#define PCMK_XE_FENCING_TOPOLOGY
Definition xml_names.h:115
#define PCMK_XA_CRM_FEATURE_SET
Definition xml_names.h:249
#define PCMK_XE_NODES
Definition xml_names.h:139
#define PCMK_XE_OP
Definition xml_names.h:143
#define PCMK_XE_RSC_DEFAULTS
Definition xml_names.h:182