pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
pcmk_sched_group.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2020 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 
14 #include <pacemaker-internal.h>
15 
16 #define VARIANT_GROUP 1
17 #include <lib/pengine/variant.h>
18 
19 pe_node_t *
21  pe_working_set_t *data_set)
22 {
23  pe_node_t *node = NULL;
24  pe_node_t *group_node = NULL;
25  GListPtr gIter = NULL;
26  group_variant_data_t *group_data = NULL;
27 
28  get_group_variant_data(group_data, rsc);
29 
30  if (!pcmk_is_set(rsc->flags, pe_rsc_provisional)) {
31  return rsc->allocated_to;
32  }
33  if (pcmk_is_set(rsc->flags, pe_rsc_allocating)) {
34  pe_rsc_debug(rsc, "Dependency loop detected involving %s", rsc->id);
35  return NULL;
36  }
37 
38  if (group_data->first_child == NULL) {
39  // Nothing to allocate
41  return NULL;
42  }
43 
45  rsc->role = group_data->first_child->role;
46 
47  group_data->first_child->rsc_cons =
48  g_list_concat(group_data->first_child->rsc_cons, rsc->rsc_cons);
49  rsc->rsc_cons = NULL;
50 
51  group_data->last_child->rsc_cons_lhs =
52  g_list_concat(group_data->last_child->rsc_cons_lhs, rsc->rsc_cons_lhs);
53  rsc->rsc_cons_lhs = NULL;
54 
55  pe__show_node_weights(!show_scores, rsc, __func__, rsc->allowed_nodes);
56 
57  gIter = rsc->children;
58  for (; gIter != NULL; gIter = gIter->next) {
59  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
60 
61  pe_rsc_trace(rsc, "Allocating group %s member %s",
62  rsc->id, child_rsc->id);
63  node = child_rsc->cmds->allocate(child_rsc, prefer, data_set);
64  if (group_node == NULL) {
65  group_node = node;
66  }
67  }
68 
69  rsc->next_role = group_data->first_child->next_role;
71 
72  if (group_data->colocated) {
73  return group_node;
74  }
75  return NULL;
76 }
77 
79 
80 void
82 {
83  pe_action_t *op = NULL;
84  const char *value = NULL;
85  GListPtr gIter = rsc->children;
86 
87  pe_rsc_trace(rsc, "Creating actions for %s", rsc->id);
88 
89  for (; gIter != NULL; gIter = gIter->next) {
90  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
91 
92  child_rsc->cmds->create_actions(child_rsc, data_set);
93  group_update_pseudo_status(rsc, child_rsc);
94  }
95 
96  op = start_action(rsc, NULL, TRUE /* !group_data->child_starting */ );
98 
99  op = custom_action(rsc, started_key(rsc),
100  RSC_STARTED, NULL, TRUE /* !group_data->child_starting */ , TRUE, data_set);
102 
103  op = stop_action(rsc, NULL, TRUE /* !group_data->child_stopping */ );
105 
106  op = custom_action(rsc, stopped_key(rsc),
107  RSC_STOPPED, NULL, TRUE /* !group_data->child_stopping */ , TRUE, data_set);
109 
110  value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_PROMOTABLE);
111  if (crm_is_true(value)) {
112  op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set);
114 
115  op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set);
117 
118  op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set);
120 
121  op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set);
123  }
124 }
125 
126 void
128 {
129  GListPtr gIter = child->actions;
130  group_variant_data_t *group_data = NULL;
131 
132  get_group_variant_data(group_data, parent);
133 
134  if (group_data->ordered == FALSE) {
135  /* If this group is not ordered, then leave the meta-actions as optional */
136  return;
137  }
138 
139  if (group_data->child_stopping && group_data->child_starting) {
140  return;
141  }
142 
143  for (; gIter != NULL; gIter = gIter->next) {
144  pe_action_t *action = (pe_action_t *) gIter->data;
145 
146  if (pcmk_is_set(action->flags, pe_action_optional)) {
147  continue;
148  }
149  if (pcmk__str_eq(RSC_STOP, action->task, pcmk__str_casei)
150  && pcmk_is_set(action->flags, pe_action_runnable)) {
151 
152  group_data->child_stopping = TRUE;
153  pe_rsc_trace(action->rsc, "Based on %s the group is stopping", action->uuid);
154 
155  } else if (pcmk__str_eq(RSC_START, action->task, pcmk__str_casei)
156  && pcmk_is_set(action->flags, pe_action_runnable)) {
157  group_data->child_starting = TRUE;
158  pe_rsc_trace(action->rsc, "Based on %s the group is starting", action->uuid);
159  }
160  }
161 }
162 
163 void
165 {
166  GListPtr gIter = rsc->children;
167  pe_resource_t *last_rsc = NULL;
168  pe_resource_t *last_active = NULL;
169  pe_resource_t *top = uber_parent(rsc);
170  group_variant_data_t *group_data = NULL;
171 
172  get_group_variant_data(group_data, rsc);
173 
174  new_rsc_order(rsc, RSC_STOPPED, rsc, RSC_START, pe_order_optional, data_set);
177 
178  for (; gIter != NULL; gIter = gIter->next) {
179  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
180  int stop = pe_order_none;
181  int stopped = pe_order_implies_then_printed;
183  int started =
185 
186  child_rsc->cmds->internal_constraints(child_rsc, data_set);
187 
188  if (last_rsc == NULL) {
189  if (group_data->ordered) {
191  stopped = pe_order_implies_then;
192  }
193 
194  } else if (group_data->colocated) {
195  rsc_colocation_new("group:internal_colocation", NULL, INFINITY,
196  child_rsc, last_rsc, NULL, NULL, data_set);
197  }
198 
199  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
200  new_rsc_order(rsc, RSC_DEMOTE, child_rsc, RSC_DEMOTE,
201  stop | pe_order_implies_first_printed, data_set);
202 
203  new_rsc_order(child_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stopped, data_set);
204 
205  new_rsc_order(child_rsc, RSC_PROMOTE, rsc, RSC_PROMOTED, started, data_set);
206 
207  new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE,
209 
210  }
211 
213  order_stop_stop(rsc, child_rsc, stop | pe_order_implies_first_printed);
214 
215  new_rsc_order(child_rsc, RSC_STOP, rsc, RSC_STOPPED, stopped, data_set);
216 
217  new_rsc_order(child_rsc, RSC_START, rsc, RSC_STARTED, started, data_set);
218 
219  if (group_data->ordered == FALSE) {
220  order_start_start(rsc, child_rsc, start | pe_order_implies_first_printed);
221  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
222  new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE,
223  start | pe_order_implies_first_printed, data_set);
224  }
225 
226  } else if (last_rsc != NULL) {
227  child_rsc->restart_type = pe_restart_restart;
228 
229  order_start_start(last_rsc, child_rsc, start);
230  order_stop_stop(child_rsc, last_rsc, pe_order_optional | pe_order_restart);
231 
232  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
233  new_rsc_order(last_rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, start, data_set);
234  new_rsc_order(child_rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, pe_order_optional,
235  data_set);
236  }
237 
238  } else {
239  /* If anyone in the group is starting, then
240  * pe_order_implies_then will cause _everyone_ in the group
241  * to be sent a start action
242  * But this is safe since starting something that is already
243  * started is required to be "safe"
244  */
245  int flags = pe_order_none;
246 
247  order_start_start(rsc, child_rsc, flags);
248  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
249  new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, flags, data_set);
250  }
251 
252  }
253 
254  /* Look for partially active groups
255  * Make sure they still shut down in sequence
256  */
257  if (child_rsc->running_on) {
258  if (group_data->ordered
259  && last_rsc
260  && last_rsc->running_on == NULL && last_active && last_active->running_on) {
261  order_stop_stop(child_rsc, last_active, pe_order_optional);
262  }
263  last_active = child_rsc;
264  }
265 
266  last_rsc = child_rsc;
267  }
268 
269  if (group_data->ordered && last_rsc != NULL) {
270  int stop_stop_flags = pe_order_implies_then;
271  int stop_stopped_flags = pe_order_optional;
272 
273  order_stop_stop(rsc, last_rsc, stop_stop_flags);
274  new_rsc_order(last_rsc, RSC_STOP, rsc, RSC_STOPPED, stop_stopped_flags, data_set);
275 
276  if (pcmk_is_set(top->flags, pe_rsc_promotable)) {
277  new_rsc_order(rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, stop_stop_flags, data_set);
278  new_rsc_order(last_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stop_stopped_flags, data_set);
279  }
280  }
281 }
282 
283 void
285  rsc_colocation_t *constraint,
286  pe_working_set_t *data_set)
287 {
288  GListPtr gIter = NULL;
289  group_variant_data_t *group_data = NULL;
290 
291  if (rsc_lh == NULL) {
292  pe_err("rsc_lh was NULL for %s", constraint->id);
293  return;
294 
295  } else if (rsc_rh == NULL) {
296  pe_err("rsc_rh was NULL for %s", constraint->id);
297  return;
298  }
299  if (constraint->score == 0) {
300  return;
301  }
302 
303  gIter = rsc_lh->children;
304  pe_rsc_trace(rsc_lh, "Processing constraints from %s", rsc_lh->id);
305 
306  get_group_variant_data(group_data, rsc_lh);
307 
308  if (group_data->colocated) {
309  group_data->first_child->cmds->rsc_colocation_lh(group_data->first_child,
310  rsc_rh, constraint,
311  data_set);
312  return;
313 
314  } else if (constraint->score >= INFINITY) {
315  pcmk__config_err("%s: Cannot perform mandatory colocation "
316  "between non-colocated group and %s",
317  rsc_lh->id, rsc_rh->id);
318  return;
319  }
320 
321  for (; gIter != NULL; gIter = gIter->next) {
322  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
323 
324  child_rsc->cmds->rsc_colocation_lh(child_rsc, rsc_rh, constraint,
325  data_set);
326  }
327 }
328 
329 void
331  rsc_colocation_t *constraint,
332  pe_working_set_t *data_set)
333 {
334  GListPtr gIter = rsc_rh->children;
335  group_variant_data_t *group_data = NULL;
336 
337  get_group_variant_data(group_data, rsc_rh);
338  CRM_CHECK(rsc_lh->variant == pe_native, return);
339 
340  if (constraint->score == 0) {
341  return;
342  }
343  pe_rsc_trace(rsc_rh, "Processing RH %s of constraint %s (LH is %s)",
344  rsc_rh->id, constraint->id, rsc_lh->id);
345 
346  if (pcmk_is_set(rsc_rh->flags, pe_rsc_provisional)) {
347  return;
348 
349  } else if (group_data->colocated && group_data->first_child) {
350  if (constraint->score >= INFINITY) {
351  /* Ensure RHS is _fully_ up before can start LHS */
352  group_data->last_child->cmds->rsc_colocation_rh(rsc_lh,
353  group_data->last_child,
354  constraint,
355  data_set);
356  } else {
357  /* A partially active RHS is fine */
358  group_data->first_child->cmds->rsc_colocation_rh(rsc_lh,
359  group_data->first_child,
360  constraint,
361  data_set);
362  }
363 
364  return;
365 
366  } else if (constraint->score >= INFINITY) {
367  pcmk__config_err("%s: Cannot perform mandatory colocation with"
368  " non-colocated group %s", rsc_lh->id, rsc_rh->id);
369  return;
370  }
371 
372  for (; gIter != NULL; gIter = gIter->next) {
373  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
374 
375  child_rsc->cmds->rsc_colocation_rh(rsc_lh, child_rsc, constraint,
376  data_set);
377  }
378 }
379 
380 enum pe_action_flags
382 {
383  GListPtr gIter = NULL;
385 
386  for (gIter = action->rsc->children; gIter != NULL; gIter = gIter->next) {
387  pe_resource_t *child = (pe_resource_t *) gIter->data;
388  enum action_tasks task = get_complex_task(child, action->task, TRUE);
389  const char *task_s = task2text(task);
390  pe_action_t *child_action = find_first_action(child->actions, NULL, task_s, node);
391 
392  if (child_action) {
393  enum pe_action_flags child_flags = child->cmds->action_flags(child_action, node);
394 
396  && !pcmk_is_set(child_flags, pe_action_optional)) {
397  pe_rsc_trace(action->rsc, "%s is mandatory because of %s", action->uuid,
398  child_action->uuid);
399  pe__clear_raw_action_flags(flags, "group action",
402  }
403  if (!pcmk__str_eq(task_s, action->task, pcmk__str_casei)
405  && !pcmk_is_set(child_flags, pe_action_runnable)) {
406 
407  pe_rsc_trace(action->rsc, "%s is not runnable because of %s", action->uuid,
408  child_action->uuid);
409  pe__clear_raw_action_flags(flags, "group action",
412  }
413 
414  } else if (task != stop_rsc && task != action_demote) {
415  pe_rsc_trace(action->rsc, "%s is not runnable because of %s (not found in %s)",
416  action->uuid, task_s, child->id);
417  pe__clear_raw_action_flags(flags, "group action",
419  }
420  }
421 
422  return flags;
423 }
424 
425 enum pe_graph_flags
427  enum pe_action_flags flags, enum pe_action_flags filter,
428  enum pe_ordering type, pe_working_set_t *data_set)
429 {
430  GListPtr gIter = then->rsc->children;
431  enum pe_graph_flags changed = pe_graph_none;
432 
433  CRM_ASSERT(then->rsc != NULL);
434  changed |= native_update_actions(first, then, node, flags, filter, type,
435  data_set);
436 
437  for (; gIter != NULL; gIter = gIter->next) {
438  pe_resource_t *child = (pe_resource_t *) gIter->data;
439  pe_action_t *child_action = find_first_action(child->actions, NULL, then->task, node);
440 
441  if (child_action) {
442  changed |= child->cmds->update_actions(first, child_action, node,
443  flags, filter, type,
444  data_set);
445  }
446  }
447 
448  return changed;
449 }
450 
451 void
453 {
454  GListPtr gIter = rsc->children;
455  GListPtr saved = constraint->node_list_rh;
456  GListPtr zero = pcmk__copy_node_list(constraint->node_list_rh, true);
457  gboolean reset_scores = TRUE;
458  group_variant_data_t *group_data = NULL;
459 
460  get_group_variant_data(group_data, rsc);
461 
462  pe_rsc_debug(rsc, "Processing rsc_location %s for %s", constraint->id, rsc->id);
463 
464  native_rsc_location(rsc, constraint);
465 
466  for (; gIter != NULL; gIter = gIter->next) {
467  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
468 
469  child_rsc->cmds->rsc_location(child_rsc, constraint);
470  if (group_data->colocated && reset_scores) {
471  reset_scores = FALSE;
472  constraint->node_list_rh = zero;
473  }
474  }
475 
476  constraint->node_list_rh = saved;
477  g_list_free_full(zero, free);
478 }
479 
480 void
482 {
483  CRM_CHECK(rsc != NULL, return);
484 
485  pe_rsc_trace(rsc, "Processing actions from %s", rsc->id);
486  native_expand(rsc, data_set);
487 
488  for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
489  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
490 
491  child_rsc->cmds->expand(child_rsc, data_set);
492  }
493 }
494 
495 GHashTable *
497  GHashTable *nodes, const char *attr, float factor,
498  uint32_t flags)
499 {
500  GListPtr gIter = rsc->rsc_cons_lhs;
501  group_variant_data_t *group_data = NULL;
502 
503  get_group_variant_data(group_data, rsc);
504 
505  if (pcmk_is_set(rsc->flags, pe_rsc_merging)) {
506  pe_rsc_info(rsc, "Breaking dependency loop with %s at %s", rsc->id, rhs);
507  return nodes;
508  }
509 
511 
512  nodes =
513  group_data->first_child->cmds->merge_weights(group_data->first_child, rhs, nodes, attr,
514  factor, flags);
515 
516  for (; gIter != NULL; gIter = gIter->next) {
517  rsc_colocation_t *constraint = (rsc_colocation_t *) gIter->data;
518 
519  if (constraint->score == 0) {
520  continue;
521  }
522  nodes = pcmk__native_merge_weights(constraint->rsc_lh, rsc->id, nodes,
523  constraint->node_attribute,
524  constraint->score / (float) INFINITY,
525  flags);
526  }
527 
529  return nodes;
530 }
531 
532 void
533 group_append_meta(pe_resource_t * rsc, xmlNode * xml)
534 {
535 }
GList * pcmk__copy_node_list(const GList *list, bool reset)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:215
gboolean rsc_colocation_new(const char *id, const char *node_attr, int score, pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, const char *state_lh, const char *state_rh, pe_working_set_t *data_set)
const char * task2text(enum action_tasks task)
Definition: common.c:410
#define RSC_STOP
Definition: crm.h:199
#define pe_rsc_debug(rsc, fmt, args...)
Definition: internal.h:19
#define INFINITY
Definition: crm.h:95
#define pe__set_action_flags(action, flags_to_set)
Definition: internal.h:59
#define demoted_key(rsc)
Definition: internal.h:447
#define stop_action(rsc, node, optional)
Definition: internal.h:417
GHashTable * pcmk__group_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
enum rsc_role_e role
Definition: pe_types.h:357
#define stopped_key(rsc)
Definition: internal.h:411
resource_alloc_functions_t * cmds
Definition: pe_types.h:320
void group_rsc_colocation_rh(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, rsc_colocation_t *constraint, pe_working_set_t *data_set)
#define pcmk__config_err(fmt...)
Definition: internal.h:107
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:391
enum rsc_role_e next_role
Definition: pe_types.h:358
#define pe__show_node_weights(level, rsc, text, nodes)
Definition: internal.h:393
GHashTable * meta
Definition: pe_types.h:360
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
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)
void native_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
#define demote_key(rsc)
Definition: internal.h:442
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
GListPtr rsc_cons
Definition: pe_types.h:344
gboolean show_scores
#define RSC_START
Definition: crm.h:196
pe_node_t *(* allocate)(pe_resource_t *, pe_node_t *, pe_working_set_t *)
pe_node_t * allocated_to
Definition: pe_types.h:350
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
#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:247
#define XML_RSC_ATTR_PROMOTABLE
Definition: msg_xml.h:197
#define pe_rsc_merging
Definition: pe_types.h:249
pe_action_flags
Definition: pe_types.h:279
#define order_stop_stop(rsc1, rsc2, type)
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:799
void(* rsc_colocation_rh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
void group_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void group_rsc_colocation_lh(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, rsc_colocation_t *constraint, pe_working_set_t *data_set)
const char * node_attribute
char * task
Definition: pe_types.h:395
#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:1480
#define promote_key(rsc)
Definition: internal.h:432
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:196
GListPtr running_on
Definition: pe_types.h:353
unsigned long long flags
Definition: pe_types.h:335
#define pe_rsc_promotable
Definition: pe_types.h:245
void(* expand)(pe_resource_t *, pe_working_set_t *)
enum pe_restart restart_type
Definition: pe_types.h:325
#define started_key(rsc)
Definition: internal.h:427
pe_graph_flags
Definition: pe_types.h:271
GListPtr rsc_cons_lhs
Definition: pe_types.h:343
char * uuid
Definition: pe_types.h:396
void group_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
pe_resource_t * rsc_lh
enum pe_action_flags(* action_flags)(pe_action_t *, pe_node_t *)
#define pe_rsc_allocating
Definition: pe_types.h:248
enum pe_obj_types variant
Definition: pe_types.h:317
int new_rsc_order(pe_resource_t *lh_rsc, const char *lh_task, pe_resource_t *rh_rsc, const char *rh_task, enum pe_ordering type, pe_working_set_t *data_set)
#define RSC_DEMOTED
Definition: crm.h:205
GListPtr actions
Definition: pe_types.h:346
void(* rsc_colocation_lh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
#define promoted_key(rsc)
Definition: internal.h:437
#define RSC_STARTED
Definition: crm.h:197
GListPtr children
Definition: pe_types.h:364
#define start_action(rsc, node, optional)
Definition: internal.h:423
#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:202
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
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)
#define order_start_start(rsc1, rsc2, type)
#define RSC_STOPPED
Definition: crm.h:200
const char * id
#define RSC_PROMOTED
Definition: crm.h:203
gboolean crm_is_true(const char *s)
Definition: strings.c:392
#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
pe_action_t * find_first_action(GListPtr input, const char *uuid, const char *task, pe_node_t *on_node)
Definition: utils.c:1503
#define pe_err(fmt...)
Definition: internal.h:22
GList * GListPtr
Definition: crm.h:214
#define pe__clear_raw_action_flags(action_flags, action_name, flags_to_clear)
Definition: internal.h:84
pe_ordering
Definition: pe_types.h:464
uint64_t flags
Definition: remote.c:149
action_tasks
Definition: common.h:62
enum crm_ais_msg_types type
Definition: internal.h:83
#define RSC_DEMOTE
Definition: crm.h:204
#define pe_rsc_info(rsc, fmt, args...)
Definition: internal.h:18
char * id
Definition: pe_types.h:308
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)
Definition: utils.c:465
GHashTable * allowed_nodes
Definition: pe_types.h:355
enum pe_action_flags group_action_flags(pe_action_t *action, pe_node_t *node)