pacemaker  2.1.6-802a72226b
Scalable High-Availability cluster resource manager
pcmk_sched_resource.c
Go to the documentation of this file.
1 /*
2  * Copyright 2014-2023 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 General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <stdlib.h>
13 #include <string.h>
14 #include <crm/msg_xml.h>
15 #include <pacemaker-internal.h>
16 
17 #include "libpacemaker_private.h"
18 
19 // Resource allocation methods that vary by resource variant
20 static resource_alloc_functions_t allocation_methods[] = {
21  {
39  },
40  {
58  },
59  {
77  },
78  {
96  }
97 };
98 
110 bool
112  const xmlNode *rsc_entry, bool active_on_node)
113 {
114  bool changed = false;
115  const char *attr_list[] = {
119  };
120 
121  for (int i = 0; i < PCMK__NELEM(attr_list); i++) {
122  const char *value = crm_element_value(rsc->xml, attr_list[i]);
123  const char *old_value = crm_element_value(rsc_entry, attr_list[i]);
124 
125  if (!pcmk__str_eq(value, old_value, pcmk__str_none)) {
126  changed = true;
127  trigger_unfencing(rsc, node, "Device definition changed", NULL,
128  rsc->cluster);
129  if (active_on_node) {
130  crm_notice("Forcing restart of %s on %s "
131  "because %s changed from '%s' to '%s'",
132  rsc->id, pe__node_name(node), attr_list[i],
133  pcmk__s(old_value, ""), pcmk__s(value, ""));
134  }
135  }
136  }
137  if (changed && active_on_node) {
138  // Make sure the resource is restarted
139  custom_action(rsc, stop_key(rsc), CRMD_ACTION_STOP, node, FALSE, TRUE,
140  rsc->cluster);
142  }
143  return changed;
144 }
145 
156 static GList *
157 add_rsc_if_matching(GList *result, pe_resource_t *rsc, const char *id)
158 {
159  if ((strcmp(rsc->id, id) == 0)
160  || ((rsc->clone_name != NULL) && (strcmp(rsc->clone_name, id) == 0))) {
161  result = g_list_prepend(result, rsc);
162  }
163  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
164  pe_resource_t *child = (pe_resource_t *) iter->data;
165 
166  result = add_rsc_if_matching(result, child, id);
167  }
168  return result;
169 }
170 
182 GList *
184 {
185  GList *result = NULL;
186 
187  CRM_CHECK((id != NULL) && (data_set != NULL), return NULL);
188  for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
189  result = add_rsc_if_matching(result, (pe_resource_t *) iter->data, id);
190  }
191  return result;
192 }
193 
201 static void
202 set_allocation_methods_for_rsc(pe_resource_t *rsc, void *ignored)
203 {
204  rsc->cmds = &allocation_methods[rsc->variant];
205  g_list_foreach(rsc->children, (GFunc) set_allocation_methods_for_rsc, NULL);
206 }
207 
214 void
216 {
217  g_list_foreach(data_set->resources, (GFunc) set_allocation_methods_for_rsc,
218  NULL);
219 }
220 
221 // Shared implementation of resource_alloc_functions_t:colocated_resources()
222 GList *
224  GList *colocated_rscs)
225 {
226  const GList *iter = NULL;
227  GList *colocations = NULL;
228 
229  if (orig_rsc == NULL) {
230  orig_rsc = rsc;
231  }
232 
233  if ((rsc == NULL) || (g_list_find(colocated_rscs, rsc) != NULL)) {
234  return colocated_rscs;
235  }
236 
237  pe_rsc_trace(orig_rsc, "%s is in colocation chain with %s",
238  rsc->id, orig_rsc->id);
239  colocated_rscs = g_list_prepend(colocated_rscs, (gpointer) rsc);
240 
241  // Follow colocations where this resource is the dependent resource
242  colocations = pcmk__this_with_colocations(rsc);
243  for (iter = colocations; iter != NULL; iter = iter->next) {
244  const pcmk__colocation_t *constraint = iter->data;
245  const pe_resource_t *primary = constraint->primary;
246 
247  if (primary == orig_rsc) {
248  continue; // Break colocation loop
249  }
250 
251  if ((constraint->score == INFINITY) &&
252  (pcmk__colocation_affects(rsc, primary, constraint,
253  true) == pcmk__coloc_affects_location)) {
254 
255  colocated_rscs = primary->cmds->colocated_resources(primary,
256  orig_rsc,
257  colocated_rscs);
258  }
259  }
260  g_list_free(colocations);
261 
262  // Follow colocations where this resource is the primary resource
263  colocations = pcmk__with_this_colocations(rsc);
264  for (iter = colocations; iter != NULL; iter = iter->next) {
265  const pcmk__colocation_t *constraint = iter->data;
266  const pe_resource_t *dependent = constraint->dependent;
267 
268  if (dependent == orig_rsc) {
269  continue; // Break colocation loop
270  }
271 
272  if (pe_rsc_is_clone(rsc) && !pe_rsc_is_clone(dependent)) {
273  continue; // We can't be sure whether dependent will be colocated
274  }
275 
276  if ((constraint->score == INFINITY) &&
277  (pcmk__colocation_affects(dependent, rsc, constraint,
278  true) == pcmk__coloc_affects_location)) {
279 
280  colocated_rscs = dependent->cmds->colocated_resources(dependent,
281  orig_rsc,
282  colocated_rscs);
283  }
284  }
285  g_list_free(colocations);
286 
287  return colocated_rscs;
288 }
289 
290 // No-op function for variants that don't need to implement add_graph_meta()
291 void
292 pcmk__noop_add_graph_meta(const pe_resource_t *rsc, xmlNode *xml)
293 {
294 }
295 
296 void
298 {
299  pcmk__output_t *out = rsc->cluster->priv;
300 
301  pe_node_t *next = NULL;
302  pe_node_t *current = NULL;
303 
304  if (rsc->children != NULL) {
305  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
306  pe_resource_t *child = (pe_resource_t *) iter->data;
307 
308  child->cmds->output_actions(child);
309  }
310  return;
311  }
312 
313  next = rsc->allocated_to;
314  if (rsc->running_on) {
315  current = pe__current_node(rsc);
316  if (rsc->role == RSC_ROLE_STOPPED) {
317  /* This can occur when resources are being recovered because
318  * the current role can change in pcmk__primitive_create_actions()
319  */
320  rsc->role = RSC_ROLE_STARTED;
321  }
322  }
323 
324  if ((current == NULL) && pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
325  /* Don't log stopped orphans */
326  return;
327  }
328 
329  out->message(out, "rsc-action", rsc, current, next);
330 }
331 
353 bool
355 {
356  pcmk__output_t *out = rsc->cluster->priv;
357 
358  CRM_ASSERT(rsc->variant == pe_native);
359 
360  if (!force && (chosen != NULL)) {
361  if ((chosen->weight < 0)
362  // Allow the graph to assume that guest node connections will come up
363  || (!pcmk__node_available(chosen, true, false)
364  && !pe__is_guest_node(chosen))) {
365 
366  crm_debug("All nodes for resource %s are unavailable, unclean or "
367  "shutting down (%s can%s run resources, with weight %d)",
368  rsc->id, pe__node_name(chosen),
369  (pcmk__node_available(chosen, true, false)? "" : "not"),
370  chosen->weight);
371  pe__set_next_role(rsc, RSC_ROLE_STOPPED, "node availability");
372  chosen = NULL;
373  }
374  }
375 
378 
379  if (chosen == NULL) {
380  crm_debug("Could not allocate a node for %s", rsc->id);
381  pe__set_next_role(rsc, RSC_ROLE_STOPPED, "unable to allocate");
382 
383  for (GList *iter = rsc->actions; iter != NULL; iter = iter->next) {
384  pe_action_t *op = (pe_action_t *) iter->data;
385 
386  crm_debug("Updating %s for allocation failure", op->uuid);
387 
388  if (pcmk__str_eq(op->task, RSC_STOP, pcmk__str_casei)) {
390 
391  } else if (pcmk__str_eq(op->task, RSC_START, pcmk__str_casei)) {
393  //pe__set_resource_flags(rsc, pe_rsc_block);
394 
395  } else {
396  // Cancel recurring actions, unless for stopped state
397  const char *interval_ms_s = NULL;
398  const char *target_rc_s = NULL;
399  char *rc_stopped = pcmk__itoa(PCMK_OCF_NOT_RUNNING);
400 
401  interval_ms_s = g_hash_table_lookup(op->meta,
403  target_rc_s = g_hash_table_lookup(op->meta,
405  if ((interval_ms_s != NULL)
406  && !pcmk__str_eq(interval_ms_s, "0", pcmk__str_none)
407  && !pcmk__str_eq(rc_stopped, target_rc_s, pcmk__str_none)) {
409  }
410  free(rc_stopped);
411  }
412  }
413  return false;
414  }
415 
416  crm_debug("Assigning %s to %s", rsc->id, pe__node_name(chosen));
417  rsc->allocated_to = pe__copy_node(chosen);
418 
419  chosen->details->allocated_rsc = g_list_prepend(chosen->details->allocated_rsc,
420  rsc);
421  chosen->details->num_resources++;
422  chosen->count++;
424 
426  out->message(out, "resource-util", rsc, chosen, __func__);
427  }
428  return true;
429 }
430 
451 bool
453 {
454  bool changed = false;
455 
456  if (rsc->children == NULL) {
457  if (rsc->allocated_to != NULL) {
458  changed = true;
459  }
460  pcmk__finalize_assignment(rsc, node, force);
461 
462  } else {
463  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
464  pe_resource_t *child_rsc = (pe_resource_t *) iter->data;
465 
466  changed |= pcmk__assign_resource(child_rsc, node, force);
467  }
468  }
469  return changed;
470 }
471 
482 void
484 {
485  pe_node_t *old = rsc->allocated_to;
486 
487  if (old == NULL) {
488  return;
489  }
490 
491  crm_info("Unassigning %s from %s", rsc->id, pe__node_name(old));
493  rsc->allocated_to = NULL;
494 
495  /* We're going to free the pe_node_t, but its details member is shared and
496  * will remain, so update that appropriately first.
497  */
498  old->details->allocated_rsc = g_list_remove(old->details->allocated_rsc,
499  rsc);
500  old->details->num_resources--;
502  free(old);
503 }
504 
516 bool
518  pe_resource_t **failed)
519 {
520  int fail_count, remaining_tries;
521  pe_resource_t *rsc_to_ban = rsc;
522 
523  // Migration threshold of 0 means never force away
524  if (rsc->migration_threshold == 0) {
525  return false;
526  }
527 
528  // If we're ignoring failures, also ignore the migration threshold
530  return false;
531  }
532 
533  // If there are no failures, there's no need to force away
534  fail_count = pe_get_failcount(node, rsc, NULL,
536  if (fail_count <= 0) {
537  return false;
538  }
539 
540  // If failed resource is anonymous clone instance, we'll force clone away
541  if (!pcmk_is_set(rsc->flags, pe_rsc_unique)) {
542  rsc_to_ban = uber_parent(rsc);
543  }
544 
545  // How many more times recovery will be tried on this node
546  remaining_tries = rsc->migration_threshold - fail_count;
547 
548  if (remaining_tries <= 0) {
549  crm_warn("%s cannot run on %s due to reaching migration threshold "
550  "(clean up resource to allow again)"
551  CRM_XS " failures=%d migration-threshold=%d",
552  rsc_to_ban->id, pe__node_name(node), fail_count,
553  rsc->migration_threshold);
554  if (failed != NULL) {
555  *failed = rsc_to_ban;
556  }
557  return true;
558  }
559 
560  crm_info("%s can fail %d more time%s on "
561  "%s before reaching migration threshold (%d)",
562  rsc_to_ban->id, remaining_tries, pcmk__plural_s(remaining_tries),
563  pe__node_name(node), rsc->migration_threshold);
564  return false;
565 }
566 
567 static void *
568 convert_const_pointer(const void *ptr)
569 {
570  /* Worst function ever */
571  return (void *)ptr;
572 }
573 
583 static int
584 get_node_weight(const pe_node_t *node, GHashTable *nodes)
585 {
586  pe_node_t *weighted_node = NULL;
587 
588  if ((node != NULL) && (nodes != NULL)) {
589  weighted_node = g_hash_table_lookup(nodes, node->details->id);
590  }
591  return (weighted_node == NULL)? -INFINITY : weighted_node->weight;
592 }
593 
605 static gint
606 cmp_resources(gconstpointer a, gconstpointer b, gpointer data)
607 {
608  const pe_resource_t *resource1 = a;
609  const pe_resource_t *resource2 = b;
610  const GList *nodes = (const GList *) data;
611 
612  int rc = 0;
613  int r1_weight = -INFINITY;
614  int r2_weight = -INFINITY;
615  pe_node_t *r1_node = NULL;
616  pe_node_t *r2_node = NULL;
617  GHashTable *r1_nodes = NULL;
618  GHashTable *r2_nodes = NULL;
619  const char *reason = NULL;
620 
621  // Resources with highest priority should be allocated first
622  reason = "priority";
623  r1_weight = resource1->priority;
624  r2_weight = resource2->priority;
625  if (r1_weight > r2_weight) {
626  rc = -1;
627  goto done;
628  }
629  if (r1_weight < r2_weight) {
630  rc = 1;
631  goto done;
632  }
633 
634  // We need nodes to make any other useful comparisons
635  reason = "no node list";
636  if (nodes == NULL) {
637  goto done;
638  }
639 
640  // Calculate and log node weights
641  resource1->cmds->add_colocated_node_scores(convert_const_pointer(resource1),
642  resource1->id, &r1_nodes, NULL,
644  resource2->cmds->add_colocated_node_scores(convert_const_pointer(resource2),
645  resource2->id, &r2_nodes, NULL,
647  pe__show_node_weights(true, NULL, resource1->id, r1_nodes,
648  resource1->cluster);
649  pe__show_node_weights(true, NULL, resource2->id, r2_nodes,
650  resource2->cluster);
651 
652  // The resource with highest score on its current node goes first
653  reason = "current location";
654  if (resource1->running_on != NULL) {
655  r1_node = pe__current_node(resource1);
656  }
657  if (resource2->running_on != NULL) {
658  r2_node = pe__current_node(resource2);
659  }
660  r1_weight = get_node_weight(r1_node, r1_nodes);
661  r2_weight = get_node_weight(r2_node, r2_nodes);
662  if (r1_weight > r2_weight) {
663  rc = -1;
664  goto done;
665  }
666  if (r1_weight < r2_weight) {
667  rc = 1;
668  goto done;
669  }
670 
671  // Otherwise a higher weight on any node will do
672  reason = "score";
673  for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
674  const pe_node_t *node = (const pe_node_t *) iter->data;
675 
676  r1_weight = get_node_weight(node, r1_nodes);
677  r2_weight = get_node_weight(node, r2_nodes);
678  if (r1_weight > r2_weight) {
679  rc = -1;
680  goto done;
681  }
682  if (r1_weight < r2_weight) {
683  rc = 1;
684  goto done;
685  }
686  }
687 
688 done:
689  crm_trace("%s (%d)%s%s %c %s (%d)%s%s: %s",
690  resource1->id, r1_weight,
691  ((r1_node == NULL)? "" : " on "),
692  ((r1_node == NULL)? "" : r1_node->details->id),
693  ((rc < 0)? '>' : ((rc > 0)? '<' : '=')),
694  resource2->id, r2_weight,
695  ((r2_node == NULL)? "" : " on "),
696  ((r2_node == NULL)? "" : r2_node->details->id),
697  reason);
698  if (r1_nodes != NULL) {
699  g_hash_table_destroy(r1_nodes);
700  }
701  if (r2_nodes != NULL) {
702  g_hash_table_destroy(r2_nodes);
703  }
704  return rc;
705 }
706 
713 void
715 {
716  GList *nodes = g_list_copy(data_set->nodes);
717 
718  nodes = pcmk__sort_nodes(nodes, NULL);
719  data_set->resources = g_list_sort_with_data(data_set->resources,
720  cmp_resources, nodes);
721  g_list_free(nodes);
722 }
void pcmk__set_allocation_methods(pe_working_set_t *data_set)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:235
G_GNUC_INTERNAL pe_node_t * pcmk__primitive_assign(pe_resource_t *rsc, const pe_node_t *prefer)
#define RSC_STOP
Definition: crm.h:202
G_GNUC_INTERNAL GList * pcmk__group_colocated_resources(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *colocated_rscs)
#define crm_notice(fmt, args...)
Definition: logging.h:379
G_GNUC_INTERNAL void pcmk__release_node_capacity(GHashTable *current_utilization, const pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_rsc_actions_to_graph(pe_resource_t *rsc)
char data[0]
Definition: cpg.c:55
void clone_append_meta(const pe_resource_t *rsc, xmlNode *xml)
#define INFINITY
Definition: crm.h:99
G_GNUC_INTERNAL uint32_t pcmk__update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
G_GNUC_INTERNAL void pcmk__primitive_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
Definition: internal.h:385
int(* message)(pcmk__output_t *out, const char *message_id,...)
void clone_create_actions(pe_resource_t *rsc)
#define XML_ATTR_TYPE
Definition: msg_xml.h:151
bool clone_create_probe(pe_resource_t *rsc, pe_node_t *node)
enum rsc_role_e role
Definition: pe_types.h:402
G_GNUC_INTERNAL void pcmk__with_bundle_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
GList * children
Definition: pe_types.h:409
int count
Definition: pe_types.h:267
resource_alloc_functions_t * cmds
Definition: pe_types.h:359
G_GNUC_INTERNAL void pcmk__with_group_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
xmlNode * xml
Definition: pe_types.h:349
#define pe_rsc_unique
Definition: pe_types.h:278
G_GNUC_INTERNAL void pcmk__clone_with_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
Service safely stopped.
Definition: results.h:174
G_GNUC_INTERNAL void pcmk__group_with_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
pe_node_t * pe__copy_node(const pe_node_t *this_node)
Definition: utils.c:89
G_GNUC_INTERNAL void pcmk__with_clone_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
void clone_expand(pe_resource_t *rsc)
G_GNUC_INTERNAL enum pe_action_flags pcmk__group_action_flags(pe_action_t *action, const pe_node_t *node)
void pcmk__output_resource_actions(pe_resource_t *rsc)
pe_resource_t * dependent
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pe_node_t *active_node)
bool pcmk__rsc_agent_changed(pe_resource_t *rsc, pe_node_t *node, const xmlNode *rsc_entry, bool active_on_node)
G_GNUC_INTERNAL void pcmk__group_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__consume_node_capacity(GHashTable *current_utilization, const pe_resource_t *rsc)
void pcmk__bundle_expand(pe_resource_t *rsc)
G_GNUC_INTERNAL uint32_t pcmk__group_update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
bool pcmk__bundle_create_probe(pe_resource_t *rsc, pe_node_t *node)
#define RSC_START
Definition: crm.h:199
int migration_threshold
Definition: pe_types.h:369
pe_node_t * allocated_to
Definition: pe_types.h:395
void pcmk__bundle_internal_constraints(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_colocated_node_scores(pe_resource_t *rsc, const char *log_id, GHashTable **nodes, const char *attr, float factor, uint32_t flags)
G_GNUC_INTERNAL pe_node_t * pcmk__clone_assign(pe_resource_t *rsc, const pe_node_t *prefer)
bool pcmk__threshold_reached(pe_resource_t *rsc, const pe_node_t *node, pe_resource_t **failed)
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:77
GList * resources
Definition: pe_types.h:181
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:616
GList * nodes
Definition: pe_types.h:180
#define pe_rsc_provisional
Definition: pe_types.h:282
#define CRMD_ACTION_STOP
Definition: crm.h:177
int weight
Definition: pe_types.h:265
void pcmk__noop_add_graph_meta(const pe_resource_t *rsc, xmlNode *xml)
#define crm_warn(fmt, args...)
Definition: logging.h:378
GList *(* colocated_resources)(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *colocated_rscs)
void pcmk__bundle_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define crm_debug(fmt, args...)
Definition: logging.h:382
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node, bool consider_score, bool consider_guest)
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:922
G_GNUC_INTERNAL uint32_t pcmk__instance_update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
GList * pcmk__with_this_colocations(const pe_resource_t *rsc)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:496
bool pe__is_guest_node(const pe_node_t *node)
Definition: remote.c:33
pe_resource_t * primary
#define stop_key(rsc)
Definition: internal.h:405
void clone_internal_constraints(pe_resource_t *rsc)
#define pe_rsc_start_pending
Definition: pe_types.h:295
char * task
Definition: pe_types.h:437
#define pe__clear_action_flags(action, flags_to_clear)
Definition: internal.h:98
#define crm_trace(fmt, args...)
Definition: logging.h:383
pe_node_t * pcmk__bundle_allocate(pe_resource_t *rsc, const pe_node_t *prefer)
G_GNUC_INTERNAL pe_node_t * pcmk__group_assign(pe_resource_t *rsc, const pe_node_t *prefer)
GList * pcmk__this_with_colocations(const pe_resource_t *rsc)
void pcmk__bundle_shutdown_lock(pe_resource_t *rsc)
GHashTable * meta
Definition: pe_types.h:447
#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:268
G_GNUC_INTERNAL void pcmk__with_primitive_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
#define XML_AGENT_ATTR_PROVIDER
Definition: msg_xml.h:283
unsigned long long flags
Definition: pe_types.h:373
pe_working_set_t * data_set
char * clone_name
Definition: pe_types.h:348
G_GNUC_INTERNAL void pcmk__primitive_add_graph_meta(const pe_resource_t *rsc, xmlNode *xml)
void(* output_actions)(pe_resource_t *rsc)
bool pcmk__finalize_assignment(pe_resource_t *rsc, pe_node_t *chosen, bool force)
#define PCMK__NELEM(a)
Definition: internal.h:44
GList * actions
Definition: pe_types.h:391
enum pe_action_flags clone_action_flags(pe_action_t *action, const pe_node_t *node)
G_GNUC_INTERNAL bool pcmk__probe_rsc_on_node(pe_resource_t *rsc, pe_node_t *node)
char * uuid
Definition: pe_types.h:438
enum pe_obj_types variant
Definition: pe_types.h:356
const char * id
Definition: pe_types.h:231
G_GNUC_INTERNAL void pcmk__output_bundle_actions(pe_resource_t *rsc)
GList * pcmk__colocated_resources(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *colocated_rscs)
G_GNUC_INTERNAL void pcmk__primitive_internal_constraints(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__clone_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__apply_location(pe_resource_t *rsc, pe__location_t *constraint)
#define CRM_XS
Definition: logging.h:55
G_GNUC_INTERNAL void pcmk__group_shutdown_lock(pe_resource_t *rsc)
void pcmk__bundle_create_actions(pe_resource_t *rsc)
pcmk__action_result_t result
Definition: pcmk_fence.c:35
#define pe_flag_show_utilization
Definition: pe_types.h:151
void pcmk__bundle_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
G_GNUC_INTERNAL void pcmk__primitive_with_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__group_internal_constraints(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__group_create_actions(pe_resource_t *rsc)
#define CRM_ASSERT(expr)
Definition: results.h:42
G_GNUC_INTERNAL void pcmk__group_add_colocated_node_scores(pe_resource_t *rsc, const char *log_id, GHashTable **nodes, const char *attr, float factor, uint32_t flags)
enum pe_action_flags pcmk__bundle_action_flags(pe_action_t *action, const pe_node_t *node)
G_GNUC_INTERNAL void pcmk__primitive_shutdown_lock(pe_resource_t *rsc)
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition: complex.c:1166
This structure contains everything that makes up a single output formatter.
#define XML_LRM_ATTR_INTERVAL_MS
Definition: msg_xml.h:313
G_GNUC_INTERNAL void pcmk__primitive_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL void pcmk__bundle_with_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
void pcmk__sort_resources(pe_working_set_t *data_set)
GHashTable * utilization
Definition: pe_types.h:258
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:83
#define pcmk__plural_s(i)
G_GNUC_INTERNAL void pcmk__bundle_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__group_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
GList * running_on
Definition: pe_types.h:398
#define pe_rsc_failure_ignored
Definition: pe_types.h:306
pe_working_set_t * cluster
Definition: pe_types.h:353
G_GNUC_INTERNAL void pcmk__group_apply_location(pe_resource_t *rsc, pe__location_t *location)
void pcmk__unassign_resource(pe_resource_t *rsc)
GList * pcmk__rscs_matching_id(const char *id, const pe_working_set_t *data_set)
bool pcmk__assign_resource(pe_resource_t *rsc, pe_node_t *node, bool force)
void pcmk__clone_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:50
G_GNUC_INTERNAL void pcmk__primitive_create_actions(pe_resource_t *rsc)
unsigned long long flags
Definition: pe_types.h:169
GList * allocated_rsc
Definition: pe_types.h:255
int pe_get_failcount(const pe_node_t *node, pe_resource_t *rsc, time_t *last_failure, uint32_t flags, const xmlNode *xml_op)
Definition: failcounts.c:275
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
Definition: pe_actions.c:942
G_GNUC_INTERNAL enum pcmk__coloc_affects pcmk__colocation_affects(const pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool preview)
#define crm_info(fmt, args...)
Definition: logging.h:380
#define pe_rsc_orphan
Definition: pe_types.h:272
#define XML_ATTR_TE_TARGET_RC
Definition: msg_xml.h:428
void(* add_colocated_node_scores)(pe_resource_t *rsc, const char *log_id, GHashTable **nodes, const char *attr, float factor, uint32_t flags)
G_GNUC_INTERNAL enum pe_action_flags pcmk__primitive_action_flags(pe_action_t *action, const pe_node_t *node)
void pcmk__clone_shutdown_lock(pe_resource_t *rsc)
#define XML_AGENT_ATTR_CLASS
Definition: msg_xml.h:282
char * id
Definition: pe_types.h:347