pacemaker  2.1.2-ada5c3b36
Scalable High-Availability cluster resource manager
pcmk_sched_group.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2021 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 <stdbool.h>
13 
14 #include <crm/msg_xml.h>
15 
16 #include <pacemaker-internal.h>
17 
18 #include "libpacemaker_private.h"
19 
20 #define VARIANT_GROUP 1
21 #include <lib/pengine/variant.h>
22 
29 static void
30 expand_group_colocations(pe_resource_t *rsc)
31 {
32  group_variant_data_t *group_data = NULL;
33  pe_resource_t *member = NULL;
34  bool any_unmanaged = false;
35 
36  get_group_variant_data(group_data, rsc);
37 
38  // Treat "group with R" colocations as "first member with R"
39  member = group_data->first_child;
40  member->rsc_cons = g_list_concat(member->rsc_cons, rsc->rsc_cons);
41 
42 
43  /* The above works for the whole group because each group member is
44  * colocated with the previous one.
45  *
46  * However, there is a special case when a group has a mandatory colocation
47  * with a resource that can't start. In that case,
48  * pcmk__block_colocated_starts() will ensure that dependent resources in
49  * mandatory colocations (i.e. the first member for groups) can't start
50  * either. But if any group member is unmanaged and already started, the
51  * internal group colocations are no longer sufficient to make that apply to
52  * later members.
53  *
54  * To handle that case, add mandatory colocations to each member after the
55  * first.
56  */
57  any_unmanaged = !pcmk_is_set(member->flags, pe_rsc_managed);
58  for (GList *item = rsc->children->next; item != NULL; item = item->next) {
59  member = item->data;
60  if (any_unmanaged) {
61  for (GList *cons_iter = rsc->rsc_cons; cons_iter != NULL;
62  cons_iter = cons_iter->next) {
63 
64  pcmk__colocation_t *constraint = (pcmk__colocation_t *) cons_iter->data;
65 
66  if (constraint->score == INFINITY) {
67  member->rsc_cons = g_list_prepend(member->rsc_cons, constraint);
68  }
69  }
70  } else if (!pcmk_is_set(member->flags, pe_rsc_managed)) {
71  any_unmanaged = true;
72  }
73  }
74 
75  rsc->rsc_cons = NULL;
76 
77  // Treat "R with group" colocations as "R with last member"
78  member = group_data->last_child;
79  member->rsc_cons_lhs = g_list_concat(member->rsc_cons_lhs,
80  rsc->rsc_cons_lhs);
81  rsc->rsc_cons_lhs = NULL;
82 }
83 
84 pe_node_t *
86  pe_working_set_t *data_set)
87 {
88  pe_node_t *node = NULL;
89  pe_node_t *group_node = NULL;
90  GList *gIter = NULL;
91  group_variant_data_t *group_data = NULL;
92 
93  get_group_variant_data(group_data, rsc);
94 
95  if (!pcmk_is_set(rsc->flags, pe_rsc_provisional)) {
96  return rsc->allocated_to;
97  }
98  if (pcmk_is_set(rsc->flags, pe_rsc_allocating)) {
99  pe_rsc_debug(rsc, "Dependency loop detected involving %s", rsc->id);
100  return NULL;
101  }
102 
103  if (group_data->first_child == NULL) {
104  // Nothing to allocate
106  return NULL;
107  }
108 
110  rsc->role = group_data->first_child->role;
111 
112  expand_group_colocations(rsc);
113 
115  rsc, __func__, rsc->allowed_nodes, data_set);
116 
117  gIter = rsc->children;
118  for (; gIter != NULL; gIter = gIter->next) {
119  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
120 
121  pe_rsc_trace(rsc, "Allocating group %s member %s",
122  rsc->id, child_rsc->id);
123  node = child_rsc->cmds->allocate(child_rsc, prefer, data_set);
124  if (group_node == NULL) {
125  group_node = node;
126  }
127  }
128 
129  pe__set_next_role(rsc, group_data->first_child->next_role,
130  "first group member");
132 
133  if (group_data->colocated) {
134  return group_node;
135  }
136  return NULL;
137 }
138 
140 
141 void
143 {
144  pe_action_t *op = NULL;
145  const char *value = NULL;
146  GList *gIter = rsc->children;
147 
148  pe_rsc_trace(rsc, "Creating actions for %s", rsc->id);
149 
150  for (; gIter != NULL; gIter = gIter->next) {
151  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
152 
153  child_rsc->cmds->create_actions(child_rsc, data_set);
154  group_update_pseudo_status(rsc, child_rsc);
155  }
156 
157  op = start_action(rsc, NULL, TRUE /* !group_data->child_starting */ );
159 
160  op = custom_action(rsc, started_key(rsc),
161  RSC_STARTED, NULL, TRUE /* !group_data->child_starting */ , TRUE, data_set);
163 
164  op = stop_action(rsc, NULL, TRUE /* !group_data->child_stopping */ );
166 
167  op = custom_action(rsc, stopped_key(rsc),
168  RSC_STOPPED, NULL, TRUE /* !group_data->child_stopping */ , TRUE, data_set);
170 
171  value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_PROMOTABLE);
172  if (crm_is_true(value)) {
173  op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set);
175 
176  op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set);
178 
179  op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set);
181 
182  op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set);
184  }
185 }
186 
187 void
189 {
190  GList *gIter = child->actions;
191  group_variant_data_t *group_data = NULL;
192 
193  get_group_variant_data(group_data, parent);
194 
195  if (group_data->ordered == FALSE) {
196  /* If this group is not ordered, then leave the meta-actions as optional */
197  return;
198  }
199 
200  if (group_data->child_stopping && group_data->child_starting) {
201  return;
202  }
203 
204  for (; gIter != NULL; gIter = gIter->next) {
205  pe_action_t *action = (pe_action_t *) gIter->data;
206 
207  if (pcmk_is_set(action->flags, pe_action_optional)) {
208  continue;
209  }
210  if (pcmk__str_eq(RSC_STOP, action->task, pcmk__str_casei)
211  && pcmk_is_set(action->flags, pe_action_runnable)) {
212 
213  group_data->child_stopping = TRUE;
214  pe_rsc_trace(action->rsc, "Based on %s the group is stopping", action->uuid);
215 
216  } else if (pcmk__str_eq(RSC_START, action->task, pcmk__str_casei)
217  && pcmk_is_set(action->flags, pe_action_runnable)) {
218  group_data->child_starting = TRUE;
219  pe_rsc_trace(action->rsc, "Based on %s the group is starting", action->uuid);
220  }
221  }
222 }
223 
224 void
226 {
227  GList *gIter = rsc->children;
228  pe_resource_t *last_rsc = NULL;
229  pe_resource_t *last_active = NULL;
230  pe_resource_t *top = uber_parent(rsc);
231  group_variant_data_t *group_data = NULL;
232 
233  get_group_variant_data(group_data, rsc);
234 
236  pe_order_optional, data_set);
238  pe_order_runnable_left, data_set);
240  pe_order_runnable_left, data_set);
241 
242  for (; gIter != NULL; gIter = gIter->next) {
243  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
244  int stop = pe_order_none;
245  int stopped = pe_order_implies_then_printed;
247  int started =
249 
250  child_rsc->cmds->internal_constraints(child_rsc, data_set);
251 
252  if (last_rsc == NULL) {
253  if (group_data->ordered) {
255  stopped = pe_order_implies_then;
256  }
257 
258  } else if (group_data->colocated) {
259  pcmk__new_colocation("group:internal_colocation", NULL, INFINITY,
260  child_rsc, last_rsc, NULL, NULL,
261  pcmk_is_set(child_rsc->flags, pe_rsc_critical),
262  data_set);
263  }
264 
265  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
268  data_set);
269 
271  RSC_DEMOTED, stopped, data_set);
272 
274  RSC_PROMOTED, started, data_set);
275 
277  RSC_PROMOTE,
279  data_set);
280 
281  }
282 
284  data_set);
285  pcmk__order_stops(rsc, child_rsc,
286  stop|pe_order_implies_first_printed, data_set);
287 
289  stopped, data_set);
291  started, data_set);
292 
293  if (group_data->ordered == FALSE) {
294  pcmk__order_starts(rsc, child_rsc,
295  start|pe_order_implies_first_printed, data_set);
296  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
298  RSC_PROMOTE,
300  data_set);
301  }
302 
303  } else if (last_rsc != NULL) {
304  pcmk__order_starts(last_rsc, child_rsc, start, data_set);
305  pcmk__order_stops(child_rsc, last_rsc,
307 
308  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
309  pcmk__order_resource_actions(last_rsc, RSC_PROMOTE, child_rsc,
310  RSC_PROMOTE, start, data_set);
311  pcmk__order_resource_actions(child_rsc, RSC_DEMOTE, last_rsc,
313  data_set);
314  }
315 
316  } else {
317  pcmk__order_starts(rsc, child_rsc, pe_order_none, data_set);
318  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
321  data_set);
322  }
323  }
324 
325  /* Look for partially active groups
326  * Make sure they still shut down in sequence
327  */
328  if (child_rsc->running_on) {
329  if (group_data->ordered
330  && last_rsc
331  && last_rsc->running_on == NULL && last_active && last_active->running_on) {
332  pcmk__order_stops(child_rsc, last_active, pe_order_optional,
333  data_set);
334  }
335  last_active = child_rsc;
336  }
337 
338  last_rsc = child_rsc;
339  }
340 
341  if (group_data->ordered && last_rsc != NULL) {
342  int stop_stop_flags = pe_order_implies_then;
343  int stop_stopped_flags = pe_order_optional;
344 
345  pcmk__order_stops(rsc, last_rsc, stop_stop_flags, data_set);
347  stop_stopped_flags, data_set);
348 
349  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
351  stop_stop_flags, data_set);
353  stop_stopped_flags, data_set);
354  }
355  }
356 }
357 
358 void
360  pcmk__colocation_t *constraint,
361  pe_working_set_t *data_set)
362 {
363  GList *gIter = NULL;
364  group_variant_data_t *group_data = NULL;
365 
366  if (dependent == NULL) {
367  pe_err("dependent was NULL for %s", constraint->id);
368  return;
369 
370  } else if (primary == NULL) {
371  pe_err("primary was NULL for %s", constraint->id);
372  return;
373  }
374 
375  gIter = dependent->children;
376  pe_rsc_trace(dependent, "Processing constraints from %s", dependent->id);
377 
378  get_group_variant_data(group_data, dependent);
379 
380  if (group_data->colocated) {
381  group_data->first_child->cmds->rsc_colocation_lh(group_data->first_child,
382  primary, constraint,
383  data_set);
384  return;
385 
386  } else if (constraint->score >= INFINITY) {
387  pcmk__config_err("%s: Cannot perform mandatory colocation "
388  "between non-colocated group and %s",
389  dependent->id, primary->id);
390  return;
391  }
392 
393  for (; gIter != NULL; gIter = gIter->next) {
394  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
395 
396  child_rsc->cmds->rsc_colocation_lh(child_rsc, primary, constraint,
397  data_set);
398  }
399 }
400 
401 void
403  pcmk__colocation_t *constraint,
404  pe_working_set_t *data_set)
405 {
406  GList *gIter = primary->children;
407  group_variant_data_t *group_data = NULL;
408 
409  get_group_variant_data(group_data, primary);
410  CRM_CHECK(dependent->variant == pe_native, return);
411 
412  pe_rsc_trace(primary, "Processing RH %s of constraint %s (LH is %s)",
413  primary->id, constraint->id, dependent->id);
414 
415  if (pcmk_is_set(primary->flags, pe_rsc_provisional)) {
416  return;
417 
418  } else if (group_data->colocated && group_data->first_child) {
419  if (constraint->score >= INFINITY) {
420  /* Ensure RHS is _fully_ up before can start LHS */
421  group_data->last_child->cmds->rsc_colocation_rh(dependent,
422  group_data->last_child,
423  constraint,
424  data_set);
425  } else {
426  /* A partially active RHS is fine */
427  group_data->first_child->cmds->rsc_colocation_rh(dependent,
428  group_data->first_child,
429  constraint,
430  data_set);
431  }
432 
433  return;
434 
435  } else if (constraint->score >= INFINITY) {
436  pcmk__config_err("%s: Cannot perform mandatory colocation with"
437  " non-colocated group %s", dependent->id, primary->id);
438  return;
439  }
440 
441  for (; gIter != NULL; gIter = gIter->next) {
442  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
443 
444  child_rsc->cmds->rsc_colocation_rh(dependent, child_rsc, constraint,
445  data_set);
446  }
447 }
448 
449 enum pe_action_flags
451 {
452  GList *gIter = NULL;
454 
455  for (gIter = action->rsc->children; gIter != NULL; gIter = gIter->next) {
456  pe_resource_t *child = (pe_resource_t *) gIter->data;
457  enum action_tasks task = get_complex_task(child, action->task, TRUE);
458  const char *task_s = task2text(task);
459  pe_action_t *child_action = find_first_action(child->actions, NULL, task_s, node);
460 
461  if (child_action) {
462  enum pe_action_flags child_flags = child->cmds->action_flags(child_action, node);
463 
465  && !pcmk_is_set(child_flags, pe_action_optional)) {
466  pe_rsc_trace(action->rsc, "%s is mandatory because of %s", action->uuid,
467  child_action->uuid);
468  pe__clear_raw_action_flags(flags, "group action",
471  }
472  if (!pcmk__str_eq(task_s, action->task, pcmk__str_casei)
474  && !pcmk_is_set(child_flags, pe_action_runnable)) {
475 
476  pe_rsc_trace(action->rsc, "%s is not runnable because of %s", action->uuid,
477  child_action->uuid);
478  pe__clear_raw_action_flags(flags, "group action",
481  }
482 
483  } else if (task != stop_rsc && task != action_demote) {
484  pe_rsc_trace(action->rsc, "%s is not runnable because of %s (not found in %s)",
485  action->uuid, task_s, child->id);
486  pe__clear_raw_action_flags(flags, "group action",
488  }
489  }
490 
491  return flags;
492 }
493 
494 enum pe_graph_flags
496  enum pe_action_flags flags, enum pe_action_flags filter,
497  enum pe_ordering type, pe_working_set_t *data_set)
498 {
499  GList *gIter = then->rsc->children;
500  enum pe_graph_flags changed = pe_graph_none;
501 
502  CRM_ASSERT(then->rsc != NULL);
503  changed |= native_update_actions(first, then, node, flags, filter, type,
504  data_set);
505 
506  for (; gIter != NULL; gIter = gIter->next) {
507  pe_resource_t *child = (pe_resource_t *) gIter->data;
508  pe_action_t *child_action = find_first_action(child->actions, NULL, then->task, node);
509 
510  if (child_action) {
511  changed |= child->cmds->update_actions(first, child_action, node,
512  flags, filter, type,
513  data_set);
514  }
515  }
516 
517  return changed;
518 }
519 
520 void
522 {
523  GList *gIter = rsc->children;
524  GList *saved = constraint->node_list_rh;
525  GList *zero = pcmk__copy_node_list(constraint->node_list_rh, true);
526  gboolean reset_scores = TRUE;
527  group_variant_data_t *group_data = NULL;
528 
529  get_group_variant_data(group_data, rsc);
530 
531  pe_rsc_debug(rsc, "Processing rsc_location %s for %s", constraint->id, rsc->id);
532 
533  pcmk__apply_location(constraint, rsc);
534 
535  for (; gIter != NULL; gIter = gIter->next) {
536  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
537 
538  child_rsc->cmds->rsc_location(child_rsc, constraint);
539  if (group_data->colocated && reset_scores) {
540  reset_scores = FALSE;
541  constraint->node_list_rh = zero;
542  }
543  }
544 
545  constraint->node_list_rh = saved;
546  g_list_free_full(zero, free);
547 }
548 
549 void
551 {
552  CRM_CHECK(rsc != NULL, return);
553 
554  pe_rsc_trace(rsc, "Processing actions from %s", rsc->id);
555  native_expand(rsc, data_set);
556 
557  for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
558  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
559 
560  child_rsc->cmds->expand(child_rsc, data_set);
561  }
562 }
563 
564 GHashTable *
565 pcmk__group_merge_weights(pe_resource_t *rsc, const char *primary_id,
566  GHashTable *nodes, const char *attr, float factor,
567  uint32_t flags)
568 {
569  GList *gIter = rsc->rsc_cons_lhs;
570  group_variant_data_t *group_data = NULL;
571 
572  get_group_variant_data(group_data, rsc);
573 
574  if (pcmk_is_set(rsc->flags, pe_rsc_merging)) {
575  pe_rsc_info(rsc, "Breaking dependency loop with %s at %s",
576  rsc->id, primary_id);
577  return nodes;
578  }
579 
581 
582  nodes = group_data->first_child->cmds->merge_weights(group_data->first_child,
583  primary_id, nodes,
584  attr, factor, flags);
585 
586  for (; gIter != NULL; gIter = gIter->next) {
587  pcmk__colocation_t *constraint = (pcmk__colocation_t *) gIter->data;
588 
589  nodes = pcmk__native_merge_weights(constraint->dependent, rsc->id,
590  nodes, constraint->node_attribute,
591  constraint->score / (float) INFINITY,
592  flags);
593  }
594 
596  return nodes;
597 }
598 
599 void
600 group_append_meta(pe_resource_t * rsc, xmlNode * xml)
601 {
602 }
603 
604 // Group implementation of resource_alloc_functions_t:colocated_resources()
605 GList *
607  GList *colocated_rscs)
608 {
609  pe_resource_t *child_rsc = NULL;
610  group_variant_data_t *group_data = NULL;
611 
612  get_group_variant_data(group_data, rsc);
613 
614  if (orig_rsc == NULL) {
615  orig_rsc = rsc;
616  }
617 
618  if (group_data->colocated || pe_rsc_is_clone(rsc->parent)) {
619  /* This group has colocated members and/or is cloned -- either way,
620  * add every child's colocated resources to the list.
621  */
622  for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
623  child_rsc = (pe_resource_t *) gIter->data;
624  colocated_rscs = child_rsc->cmds->colocated_resources(child_rsc,
625  orig_rsc,
626  colocated_rscs);
627  }
628 
629  } else if (group_data->first_child != NULL) {
630  /* This group's members are not colocated, and the group is not cloned,
631  * so just add the first child's colocations to the list.
632  */
633  child_rsc = group_data->first_child;
634  colocated_rscs = child_rsc->cmds->colocated_resources(child_rsc,
635  orig_rsc,
636  colocated_rscs);
637  }
638 
639  // Now consider colocations where the group itself is specified
640  colocated_rscs = pcmk__colocated_resources(rsc, orig_rsc, colocated_rscs);
641 
642  return colocated_rscs;
643 }
GList * pcmk__copy_node_list(const GList *list, bool reset)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:225
const char * task2text(enum action_tasks task)
Definition: common.c:406
#define RSC_STOP
Definition: crm.h:204
#define pe_rsc_debug(rsc, fmt, args...)
Definition: internal.h:19
#define INFINITY
Definition: crm.h:99
GList * rsc_cons
Definition: pe_types.h:357
#define pe__set_action_flags(action, flags_to_set)
Definition: internal.h:59
#define demoted_key(rsc)
Definition: internal.h:407
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
Definition: internal.h:353
G_GNUC_INTERNAL GList * pcmk__colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
#define pcmk__order_starts(rsc1, rsc2, type, data_set)
#define stop_action(rsc, node, optional)
Definition: internal.h:377
enum rsc_role_e role
Definition: pe_types.h:370
GList * children
Definition: pe_types.h:377
#define stopped_key(rsc)
Definition: internal.h:371
resource_alloc_functions_t * cmds
Definition: pe_types.h:334
enum pe_graph_flags(* update_actions)(pe_action_t *, pe_action_t *, pe_node_t *, enum pe_action_flags, enum pe_action_flags, enum pe_ordering, pe_working_set_t *data_set)
pe_resource_t * rsc
Definition: pe_types.h:410
enum rsc_role_e next_role
Definition: pe_types.h:371
#define pcmk__config_err(fmt...)
GHashTable * meta
Definition: pe_types.h:373
void group_rsc_colocation_lh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
pe_resource_t * dependent
#define pe_rsc_critical
Definition: pe_types.h:265
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
#define pcmk__order_stops(rsc1, rsc2, type, data_set)
GHashTable * pcmk__group_merge_weights(pe_resource_t *rsc, const char *primary_id, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
void(* internal_constraints)(pe_resource_t *, pe_working_set_t *)
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)
GList * rsc_cons_lhs
Definition: pe_types.h:356
void native_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
enum crm_ais_msg_types type
Definition: cpg.c:48
#define demote_key(rsc)
Definition: internal.h:402
#define RSC_START
Definition: crm.h:201
pe_node_t *(* allocate)(pe_resource_t *, pe_node_t *, pe_working_set_t *)
pe_node_t * allocated_to
Definition: pe_types.h:363
GHashTable * pcmk__native_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
const char * action
Definition: pcmk_fence.c:30
G_GNUC_INTERNAL void pcmk__new_colocation(const char *id, const char *node_attr, int score, pe_resource_t *dependent, pe_resource_t *primary, const char *dependent_role, const char *primary_role, bool influence, pe_working_set_t *data_set)
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:47
void group_update_pseudo_status(pe_resource_t *parent, pe_resource_t *child)
#define pe_rsc_provisional
Definition: pe_types.h:258
#define XML_RSC_ATTR_PROMOTABLE
Definition: msg_xml.h:229
#define pe_rsc_merging
Definition: pe_types.h:260
pe_action_flags
Definition: pe_types.h:291
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:903
void group_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void(* rsc_colocation_lh)(pe_resource_t *, pe_resource_t *, pcmk__colocation_t *, pe_working_set_t *)
GList * pcmk__group_colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
char * task
Definition: pe_types.h:414
#define pe__clear_action_flags(action, flags_to_clear)
Definition: internal.h:68
enum action_tasks get_complex_task(pe_resource_t *rsc, const char *name, gboolean allow_non_atomic)
Definition: utils.c:1517
GList *(* colocated_resources)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
#define promote_key(rsc)
Definition: internal.h:392
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:114
unsigned long long flags
Definition: pe_types.h:348
#define pe_rsc_promotable
Definition: pe_types.h:256
void(* expand)(pe_resource_t *, pe_working_set_t *)
#define pcmk__order_resource_actions(lh_rsc, lh_task, rh_rsc, rh_task, flags, data_set)
#define started_key(rsc)
Definition: internal.h:387
GList * actions
Definition: pe_types.h:359
pe_graph_flags
Definition: pe_types.h:283
void group_rsc_colocation_rh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
char * uuid
Definition: pe_types.h:415
void(* rsc_colocation_rh)(pe_resource_t *, pe_resource_t *, pcmk__colocation_t *, pe_working_set_t *)
void group_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
enum pe_action_flags(* action_flags)(pe_action_t *, pe_node_t *)
#define pe_rsc_allocating
Definition: pe_types.h:259
enum pe_obj_types variant
Definition: pe_types.h:331
#define RSC_DEMOTED
Definition: crm.h:210
#define promoted_key(rsc)
Definition: internal.h:397
#define RSC_STARTED
Definition: crm.h:202
#define start_action(rsc, node, optional)
Definition: internal.h:383
#define CRM_ASSERT(expr)
Definition: results.h:42
pe_node_t * pcmk__group_allocate(pe_resource_t *rsc, pe_node_t *prefer, pe_working_set_t *data_set)
#define RSC_PROMOTE
Definition: crm.h:207
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition: complex.c:1116
void(* rsc_location)(pe_resource_t *, pe__location_t *)
void group_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:53
GList * running_on
Definition: pe_types.h:366
void(* create_actions)(pe_resource_t *, pe_working_set_t *)
void group_append_meta(pe_resource_t *rsc, xmlNode *xml)
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)
const char * node_attribute
#define RSC_STOPPED
Definition: crm.h:205
#define RSC_PROMOTED
Definition: crm.h:208
gboolean crm_is_true(const char *s)
Definition: strings.c:416
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:20
#define pe__set_order_flags(order_flags, flags_to_set)
Definition: internal.h:111
unsigned long long flags
Definition: pe_types.h:146
#define pe_err(fmt...)
Definition: internal.h:22
#define pe_flag_show_scores
Definition: pe_types.h:133
#define pe__clear_raw_action_flags(action_flags, action_name, flags_to_clear)
Definition: internal.h:84
#define pe_rsc_managed
Definition: pe_types.h:249
pe_action_t * find_first_action(GList *input, const char *uuid, const char *task, pe_node_t *on_node)
Definition: utils.c:1540
pe_ordering
Definition: pe_types.h:483
G_GNUC_INTERNAL void pcmk__apply_location(pe__location_t *constraint, pe_resource_t *rsc)
uint64_t flags
Definition: remote.c:149
action_tasks
Definition: common.h:62
pe_resource_t * parent
Definition: pe_types.h:329
#define RSC_DEMOTE
Definition: crm.h:209
#define pe_rsc_info(rsc, fmt, args...)
Definition: internal.h:18
char * id
Definition: pe_types.h:322
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:731
GHashTable * allowed_nodes
Definition: pe_types.h:368
enum pe_action_flags group_action_flags(pe_action_t *action, pe_node_t *node)