pacemaker  2.1.5-b7adf64e51
Scalable High-Availability cluster resource manager
utils.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 <glib.h>
13 #include <stdbool.h>
14 
15 #include <crm/crm.h>
16 #include <crm/msg_xml.h>
17 #include <crm/pengine/rules.h>
18 #include <crm/pengine/internal.h>
19 
20 #include "pe_status_private.h"
21 
22 extern bool pcmk__is_daemon;
23 
24 gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data);
25 
35 bool
37 {
38  if (pe__is_guest_node(node)) {
39  /* Guest nodes are fenced by stopping their container resource. We can
40  * do that if the container's host is either online or fenceable.
41  */
43 
44  for (GList *n = rsc->running_on; n != NULL; n = n->next) {
45  pe_node_t *container_node = n->data;
46 
47  if (!container_node->details->online
48  && !pe_can_fence(data_set, container_node)) {
49  return false;
50  }
51  }
52  return true;
53 
55  return false; /* Turned off */
56 
58  return false; /* No devices */
59 
61  return true;
62 
64  return true;
65 
66  } else if(node == NULL) {
67  return false;
68 
69  } else if(node->details->online) {
70  crm_notice("We can fence %s without quorum because they're in our membership",
71  pe__node_name(node));
72  return true;
73  }
74 
75  crm_trace("Cannot fence %s", pe__node_name(node));
76  return false;
77 }
78 
88 pe_node_t *
89 pe__copy_node(const pe_node_t *this_node)
90 {
91  pe_node_t *new_node = NULL;
92 
93  CRM_ASSERT(this_node != NULL);
94 
95  new_node = calloc(1, sizeof(pe_node_t));
96  CRM_ASSERT(new_node != NULL);
97 
98  new_node->rsc_discover_mode = this_node->rsc_discover_mode;
99  new_node->weight = this_node->weight;
100  new_node->fixed = this_node->fixed;
101  new_node->details = this_node->details;
102 
103  return new_node;
104 }
105 
106 /* any node in list1 or list2 and not in the other gets a score of -INFINITY */
107 void
108 node_list_exclude(GHashTable * hash, GList *list, gboolean merge_scores)
109 {
110  GHashTable *result = hash;
111  pe_node_t *other_node = NULL;
112  GList *gIter = list;
113 
114  GHashTableIter iter;
115  pe_node_t *node = NULL;
116 
117  g_hash_table_iter_init(&iter, hash);
118  while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
119 
120  other_node = pe_find_node_id(list, node->details->id);
121  if (other_node == NULL) {
122  node->weight = -INFINITY;
123  } else if (merge_scores) {
124  node->weight = pcmk__add_scores(node->weight, other_node->weight);
125  }
126  }
127 
128  for (; gIter != NULL; gIter = gIter->next) {
129  pe_node_t *node = (pe_node_t *) gIter->data;
130 
131  other_node = pe_hash_table_lookup(result, node->details->id);
132 
133  if (other_node == NULL) {
134  pe_node_t *new_node = pe__copy_node(node);
135 
136  new_node->weight = -INFINITY;
137  g_hash_table_insert(result, (gpointer) new_node->details->id, new_node);
138  }
139  }
140 }
141 
150 GHashTable *
152 {
153  GHashTable *result = NULL;
154 
155  result = pcmk__strkey_table(NULL, free);
156  for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
157  pe_node_t *new_node = pe__copy_node((pe_node_t *) gIter->data);
158 
159  g_hash_table_insert(result, (gpointer) new_node->details->id, new_node);
160  }
161  return result;
162 }
163 
179 gint
180 pe__cmp_node_name(gconstpointer a, gconstpointer b)
181 {
182  const pe_node_t *node1 = (const pe_node_t *) a;
183  const pe_node_t *node2 = (const pe_node_t *) b;
184 
185  if ((node1 == NULL) && (node2 == NULL)) {
186  return 0;
187  }
188 
189  if (node1 == NULL) {
190  return -1;
191  }
192 
193  if (node2 == NULL) {
194  return 1;
195  }
196 
198  node2->details->uname);
199 }
200 
209 static void
210 pe__output_node_weights(pe_resource_t *rsc, const char *comment,
211  GHashTable *nodes, pe_working_set_t *data_set)
212 {
213  pcmk__output_t *out = data_set->priv;
214 
215  // Sort the nodes so the output is consistent for regression tests
216  GList *list = g_list_sort(g_hash_table_get_values(nodes),
218 
219  for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
220  pe_node_t *node = (pe_node_t *) gIter->data;
221 
222  out->message(out, "node-weight", rsc, comment, node->details->uname,
223  pcmk_readable_score(node->weight));
224  }
225  g_list_free(list);
226 }
227 
239 static void
240 pe__log_node_weights(const char *file, const char *function, int line,
241  pe_resource_t *rsc, const char *comment, GHashTable *nodes)
242 {
243  GHashTableIter iter;
244  pe_node_t *node = NULL;
245 
246  // Don't waste time if we're not tracing at this point
247  pcmk__log_else(LOG_TRACE, return);
248 
249  g_hash_table_iter_init(&iter, nodes);
250  while (g_hash_table_iter_next(&iter, NULL, (void **) &node)) {
251  if (rsc) {
252  qb_log_from_external_source(function, file,
253  "%s: %s allocation score on %s: %s",
254  LOG_TRACE, line, 0,
255  comment, rsc->id,
256  pe__node_name(node),
257  pcmk_readable_score(node->weight));
258  } else {
259  qb_log_from_external_source(function, file, "%s: %s = %s",
260  LOG_TRACE, line, 0,
261  comment, pe__node_name(node),
262  pcmk_readable_score(node->weight));
263  }
264  }
265 }
266 
279 void
280 pe__show_node_weights_as(const char *file, const char *function, int line,
281  bool to_log, pe_resource_t *rsc, const char *comment,
282  GHashTable *nodes, pe_working_set_t *data_set)
283 {
284  if (rsc != NULL && pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
285  // Don't show allocation scores for orphans
286  return;
287  }
288  if (nodes == NULL) {
289  // Nothing to show
290  return;
291  }
292 
293  if (to_log) {
294  pe__log_node_weights(file, function, line, rsc, comment, nodes);
295  } else {
296  pe__output_node_weights(rsc, comment, nodes, data_set);
297  }
298 
299  // If this resource has children, repeat recursively for each
300  if (rsc && rsc->children) {
301  for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
302  pe_resource_t *child = (pe_resource_t *) gIter->data;
303 
304  pe__show_node_weights_as(file, function, line, to_log, child,
305  comment, child->allowed_nodes, data_set);
306  }
307  }
308 }
309 
324 gint
325 pe__cmp_rsc_priority(gconstpointer a, gconstpointer b)
326 {
327  const pe_resource_t *resource1 = (const pe_resource_t *)a;
328  const pe_resource_t *resource2 = (const pe_resource_t *)b;
329 
330  if (a == NULL && b == NULL) {
331  return 0;
332  }
333  if (a == NULL) {
334  return 1;
335  }
336  if (b == NULL) {
337  return -1;
338  }
339 
340  if (resource1->priority > resource2->priority) {
341  return -1;
342  }
343 
344  if (resource1->priority < resource2->priority) {
345  return 1;
346  }
347 
348  return 0;
349 }
350 
351 static void
352 resource_node_score(pe_resource_t * rsc, pe_node_t * node, int score, const char *tag)
353 {
354  pe_node_t *match = NULL;
355 
357  && pcmk__str_eq(tag, "symmetric_default", pcmk__str_casei)) {
358  /* This string comparision may be fragile, but exclusive resources and
359  * exclusive nodes should not have the symmetric_default constraint
360  * applied to them.
361  */
362  return;
363 
364  } else if (rsc->children) {
365  GList *gIter = rsc->children;
366 
367  for (; gIter != NULL; gIter = gIter->next) {
368  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
369 
370  resource_node_score(child_rsc, node, score, tag);
371  }
372  }
373 
374  pe_rsc_trace(rsc, "Setting %s for %s on %s: %d",
375  tag, rsc->id, pe__node_name(node), score);
376  match = pe_hash_table_lookup(rsc->allowed_nodes, node->details->id);
377  if (match == NULL) {
378  match = pe__copy_node(node);
379  g_hash_table_insert(rsc->allowed_nodes, (gpointer) match->details->id, match);
380  }
381  match->weight = pcmk__add_scores(match->weight, score);
382 }
383 
384 void
385 resource_location(pe_resource_t * rsc, pe_node_t * node, int score, const char *tag,
387 {
388  if (node != NULL) {
389  resource_node_score(rsc, node, score, tag);
390 
391  } else if (data_set != NULL) {
392  GList *gIter = data_set->nodes;
393 
394  for (; gIter != NULL; gIter = gIter->next) {
395  pe_node_t *node_iter = (pe_node_t *) gIter->data;
396 
397  resource_node_score(rsc, node_iter, score, tag);
398  }
399 
400  } else {
401  GHashTableIter iter;
402  pe_node_t *node_iter = NULL;
403 
404  g_hash_table_iter_init(&iter, rsc->allowed_nodes);
405  while (g_hash_table_iter_next(&iter, NULL, (void **)&node_iter)) {
406  resource_node_score(rsc, node_iter, score, tag);
407  }
408  }
409 
410  if (node == NULL && score == -INFINITY) {
411  if (rsc->allocated_to) {
412  crm_info("Deallocating %s from %s",
413  rsc->id, pe__node_name(rsc->allocated_to));
414  free(rsc->allocated_to);
415  rsc->allocated_to = NULL;
416  }
417  }
418 }
419 
420 time_t
422 {
423  if(data_set) {
424  if (data_set->now == NULL) {
425  crm_trace("Recording a new 'now'");
426  data_set->now = crm_time_new(NULL);
427  }
429  }
430 
431  crm_trace("Defaulting to 'now'");
432  return time(NULL);
433 }
434 
435 gboolean
437 {
438  enum rsc_role_e local_role = RSC_ROLE_UNKNOWN;
439  const char *value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
440 
441  CRM_CHECK(role != NULL, return FALSE);
442 
443  if (pcmk__str_eq(value, "started", pcmk__str_null_matches | pcmk__str_casei)
444  || pcmk__str_eq("default", value, pcmk__str_casei)) {
445  return FALSE;
446  }
447 
448  local_role = text2role(value);
449  if (local_role == RSC_ROLE_UNKNOWN) {
450  pcmk__config_err("Ignoring '" XML_RSC_ATTR_TARGET_ROLE "' for %s "
451  "because '%s' is not valid", rsc->id, value);
452  return FALSE;
453 
454  } else if (local_role > RSC_ROLE_STARTED) {
456  if (local_role > RSC_ROLE_UNPROMOTED) {
457  /* This is what we'd do anyway, just leave the default to avoid messing up the placement algorithm */
458  return FALSE;
459  }
460 
461  } else {
462  pcmk__config_err("Ignoring '" XML_RSC_ATTR_TARGET_ROLE "' for %s "
463  "because '%s' only makes sense for promotable "
464  "clones", rsc->id, value);
465  return FALSE;
466  }
467  }
468 
469  *role = local_role;
470  return TRUE;
471 }
472 
473 gboolean
474 order_actions(pe_action_t * lh_action, pe_action_t * rh_action, enum pe_ordering order)
475 {
476  GList *gIter = NULL;
477  pe_action_wrapper_t *wrapper = NULL;
478  GList *list = NULL;
479 
480  if (order == pe_order_none) {
481  return FALSE;
482  }
483 
484  if (lh_action == NULL || rh_action == NULL) {
485  return FALSE;
486  }
487 
488  crm_trace("Creating action wrappers for ordering: %s then %s",
489  lh_action->uuid, rh_action->uuid);
490 
491  /* Ensure we never create a dependency on ourselves... it's happened */
492  CRM_ASSERT(lh_action != rh_action);
493 
494  /* Filter dups, otherwise update_action_states() has too much work to do */
495  gIter = lh_action->actions_after;
496  for (; gIter != NULL; gIter = gIter->next) {
497  pe_action_wrapper_t *after = (pe_action_wrapper_t *) gIter->data;
498 
499  if (after->action == rh_action && (after->type & order)) {
500  return FALSE;
501  }
502  }
503 
504  wrapper = calloc(1, sizeof(pe_action_wrapper_t));
505  wrapper->action = rh_action;
506  wrapper->type = order;
507  list = lh_action->actions_after;
508  list = g_list_prepend(list, wrapper);
509  lh_action->actions_after = list;
510 
511  wrapper = calloc(1, sizeof(pe_action_wrapper_t));
512  wrapper->action = lh_action;
513  wrapper->type = order;
514  list = rh_action->actions_before;
515  list = g_list_prepend(list, wrapper);
516  rh_action->actions_before = list;
517  return TRUE;
518 }
519 
520 void
522 {
523  pe_ticket_t *ticket = data;
524 
525  if (ticket->state) {
526  g_hash_table_destroy(ticket->state);
527  }
528  free(ticket->id);
529  free(ticket);
530 }
531 
532 pe_ticket_t *
533 ticket_new(const char *ticket_id, pe_working_set_t * data_set)
534 {
535  pe_ticket_t *ticket = NULL;
536 
537  if (pcmk__str_empty(ticket_id)) {
538  return NULL;
539  }
540 
541  if (data_set->tickets == NULL) {
543  }
544 
545  ticket = g_hash_table_lookup(data_set->tickets, ticket_id);
546  if (ticket == NULL) {
547 
548  ticket = calloc(1, sizeof(pe_ticket_t));
549  if (ticket == NULL) {
550  crm_err("Cannot allocate ticket '%s'", ticket_id);
551  return NULL;
552  }
553 
554  crm_trace("Creaing ticket entry for %s", ticket_id);
555 
556  ticket->id = strdup(ticket_id);
557  ticket->granted = FALSE;
558  ticket->last_granted = -1;
559  ticket->standby = FALSE;
560  ticket->state = pcmk__strkey_table(free, free);
561 
562  g_hash_table_insert(data_set->tickets, strdup(ticket->id), ticket);
563  }
564 
565  return ticket;
566 }
567 
569 {
570  if (!pcmk_is_set(rsc->flags, pe_rsc_unique)) {
571  return ID(rsc->xml);
572  }
573  return rsc->id;
574 }
575 
576 void
578 {
580  for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
582  }
583 }
584 
585 void
587 {
588  for (GList *lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
589  pe_resource_t *r = (pe_resource_t *) lpc->data;
591  }
592 }
593 
594 void
596 {
598  for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
600  }
601 }
602 
603 void
605  pe_resource_t * rsc, pe_node_t *node, const char *reason, pe_action_t *dependency, pe_working_set_t * data_set)
606 {
608  /* No resources require it */
609  return;
610 
611  } else if ((rsc != NULL)
613  /* Wasn't a stonith device */
614  return;
615 
616  } else if(node
617  && node->details->online
618  && node->details->unclean == FALSE
619  && node->details->shutdown == FALSE) {
620  pe_action_t *unfence = pe_fence_op(node, "on", FALSE, reason, FALSE, data_set);
621 
622  if(dependency) {
623  order_actions(unfence, dependency, pe_order_optional);
624  }
625 
626  } else if(rsc) {
627  GHashTableIter iter;
628 
629  g_hash_table_iter_init(&iter, rsc->allowed_nodes);
630  while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
631  if(node->details->online && node->details->unclean == FALSE && node->details->shutdown == FALSE) {
632  trigger_unfencing(rsc, node, reason, dependency, data_set);
633  }
634  }
635  }
636 }
637 
638 gboolean
639 add_tag_ref(GHashTable * tags, const char * tag_name, const char * obj_ref)
640 {
641  pe_tag_t *tag = NULL;
642  GList *gIter = NULL;
643  gboolean is_existing = FALSE;
644 
645  CRM_CHECK(tags && tag_name && obj_ref, return FALSE);
646 
647  tag = g_hash_table_lookup(tags, tag_name);
648  if (tag == NULL) {
649  tag = calloc(1, sizeof(pe_tag_t));
650  if (tag == NULL) {
651  return FALSE;
652  }
653  tag->id = strdup(tag_name);
654  tag->refs = NULL;
655  g_hash_table_insert(tags, strdup(tag_name), tag);
656  }
657 
658  for (gIter = tag->refs; gIter != NULL; gIter = gIter->next) {
659  const char *existing_ref = (const char *) gIter->data;
660 
661  if (pcmk__str_eq(existing_ref, obj_ref, pcmk__str_none)){
662  is_existing = TRUE;
663  break;
664  }
665  }
666 
667  if (is_existing == FALSE) {
668  tag->refs = g_list_append(tag->refs, strdup(obj_ref));
669  crm_trace("Added: tag=%s ref=%s", tag->id, obj_ref);
670  }
671 
672  return TRUE;
673 }
674 
687 bool
689 {
690  const char *shutdown = pe_node_attribute_raw(node, XML_CIB_ATTR_SHUTDOWN);
691 
692  return !pcmk__str_eq(shutdown, "0", pcmk__str_null_matches);
693 }
694 
702 void
704 {
705  if ((recheck > get_effective_time(data_set))
706  && ((data_set->recheck_by == 0)
707  || (data_set->recheck_by > recheck))) {
708  data_set->recheck_by = recheck;
709  }
710 }
711 
716 void
717 pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name,
718  pe_rule_eval_data_t *rule_data, GHashTable *hash,
719  const char *always_first, gboolean overwrite,
721 {
722  crm_time_t *next_change = crm_time_new_undefined();
723 
724  pe_eval_nvpairs(data_set->input, xml_obj, set_name, rule_data, hash,
725  always_first, overwrite, next_change);
726  if (crm_time_is_defined(next_change)) {
727  time_t recheck = (time_t) crm_time_get_seconds_since_epoch(next_change);
728 
730  }
731  crm_time_free(next_change);
732 }
733 
734 bool
736 {
737  const char *target_role = NULL;
738 
739  CRM_CHECK(rsc != NULL, return false);
740  target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
741  if (target_role) {
742  enum rsc_role_e target_role_e = text2role(target_role);
743 
744  if ((target_role_e == RSC_ROLE_STOPPED)
745  || ((target_role_e == RSC_ROLE_UNPROMOTED)
747  return true;
748  }
749  }
750  return false;
751 }
752 
753 bool
754 pe__rsc_running_on_any(pe_resource_t *rsc, GList *node_list)
755 {
756  for (GList *ele = rsc->running_on; ele; ele = ele->next) {
757  pe_node_t *node = (pe_node_t *) ele->data;
758  if (pcmk__str_in_list(node->details->uname, node_list,
760  return true;
761  }
762  }
763 
764  return false;
765 }
766 
767 bool
769 {
770  return (rsc->fns->active(rsc, FALSE) && !pe__rsc_running_on_any(rsc, only_node));
771 }
772 
773 GList *
774 pe__filter_rsc_list(GList *rscs, GList *filter)
775 {
776  GList *retval = NULL;
777 
778  for (GList *gIter = rscs; gIter; gIter = gIter->next) {
779  pe_resource_t *rsc = (pe_resource_t *) gIter->data;
780 
781  /* I think the second condition is safe here for all callers of this
782  * function. If not, it needs to move into pe__node_text.
783  */
786  retval = g_list_prepend(retval, rsc);
787  }
788  }
789 
790  return retval;
791 }
792 
793 GList *
795  GList *nodes = NULL;
796 
797  if (pcmk__str_eq(s, "*", pcmk__str_null_matches)) {
798  /* Nothing was given so return a list of all node names. Or, '*' was
799  * given. This would normally fall into the pe__unames_with_tag branch
800  * where it will return an empty list. Catch it here instead.
801  */
802  nodes = g_list_prepend(nodes, strdup("*"));
803  } else {
804  pe_node_t *node = pe_find_node(data_set->nodes, s);
805 
806  if (node) {
807  /* The given string was a valid uname for a node. Return a
808  * singleton list containing just that uname.
809  */
810  nodes = g_list_prepend(nodes, strdup(s));
811  } else {
812  /* The given string was not a valid uname. It's either a tag or
813  * it's a typo or something. In the first case, we'll return a
814  * list of all the unames of the nodes with the given tag. In the
815  * second case, we'll return a NULL pointer and nothing will
816  * get displayed.
817  */
818  nodes = pe__unames_with_tag(data_set, s);
819  }
820  }
821 
822  return nodes;
823 }
824 
825 GList *
827  GList *resources = NULL;
828 
829  if (pcmk__str_eq(s, "*", pcmk__str_null_matches)) {
830  resources = g_list_prepend(resources, strdup("*"));
831  } else {
834 
835  if (rsc) {
836  /* A colon in the name we were given means we're being asked to filter
837  * on a specific instance of a cloned resource. Put that exact string
838  * into the filter list. Otherwise, use the printable ID of whatever
839  * resource was found that matches what was asked for.
840  */
841  if (strstr(s, ":") != NULL) {
842  resources = g_list_prepend(resources, strdup(rsc->id));
843  } else {
844  resources = g_list_prepend(resources, strdup(rsc_printable_id(rsc)));
845  }
846  } else {
847  /* The given string was not a valid resource name. It's a tag or a
848  * typo or something. See pe__build_node_name_list() for more
849  * detail.
850  */
851  resources = pe__rscs_with_tag(data_set, s);
852  }
853  }
854 
855  return resources;
856 }
857 
858 xmlNode *
860 {
862  const char *rsc_id = rsc->id;
863 
864  if (rsc->variant == pe_clone) {
865  rsc_id = pe__clone_child_id(rsc);
866  } else if (parent->variant == pe_clone) {
867  rsc_id = pe__clone_child_id(parent);
868  }
869 
870  for (xmlNode *xml_op = pcmk__xml_first_child(rsc->cluster->failed); xml_op != NULL;
871  xml_op = pcmk__xml_next(xml_op)) {
872  const char *value = NULL;
873  char *op_id = NULL;
874 
875  /* This resource operation is not a failed probe. */
876  if (!pcmk_xe_mask_probe_failure(xml_op)) {
877  continue;
878  }
879 
880  /* This resource operation was not run on the given node. Note that if name is
881  * NULL, this will always succeed.
882  */
883  value = crm_element_value(xml_op, XML_LRM_ATTR_TARGET);
884  if (value == NULL || !pcmk__str_eq(value, name, pcmk__str_casei|pcmk__str_null_matches)) {
885  continue;
886  }
887 
888  /* This resource operation has no operation_key. */
889  value = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY);
890  if (!parse_op_key(value ? value : ID(xml_op), &op_id, NULL, NULL)) {
891  continue;
892  }
893 
894  /* This resource operation's ID does not match the rsc_id we are looking for. */
895  if (!pcmk__str_eq(op_id, rsc_id, pcmk__str_none)) {
896  free(op_id);
897  continue;
898  }
899 
900  free(op_id);
901  return xml_op;
902  }
903 
904  return NULL;
905 }
crm_time_t * crm_time_new_undefined(void)
Allocate memory for an uninitialized time object.
Definition: iso8601.c:116
#define LOG_TRACE
Definition: logging.h:37
bool pe__shutdown_requested(pe_node_t *node)
Definition: utils.c:688
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:227
pe_node_t * pe_find_node(GList *node_list, const char *uname)
Definition: status.c:443
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:156
A dumping ground.
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
Definition: operations.c:185
void destroy_ticket(gpointer data)
Definition: utils.c:521
#define crm_notice(fmt, args...)
Definition: logging.h:361
xmlNode * failed
Definition: pe_types.h:172
pe_resource_t * pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
Definition: status.c:397
pe_node_t * pe__copy_node(const pe_node_t *this_node)
Definition: utils.c:89
gboolean fixed
Definition: pe_types.h:250
char data[0]
Definition: cpg.c:55
#define INFINITY
Definition: crm.h:99
void trigger_unfencing(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_action_t *dependency, pe_working_set_t *data_set)
Definition: utils.c:604
time_t get_effective_time(pe_working_set_t *data_set)
Definition: utils.c:421
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
Definition: utils.c:474
bool crm_time_is_defined(const crm_time_t *t)
Check whether a time object has been initialized yet.
Definition: iso8601.c:132
GHashTable * state
Definition: pe_types.h:457
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition: scores.c:86
GList * pe__build_rsc_list(pe_working_set_t *data_set, const char *s)
Definition: utils.c:826
void pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name, pe_rule_eval_data_t *rule_data, GHashTable *hash, const char *always_first, gboolean overwrite, pe_working_set_t *data_set)
Definition: utils.c:717
pe_resource_t * container
Definition: pe_types.h:387
const char * name
Definition: cib.c:24
void pe_eval_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name, pe_rule_eval_data_t *rule_data, GHashTable *hash, const char *always_first, gboolean overwrite, crm_time_t *next_change)
Definition: rules.c:515
int(* message)(pcmk__output_t *out, const char *message_id,...)
struct crm_time_s crm_time_t
Definition: iso8601.h:32
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
Definition: utils.c:385
GList * children
Definition: pe_types.h:384
gboolean standby
Definition: pe_types.h:456
xmlNode * xml
Definition: pe_types.h:331
gboolean exclusive_discover
Definition: pe_types.h:359
#define pcmk__config_err(fmt...)
pe_resource_t * remote_rsc
Definition: pe_types.h:237
GHashTable * meta
Definition: pe_types.h:380
#define pe_rsc_unique
Definition: pe_types.h:262
resource_object_functions_t * fns
Definition: pe_types.h:340
char * id
Definition: pe_types.h:461
#define pcmk__log_else(level, else_action)
void pe__show_node_weights_as(const char *file, const char *function, int line, bool to_log, pe_resource_t *rsc, const char *comment, GHashTable *nodes, pe_working_set_t *data_set)
Definition: utils.c:280
GHashTable * tickets
Definition: pe_types.h:159
bool pcmk__rsc_filtered_by_node(pe_resource_t *rsc, GList *only_node)
Definition: utils.c:768
bool pe_can_fence(pe_working_set_t *data_set, pe_node_t *node)
Definition: utils.c:36
pe_node_t * allocated_to
Definition: pe_types.h:370
pe_action_t * action
Definition: pe_types.h:530
#define pe_flag_have_quorum
Definition: pe_types.h:95
pe_ticket_t * ticket_new(const char *ticket_id, pe_working_set_t *data_set)
Definition: utils.c:533
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
Definition: utils.c:703
GList * pe__rscs_with_tag(pe_working_set_t *data_set, const char *tag_name)
Definition: tags.c:20
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:74
GList * resources
Definition: pe_types.h:165
GList * nodes
Definition: pe_types.h:164
bool pe__resource_is_disabled(pe_resource_t *rsc)
Definition: utils.c:735
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:301
gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data)
const char * pe__clone_child_id(pe_resource_t *rsc)
Definition: clone.c:1200
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
Definition: utils.c:639
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
Definition: utils.c:180
int weight
Definition: pe_types.h:249
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:912
#define XML_CIB_ATTR_SHUTDOWN
Definition: msg_xml.h:286
bool pe__rsc_running_on_any(pe_resource_t *rsc, GList *node_list)
Definition: utils.c:754
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:517
void node_list_exclude(GHashTable *hash, GList *list, gboolean merge_scores)
Definition: utils.c:108
const char * pe_node_attribute_raw(const pe_node_t *node, const char *name)
Definition: common.c:562
bool pe__is_guest_node(const pe_node_t *node)
Definition: remote.c:33
GHashTable * pe__node_list2table(GList *list)
Definition: utils.c:151
gboolean get_target_role(pe_resource_t *rsc, enum rsc_role_e *role)
Definition: utils.c:436
GList * actions_after
Definition: pe_types.h:444
#define crm_trace(fmt, args...)
Definition: logging.h:365
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:121
struct pe_node_shared_s * details
Definition: pe_types.h:252
unsigned long long flags
Definition: pe_types.h:355
const char * uname
Definition: pe_types.h:216
#define pe_rsc_promotable
Definition: pe_types.h:264
pe_working_set_t * data_set
bool pcmk_xe_mask_probe_failure(xmlNode *xml_op)
Definition: operations.c:562
time_t recheck_by
Definition: pe_types.h:194
#define pe_flag_stonith_enabled
Definition: pe_types.h:99
time_t last_granted
Definition: pe_types.h:455
#define XML_RSC_ATTR_TARGET_ROLE
Definition: msg_xml.h:236
pe_node_t node1
char * uuid
Definition: pe_types.h:411
void pe__clear_resource_flags_recursive(pe_resource_t *rsc, uint64_t flags)
Definition: utils.c:577
match base name of any clone instance
Definition: pe_types.h:90
enum rsc_role_e text2role(const char *role)
Definition: common.c:483
enum pe_obj_types variant
Definition: pe_types.h:338
xmlNode * input
Definition: pe_types.h:144
gboolean granted
Definition: pe_types.h:454
long long crm_time_get_seconds_since_epoch(const crm_time_t *dt)
Definition: iso8601.c:352
pe_node_t node2
int rsc_discover_mode
Definition: pe_types.h:253
const char * id
Definition: pe_types.h:215
char * id
Definition: pe_types.h:453
#define pe_rsc_fence_device
Definition: pe_types.h:263
pe_node_t * pe_find_node_id(GList *node_list, const char *id)
Definition: status.c:427
GList * refs
Definition: pe_types.h:462
match resource ID or LRM history ID
Definition: pe_types.h:85
GList * pe__build_node_name_list(pe_working_set_t *data_set, const char *s)
Definition: utils.c:794
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition: strings.c:611
pcmk__action_result_t result
Definition: pcmk_fence.c:35
#define crm_err(fmt, args...)
Definition: logging.h:359
#define CRM_ASSERT(expr)
Definition: results.h:42
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:92
This structure contains everything that makes up a single output formatter.
gboolean shutdown
Definition: pe_types.h:226
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:80
int pcmk__numeric_strcasecmp(const char *s1, const char *s2)
Definition: strings.c:1018
rsc_role_e
Possible roles that a resource can be in.
Definition: common.h:92
void pe__set_resource_flags_recursive(pe_resource_t *rsc, uint64_t flags)
Definition: utils.c:595
GList * running_on
Definition: pe_types.h:373
pe_working_set_t * cluster
Definition: pe_types.h:335
int pcmk__add_scores(int score1, int score2)
Definition: scores.c:113
void pe__clear_resource_flags_on_all(pe_working_set_t *data_set, uint64_t flag)
Definition: utils.c:586
GList * pe__filter_rsc_list(GList *rscs, GList *filter)
Definition: utils.c:774
bool pcmk__is_daemon
Definition: logging.c:47
#define pe_flag_have_stonith_resource
Definition: pe_types.h:100
#define pe_flag_enable_unfencing
Definition: pe_types.h:101
const char * rsc_printable_id(pe_resource_t *rsc)
Definition: utils.c:568
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:302
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:47
#define ID(x)
Definition: msg_xml.h:468
unsigned long long flags
Definition: pe_types.h:153
const char * parent
Definition: cib.c:25
GList * pe__unames_with_tag(pe_working_set_t *data_set, const char *tag_name)
Definition: tags.c:51
enum pe_ordering type
Definition: pe_types.h:528
gboolean unclean
Definition: pe_types.h:224
crm_time_t * now
Definition: pe_types.h:145
#define crm_info(fmt, args...)
Definition: logging.h:362
#define pe_rsc_orphan
Definition: pe_types.h:256
gint pe__cmp_rsc_priority(gconstpointer a, gconstpointer b)
Definition: utils.c:325
pe_ordering
Definition: pe_types.h:479
gboolean online
Definition: pe_types.h:220
xmlNode * pe__failed_probe_for_rsc(pe_resource_t *rsc, const char *name)
Definition: utils.c:859
uint64_t flags
Definition: remote.c:215
GList * actions_before
Definition: pe_types.h:443
pe_resource_t * parent
Definition: pe_types.h:336
pe_action_t * pe_fence_op(pe_node_t *node, const char *op, bool optional, const char *reason, bool priority_delay, pe_working_set_t *data_set)
Definition: pe_actions.c:1081
gboolean(* active)(pe_resource_t *, gboolean)
Definition: pe_types.h:53
char * id
Definition: pe_types.h:329
GHashTable * allowed_nodes
Definition: pe_types.h:375
gboolean pcmk__str_in_list(const gchar *s, const GList *lst, uint32_t flags)
Definition: strings.c:883
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:140