pacemaker  2.1.7-0f7f88312f
Scalable High-Availability cluster resource manager
pcmk_sched_clone.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-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 <crm/msg_xml.h>
13 #include <pacemaker-internal.h>
14 
15 #include "libpacemaker_private.h"
16 
38  bool stop_if_fail)
39 {
40  GList *colocations = NULL;
41 
42  CRM_ASSERT(pe_rsc_is_clone(rsc));
43 
45  return NULL; // Assignment has already been done
46  }
47 
48  // Detect assignment loops
50  pe_rsc_debug(rsc, "Breaking assignment loop involving %s", rsc->id);
51  return NULL;
52  }
54 
55  // If this clone is promotable, consider nodes' promotion scores
58  }
59 
60  // If this clone is colocated with any other resources, assign those first
61  colocations = pcmk__this_with_colocations(rsc);
62  for (GList *iter = colocations; iter != NULL; iter = iter->next) {
63  pcmk__colocation_t *constraint = (pcmk__colocation_t *) iter->data;
64 
65  pe_rsc_trace(rsc, "%s: Assigning colocation %s primary %s first",
66  rsc->id, constraint->id, constraint->primary->id);
67  constraint->primary->cmds->assign(constraint->primary, prefer,
68  stop_if_fail);
69  }
70  g_list_free(colocations);
71 
72  // If any resources are colocated with this one, consider their preferences
73  colocations = pcmk__with_this_colocations(rsc);
74  g_list_foreach(colocations, pcmk__add_dependent_scores, rsc);
75  g_list_free(colocations);
76 
79  rsc, __func__, rsc->allowed_nodes, rsc->cluster);
80 
81  rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance);
83  pe__clone_node_max(rsc));
84 
87  }
88 
90  pe_rsc_trace(rsc, "Assigned clone %s", rsc->id);
91  return NULL;
92 }
93 
100 void
102 {
103  CRM_ASSERT(pe_rsc_is_clone(rsc));
104 
105  pe_rsc_trace(rsc, "Creating actions for clone %s", rsc->id);
109  }
110 }
111 
118 void
120 {
121  bool ordered = false;
122 
123  CRM_ASSERT(pe_rsc_is_clone(rsc));
124 
125  pe_rsc_trace(rsc, "Creating internal constraints for clone %s", rsc->id);
126 
127  // Restart ordering: Stop -> stopped -> start -> started
129  rsc, PCMK_ACTION_START,
132  rsc, PCMK_ACTION_RUNNING,
135  rsc, PCMK_ACTION_STOPPED,
137 
138  // Demoted -> stop and started -> promote
141  rsc, PCMK_ACTION_STOP,
144  rsc, PCMK_ACTION_PROMOTE,
146  }
147 
148  ordered = pe__clone_is_ordered(rsc);
149  if (ordered) {
150  /* Ordered clone instances must start and stop by instance number. The
151  * instances might have been previously shuffled for assignment or
152  * promotion purposes, so re-sort them.
153  */
154  rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance_number);
155  }
156  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
157  pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
158 
159  instance->cmds->internal_constraints(instance);
160 
161  // Start clone -> start instance -> clone started
165  rsc, PCMK_ACTION_RUNNING,
167 
168  // Stop clone -> stop instance -> clone stopped
171  rsc, PCMK_ACTION_STOPPED,
173 
174  /* Instances of ordered clones must be started and stopped by instance
175  * number. Since only some instances may be starting or stopping, order
176  * each instance relative to every later instance.
177  */
178  if (ordered) {
179  for (GList *later = iter->next;
180  later != NULL; later = later->next) {
181  pcmk__order_starts(instance, (pcmk_resource_t *) later->data,
183  pcmk__order_stops((pcmk_resource_t *) later->data, instance,
185  }
186  }
187  }
190  }
191 }
192 
201 static bool
202 can_interleave(const pcmk__colocation_t *colocation)
203 {
204  const pcmk_resource_t *dependent = colocation->dependent;
205 
206  // Only colocations between clone or bundle resources use interleaving
207  if (dependent->variant <= pcmk_rsc_variant_group) {
208  return false;
209  }
210 
211  // Only the dependent needs to be marked for interleaving
212  if (!crm_is_true(g_hash_table_lookup(dependent->meta,
214  return false;
215  }
216 
217  /* @TODO Do we actually care about multiple primary instances sharing a
218  * dependent instance?
219  */
220  if (dependent->fns->max_per_node(dependent)
221  != colocation->primary->fns->max_per_node(colocation->primary)) {
222  pcmk__config_err("Cannot interleave %s and %s because they do not "
223  "support the same number of instances per node",
224  dependent->id, colocation->primary->id);
225  return false;
226  }
227 
228  return true;
229 }
230 
244 void
246  const pcmk_resource_t *primary,
247  const pcmk__colocation_t *colocation,
248  bool for_dependent)
249 {
250  const GList *iter = NULL;
251 
252  /* This should never be called for the clone itself as a dependent. Instead,
253  * we add its colocation constraints to its instances and call the
254  * apply_coloc_score() method for the instances as dependents.
255  */
256  CRM_ASSERT(!for_dependent);
257 
258  CRM_ASSERT((colocation != NULL) && pe_rsc_is_clone(primary)
259  && (dependent != NULL)
260  && (dependent->variant == pcmk_rsc_variant_primitive));
261 
262  if (pcmk_is_set(primary->flags, pcmk_rsc_unassigned)) {
263  pe_rsc_trace(primary,
264  "Delaying processing colocation %s "
265  "because cloned primary %s is still provisional",
266  colocation->id, primary->id);
267  return;
268  }
269 
270  pe_rsc_trace(primary, "Processing colocation %s (%s with clone %s @%s)",
271  colocation->id, dependent->id, primary->id,
272  pcmk_readable_score(colocation->score));
273 
274  // Apply role-specific colocations
275  if (pcmk_is_set(primary->flags, pcmk_rsc_promotable)
276  && (colocation->primary_role != pcmk_role_unknown)) {
277 
278  if (pcmk_is_set(dependent->flags, pcmk_rsc_unassigned)) {
279  // We're assigning the dependent to a node
280  pcmk__update_dependent_with_promotable(primary, dependent,
281  colocation);
282  return;
283  }
284 
285  if (colocation->dependent_role == pcmk_role_promoted) {
286  // We're choosing a role for the dependent
288  colocation);
289  return;
290  }
291  }
292 
293  // Apply interleaved colocations
294  if (can_interleave(colocation)) {
295  const pcmk_resource_t *primary_instance = NULL;
296 
297  primary_instance = pcmk__find_compatible_instance(dependent, primary,
299  false);
300  if (primary_instance != NULL) {
301  pe_rsc_debug(primary, "Interleaving %s with %s",
302  dependent->id, primary_instance->id);
303  dependent->cmds->apply_coloc_score(dependent, primary_instance,
304  colocation, true);
305 
306  } else if (colocation->score >= INFINITY) {
307  crm_notice("%s cannot run because it cannot interleave with "
308  "any instance of %s", dependent->id, primary->id);
309  pcmk__assign_resource(dependent, NULL, true, true);
310 
311  } else {
312  pe_rsc_debug(primary,
313  "%s will not colocate with %s "
314  "because no instance can interleave with it",
315  dependent->id, primary->id);
316  }
317 
318  return;
319  }
320 
321  // Apply mandatory colocations
322  if (colocation->score >= INFINITY) {
323  GList *primary_nodes = NULL;
324 
325  // Dependent can run only where primary will have unblocked instances
326  for (iter = primary->children; iter != NULL; iter = iter->next) {
327  const pcmk_resource_t *instance = iter->data;
328  pcmk_node_t *chosen = instance->fns->location(instance, NULL, 0);
329 
330  if ((chosen != NULL)
331  && !is_set_recursive(instance, pcmk_rsc_blocked, TRUE)) {
332  pe_rsc_trace(primary, "Allowing %s: %s %d",
333  colocation->id, pe__node_name(chosen),
334  chosen->weight);
335  primary_nodes = g_list_prepend(primary_nodes, chosen);
336  }
337  }
338  pcmk__colocation_intersect_nodes(dependent, primary, colocation,
339  primary_nodes, false);
340  g_list_free(primary_nodes);
341  return;
342  }
343 
344  // Apply optional colocations
345  for (iter = primary->children; iter != NULL; iter = iter->next) {
346  const pcmk_resource_t *instance = iter->data;
347 
348  instance->cmds->apply_coloc_score(dependent, instance, colocation,
349  false);
350  }
351 }
352 
353 // Clone implementation of pcmk_assignment_methods_t:with_this_colocations()
354 void
356  const pcmk_resource_t *orig_rsc, GList **list)
357 {
358  CRM_CHECK((rsc != NULL) && (orig_rsc != NULL) && (list != NULL), return);
359 
360  pcmk__add_with_this_list(list, rsc->rsc_cons_lhs, orig_rsc);
361 
362  if (rsc->parent != NULL) {
363  rsc->parent->cmds->with_this_colocations(rsc->parent, orig_rsc, list);
364  }
365 }
366 
367 // Clone implementation of pcmk_assignment_methods_t:this_with_colocations()
368 void
370  const pcmk_resource_t *orig_rsc, GList **list)
371 {
372  CRM_CHECK((rsc != NULL) && (orig_rsc != NULL) && (list != NULL), return);
373 
374  pcmk__add_this_with_list(list, rsc->rsc_cons, orig_rsc);
375 
376  if (rsc->parent != NULL) {
377  rsc->parent->cmds->this_with_colocations(rsc->parent, orig_rsc, list);
378  }
379 }
380 
390 uint32_t
392 {
393  CRM_ASSERT((action != NULL) && pe_rsc_is_clone(action->rsc));
394 
395  return pcmk__collective_action_flags(action, action->rsc->children, node);
396 }
397 
405 void
407 {
408  CRM_CHECK((location != NULL) && pe_rsc_is_clone(rsc), return);
409 
410  pcmk__apply_location(rsc, location);
411 
412  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
413  pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
414 
415  instance->cmds->apply_location(instance, location);
416  }
417 }
418 
419 // GFunc wrapper for calling the action_flags() resource method
420 static void
421 call_action_flags(gpointer data, gpointer user_data)
422 {
423  pcmk_resource_t *rsc = user_data;
424 
425  rsc->cmds->action_flags((pcmk_action_t *) data, NULL);
426 }
427 
434 void
436 {
437  CRM_ASSERT(pe_rsc_is_clone(rsc));
438 
439  g_list_foreach(rsc->actions, call_action_flags, rsc);
441 
442  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
443  pcmk_resource_t *child_rsc = (pcmk_resource_t *) iter->data;
444 
445  child_rsc->cmds->add_actions_to_graph(child_rsc);
446  }
447 
450 }
451 
462 static bool
463 rsc_probed_on(const pcmk_resource_t *rsc, const pcmk_node_t *node)
464 {
465  if (rsc->children != NULL) {
466  for (GList *child_iter = rsc->children; child_iter != NULL;
467  child_iter = child_iter->next) {
468 
469  pcmk_resource_t *child = (pcmk_resource_t *) child_iter->data;
470 
471  if (rsc_probed_on(child, node)) {
472  return true;
473  }
474  }
475  return false;
476  }
477 
478  if (rsc->known_on != NULL) {
479  GHashTableIter iter;
480  pcmk_node_t *known_node = NULL;
481 
482  g_hash_table_iter_init(&iter, rsc->known_on);
483  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &known_node)) {
484  if (pe__same_node(node, known_node)) {
485  return true;
486  }
487  }
488  }
489  return false;
490 }
491 
502 static pcmk_resource_t *
503 find_probed_instance_on(const pcmk_resource_t *clone, const pcmk_node_t *node)
504 {
505  for (GList *iter = clone->children; iter != NULL; iter = iter->next) {
506  pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
507 
508  if (rsc_probed_on(instance, node)) {
509  return instance;
510  }
511  }
512  return NULL;
513 }
514 
522 static bool
523 probe_anonymous_clone(pcmk_resource_t *clone, pcmk_node_t *node)
524 {
525  // Check whether we already probed an instance on this node
526  pcmk_resource_t *child = find_probed_instance_on(clone, node);
527 
528  // Otherwise, check if we plan to start an instance on this node
529  for (GList *iter = clone->children; (iter != NULL) && (child == NULL);
530  iter = iter->next) {
531  pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
532  const pcmk_node_t *instance_node = NULL;
533 
534  instance_node = instance->fns->location(instance, NULL, 0);
535  if (pe__same_node(instance_node, node)) {
536  child = instance;
537  }
538  }
539 
540  // Otherwise, use the first clone instance
541  if (child == NULL) {
542  child = clone->children->data;
543  }
544 
545  // Anonymous clones only need to probe a single instance
546  return child->cmds->create_probe(child, node);
547 }
548 
558 bool
560 {
561  CRM_ASSERT((node != NULL) && pe_rsc_is_clone(rsc));
562 
563  if (rsc->exclusive_discover) {
564  /* The clone is configured to be probed only where a location constraint
565  * exists with resource-discovery set to exclusive.
566  *
567  * This check is not strictly necessary here since the instance's
568  * create_probe() method would also check, but doing it here is more
569  * efficient (especially for unique clones with a large number of
570  * instances), and affects the CRM_meta_notify_available_uname variable
571  * passed with notify actions.
572  */
573  pcmk_node_t *allowed = g_hash_table_lookup(rsc->allowed_nodes,
574  node->details->id);
575 
576  if ((allowed == NULL)
577  || (allowed->rsc_discover_mode != pcmk_probe_exclusive)) {
578  /* This node is not marked for resource discovery. Remove it from
579  * allowed_nodes so that notifications contain only nodes that the
580  * clone can possibly run on.
581  */
582  pe_rsc_trace(rsc,
583  "Skipping probe for %s on %s because resource has "
584  "exclusive discovery but is not allowed on node",
585  rsc->id, pe__node_name(node));
586  g_hash_table_remove(rsc->allowed_nodes, node->details->id);
587  return false;
588  }
589  }
590 
591  rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance_number);
592  if (pcmk_is_set(rsc->flags, pcmk_rsc_unique)) {
593  return pcmk__probe_resource_list(rsc->children, node);
594  } else {
595  return probe_anonymous_clone(rsc, node);
596  }
597 }
598 
608 void
610 {
611  char *name = NULL;
612 
613  CRM_ASSERT(pe_rsc_is_clone(rsc) && (xml != NULL));
614 
616  crm_xml_add(xml, name, pe__rsc_bool_str(rsc, pcmk_rsc_unique));
617  free(name);
618 
620  crm_xml_add(xml, name, pe__rsc_bool_str(rsc, pcmk_rsc_notify));
621  free(name);
622 
624  crm_xml_add_int(xml, name, pe__clone_max(rsc));
625  free(name);
626 
629  free(name);
630 
632  int promoted_max = pe__clone_promoted_max(rsc);
633  int promoted_node_max = pe__clone_promoted_node_max(rsc);
634 
636  crm_xml_add_int(xml, name, promoted_max);
637  free(name);
638 
640  crm_xml_add_int(xml, name, promoted_node_max);
641  free(name);
642 
643  /* @COMPAT Maintain backward compatibility with resource agents that
644  * expect the old names (deprecated since 2.0.0).
645  */
647  crm_xml_add_int(xml, name, promoted_max);
648  free(name);
649 
651  crm_xml_add_int(xml, name, promoted_node_max);
652  free(name);
653  }
654 }
655 
656 // Clone implementation of pcmk_assignment_methods_t:add_utilization()
657 void
659  const pcmk_resource_t *orig_rsc, GList *all_rscs,
660  GHashTable *utilization)
661 {
662  bool existing = false;
663  pcmk_resource_t *child = NULL;
664 
665  CRM_ASSERT(pe_rsc_is_clone(rsc) && (orig_rsc != NULL)
666  && (utilization != NULL));
667 
668  if (!pcmk_is_set(rsc->flags, pcmk_rsc_unassigned)) {
669  return;
670  }
671 
672  // Look for any child already existing in the list
673  for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
674  child = (pcmk_resource_t *) iter->data;
675  if (g_list_find(all_rscs, child)) {
676  existing = true; // Keep checking remaining children
677  } else {
678  // If this is a clone of a group, look for group's members
679  for (GList *member_iter = child->children; member_iter != NULL;
680  member_iter = member_iter->next) {
681 
682  pcmk_resource_t *member = (pcmk_resource_t *) member_iter->data;
683 
684  if (g_list_find(all_rscs, member) != NULL) {
685  // Add *child's* utilization, not group member's
686  child->cmds->add_utilization(child, orig_rsc, all_rscs,
687  utilization);
688  existing = true;
689  break;
690  }
691  }
692  }
693  }
694 
695  if (!existing && (rsc->children != NULL)) {
696  // If nothing was found, still add first child's utilization
697  child = (pcmk_resource_t *) rsc->children->data;
698 
699  child->cmds->add_utilization(child, orig_rsc, all_rscs, utilization);
700  }
701 }
702 
703 // Clone implementation of pcmk_assignment_methods_t:shutdown_lock()
704 void
706 {
707  CRM_ASSERT(pe_rsc_is_clone(rsc));
708  return; // Clones currently don't support shutdown locks
709 }
pcmk_assignment_methods_t * cmds
Resource assignment methods.
Definition: resources.h:417
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:238
Whether resource has clone notifications enabled.
Definition: resources.h:115
#define PCMK_XA_PROMOTED_MAX_LEGACY
Definition: msg_xml.h:56
#define pcmk__order_starts(rsc1, rsc2, flags)
void pcmk__clone_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL uint32_t pcmk__collective_action_flags(pcmk_action_t *action, const GList *instances, const pcmk_node_t *node)
#define crm_notice(fmt, args...)
Definition: logging.h:383
GHashTable * known_on
Nodes where resource has been probed (key is node ID, not name)
Definition: resources.h:463
&#39;then&#39; is runnable (and migratable) only if &#39;first&#39; is runnable
pcmk_scheduler_t * cluster
Cluster that resource is part of.
Definition: resources.h:412
#define pe_rsc_debug(rsc, fmt, args...)
Definition: internal.h:36
char data[0]
Definition: cpg.c:55
#define INFINITY
Definition: crm.h:98
GList * rsc_cons
Definition: resources.h:445
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
List nodes where a resource (or any of its children) is.
Definition: resources.h:339
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition: scores.c:86
const char * name
Definition: cib.c:26
uint32_t(* action_flags)(pcmk_action_t *action, const pcmk_node_t *node)
G_GNUC_INTERNAL bool pcmk__probe_resource_list(GList *rscs, pcmk_node_t *node)
GList * children
Resource&#39;s child resources, if any.
Definition: resources.h:475
#define pcmk__order_stops(rsc1, rsc2, flags)
uint32_t pcmk__clone_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:349
gboolean exclusive_discover
Whether exclusive probing is enabled.
Definition: resources.h:433
Implementation of pcmk_action_t.
Definition: actions.h:390
#define pcmk__config_err(fmt...)
Whether node scores should be output instead of logged.
Definition: scheduler.h:158
GHashTable * meta
Resource&#39;s meta-attributes.
Definition: resources.h:471
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_compatible_instance(const pcmk_resource_t *match_rsc, const pcmk_resource_t *rsc, enum rsc_role_e role, bool current)
G_GNUC_INTERNAL void pcmk__order_promotable_instances(pcmk_resource_t *clone)
G_GNUC_INTERNAL void pcmk__create_instance_actions(pcmk_resource_t *rsc, GList *instances)
int pe__clone_max(const pcmk_resource_t *clone)
Definition: clone.c:63
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:302
Promoted.
Definition: roles.h:32
pcmk_node_t *(* assign)(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__create_promotable_actions(pcmk_resource_t *clone)
Group resource.
Definition: resources.h:35
GList * rsc_cons_lhs
Definition: resources.h:444
char * crm_meta_name(const char *field)
Definition: utils.c:468
const char * action
Definition: pcmk_fence.c:30
G_GNUC_INTERNAL bool pcmk__assign_resource(pcmk_resource_t *rsc, pcmk_node_t *node, bool force, bool stop_if_fail)
void(* add_actions_to_graph)(pcmk_resource_t *rsc)
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:64
#define PCMK_XA_PROMOTED_NODE_MAX_LEGACY
Definition: msg_xml.h:57
void(* with_this_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
void pcmk__clone_shutdown_lock(pcmk_resource_t *rsc)
int weight
Node score for a given resource.
Definition: nodes.h:131
pcmk_resource_t * parent
Resource&#39;s parent resource, if any.
Definition: resources.h:413
Whether resource is in the process of being assigned to a node.
Definition: resources.h:130
G_GNUC_INTERNAL void pcmk__add_with_this_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
unsigned int(* max_per_node)(const pcmk_resource_t *rsc)
Get maximum resource instances per node.
Definition: resources.h:395
Implementation of pcmk_resource_t.
Definition: resources.h:399
Actions are ordered (optionally, if no other flags are set)
void(* apply_location)(pcmk_resource_t *rsc, pe__location_t *location)
Primitive resource.
Definition: resources.h:34
#define PCMK_META_CLONE_MAX
Definition: msg_xml.h:64
void(* this_with_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__set_instance_roles(pcmk_resource_t *rsc)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:99
G_GNUC_INTERNAL void pcmk__add_promotion_scores(pcmk_resource_t *rsc)
struct pe_node_shared_s * details
Basic node information.
Definition: nodes.h:134
#define PCMK_ACTION_START
Definition: actions.h:71
G_GNUC_INTERNAL gint pcmk__cmp_instance(gconstpointer a, gconstpointer b)
unsigned long long flags
Group of enum pcmk_rsc_flags.
Definition: resources.h:429
void pcmk__clone_apply_location(pcmk_resource_t *rsc, pe__location_t *location)
#define PCMK_ACTION_STOP
Definition: actions.h:74
GList * actions
Definition: resources.h:447
Never probe resource on node.
Definition: nodes.h:51
void pcmk__clone_create_actions(pcmk_resource_t *rsc)
#define PCMK_META_PROMOTED_MAX
Definition: msg_xml.h:70
G_GNUC_INTERNAL void pcmk__assign_instances(pcmk_resource_t *collective, GList *instances, int max_total, int max_per_node)
G_GNUC_INTERNAL gint pcmk__cmp_instance_number(gconstpointer a, gconstpointer b)
Whether resource is blocked from further action.
Definition: resources.h:109
Implementation of pcmk_node_t.
Definition: nodes.h:130
bool is_set_recursive(const pcmk_resource_t *rsc, long long flag, bool any)
Definition: clone.c:558
enum pe_obj_types variant
Resource variant.
Definition: resources.h:414
#define PCMK_META_PROMOTED_NODE_MAX
Definition: msg_xml.h:71
bool(* create_probe)(pcmk_resource_t *rsc, pcmk_node_t *node)
int pe__clone_promoted_node_max(const pcmk_resource_t *clone)
Definition: clone.c:114
int pe__clone_promoted_max(const pcmk_resource_t *clone)
Definition: clone.c:97
int rsc_discover_mode
Probe mode (enum pe_discover_e)
Definition: nodes.h:137
void pcmk__clone_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
#define XML_RSC_ATTR_NOTIFY
Definition: msg_xml.h:251
G_GNUC_INTERNAL void pcmk__apply_location(pcmk_resource_t *rsc, pe__location_t *constraint)
const char * id
Node ID at the cluster layer.
Definition: nodes.h:67
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
void(* apply_coloc_score)(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
#define XML_RSC_ATTR_UNIQUE
Definition: msg_xml.h:250
pcmk_resource_t * primary
G_GNUC_INTERNAL void pcmk__add_rsc_actions_to_graph(pcmk_resource_t *rsc)
Whether resource has not yet been assigned to a node.
Definition: resources.h:127
pcmk_node_t * pcmk__clone_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__update_dependent_with_promotable(const pcmk_resource_t *primary, pcmk_resource_t *dependent, const pcmk__colocation_t *colocation)
Update dependent for a colocation with a promotable clone.
If &#39;then&#39; is required, &#39;first&#39; must be added to the transition graph.
void pe__create_clone_notifications(pcmk_resource_t *clone)
Definition: clone.c:1426
G_GNUC_INTERNAL GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_dependent_scores(gpointer data, gpointer user_data)
void(* internal_constraints)(pcmk_resource_t *rsc)
pcmk_rsc_methods_t * fns
Resource object methods.
Definition: resources.h:416
void pcmk__clone_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void pe__free_clone_notification_data(pcmk_resource_t *clone)
Definition: clone.c:1445
G_GNUC_INTERNAL void pcmk__add_this_with_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
void pcmk__clone_add_graph_meta(const pcmk_resource_t *rsc, xmlNode *xml)
#define CRM_ASSERT(expr)
Definition: results.h:42
If &#39;first&#39; is required and runnable, &#39;then&#39; must be in graph.
#define PCMK_ACTION_STOPPED
Definition: actions.h:75
G_GNUC_INTERNAL GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
void pcmk__clone_add_actions_to_graph(pcmk_resource_t *rsc)
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:70
void pcmk__with_clone_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
#define PCMK_ACTION_PROMOTE
Definition: actions.h:65
pcmk_resource_t * dependent
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
Definition: internal.h:341
int pe__clone_node_max(const pcmk_resource_t *clone)
Definition: clone.c:80
#define PCMK_META_CLONE_NODE_MAX
Definition: msg_xml.h:66
gboolean crm_is_true(const char *s)
Definition: strings.c:416
Whether resource can be promoted and demoted.
Definition: resources.h:124
Resource role is unknown.
Definition: roles.h:28
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:37
bool pe__clone_is_ordered(const pcmk_resource_t *clone)
Definition: clone.c:1300
#define PCMK_ACTION_RUNNING
Definition: actions.h:70
unsigned long long flags
Group of enum pcmk_scheduler_flags.
Definition: scheduler.h:183
#define XML_RSC_ATTR_INTERLEAVE
Definition: msg_xml.h:245
#define PCMK_ACTION_DEMOTED
Definition: actions.h:50
G_GNUC_INTERNAL void pcmk__update_promotable_dependent_priority(const pcmk_resource_t *primary, pcmk_resource_t *dependent, const pcmk__colocation_t *colocation)
void(* add_utilization)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL void pcmk__colocation_intersect_nodes(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, const GList *primary_nodes, bool merge_scores)
Whether resource is not an anonymous clone instance.
Definition: resources.h:118
bool pcmk__clone_create_probe(pcmk_resource_t *rsc, pcmk_node_t *node)
char * id
Resource ID in configuration.
Definition: resources.h:400
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
Definition: resources.h:466
void pcmk__clone_internal_constraints(pcmk_resource_t *rsc)