pacemaker  2.0.4-2deceaa
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 (is_not_set(rsc->flags, pe_rsc_provisional)) {
31  return rsc->allocated_to;
32  }
33  if (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, __FUNCTION__, 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;
72 
73  if (group_data->colocated) {
74  return group_node;
75  }
76  return NULL;
77 }
78 
80 
81 void
83 {
84  pe_action_t *op = NULL;
85  const char *value = NULL;
86  GListPtr gIter = rsc->children;
87 
88  pe_rsc_trace(rsc, "Creating actions for %s", rsc->id);
89 
90  for (; gIter != NULL; gIter = gIter->next) {
91  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
92 
93  child_rsc->cmds->create_actions(child_rsc, data_set);
94  group_update_pseudo_status(rsc, child_rsc);
95  }
96 
97  op = start_action(rsc, NULL, TRUE /* !group_data->child_starting */ );
99 
100  op = custom_action(rsc, started_key(rsc),
101  RSC_STARTED, NULL, TRUE /* !group_data->child_starting */ , TRUE, data_set);
103 
104  op = stop_action(rsc, NULL, TRUE /* !group_data->child_stopping */ );
106 
107  op = custom_action(rsc, stopped_key(rsc),
108  RSC_STOPPED, NULL, TRUE /* !group_data->child_stopping */ , TRUE, data_set);
110 
111  value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_PROMOTABLE);
112  if (crm_is_true(value)) {
113  op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set);
116  op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set);
119 
120  op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set);
123  op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set);
126  }
127 }
128 
129 void
131 {
132  GListPtr gIter = child->actions;
133  group_variant_data_t *group_data = NULL;
134 
135  get_group_variant_data(group_data, parent);
136 
137  if (group_data->ordered == FALSE) {
138  /* If this group is not ordered, then leave the meta-actions as optional */
139  return;
140  }
141 
142  if (group_data->child_stopping && group_data->child_starting) {
143  return;
144  }
145 
146  for (; gIter != NULL; gIter = gIter->next) {
147  pe_action_t *action = (pe_action_t *) gIter->data;
148 
149  if (is_set(action->flags, pe_action_optional)) {
150  continue;
151  }
152  if (safe_str_eq(RSC_STOP, action->task) && is_set(action->flags, pe_action_runnable)) {
153  group_data->child_stopping = TRUE;
154  pe_rsc_trace(action->rsc, "Based on %s the group is stopping", action->uuid);
155 
156  } else if (safe_str_eq(RSC_START, action->task)
157  && is_set(action->flags, pe_action_runnable)) {
158  group_data->child_starting = TRUE;
159  pe_rsc_trace(action->rsc, "Based on %s the group is starting", action->uuid);
160  }
161  }
162 }
163 
164 void
166 {
167  GListPtr gIter = rsc->children;
168  pe_resource_t *last_rsc = NULL;
169  pe_resource_t *last_active = NULL;
170  pe_resource_t *top = uber_parent(rsc);
171  group_variant_data_t *group_data = NULL;
172 
173  get_group_variant_data(group_data, rsc);
174 
175  new_rsc_order(rsc, RSC_STOPPED, rsc, RSC_START, pe_order_optional, data_set);
178 
179  for (; gIter != NULL; gIter = gIter->next) {
180  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
181  int stop = pe_order_none;
182  int stopped = pe_order_implies_then_printed;
184  int started =
186 
187  child_rsc->cmds->internal_constraints(child_rsc, data_set);
188 
189  if (last_rsc == NULL) {
190  if (group_data->ordered) {
191  stop |= pe_order_optional;
192  stopped = pe_order_implies_then;
193  }
194 
195  } else if (group_data->colocated) {
196  rsc_colocation_new("group:internal_colocation", NULL, INFINITY,
197  child_rsc, last_rsc, NULL, NULL, data_set);
198  }
199 
200  if (is_set(top->flags, pe_rsc_promotable)) {
201  new_rsc_order(rsc, RSC_DEMOTE, child_rsc, RSC_DEMOTE,
202  stop | pe_order_implies_first_printed, data_set);
203 
204  new_rsc_order(child_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stopped, data_set);
205 
206  new_rsc_order(child_rsc, RSC_PROMOTE, rsc, RSC_PROMOTED, started, data_set);
207 
208  new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE,
210 
211  }
212 
214  order_stop_stop(rsc, child_rsc, stop | pe_order_implies_first_printed);
215 
216  new_rsc_order(child_rsc, RSC_STOP, rsc, RSC_STOPPED, stopped, data_set);
217 
218  new_rsc_order(child_rsc, RSC_START, rsc, RSC_STARTED, started, data_set);
219 
220  if (group_data->ordered == FALSE) {
221  order_start_start(rsc, child_rsc, start | pe_order_implies_first_printed);
222  if (is_set(top->flags, pe_rsc_promotable)) {
223  new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE,
224  start | pe_order_implies_first_printed, data_set);
225  }
226 
227  } else if (last_rsc != NULL) {
228  child_rsc->restart_type = pe_restart_restart;
229 
230  order_start_start(last_rsc, child_rsc, start);
231  order_stop_stop(child_rsc, last_rsc, pe_order_optional | pe_order_restart);
232 
233  if (is_set(top->flags, pe_rsc_promotable)) {
234  new_rsc_order(last_rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, start, data_set);
235  new_rsc_order(child_rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, pe_order_optional,
236  data_set);
237  }
238 
239  } else {
240  /* If anyone in the group is starting, then
241  * pe_order_implies_then will cause _everyone_ in the group
242  * to be sent a start action
243  * But this is safe since starting something that is already
244  * started is required to be "safe"
245  */
246  int flags = pe_order_none;
247 
248  order_start_start(rsc, child_rsc, flags);
249  if (is_set(top->flags, pe_rsc_promotable)) {
250  new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, flags, data_set);
251  }
252 
253  }
254 
255  /* Look for partially active groups
256  * Make sure they still shut down in sequence
257  */
258  if (child_rsc->running_on) {
259  if (group_data->ordered
260  && last_rsc
261  && last_rsc->running_on == NULL && last_active && last_active->running_on) {
262  order_stop_stop(child_rsc, last_active, pe_order_optional);
263  }
264  last_active = child_rsc;
265  }
266 
267  last_rsc = child_rsc;
268  }
269 
270  if (group_data->ordered && last_rsc != NULL) {
271  int stop_stop_flags = pe_order_implies_then;
272  int stop_stopped_flags = pe_order_optional;
273 
274  order_stop_stop(rsc, last_rsc, stop_stop_flags);
275  new_rsc_order(last_rsc, RSC_STOP, rsc, RSC_STOPPED, stop_stopped_flags, data_set);
276 
277  if (is_set(top->flags, pe_rsc_promotable)) {
278  new_rsc_order(rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, stop_stop_flags, data_set);
279  new_rsc_order(last_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stop_stopped_flags, data_set);
280  }
281  }
282 }
283 
284 void
286  rsc_colocation_t *constraint,
287  pe_working_set_t *data_set)
288 {
289  GListPtr gIter = NULL;
290  group_variant_data_t *group_data = NULL;
291 
292  if (rsc_lh == NULL) {
293  pe_err("rsc_lh was NULL for %s", constraint->id);
294  return;
295 
296  } else if (rsc_rh == NULL) {
297  pe_err("rsc_rh was NULL for %s", constraint->id);
298  return;
299  }
300  if (constraint->score == 0) {
301  return;
302  }
303 
304  gIter = rsc_lh->children;
305  pe_rsc_trace(rsc_lh, "Processing constraints from %s", rsc_lh->id);
306 
307  get_group_variant_data(group_data, rsc_lh);
308 
309  if (group_data->colocated) {
310  group_data->first_child->cmds->rsc_colocation_lh(group_data->first_child,
311  rsc_rh, constraint,
312  data_set);
313  return;
314 
315  } else if (constraint->score >= INFINITY) {
316  pcmk__config_err("%s: Cannot perform mandatory colocation "
317  "between non-colocated group and %s",
318  rsc_lh->id, rsc_rh->id);
319  return;
320  }
321 
322  for (; gIter != NULL; gIter = gIter->next) {
323  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
324 
325  child_rsc->cmds->rsc_colocation_lh(child_rsc, rsc_rh, constraint,
326  data_set);
327  }
328 }
329 
330 void
332  rsc_colocation_t *constraint,
333  pe_working_set_t *data_set)
334 {
335  GListPtr gIter = rsc_rh->children;
336  group_variant_data_t *group_data = NULL;
337 
338  get_group_variant_data(group_data, rsc_rh);
339  CRM_CHECK(rsc_lh->variant == pe_native, return);
340 
341  if (constraint->score == 0) {
342  return;
343  }
344  pe_rsc_trace(rsc_rh, "Processing RH %s of constraint %s (LH is %s)",
345  rsc_rh->id, constraint->id, rsc_lh->id);
346 
347  if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
348  return;
349 
350  } else if (group_data->colocated && group_data->first_child) {
351  if (constraint->score >= INFINITY) {
352  /* Ensure RHS is _fully_ up before can start LHS */
353  group_data->last_child->cmds->rsc_colocation_rh(rsc_lh,
354  group_data->last_child,
355  constraint,
356  data_set);
357  } else {
358  /* A partially active RHS is fine */
359  group_data->first_child->cmds->rsc_colocation_rh(rsc_lh,
360  group_data->first_child,
361  constraint,
362  data_set);
363  }
364 
365  return;
366 
367  } else if (constraint->score >= INFINITY) {
368  pcmk__config_err("%s: Cannot perform mandatory colocation with"
369  " non-colocated group %s", rsc_lh->id, rsc_rh->id);
370  return;
371  }
372 
373  for (; gIter != NULL; gIter = gIter->next) {
374  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
375 
376  child_rsc->cmds->rsc_colocation_rh(rsc_lh, child_rsc, constraint,
377  data_set);
378  }
379 }
380 
381 enum pe_action_flags
383 {
384  GListPtr gIter = NULL;
386 
387  for (gIter = action->rsc->children; gIter != NULL; gIter = gIter->next) {
388  pe_resource_t *child = (pe_resource_t *) gIter->data;
389  enum action_tasks task = get_complex_task(child, action->task, TRUE);
390  const char *task_s = task2text(task);
391  pe_action_t *child_action = find_first_action(child->actions, NULL, task_s, node);
392 
393  if (child_action) {
394  enum pe_action_flags child_flags = child->cmds->action_flags(child_action, node);
395 
396  if (is_set(flags, pe_action_optional)
397  && is_set(child_flags, pe_action_optional) == FALSE) {
398  pe_rsc_trace(action->rsc, "%s is mandatory because of %s", action->uuid,
399  child_action->uuid);
402  }
403  if (safe_str_neq(task_s, action->task)
404  && is_set(flags, pe_action_runnable)
405  && is_set(child_flags, pe_action_runnable) == FALSE) {
406  pe_rsc_trace(action->rsc, "%s is not runnable because of %s", action->uuid,
407  child_action->uuid);
410  }
411 
412  } else if (task != stop_rsc && task != action_demote) {
413  pe_rsc_trace(action->rsc, "%s is not runnable because of %s (not found in %s)",
414  action->uuid, task_s, child->id);
416  }
417  }
418 
419  return flags;
420 }
421 
422 enum pe_graph_flags
424  enum pe_action_flags flags, enum pe_action_flags filter,
425  enum pe_ordering type, pe_working_set_t *data_set)
426 {
427  GListPtr gIter = then->rsc->children;
428  enum pe_graph_flags changed = pe_graph_none;
429 
430  CRM_ASSERT(then->rsc != NULL);
431  changed |= native_update_actions(first, then, node, flags, filter, type,
432  data_set);
433 
434  for (; gIter != NULL; gIter = gIter->next) {
435  pe_resource_t *child = (pe_resource_t *) gIter->data;
436  pe_action_t *child_action = find_first_action(child->actions, NULL, then->task, node);
437 
438  if (child_action) {
439  changed |= child->cmds->update_actions(first, child_action, node,
440  flags, filter, type,
441  data_set);
442  }
443  }
444 
445  return changed;
446 }
447 
448 void
450 {
451  GListPtr gIter = rsc->children;
452  GListPtr saved = constraint->node_list_rh;
453  GListPtr zero = pcmk__copy_node_list(constraint->node_list_rh, true);
454  gboolean reset_scores = TRUE;
455  group_variant_data_t *group_data = NULL;
456 
457  get_group_variant_data(group_data, rsc);
458 
459  pe_rsc_debug(rsc, "Processing rsc_location %s for %s", constraint->id, rsc->id);
460 
461  native_rsc_location(rsc, constraint);
462 
463  for (; gIter != NULL; gIter = gIter->next) {
464  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
465 
466  child_rsc->cmds->rsc_location(child_rsc, constraint);
467  if (group_data->colocated && reset_scores) {
468  reset_scores = FALSE;
469  constraint->node_list_rh = zero;
470  }
471  }
472 
473  constraint->node_list_rh = saved;
474  g_list_free_full(zero, free);
475 }
476 
477 void
479 {
480  CRM_CHECK(rsc != NULL, return);
481 
482  pe_rsc_trace(rsc, "Processing actions from %s", rsc->id);
483  native_expand(rsc, data_set);
484 
485  for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
486  pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
487 
488  child_rsc->cmds->expand(child_rsc, data_set);
489  }
490 }
491 
492 GHashTable *
494  GHashTable *nodes, const char *attr, float factor,
495  uint32_t flags)
496 {
497  GListPtr gIter = rsc->rsc_cons_lhs;
498  group_variant_data_t *group_data = NULL;
499 
500  get_group_variant_data(group_data, rsc);
501 
502  if (is_set(rsc->flags, pe_rsc_merging)) {
503  pe_rsc_info(rsc, "Breaking dependency loop with %s at %s", rsc->id, rhs);
504  return nodes;
505  }
506 
508 
509  nodes =
510  group_data->first_child->cmds->merge_weights(group_data->first_child, rhs, nodes, attr,
511  factor, flags);
512 
513  for (; gIter != NULL; gIter = gIter->next) {
514  rsc_colocation_t *constraint = (rsc_colocation_t *) gIter->data;
515 
516  if (constraint->score == 0) {
517  continue;
518  }
519  nodes = pcmk__native_merge_weights(constraint->rsc_lh, rsc->id, nodes,
520  constraint->node_attribute,
521  constraint->score / (float) INFINITY,
522  flags);
523  }
524 
526  return nodes;
527 }
528 
529 void
530 group_append_meta(pe_resource_t * rsc, xmlNode * xml)
531 {
532 }
GList * pcmk__copy_node_list(const GList *list, bool reset)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:233
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)
void group_append_meta(pe_resource_t *rsc, xmlNode *xml)
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:18
gboolean safe_str_neq(const char *a, const char *b)
Definition: strings.c:263
#define INFINITY
Definition: crm.h:95
#define demoted_key(rsc)
Definition: internal.h:327
#define stop_action(rsc, node, optional)
Definition: internal.h:297
enum rsc_role_e role
Definition: pe_types.h:354
#define stopped_key(rsc)
Definition: internal.h:291
resource_alloc_functions_t * cmds
Definition: pe_types.h:317
#define pcmk__config_err(fmt...)
Definition: internal.h:95
enum pe_action_flags(* action_flags)(pe_action_t *, pe_node_t *)
pe_resource_t * rsc
Definition: pe_types.h:388
enum rsc_role_e next_role
Definition: pe_types.h:355
#define pe__show_node_weights(level, rsc, text, nodes)
Definition: internal.h:273
GHashTable * meta
Definition: pe_types.h:357
void(* rsc_colocation_lh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
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)
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
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:322
#define clear_bit(word, bit)
Definition: crm_internal.h:69
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
GListPtr rsc_cons
Definition: pe_types.h:341
gboolean show_scores
#define RSC_START
Definition: crm.h:196
pe_node_t * allocated_to
Definition: pe_types.h:347
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:29
void(* rsc_colocation_rh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
void group_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set)
void group_update_pseudo_status(pe_resource_t *parent, pe_resource_t *child)
#define pe_rsc_provisional
Definition: pe_types.h:245
#define XML_RSC_ATTR_PROMOTABLE
Definition: msg_xml.h:190
#define pe_rsc_merging
Definition: pe_types.h:247
#define set_bit(word, bit)
Definition: crm_internal.h:68
void(* create_actions)(pe_resource_t *, pe_working_set_t *)
pe_action_flags
Definition: pe_types.h:276
#define order_stop_stop(rsc1, rsc2, type)
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:762
const char * node_attribute
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)
char * task
Definition: pe_types.h:392
void group_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set)
enum action_tasks get_complex_task(pe_resource_t *rsc, const char *name, gboolean allow_non_atomic)
Definition: utils.c:1418
#define promote_key(rsc)
Definition: internal.h:312
GListPtr running_on
Definition: pe_types.h:350
unsigned long long flags
Definition: pe_types.h:332
#define pe_rsc_promotable
Definition: pe_types.h:243
GHashTable * pcmk__group_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
void(* expand)(pe_resource_t *, pe_working_set_t *)
enum pe_restart restart_type
Definition: pe_types.h:322
#define started_key(rsc)
Definition: internal.h:307
pe_graph_flags
Definition: pe_types.h:268
GListPtr rsc_cons_lhs
Definition: pe_types.h:340
char * uuid
Definition: pe_types.h:393
pe_resource_t * rsc_lh
#define pe_rsc_allocating
Definition: pe_types.h:246
void group_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
enum pe_obj_types variant
Definition: pe_types.h:314
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:343
void(* rsc_location)(pe_resource_t *, pe__location_t *)
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)
#define promoted_key(rsc)
Definition: internal.h:317
#define RSC_STARTED
Definition: crm.h:197
GListPtr children
Definition: pe_types.h:361
#define start_action(rsc, node, optional)
Definition: internal.h:303
#define CRM_ASSERT(expr)
Definition: results.h:42
#define RSC_PROMOTE
Definition: crm.h:202
#define pe_clear_action_bit(action, bit)
Definition: internal.h:26
void(* internal_constraints)(pe_resource_t *, pe_working_set_t *)
enum pe_action_flags flags
Definition: pe_types.h:397
#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:278
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:19
pe_action_t * find_first_action(GListPtr input, const char *uuid, const char *task, pe_node_t *on_node)
Definition: utils.c:1442
#define pe_err(fmt...)
Definition: internal.h:21
#define safe_str_eq(a, b)
Definition: util.h:65
GList * GListPtr
Definition: crm.h:214
void group_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
pe_ordering
Definition: pe_types.h:461
uint64_t flags
Definition: remote.c:149
action_tasks
Definition: common.h:47
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:17
char * id
Definition: pe_types.h:305
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:485
GHashTable * allowed_nodes
Definition: pe_types.h:352
pe_node_t *(* allocate)(pe_resource_t *, pe_node_t *, pe_working_set_t *)
pe_node_t * pcmk__group_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)