pacemaker 2.1.1-77db578727
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
status.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2021 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) {
53 pe_reset_working_set(data_set);
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 *config = get_xpath_object("//"XML_CIB_TAG_CRMCONFIG, data_set->input, LOG_TRACE);
74 xmlNode *cib_nodes = get_xpath_object("//"XML_CIB_TAG_NODES, data_set->input, LOG_TRACE);
75 xmlNode *cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE);
76 xmlNode *cib_status = get_xpath_object("//"XML_CIB_TAG_STATUS, data_set->input, LOG_TRACE);
77 xmlNode *cib_tags = get_xpath_object("//" XML_CIB_TAG_TAGS, data_set->input,
78 LOG_NEVER);
79 const char *value = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM);
80
81 crm_trace("Beginning unpack");
82
83 /* reset remaining global variables */
84 data_set->failed = create_xml_node(NULL, "failed-ops");
85
86 if (data_set->input == NULL) {
87 return FALSE;
88 }
89
90 if (data_set->now == NULL) {
91 data_set->now = crm_time_new(NULL);
92 }
93
94 if (data_set->dc_uuid == NULL) {
95 data_set->dc_uuid = crm_element_value_copy(data_set->input,
97 }
98
99 if (crm_is_true(value)) {
101 } else {
103 }
104
106 data_set->input, LOG_NEVER);
108 data_set->input, LOG_NEVER);
109
110 unpack_config(config, data_set);
111
112 if (!pcmk_any_flags_set(data_set->flags,
114 && (data_set->no_quorum_policy != no_quorum_ignore)) {
115 crm_warn("Fencing and resource management disabled due to lack of quorum");
116 }
117
118 unpack_nodes(cib_nodes, data_set);
119
120 if (!pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
121 unpack_remote_nodes(cib_resources, data_set);
122 }
123
124 unpack_resources(cib_resources, data_set);
125 unpack_tags(cib_tags, data_set);
126
127 if (!pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
128 unpack_status(cib_status, data_set);
129 }
130
131 if (!pcmk_is_set(data_set->flags, pe_flag_no_counts)) {
132 for (GList *item = data_set->resources; item != NULL;
133 item = item->next) {
134 ((pe_resource_t *) (item->data))->fns->count(item->data);
135 }
136 }
137
139 return TRUE;
140}
141
153static void
154pe_free_resources(GList *resources)
155{
156 pe_resource_t *rsc = NULL;
157 GList *iterator = resources;
158
159 while (iterator != NULL) {
160 rsc = (pe_resource_t *) iterator->data;
161 iterator = iterator->next;
162 rsc->fns->free(rsc);
163 }
164 if (resources != NULL) {
165 g_list_free(resources);
166 }
167}
168
169static void
170pe_free_actions(GList *actions)
171{
172 GList *iterator = actions;
173
174 while (iterator != NULL) {
175 pe_free_action(iterator->data);
176 iterator = iterator->next;
177 }
178 if (actions != NULL) {
179 g_list_free(actions);
180 }
181}
182
183static void
184pe_free_nodes(GList *nodes)
185{
186 for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
187 pe_node_t *node = (pe_node_t *) iterator->data;
188
189 // Shouldn't be possible, but to be safe ...
190 if (node == NULL) {
191 continue;
192 }
193 if (node->details == NULL) {
194 free(node);
195 continue;
196 }
197
198 /* This is called after pe_free_resources(), which means that we can't
199 * use node->details->uname for Pacemaker Remote nodes.
200 */
201 crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
202 "(guest or remote)" : node->details->uname));
203
204 if (node->details->attrs != NULL) {
205 g_hash_table_destroy(node->details->attrs);
206 }
207 if (node->details->utilization != NULL) {
208 g_hash_table_destroy(node->details->utilization);
209 }
210 if (node->details->digest_cache != NULL) {
211 g_hash_table_destroy(node->details->digest_cache);
212 }
213 g_list_free(node->details->running_rsc);
214 g_list_free(node->details->allocated_rsc);
215 free(node->details);
216 free(node);
217 }
218 if (nodes != NULL) {
219 g_list_free(nodes);
220 }
221}
222
223static void
224pe__free_ordering(GList *constraints)
225{
226 GList *iterator = constraints;
227
228 while (iterator != NULL) {
229 pe__ordering_t *order = iterator->data;
230
231 iterator = iterator->next;
232
233 free(order->lh_action_task);
234 free(order->rh_action_task);
235 free(order);
236 }
237 if (constraints != NULL) {
238 g_list_free(constraints);
239 }
240}
241
242static void
243pe__free_location(GList *constraints)
244{
245 GList *iterator = constraints;
246
247 while (iterator != NULL) {
248 pe__location_t *cons = iterator->data;
249
250 iterator = iterator->next;
251
252 g_list_free_full(cons->node_list_rh, free);
253 free(cons->id);
254 free(cons);
255 }
256 if (constraints != NULL) {
257 g_list_free(constraints);
258 }
259}
260
269void
271{
272 if (data_set == NULL) {
273 return;
274 }
275
277 if (data_set->config_hash != NULL) {
278 g_hash_table_destroy(data_set->config_hash);
279 }
280
281 if (data_set->singletons != NULL) {
282 g_hash_table_destroy(data_set->singletons);
283 }
284
285 if (data_set->tickets) {
286 g_hash_table_destroy(data_set->tickets);
287 }
288
289 if (data_set->template_rsc_sets) {
290 g_hash_table_destroy(data_set->template_rsc_sets);
291 }
292
293 if (data_set->tags) {
294 g_hash_table_destroy(data_set->tags);
295 }
296
297 free(data_set->dc_uuid);
298
299 crm_trace("deleting resources");
300 pe_free_resources(data_set->resources);
301
302 crm_trace("deleting actions");
303 pe_free_actions(data_set->actions);
304
305 crm_trace("deleting nodes");
306 pe_free_nodes(data_set->nodes);
307
308 pe__free_param_checks(data_set);
309 g_list_free(data_set->stop_needed);
310 free_xml(data_set->graph);
311 crm_time_free(data_set->now);
312 free_xml(data_set->input);
313 free_xml(data_set->failed);
314
315 set_working_set_defaults(data_set);
316
317 CRM_CHECK(data_set->ordering_constraints == NULL,;
318 );
319 CRM_CHECK(data_set->placement_constraints == NULL,;
320 );
321}
322
328void
330{
331 if (data_set == NULL) {
332 return;
333 }
334
335 crm_trace("Deleting %d ordering constraints",
336 g_list_length(data_set->ordering_constraints));
337 pe__free_ordering(data_set->ordering_constraints);
338 data_set->ordering_constraints = NULL;
339
340 crm_trace("Deleting %d location constraints",
341 g_list_length(data_set->placement_constraints));
342 pe__free_location(data_set->placement_constraints);
343 data_set->placement_constraints = NULL;
344
345 crm_trace("Deleting %d colocation constraints",
346 g_list_length(data_set->colocation_constraints));
347 g_list_free_full(data_set->colocation_constraints, free);
348 data_set->colocation_constraints = NULL;
349
350 crm_trace("Deleting %d ticket constraints",
351 g_list_length(data_set->ticket_constraints));
352 g_list_free_full(data_set->ticket_constraints, free);
353 data_set->ticket_constraints = NULL;
354
355 cleanup_calculations(data_set);
356}
357
358void
360{
361 void *priv = data_set->priv;
362
363 memset(data_set, 0, sizeof(pe_working_set_t));
364
365 data_set->priv = priv;
366 data_set->order_id = 1;
367 data_set->action_id = 1;
369
370 data_set->flags = 0x0ULL;
371
376 if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, "true")) {
378 }
379}
380
382pe_find_resource(GList *rsc_list, const char *id)
383{
384 return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
385}
386
388pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
389{
390 GList *rIter = NULL;
391
392 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
393 pe_resource_t *parent = rIter->data;
394
395 pe_resource_t *match =
396 parent->fns->find_rsc(parent, id, NULL, flags);
397 if (match != NULL) {
398 return match;
399 }
400 }
401 crm_trace("No match for %s", id);
402 return NULL;
403}
404
405pe_node_t *
406pe_find_node_any(GList *nodes, const char *id, const char *uname)
407{
408 pe_node_t *match = pe_find_node_id(nodes, id);
409
410 if (match) {
411 return match;
412 }
413 crm_trace("Looking up %s via its uname instead", uname);
414 return pe_find_node(nodes, uname);
415}
416
417pe_node_t *
418pe_find_node_id(GList *nodes, const char *id)
419{
420 GList *gIter = nodes;
421
422 for (; gIter != NULL; gIter = gIter->next) {
423 pe_node_t *node = (pe_node_t *) gIter->data;
424
425 if (node && pcmk__str_eq(node->details->id, id, pcmk__str_casei)) {
426 return node;
427 }
428 }
429 /* error */
430 return NULL;
431}
432
433pe_node_t *
434pe_find_node(GList *nodes, const char *uname)
435{
436 GList *gIter = nodes;
437
438 for (; gIter != NULL; gIter = gIter->next) {
439 pe_node_t *node = (pe_node_t *) gIter->data;
440
441 if (node && pcmk__str_eq(node->details->uname, uname, pcmk__str_casei)) {
442 return node;
443 }
444 }
445 /* error */
446 return NULL;
447}
uint64_t flags
Definition remote.c:3
gboolean crm_is_true(const char *s)
Definition strings.c:415
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:114
#define PCMK__CONCURRENT_FENCING_DEFAULT
Definition config.h:510
char uname[MAX_NAME]
Definition cpg.c:5
A dumping ground.
void crm_time_free(crm_time_t *dt)
Definition iso8601.c:141
crm_time_t * crm_time_new(const char *string)
Definition iso8601.c:93
#define crm_warn(fmt, args...)
Definition logging.h:351
#define CRM_CHECK(expr, failure_action)
Definition logging.h:218
#define LOG_NEVER
Definition logging.h:46
#define crm_trace(fmt, args...)
Definition logging.h:356
#define LOG_TRACE
Definition logging.h:36
#define XML_CIB_TAG_RESOURCES
Definition msg_xml.h:180
#define XML_CIB_TAG_TAGS
Definition msg_xml.h:429
#define XML_CIB_TAG_RSCCONFIG
Definition msg_xml.h:186
#define XML_CIB_TAG_CRMCONFIG
Definition msg_xml.h:184
#define XML_ATTR_HAVE_QUORUM
Definition msg_xml.h:118
#define XML_CIB_TAG_NODES
Definition msg_xml.h:181
#define XML_CIB_TAG_STATUS
Definition msg_xml.h:179
#define XML_ATTR_DC_UUID
Definition msg_xml.h:135
#define XML_CIB_TAG_OPCONFIG
Definition msg_xml.h:185
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition nvpair.c:530
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition nvpair.c:727
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition unpack.c:629
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition unpack.c:530
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition unpack.c:198
G_GNUC_INTERNAL gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition unpack.c:766
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition unpack.c:827
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition unpack.c:1249
@ no_quorum_ignore
Definition pe_types.h:65
@ no_quorum_stop
Definition pe_types.h:64
#define pe_flag_have_quorum
Definition pe_types.h:94
#define pe_flag_symmetric_cluster
Definition pe_types.h:95
#define pe_flag_quick_location
Definition pe_types.h:119
#define pe_flag_concurrent_fencing
Definition pe_types.h:101
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition pe_types.h:83
@ pe_find_renamed
match resource ID or LRM history ID
Definition pe_types.h:84
#define pe_flag_stop_rsc_orphans
Definition pe_types.h:103
#define pe_flag_stop_action_orphans
Definition pe_types.h:104
#define pe_flag_no_counts
Don't count total, disabled and blocked resource instances.
Definition pe_types.h:126
#define pe_flag_have_status
Definition pe_types.h:116
void pe__free_param_checks(pe_working_set_t *data_set)
Definition remote.c:261
void pe_free_action(pe_action_t *action)
Definition utils.c:1344
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition internal.h:35
#define pe__clear_working_set_flags(working_set, flags_to_clear)
Definition internal.h:41
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:418
pe_node_t * pe_find_node(GList *nodes, const char *uname)
Definition status.c:434
pe_resource_t * pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
Definition status.c:388
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition status.c:270
gboolean cluster_status(pe_working_set_t *data_set)
Definition status.c:71
pe_working_set_t * pe_new_working_set()
Create a new working set.
Definition status.c:34
pe_node_t * pe_find_node_any(GList *nodes, const char *id, const char *uname)
Definition status.c:406
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:382
void set_working_set_defaults(pe_working_set_t *data_set)
Definition status.c:359
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition status.c:329
@ pcmk__str_casei
struct pe_node_shared_s * details
Definition pe_types.h:244
const char * id
Definition pe_types.h:208
const char * uname
Definition pe_types.h:209
resource_object_functions_t * fns
Definition pe_types.h:333
GHashTable * singletons
Definition pe_types.h:155
GList * colocation_constraints
Definition pe_types.h:161
GList * ticket_constraints
Definition pe_types.h:162
GHashTable * tags
Definition pe_types.h:180
GHashTable * config_hash
Definition pe_types.h:151
GList * actions
Definition pe_types.h:164
GHashTable * template_rsc_sets
Definition pe_types.h:178
xmlNode * input
Definition pe_types.h:137
GList * resources
Definition pe_types.h:158
xmlNode * failed
Definition pe_types.h:165
xmlNode * graph
Definition pe_types.h:176
unsigned long long flags
Definition pe_types.h:146
xmlNode * rsc_defaults
Definition pe_types.h:167
xmlNode * op_defaults
Definition pe_types.h:166
enum pe_quorum_policy no_quorum_policy
Definition pe_types.h:149
GList * stop_needed
Definition pe_types.h:186
GHashTable * tickets
Definition pe_types.h:152
GList * placement_constraints
Definition pe_types.h:159
GList * ordering_constraints
Definition pe_types.h:160
crm_time_t * now
Definition pe_types.h:138
int order_id
Deprecated (will be removed in a future release)
Definition pe_types.h:172
void(* free)(pe_resource_t *)
Definition pe_types.h:55
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
Definition pe_types.h:45
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:823
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition xml.c:696