pacemaker  2.1.4-dc6eb4362
Scalable High-Availability cluster resource manager
pcmk_sched_resource.c
Go to the documentation of this file.
1 /*
2  * Copyright 2014-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 General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 #include <crm/msg_xml.h>
12 #include <pacemaker-internal.h>
13 
14 #include "libpacemaker_private.h"
15 
16 // Resource allocation methods that vary by resource variant
17 static resource_alloc_functions_t allocation_methods[] = {
18  {
35  },
36  {
53  },
54  {
71  },
72  {
89  }
90 };
91 
103 bool
105  const xmlNode *rsc_entry, bool active_on_node)
106 {
107  bool changed = false;
108  const char *attr_list[] = {
112  };
113 
114  for (int i = 0; i < PCMK__NELEM(attr_list); i++) {
115  const char *value = crm_element_value(rsc->xml, attr_list[i]);
116  const char *old_value = crm_element_value(rsc_entry, attr_list[i]);
117 
118  if (!pcmk__str_eq(value, old_value, pcmk__str_none)) {
119  changed = true;
120  trigger_unfencing(rsc, node, "Device definition changed", NULL,
121  rsc->cluster);
122  if (active_on_node) {
123  crm_notice("Forcing restart of %s on %s "
124  "because %s changed from '%s' to '%s'",
125  rsc->id, node->details->uname, attr_list[i],
126  crm_str(old_value), crm_str(value));
127  }
128  }
129  }
130  if (changed && active_on_node) {
131  // Make sure the resource is restarted
132  custom_action(rsc, stop_key(rsc), CRMD_ACTION_STOP, node, FALSE, TRUE,
133  rsc->cluster);
135  }
136  return changed;
137 }
138 
149 static GList *
150 add_rsc_if_matching(GList *result, pe_resource_t *rsc, const char *id)
151 {
152  if ((strcmp(rsc->id, id) == 0)
153  || ((rsc->clone_name != NULL) && (strcmp(rsc->clone_name, id) == 0))) {
154  result = g_list_prepend(result, rsc);
155  }
156  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
157  pe_resource_t *child = (pe_resource_t *) iter->data;
158 
159  result = add_rsc_if_matching(result, child, id);
160  }
161  return result;
162 }
163 
175 GList *
177 {
178  GList *result = NULL;
179 
180  CRM_CHECK((id != NULL) && (data_set != NULL), return NULL);
181  for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
182  result = add_rsc_if_matching(result, (pe_resource_t *) iter->data, id);
183  }
184  return result;
185 }
186 
194 static void
195 set_allocation_methods_for_rsc(pe_resource_t *rsc, void *ignored)
196 {
197  rsc->cmds = &allocation_methods[rsc->variant];
198  g_list_foreach(rsc->children, (GFunc) set_allocation_methods_for_rsc, NULL);
199 }
200 
207 void
209 {
210  g_list_foreach(data_set->resources, (GFunc) set_allocation_methods_for_rsc,
211  NULL);
212 }
213 
214 // Shared implementation of resource_alloc_functions_t:colocated_resources()
215 GList *
217  GList *colocated_rscs)
218 {
219  GList *gIter = NULL;
220 
221  if (orig_rsc == NULL) {
222  orig_rsc = rsc;
223  }
224 
225  if ((rsc == NULL) || (g_list_find(colocated_rscs, rsc) != NULL)) {
226  return colocated_rscs;
227  }
228 
229  pe_rsc_trace(orig_rsc, "%s is in colocation chain with %s",
230  rsc->id, orig_rsc->id);
231  colocated_rscs = g_list_append(colocated_rscs, rsc);
232 
233  // Follow colocations where this resource is the dependent resource
234  for (gIter = rsc->rsc_cons; gIter != NULL; gIter = gIter->next) {
235  pcmk__colocation_t *constraint = (pcmk__colocation_t *) gIter->data;
236  pe_resource_t *primary = constraint->primary;
237 
238  if (primary == orig_rsc) {
239  continue; // Break colocation loop
240  }
241 
242  if ((constraint->score == INFINITY) &&
243  (pcmk__colocation_affects(rsc, primary, constraint,
244  true) == pcmk__coloc_affects_location)) {
245 
246  colocated_rscs = primary->cmds->colocated_resources(primary,
247  orig_rsc,
248  colocated_rscs);
249  }
250  }
251 
252  // Follow colocations where this resource is the primary resource
253  for (gIter = rsc->rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
254  pcmk__colocation_t *constraint = (pcmk__colocation_t *) gIter->data;
255  pe_resource_t *dependent = constraint->dependent;
256 
257  if (dependent == orig_rsc) {
258  continue; // Break colocation loop
259  }
260 
261  if (pe_rsc_is_clone(rsc) && !pe_rsc_is_clone(dependent)) {
262  continue; // We can't be sure whether dependent will be colocated
263  }
264 
265  if ((constraint->score == INFINITY) &&
266  (pcmk__colocation_affects(dependent, rsc, constraint,
267  true) == pcmk__coloc_affects_location)) {
268 
269  colocated_rscs = dependent->cmds->colocated_resources(dependent,
270  orig_rsc,
271  colocated_rscs);
272  }
273  }
274 
275  return colocated_rscs;
276 }
277 
278 void
280 {
281  pcmk__output_t *out = rsc->cluster->priv;
282 
283  pe_node_t *next = NULL;
284  pe_node_t *current = NULL;
285 
286  if (rsc->children != NULL) {
287  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
288  pe_resource_t *child = (pe_resource_t *) iter->data;
289 
290  child->cmds->output_actions(child);
291  }
292  return;
293  }
294 
295  next = rsc->allocated_to;
296  if (rsc->running_on) {
297  current = pe__current_node(rsc);
298  if (rsc->role == RSC_ROLE_STOPPED) {
299  /*
300  * This can occur when resources are being recovered
301  * We fiddle with the current role in native_create_actions()
302  */
303  rsc->role = RSC_ROLE_STARTED;
304  }
305  }
306 
307  if ((current == NULL) && pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
308  /* Don't log stopped orphans */
309  return;
310  }
311 
312  out->message(out, "rsc-action", rsc, current, next);
313 }
314 
336 bool
338 {
339  pcmk__output_t *out = rsc->cluster->priv;
340 
341  CRM_ASSERT(rsc->variant == pe_native);
342 
343  if (!force && (chosen != NULL)) {
344  if ((chosen->weight < 0)
345  // Allow the graph to assume that guest node connections will come up
346  || (!pcmk__node_available(chosen) && !pe__is_guest_node(chosen))) {
347 
348  crm_debug("All nodes for resource %s are unavailable, unclean or "
349  "shutting down (%s can%s run resources, with weight %d)",
350  rsc->id, chosen->details->uname,
351  (pcmk__node_available(chosen)? "" : "not"),
352  chosen->weight);
353  pe__set_next_role(rsc, RSC_ROLE_STOPPED, "node availability");
354  chosen = NULL;
355  }
356  }
357 
360 
361  if (chosen == NULL) {
362  crm_debug("Could not allocate a node for %s", rsc->id);
363  pe__set_next_role(rsc, RSC_ROLE_STOPPED, "unable to allocate");
364 
365  for (GList *iter = rsc->actions; iter != NULL; iter = iter->next) {
366  pe_action_t *op = (pe_action_t *) iter->data;
367 
368  crm_debug("Updating %s for allocation failure", op->uuid);
369 
370  if (pcmk__str_eq(op->task, RSC_STOP, pcmk__str_casei)) {
372 
373  } else if (pcmk__str_eq(op->task, RSC_START, pcmk__str_casei)) {
375  //pe__set_resource_flags(rsc, pe_rsc_block);
376 
377  } else {
378  // Cancel recurring actions, unless for stopped state
379  const char *interval_ms_s = NULL;
380  const char *target_rc_s = NULL;
381  char *rc_stopped = pcmk__itoa(PCMK_OCF_NOT_RUNNING);
382 
383  interval_ms_s = g_hash_table_lookup(op->meta,
385  target_rc_s = g_hash_table_lookup(op->meta,
387  if ((interval_ms_s != NULL)
388  && !pcmk__str_eq(interval_ms_s, "0", pcmk__str_none)
389  && !pcmk__str_eq(rc_stopped, target_rc_s, pcmk__str_none)) {
391  }
392  free(rc_stopped);
393  }
394  }
395  return false;
396  }
397 
398  crm_debug("Assigning %s to %s", rsc->id, chosen->details->uname);
399  rsc->allocated_to = pe__copy_node(chosen);
400 
401  chosen->details->allocated_rsc = g_list_prepend(chosen->details->allocated_rsc,
402  rsc);
403  chosen->details->num_resources++;
404  chosen->count++;
406 
408  out->message(out, "resource-util", rsc, chosen, __func__);
409  }
410  return true;
411 }
412 
433 bool
435 {
436  bool changed = false;
437 
438  if (rsc->children == NULL) {
439  if (rsc->allocated_to != NULL) {
440  changed = true;
441  }
442  pcmk__assign_primitive(rsc, node, force);
443 
444  } else {
445  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
446  pe_resource_t *child_rsc = (pe_resource_t *) iter->data;
447 
448  changed |= pcmk__assign_resource(child_rsc, node, force);
449  }
450  }
451  return changed;
452 }
453 
464 void
466 {
467  pe_node_t *old = rsc->allocated_to;
468 
469  if (old == NULL) {
470  return;
471  }
472 
473  crm_info("Unassigning %s from %s", rsc->id, old->details->uname);
475  rsc->allocated_to = NULL;
476 
477  /* We're going to free the pe_node_t, but its details member is shared and
478  * will remain, so update that appropriately first.
479  */
480  old->details->allocated_rsc = g_list_remove(old->details->allocated_rsc,
481  rsc);
482  old->details->num_resources--;
484  free(old);
485 }
486 
498 bool
500  pe_resource_t **failed)
501 {
502  int fail_count, remaining_tries;
503  pe_resource_t *rsc_to_ban = rsc;
504 
505  // Migration threshold of 0 means never force away
506  if (rsc->migration_threshold == 0) {
507  return false;
508  }
509 
510  // If we're ignoring failures, also ignore the migration threshold
512  return false;
513  }
514 
515  // If there are no failures, there's no need to force away
516  fail_count = pe_get_failcount(node, rsc, NULL,
518  rsc->cluster);
519  if (fail_count <= 0) {
520  return false;
521  }
522 
523  // If failed resource is anonymous clone instance, we'll force clone away
524  if (!pcmk_is_set(rsc->flags, pe_rsc_unique)) {
525  rsc_to_ban = uber_parent(rsc);
526  }
527 
528  // How many more times recovery will be tried on this node
529  remaining_tries = rsc->migration_threshold - fail_count;
530 
531  if (remaining_tries <= 0) {
532  crm_warn("%s cannot run on %s due to reaching migration threshold "
533  "(clean up resource to allow again)"
534  CRM_XS " failures=%d migration-threshold=%d",
535  rsc_to_ban->id, node->details->uname, fail_count,
536  rsc->migration_threshold);
537  if (failed != NULL) {
538  *failed = rsc_to_ban;
539  }
540  return true;
541  }
542 
543  crm_info("%s can fail %d more time%s on "
544  "%s before reaching migration threshold (%d)",
545  rsc_to_ban->id, remaining_tries, pcmk__plural_s(remaining_tries),
546  node->details->uname, rsc->migration_threshold);
547  return false;
548 }
549 
550 static void *
551 convert_const_pointer(const void *ptr)
552 {
553  /* Worst function ever */
554  return (void *)ptr;
555 }
556 
566 static int
567 get_node_weight(pe_node_t *node, GHashTable *nodes)
568 {
569  pe_node_t *weighted_node = NULL;
570 
571  if ((node != NULL) && (nodes != NULL)) {
572  weighted_node = g_hash_table_lookup(nodes, node->details->id);
573  }
574  return (weighted_node == NULL)? -INFINITY : weighted_node->weight;
575 }
576 
588 static gint
589 cmp_resources(gconstpointer a, gconstpointer b, gpointer data)
590 {
591  const pe_resource_t *resource1 = a;
592  const pe_resource_t *resource2 = b;
593  GList *nodes = (GList *) data;
594 
595  int rc = 0;
596  int r1_weight = -INFINITY;
597  int r2_weight = -INFINITY;
598  pe_node_t *r1_node = NULL;
599  pe_node_t *r2_node = NULL;
600  GHashTable *r1_nodes = NULL;
601  GHashTable *r2_nodes = NULL;
602  const char *reason = NULL;
603 
604  // Resources with highest priority should be allocated first
605  reason = "priority";
606  r1_weight = resource1->priority;
607  r2_weight = resource2->priority;
608  if (r1_weight > r2_weight) {
609  rc = -1;
610  goto done;
611  }
612  if (r1_weight < r2_weight) {
613  rc = 1;
614  goto done;
615  }
616 
617  // We need nodes to make any other useful comparisons
618  reason = "no node list";
619  if (nodes == NULL) {
620  goto done;
621  }
622 
623  // Calculate and log node weights
624  r1_nodes = pcmk__native_merge_weights(convert_const_pointer(resource1),
625  resource1->id, NULL, NULL, 1,
627  r2_nodes = pcmk__native_merge_weights(convert_const_pointer(resource2),
628  resource2->id, NULL, NULL, 1,
630  pe__show_node_weights(true, NULL, resource1->id, r1_nodes,
631  resource1->cluster);
632  pe__show_node_weights(true, NULL, resource2->id, r2_nodes,
633  resource2->cluster);
634 
635  // The resource with highest score on its current node goes first
636  reason = "current location";
637  if (resource1->running_on != NULL) {
638  r1_node = pe__current_node(resource1);
639  }
640  if (resource2->running_on != NULL) {
641  r2_node = pe__current_node(resource2);
642  }
643  r1_weight = get_node_weight(r1_node, r1_nodes);
644  r2_weight = get_node_weight(r2_node, r2_nodes);
645  if (r1_weight > r2_weight) {
646  rc = -1;
647  goto done;
648  }
649  if (r1_weight < r2_weight) {
650  rc = 1;
651  goto done;
652  }
653 
654  // Otherwise a higher weight on any node will do
655  reason = "score";
656  for (GList *iter = nodes; iter != NULL; iter = iter->next) {
657  pe_node_t *node = (pe_node_t *) iter->data;
658 
659  r1_weight = get_node_weight(node, r1_nodes);
660  r2_weight = get_node_weight(node, r2_nodes);
661  if (r1_weight > r2_weight) {
662  rc = -1;
663  goto done;
664  }
665  if (r1_weight < r2_weight) {
666  rc = 1;
667  goto done;
668  }
669  }
670 
671 done:
672  crm_trace("%s (%d)%s%s %c %s (%d)%s%s: %s",
673  resource1->id, r1_weight,
674  ((r1_node == NULL)? "" : " on "),
675  ((r1_node == NULL)? "" : r1_node->details->id),
676  ((rc < 0)? '>' : ((rc > 0)? '<' : '=')),
677  resource2->id, r2_weight,
678  ((r2_node == NULL)? "" : " on "),
679  ((r2_node == NULL)? "" : r2_node->details->id),
680  reason);
681  if (r1_nodes != NULL) {
682  g_hash_table_destroy(r1_nodes);
683  }
684  if (r2_nodes != NULL) {
685  g_hash_table_destroy(r2_nodes);
686  }
687  return rc;
688 }
689 
696 void
698 {
699  GList *nodes = g_list_copy(data_set->nodes);
700 
701  nodes = pcmk__sort_nodes(nodes, NULL, data_set);
702  data_set->resources = g_list_sort_with_data(data_set->resources,
703  cmp_resources, nodes);
704  g_list_free(nodes);
705 }
void pcmk__set_allocation_methods(pe_working_set_t *data_set)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
void group_append_meta(pe_resource_t *rsc, xmlNode *xml)
enum pe_action_flags clone_action_flags(pe_action_t *action, pe_node_t *node)
#define RSC_STOP
Definition: crm.h:204
void clone_append_meta(pe_resource_t *rsc, xmlNode *xml)
#define crm_notice(fmt, args...)
Definition: logging.h:360
enum pe_action_flags pcmk__bundle_action_flags(pe_action_t *action, pe_node_t *node)
char data[0]
Definition: cpg.c:55
#define INFINITY
Definition: crm.h:99
GList * rsc_cons
Definition: pe_types.h:371
GList * pcmk__colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
Definition: internal.h:355
int(* message)(pcmk__output_t *out, const char *message_id,...)
#define XML_ATTR_TYPE
Definition: msg_xml.h:138
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node)
enum rsc_role_e role
Definition: pe_types.h:384
GList * children
Definition: pe_types.h:391
int count
Definition: pe_types.h:251
resource_alloc_functions_t * cmds
Definition: pe_types.h:348
xmlNode * xml
Definition: pe_types.h:338
#define pe_rsc_unique
Definition: pe_types.h:262
Service safely stopped.
Definition: results.h:169
void pcmk__primitive_shutdown_lock(pe_resource_t *rsc)
void pcmk__group_add_utilization(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
pe_node_t * pe__copy_node(const pe_node_t *this_node)
Definition: utils.c:141
void pcmk__output_resource_actions(pe_resource_t *rsc)
pe_resource_t * dependent
void pcmk__primitive_add_utilization(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
bool pcmk__rsc_agent_changed(pe_resource_t *rsc, pe_node_t *node, const xmlNode *rsc_entry, bool active_on_node)
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
GList * rsc_cons_lhs
Definition: pe_types.h:370
enum pe_graph_flags native_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set)
void native_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
#define RSC_START
Definition: crm.h:201
int migration_threshold
Definition: pe_types.h:358
void native_rsc_colocation_lh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
pe_node_t * allocated_to
Definition: pe_types.h:377
GHashTable * pcmk__native_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
void pcmk__group_shutdown_lock(pe_resource_t *rsc)
void native_rsc_colocation_rh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
void pcmk__bundle_rsc_colocation_rh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
void pcmk__clone_add_utilization(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:49
GList * resources
Definition: pe_types.h:165
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:2244
GList * nodes
Definition: pe_types.h:164
void pcmk__bundle_rsc_colocation_lh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define pe_rsc_provisional
Definition: pe_types.h:266
void native_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void group_rsc_colocation_lh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define CRMD_ACTION_STOP
Definition: crm.h:179
int weight
Definition: pe_types.h:249
#define crm_warn(fmt, args...)
Definition: logging.h:359
void native_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
void clone_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
#define crm_debug(fmt, args...)
Definition: logging.h:363
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pe_node_t *active_node, pe_working_set_t *data_set)
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:913
pe_node_t * pcmk__clone_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
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:378
enum pe_graph_flags group_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set)
#define pe_rsc_start_pending
Definition: pe_types.h:278
char * task
Definition: pe_types.h:428
#define pe__clear_action_flags(action, flags_to_clear)
Definition: internal.h:70
#define crm_trace(fmt, args...)
Definition: logging.h:364
G_GNUC_INTERNAL GList * pcmk__group_colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
GList *(* colocated_resources)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
void pcmk__bundle_shutdown_lock(pe_resource_t *rsc)
GHashTable * meta
Definition: pe_types.h:438
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:122
bool pcmk__assign_primitive(pe_resource_t *rsc, pe_node_t *chosen, bool force)
struct pe_node_shared_s * details
Definition: pe_types.h:252
#define XML_AGENT_ATTR_PROVIDER
Definition: msg_xml.h:273
unsigned long long flags
Definition: pe_types.h:362
const char * uname
Definition: pe_types.h:216
GHashTable * pcmk__group_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
pe_working_set_t * data_set
char * clone_name
Definition: pe_types.h:337
void(* output_actions)(pe_resource_t *rsc)
#define PCMK__NELEM(a)
Definition: internal.h:42
GList * actions
Definition: pe_types.h:373
gboolean native_create_probe(pe_resource_t *rsc, pe_node_t *node, pe_action_t *complete, gboolean force, pe_working_set_t *data_set)
char * uuid
Definition: pe_types.h:429
bool pcmk__threshold_reached(pe_resource_t *rsc, pe_node_t *node, pe_resource_t **failed)
void group_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
pe_node_t * pcmk__bundle_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
enum pe_obj_types variant
Definition: pe_types.h:345
const char * id
Definition: pe_types.h:215
G_GNUC_INTERNAL void pcmk__output_bundle_actions(pe_resource_t *rsc)
gboolean pcmk__bundle_create_probe(pe_resource_t *rsc, pe_node_t *node, pe_action_t *complete, gboolean force, pe_working_set_t *data_set)
#define CRM_XS
Definition: logging.h:55
void group_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
enum pe_action_flags group_action_flags(pe_action_t *action, pe_node_t *node)
pcmk__action_result_t result
Definition: pcmk_fence.c:34
#define pe_flag_show_utilization
Definition: pe_types.h:135
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__release_node_capacity(GHashTable *current_utilization, pe_resource_t *rsc)
void group_rsc_colocation_rh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define CRM_ASSERT(expr)
Definition: results.h:42
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition: complex.c:1126
void pcmk__bundle_add_utilization(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL void pcmk__consume_node_capacity(GHashTable *current_utilization, pe_resource_t *rsc)
This structure contains everything that makes up a single output formatter.
#define XML_LRM_ATTR_INTERVAL_MS
Definition: msg_xml.h:301
void clone_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
void pcmk__sort_resources(pe_working_set_t *data_set)
GHashTable * utilization
Definition: pe_types.h:242
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:55
#define crm_str(x)
Definition: logging.h:384
void pcmk__bundle_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
gboolean clone_create_probe(pe_resource_t *rsc, pe_node_t *node, pe_action_t *complete, gboolean force, pe_working_set_t *data_set)
#define pcmk__plural_s(i)
void clone_rsc_colocation_lh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
void native_append_meta(pe_resource_t *rsc, xmlNode *xml)
GList * running_on
Definition: pe_types.h:380
#define pe_rsc_failure_ignored
Definition: pe_types.h:289
pe_working_set_t * cluster
Definition: pe_types.h:342
void clone_rsc_colocation_rh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
void pcmk__unassign_resource(pe_resource_t *rsc)
G_GNUC_INTERNAL enum pcmk__coloc_affects pcmk__colocation_affects(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, bool preview)
bool pcmk__assign_resource(pe_resource_t *rsc, pe_node_t *node, bool force)
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:22
unsigned long long flags
Definition: pe_types.h:153
GList * allocated_rsc
Definition: pe_types.h:239
void clone_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
GList * pcmk__rscs_matching_id(const char *id, pe_working_set_t *data_set)
void group_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
void pcmk__bundle_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
#define crm_info(fmt, args...)
Definition: logging.h:361
enum pe_action_flags native_action_flags(pe_action_t *action, pe_node_t *node)
#define pe_rsc_orphan
Definition: pe_types.h:256
enum pe_graph_flags pcmk__multi_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set)
void pcmk__bundle_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void pcmk__bundle_append_meta(pe_resource_t *rsc, xmlNode *xml)
#define XML_ATTR_TE_TARGET_RC
Definition: msg_xml.h:408
int pe_get_failcount(pe_node_t *node, pe_resource_t *rsc, time_t *last_failure, uint32_t flags, xmlNode *xml_op, pe_working_set_t *data_set)
Definition: failcounts.c:251
void pcmk__clone_shutdown_lock(pe_resource_t *rsc)
pe_node_t * pcmk__native_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
#define XML_AGENT_ATTR_CLASS
Definition: msg_xml.h:272
char * id
Definition: pe_types.h:336
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
Definition: utils.c:730
pe_node_t * pcmk__group_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)