pacemaker 2.1.5-a3f44794f94
Scalable High-Availability cluster resource manager
status.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2022 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/msg_xml.h>
16#include <crm/common/xml.h>
17
18#include <glib.h>
19
21#include <pe_status_private.h>
22
35{
36 pe_working_set_t *data_set = calloc(1, sizeof(pe_working_set_t));
37
38 if (data_set != NULL) {
40 }
41 return data_set;
42}
43
49void
51{
52 if (data_set != NULL) {
54 data_set->priv = NULL;
55 free(data_set);
56 }
57}
58
59/*
60 * Unpack everything
61 * At the end you'll have:
62 * - A list of nodes
63 * - A list of resources (each with any dependencies on other resources)
64 * - A list of constraints between resources and nodes
65 * - A list of constraints between start/stop actions
66 * - A list of nodes that need to be stonith'd
67 * - A list of nodes that need to be shutdown
68 * - A list of the possible stop/start actions (without dependencies)
69 */
70gboolean
72{
73 xmlNode *section = NULL;
74
75 if ((data_set == NULL) || (data_set->input == NULL)) {
76 return FALSE;
77 }
78
79 crm_trace("Beginning unpack");
80
81 if (data_set->failed != NULL) {
83 }
84 data_set->failed = create_xml_node(NULL, "failed-ops");
85
86 if (data_set->now == NULL) {
87 data_set->now = crm_time_new(NULL);
88 }
89
90 if (data_set->dc_uuid == NULL) {
93 }
94
97 } else {
99 }
100
105
107 LOG_TRACE);
108 unpack_config(section, data_set);
109
110 if (!pcmk_any_flags_set(data_set->flags,
113 crm_warn("Fencing and resource management disabled due to lack of quorum");
114 }
115
117 LOG_TRACE);
118 unpack_nodes(section, data_set);
119
121 LOG_TRACE);
124 }
125 unpack_resources(section, data_set);
126
128 LOG_NEVER);
129 unpack_tags(section, data_set);
130
133 LOG_TRACE);
134 unpack_status(section, data_set);
135 }
136
138 for (GList *item = data_set->resources; item != NULL;
139 item = item->next) {
140 ((pe_resource_t *) (item->data))->fns->count(item->data);
141 }
142 crm_trace("Cluster resource count: %d (%d disabled, %d blocked)",
145 }
146
148 return TRUE;
149}
150
162static void
163pe_free_resources(GList *resources)
164{
165 pe_resource_t *rsc = NULL;
166 GList *iterator = resources;
167
168 while (iterator != NULL) {
169 rsc = (pe_resource_t *) iterator->data;
170 iterator = iterator->next;
171 rsc->fns->free(rsc);
172 }
173 if (resources != NULL) {
174 g_list_free(resources);
175 }
176}
177
178static void
179pe_free_actions(GList *actions)
180{
181 GList *iterator = actions;
182
183 while (iterator != NULL) {
184 pe_free_action(iterator->data);
185 iterator = iterator->next;
186 }
187 if (actions != NULL) {
188 g_list_free(actions);
189 }
190}
191
192static void
193pe_free_nodes(GList *nodes)
194{
195 for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
196 pe_node_t *node = (pe_node_t *) iterator->data;
197
198 // Shouldn't be possible, but to be safe ...
199 if (node == NULL) {
200 continue;
201 }
202 if (node->details == NULL) {
203 free(node);
204 continue;
205 }
206
207 /* This is called after pe_free_resources(), which means that we can't
208 * use node->details->uname for Pacemaker Remote nodes.
209 */
210 crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
211 "(guest or remote)" : pe__node_name(node)));
212
213 if (node->details->attrs != NULL) {
214 g_hash_table_destroy(node->details->attrs);
215 }
216 if (node->details->utilization != NULL) {
217 g_hash_table_destroy(node->details->utilization);
218 }
219 if (node->details->digest_cache != NULL) {
220 g_hash_table_destroy(node->details->digest_cache);
221 }
222 g_list_free(node->details->running_rsc);
223 g_list_free(node->details->allocated_rsc);
224 free(node->details);
225 free(node);
226 }
227 if (nodes != NULL) {
228 g_list_free(nodes);
229 }
230}
231
232static void
233pe__free_ordering(GList *constraints)
234{
235 GList *iterator = constraints;
236
237 while (iterator != NULL) {
238 pe__ordering_t *order = iterator->data;
239
240 iterator = iterator->next;
241
242 free(order->lh_action_task);
243 free(order->rh_action_task);
244 free(order);
245 }
246 if (constraints != NULL) {
247 g_list_free(constraints);
248 }
249}
250
251static void
252pe__free_location(GList *constraints)
253{
254 GList *iterator = constraints;
255
256 while (iterator != NULL) {
257 pe__location_t *cons = iterator->data;
258
259 iterator = iterator->next;
260
261 g_list_free_full(cons->node_list_rh, free);
262 free(cons->id);
263 free(cons);
264 }
265 if (constraints != NULL) {
266 g_list_free(constraints);
267 }
268}
269
278void
280{
281 if (data_set == NULL) {
282 return;
283 }
284
286 if (data_set->config_hash != NULL) {
287 g_hash_table_destroy(data_set->config_hash);
288 }
289
290 if (data_set->singletons != NULL) {
291 g_hash_table_destroy(data_set->singletons);
292 }
293
294 if (data_set->tickets) {
295 g_hash_table_destroy(data_set->tickets);
296 }
297
299 g_hash_table_destroy(data_set->template_rsc_sets);
300 }
301
302 if (data_set->tags) {
303 g_hash_table_destroy(data_set->tags);
304 }
305
306 free(data_set->dc_uuid);
307
308 crm_trace("deleting resources");
309 pe_free_resources(data_set->resources);
310
311 crm_trace("deleting actions");
312 pe_free_actions(data_set->actions);
313
314 crm_trace("deleting nodes");
315 pe_free_nodes(data_set->nodes);
316
318 g_list_free(data_set->stop_needed);
323
325
327 );
329 );
330}
331
337void
339{
340 if (data_set == NULL) {
341 return;
342 }
343
344 crm_trace("Deleting %d ordering constraints",
345 g_list_length(data_set->ordering_constraints));
346 pe__free_ordering(data_set->ordering_constraints);
348
349 crm_trace("Deleting %d location constraints",
350 g_list_length(data_set->placement_constraints));
351 pe__free_location(data_set->placement_constraints);
353
354 crm_trace("Deleting %d colocation constraints",
355 g_list_length(data_set->colocation_constraints));
356 g_list_free_full(data_set->colocation_constraints, free);
358
359 crm_trace("Deleting %d ticket constraints",
360 g_list_length(data_set->ticket_constraints));
361 g_list_free_full(data_set->ticket_constraints, free);
363
365}
366
367void
369{
370 void *priv = data_set->priv;
371
372 memset(data_set, 0, sizeof(pe_working_set_t));
373
374 data_set->priv = priv;
375 data_set->order_id = 1;
376 data_set->action_id = 1;
378
379 data_set->flags = 0x0ULL;
380
385 if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, "true")) {
387 }
388}
389
391pe_find_resource(GList *rsc_list, const char *id)
392{
393 return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
394}
395
397pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
398{
399 GList *rIter = NULL;
400
401 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
402 pe_resource_t *parent = rIter->data;
403
404 pe_resource_t *match =
405 parent->fns->find_rsc(parent, id, NULL, flags);
406 if (match != NULL) {
407 return match;
408 }
409 }
410 crm_trace("No match for %s", id);
411 return NULL;
412}
413
414pe_node_t *
415pe_find_node_any(GList *nodes, const char *id, const char *uname)
416{
417 pe_node_t *match = pe_find_node_id(nodes, id);
418
419 if (match) {
420 return match;
421 }
422 crm_trace("Looking up %s via its uname instead", uname);
423 return pe_find_node(nodes, uname);
424}
425
426pe_node_t *
427pe_find_node_id(GList *nodes, const char *id)
428{
429 GList *gIter = nodes;
430
431 for (; gIter != NULL; gIter = gIter->next) {
432 pe_node_t *node = (pe_node_t *) gIter->data;
433
434 if (node && pcmk__str_eq(node->details->id, id, pcmk__str_casei)) {
435 return node;
436 }
437 }
438 /* error */
439 return NULL;
440}
441
442pe_node_t *
443pe_find_node(GList *nodes, const char *uname)
444{
445 GList *gIter = nodes;
446
447 for (; gIter != NULL; gIter = gIter->next) {
448 pe_node_t *node = (pe_node_t *) gIter->data;
449
450 if (node && pcmk__str_eq(node->details->uname, uname, pcmk__str_casei)) {
451 return node;
452 }
453 }
454 /* error */
455 return NULL;
456}
const char * parent
Definition: cib.c:25
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
Definition: nvpair.c:975
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:121
#define PCMK__CONCURRENT_FENCING_DEFAULT
Definition: config.h:535
char uname[MAX_NAME]
Definition: cpg.c:5
A dumping ground.
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:140
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:92
#define crm_warn(fmt, args...)
Definition: logging.h:360
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:227
#define LOG_NEVER
Definition: logging.h:47
#define crm_trace(fmt, args...)
Definition: logging.h:365
#define LOG_TRACE
Definition: logging.h:37
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:186
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:443
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:192
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:190
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:123
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:187
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:185
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:141
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:191
pe_working_set_t * data_set
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:714
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:625
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:538
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:196
G_GNUC_INTERNAL gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:762
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:828
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1253
@ no_quorum_ignore
Definition: pe_types.h:66
@ no_quorum_stop
Definition: pe_types.h:65
#define pe_flag_have_quorum
Definition: pe_types.h:95
#define pe_flag_symmetric_cluster
Definition: pe_types.h:96
#define pe_flag_quick_location
Definition: pe_types.h:120
#define pe_flag_concurrent_fencing
Definition: pe_types.h:102
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:84
@ pe_find_renamed
match resource ID or LRM history ID
Definition: pe_types.h:85
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:104
#define pe_flag_stop_action_orphans
Definition: pe_types.h:105
#define pe_flag_no_counts
Don't count total, disabled and blocked resource instances.
Definition: pe_types.h:127
#define pe_flag_have_status
Definition: pe_types.h:117
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:261
void pe_free_action(pe_action_t *action)
Definition: pe_actions.c:1193
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition: internal.h:62
#define pe__clear_working_set_flags(working_set, flags_to_clear)
Definition: internal.h:68
bool pe__is_guest_or_remote_node(const pe_node_t *node)
Definition: remote.c:41
pe_node_t * pe_find_node_id(GList *nodes, const char *id)
Definition: status.c:427
pe_node_t * pe_find_node(GList *nodes, const char *uname)
Definition: status.c:443
pe_resource_t * pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
Definition: status.c:397
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:279
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:71
pe_node_t * pe_find_node_any(GList *nodes, const char *id, const char *uname)
Definition: status.c:415
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:50
pe_resource_t * pe_find_resource(GList *rsc_list, const char *id)
Definition: status.c:391
pe_working_set_t * pe_new_working_set(void)
Create a new working set.
Definition: status.c:34
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:368
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition: status.c:338
@ pcmk__str_casei
struct pe_node_shared_s * details
Definition: pe_types.h:252
GHashTable * attrs
Definition: pe_types.h:241
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:243
const char * id
Definition: pe_types.h:215
const char * uname
Definition: pe_types.h:216
GHashTable * utilization
Definition: pe_types.h:242
GList * allocated_rsc
Definition: pe_types.h:239
GList * running_rsc
Definition: pe_types.h:238
resource_object_functions_t * fns
Definition: pe_types.h:340
GHashTable * singletons
Definition: pe_types.h:162
GList * colocation_constraints
Definition: pe_types.h:168
GList * ticket_constraints
Definition: pe_types.h:169
char * dc_uuid
Definition: pe_types.h:148
GHashTable * tags
Definition: pe_types.h:187
int blocked_resources
Definition: pe_types.h:189
GHashTable * config_hash
Definition: pe_types.h:158
GList * actions
Definition: pe_types.h:171
GHashTable * template_rsc_sets
Definition: pe_types.h:185
xmlNode * input
Definition: pe_types.h:144
GList * resources
Definition: pe_types.h:165
xmlNode * failed
Definition: pe_types.h:172
xmlNode * graph
Definition: pe_types.h:183
int disabled_resources
Definition: pe_types.h:190
unsigned long long flags
Definition: pe_types.h:153
xmlNode * rsc_defaults
Definition: pe_types.h:174
xmlNode * op_defaults
Definition: pe_types.h:173
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:156
GList * stop_needed
Definition: pe_types.h:193
GHashTable * tickets
Definition: pe_types.h:159
GList * placement_constraints
Definition: pe_types.h:166
GList * nodes
Definition: pe_types.h:164
GList * ordering_constraints
Definition: pe_types.h:167
crm_time_t * now
Definition: pe_types.h:145
int order_id
Deprecated (will be removed in a future release)
Definition: pe_types.h:179
void(* free)(pe_resource_t *)
Definition: pe_types.h:56
Wrappers for and extensions to libxml2.
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:214
void free_xml(xmlNode *child)
Definition: xml.c:885
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:749