pacemaker  2.1.3-ea053b43a
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 
20 #include <crm/pengine/internal.h>
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 
49 void
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  */
70 gboolean
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);
123  unpack_remote_nodes(section, data_set);
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 
162 static void
163 pe_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 
178 static void
179 pe_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 
192 static void
193 pe_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)" : node->details->uname));
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 
232 static void
233 pe__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 
251 static void
252 pe__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 
278 void
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 
337 void
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 
367 void
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 
391 pe_find_resource(GList *rsc_list, const char *id)
392 {
393  return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
394 }
395 
397 pe_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 
414 pe_node_t *
415 pe_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 
426 pe_node_t *
427 pe_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 
442 pe_node_t *
443 pe_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 }
GHashTable * tags
Definition: pe_types.h:187
#define LOG_TRACE
Definition: logging.h:37
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
pe_node_t * pe_find_node(GList *nodes, const char *uname)
Definition: status.c:443
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:156
A dumping ground.
xmlNode * failed
Definition: pe_types.h:172
#define pe_flag_stop_action_orphans
Definition: pe_types.h:105
bool pe__is_guest_or_remote_node(const pe_node_t *node)
Definition: remote.c:41
GHashTable * attrs
Definition: pe_types.h:241
pe_node_t * pe_find_node_any(GList *nodes, const char *id, const char *uname)
Definition: status.c:415
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:368
pe_resource_t * pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
Definition: status.c:397
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:629
#define pe_flag_concurrent_fencing
Definition: pe_types.h:102
#define pe_flag_symmetric_cluster
Definition: pe_types.h:96
xmlNode * op_defaults
Definition: pe_types.h:173
pe_resource_t * pe_find_resource(GList *rsc_list, const char *id)
Definition: status.c:391
resource_object_functions_t * fns
Definition: pe_types.h:347
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1249
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:141
#define pe_flag_no_counts
Don&#39;t count total, disabled and blocked resource instances.
Definition: pe_types.h:127
#define pe_flag_have_status
Definition: pe_types.h:117
GList * actions
Definition: pe_types.h:171
int order_id
Deprecated (will be removed in a future release)
Definition: pe_types.h:179
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:279
GHashTable * tickets
Definition: pe_types.h:159
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:187
#define pe_flag_have_quorum
Definition: pe_types.h:95
#define LOG_NEVER
Definition: logging.h:47
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:214
char * dc_uuid
Definition: pe_types.h:148
#define PCMK__CONCURRENT_FENCING_DEFAULT
Definition: config.h:537
GList * resources
Definition: pe_types.h:165
GList * nodes
Definition: pe_types.h:164
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:186
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:827
GList * ticket_constraints
Definition: pe_types.h:169
#define crm_warn(fmt, args...)
Definition: logging.h:359
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:84
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:536
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:726
xmlNode * rsc_defaults
Definition: pe_types.h:174
#define crm_trace(fmt, args...)
Definition: logging.h:364
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:122
int blocked_resources
Definition: pe_types.h:189
pe_node_t * pe_find_node_id(GList *nodes, const char *id)
Definition: status.c:427
struct pe_node_shared_s * details
Definition: pe_types.h:252
G_GNUC_INTERNAL gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:766
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:124
const char * uname
Definition: pe_types.h:216
pe_working_set_t * data_set
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Definition: pe_types.h:158
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:696
void(* free)(pe_resource_t *)
Definition: pe_types.h:56
void free_xml(xmlNode *child)
Definition: xml.c:824
xmlNode * input
Definition: pe_types.h:144
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:261
const char * id
Definition: pe_types.h:215
GList * running_rsc
Definition: pe_types.h:238
match resource ID or LRM history ID
Definition: pe_types.h:85
#define pe_flag_quick_location
Definition: pe_types.h:120
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:50
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:71
GList * ordering_constraints
Definition: pe_types.h:167
int disabled_resources
Definition: pe_types.h:190
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:92
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:190
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:192
GList * colocation_constraints
Definition: pe_types.h:168
GHashTable * utilization
Definition: pe_types.h:242
char uname[MAX_NAME]
Definition: cpg.c:50
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition: internal.h:37
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:243
GList * placement_constraints
Definition: pe_types.h:166
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:185
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:435
bool pcmk__xe_attr_is_true(xmlNodePtr node, const char *name)
Definition: nvpair.c:986
GHashTable * singletons
Definition: pe_types.h:162
unsigned long long flags
Definition: pe_types.h:153
GList * allocated_rsc
Definition: pe_types.h:239
const char * parent
Definition: cib.c:25
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:196
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:191
#define pe__clear_working_set_flags(working_set, flags_to_clear)
Definition: internal.h:43
crm_time_t * now
Definition: pe_types.h:145
GHashTable * template_rsc_sets
Definition: pe_types.h:185
uint64_t flags
Definition: remote.c:149
pe_working_set_t * pe_new_working_set()
Create a new working set.
Definition: status.c:34
GList * stop_needed
Definition: pe_types.h:193
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
void pe_free_action(pe_action_t *action)
Definition: utils.c:1457
xmlNode * graph
Definition: pe_types.h:183
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:140
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:104