32 #define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name) do {                      \    33         __rsc = pcmk__find_constraint_resource(data_set->resources, __name);    \    34         if (__rsc == NULL) {                                                    \    35             pcmk__config_err("%s: No resource found for %s", __set, __name);    \    36             return pcmk_rc_unpack_error;                                        \    41 invert_action(
const char *
action)
    67     crm_warn(
"Unknown action '%s' specified in order constraint", 
action);
    72 get_ordering_type(xmlNode *xml_obj)
    90                          "Support for 'score' in rsc_order is deprecated "    91                          "and will be removed in a future release "    92                          "(use 'kind' instead)");
   106                          "%s to 'Mandatory' because '%s' is not valid",
   107                          pcmk__s(
ID(xml_obj), 
"missing ID"), kind);
   124 get_ordering_symmetry(xmlNode *xml_obj, 
enum pe_order_kind parent_kind,
   125                       const char *parent_symmetrical_s)
   128     bool symmetric = 
false;
   134         kind = get_ordering_type(xml_obj);
   140     if (rc != 
pcmk_rc_ok && parent_symmetrical_s != NULL) {
   149                                   " for '%s' because not valid with "   177 ordering_flags_for_kind(
enum pe_order_kind kind, 
const char *first,
   229 get_ordering_resource(xmlNode *xml, 
const char *resource_attr,
   237     if (rsc_id == NULL) {
   239                          ID(xml), resource_attr);
   246                          "does not exist", 
ID(xml), rsc_id);
   250     if (instance_id != NULL) {
   254                      "removed in a future release.");
   256         if (!pe_rsc_is_clone(rsc)) {
   258                              "is not a clone but instance '%s' was requested",
   259                              ID(xml), rsc_id, instance_id);
   265                              "does not have an instance '%s'",
   266                              "'%s'", 
ID(xml), rsc_id, instance_id);
   283 get_minimum_first_instances(
pe_resource_t *rsc, xmlNode *xml)
   285     const char *clone_min = NULL;
   286     bool require_all = 
false;
   288     if (!pe_rsc_is_clone(rsc)) {
   292     clone_min = g_hash_table_lookup(rsc->
meta,
   294     if (clone_min != NULL) {
   295         int clone_min_int = 0;
   298         return clone_min_int;
   306                      "Support for require-all in ordering constraints "   307                      "is deprecated and will be removed in a future release"   308                      " (use clone-min clone meta-attribute instead)");
   331 clone_min_ordering(
const char *
id,
   349     for (GList *rIter = rsc_first->
children; rIter != NULL;
   350          rIter = rIter->next) {
   355                            NULL, NULL, NULL, clone_min_met,
   379 #define handle_restart_type(rsc, kind, flag, flags) do {        \   380         if (((kind) == pe_order_kind_optional)                  \   381             && ((rsc)->restart_type == pe_restart_restart)) {   \   382             pe__set_order_flags((flags), (flag));               \   404     action_then = invert_action(action_then);
   405     action_first = invert_action(action_first);
   406     if ((action_then == NULL) || (action_first == NULL)) {
   408                           "(please specify inverse manually)", 
id);
   410         uint32_t 
flags = ordering_flags_for_kind(kind, action_first,
   415                                      action_first, 
flags);
   424     int min_required_before = 0;
   429     const char *action_then = NULL;
   430     const char *action_first = NULL;
   431     const char *
id = NULL;
   438                          crm_element_name(xml_obj));
   445     if (rsc_first == NULL) {
   452     if (rsc_then == NULL) {
   457     if (action_first == NULL) {
   462     if (action_then == NULL) {
   463         action_then = action_first;
   466     kind = get_ordering_type(xml_obj);
   468     symmetry = get_ordering_symmetry(xml_obj, kind, NULL);
   469     cons_weight = ordering_flags_for_kind(kind, action_first, symmetry);
   478     min_required_before = get_minimum_first_instances(rsc_first, xml_obj);
   479     if (min_required_before > 0) {
   480         clone_min_ordering(
id, rsc_first, action_first, rsc_then, action_then,
   481                            cons_weight, min_required_before, 
data_set);
   484                                      action_then, cons_weight);
   488         inverse_ordering(
id, kind, rsc_first, action_first,
   530     CRM_CHECK(((first_action != NULL) || (first_rsc != NULL))
   531               && ((then_action != NULL) || (then_rsc != NULL)),
   532               free(first_action_task); free(then_action_task); 
return);
   534     if ((first_rsc == NULL) && (first_action != NULL)) {
   535         first_rsc = first_action->
rsc;
   537     if ((then_rsc == NULL) && (then_action != NULL)) {
   538         then_rsc = then_action->
rsc;
   546     order->
lh_rsc = first_rsc;
   561     if ((order->
lh_rsc == NULL) && (first_action != NULL)) {
   565     if ((order->
rh_rsc == NULL) && (then_action != NULL)) {
   569     pe_rsc_trace(first_rsc, 
"Created ordering %d for %s then %s",
   571                  ((first_action_task == NULL)? 
"?" : first_action_task),
   572                  ((then_action_task == NULL)? 
"?" : then_action_task));
   590 unpack_order_set(xmlNode *
set, 
enum pe_order_kind parent_kind,
   593     xmlNode *xml_rsc = NULL;
   594     GList *set_iter = NULL;
   595     GList *resources = NULL;
   600     int local_kind = parent_kind;
   601     bool sequential = 
false;
   606     const char *
id = 
ID(
set);
   616         local_kind = get_ordering_type(
set);
   618     if (sequential_s == NULL) {
   624     symmetry = get_ordering_symmetry(
set, parent_kind, parent_symmetrical_s);
   625     flags = ordering_flags_for_kind(local_kind, 
action, symmetry);
   631         resources = g_list_append(resources, resource);
   634     if (pcmk__list_of_1(resources)) {
   639     set_iter = resources;
   640     while (set_iter != NULL) {
   642         set_iter = set_iter->next;
   649             for (GList *gIter = set_iter; gIter != NULL; gIter = gIter->next) {
   657         } 
else if (sequential) {
   674     flags = ordering_flags_for_kind(local_kind, 
action,
   677     set_iter = resources;
   678     while (set_iter != NULL) {
   680         set_iter = set_iter->next;
   692     g_list_free(resources);
   709 order_rsc_sets(
const char *
id, xmlNode *set1, xmlNode *set2,
   714     xmlNode *xml_rsc = NULL;
   715     xmlNode *xml_rsc_2 = NULL;
   725     bool require_all = 
true;
   729     if (action_1 == NULL) {
   733     if (action_2 == NULL) {
   738         action_1 = invert_action(action_1);
   739         action_2 = invert_action(action_2);
   753     flags = ordering_flags_for_kind(kind, action_2, symmetry);
   775                                NULL, NULL, NULL, unordered_action,
   800             if (xml_rsc != NULL) {
   806             const char *rid = NULL;
   820             const char *rid = NULL;
   832             if (xml_rsc != NULL) {
   838     if ((rsc_1 != NULL) && (rsc_2 != NULL)) {
   841     } 
else if (rsc_1 != NULL) {
   850     } 
else if (rsc_2 != NULL) {
   890 unpack_order_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
   893     const char *id_first = NULL;
   894     const char *id_then = NULL;
   895     const char *action_first = NULL;
   896     const char *action_then = NULL;
   903     xmlNode *rsc_set_first = NULL;
   904     xmlNode *rsc_set_then = NULL;
   905     bool any_sets = 
false;
   909     if (*expanded_xml != NULL) {
   916     if ((id_first == NULL) || (id_then == NULL)) {
   923                          "valid resource or tag", 
ID(xml_obj), id_first);
   929                          "valid resource or tag", 
ID(xml_obj), id_then);
   933     if ((rsc_first != NULL) && (rsc_then != NULL)) {
   947         *expanded_xml = NULL;
   951     if (rsc_set_first != NULL) {
   952         if (action_first != NULL) {
   954             crm_xml_add(rsc_set_first, 
"action", action_first);
   964         *expanded_xml = NULL;
   968     if (rsc_set_then != NULL) {
   969         if (action_then != NULL) {
   981         *expanded_xml = NULL;
   998     xmlNode *last = NULL;
  1000     xmlNode *orig_xml = NULL;
  1001     xmlNode *expanded_xml = NULL;
  1014     if (expanded_xml != NULL) {
  1016         xml_obj = expanded_xml;
  1027             if (expanded_xml != NULL) {
  1035             if (order_rsc_sets(
id, last, 
set, kind, 
data_set,
  1037                 if (expanded_xml != NULL) {
  1044                 && (order_rsc_sets(
id, 
set, last, kind, 
data_set,
  1046                 if (expanded_xml != NULL) {
  1063         return unpack_simple_rsc_order(xml_obj, 
data_set);
  1074         && (
input->action->rsc != NULL)
  1077         crm_warn(
"Invalid ordering constraint between %s and %s",
  1101     for (GList *iter = 
data_set->
actions; iter != NULL; iter = iter->next) {
  1105         for (GList *input_iter = 
action->actions_before;
  1106              input_iter != NULL; input_iter = input_iter->next) {
  1127          iter != NULL; iter = iter->next) {
  1142                          "Not ordering %s before shutdown of %s because "  1143                          "resource in maintenance mode",
  1144                          action->uuid, pe__node_name(node));
  1149                          "Not ordering %s before shutdown of %s because "  1150                          "node in maintenance mode",
  1151                          action->uuid, pe__node_name(node));
  1159         if (!pcmk_any_flags_set(
action->rsc->flags,
  1162                          "Not ordering %s before shutdown of %s because "  1163                          "resource is unmanaged or blocked",
  1164                          action->uuid, pe__node_name(node));
  1169                      action->uuid, pe__node_name(node));
  1189 find_actions_by_task(
const pe_resource_t *rsc, 
const char *original_key)
  1198         guint interval_ms = 0;
  1200         if (
parse_op_key(original_key, NULL, &task, &interval_ms)) {
  1206             crm_err(
"Invalid operation key (bug?): %s", original_key);
  1221 order_resource_actions_after(
pe_action_t *first_action,
  1224     GList *then_actions = NULL;
  1227     CRM_CHECK((rsc != NULL) && (order != NULL), 
return);
  1230     pe_rsc_trace(rsc, 
"Applying ordering %d for 'then' resource %s",
  1231                  order->
id, rsc->
id);
  1234         then_actions = g_list_prepend(NULL, order->
rh_action);
  1240     if (then_actions == NULL) {
  1241         pe_rsc_trace(rsc, 
"Ignoring ordering %d: no %s actions found for %s",
  1246     if ((first_action != NULL) && (first_action->
rsc == rsc)
  1250                      "Detected dangling migration ordering (%s then %s %s)",
  1257                      "Ignoring ordering %d for %s: No first action found",
  1258                      order->
id, rsc->
id);
  1259         g_list_free(then_actions);
  1263     for (GList *iter = then_actions; iter != NULL; iter = iter->next) {
  1266         if (first_action != NULL) {
  1270             crm_warn(
"%s of %s is unrunnable because there is no %s of %s "  1271                      "to order it after", then_action_iter->
task, rsc->
id,
  1276     g_list_free(then_actions);
  1283     GList *first_actions = NULL;
  1288     pe_rsc_trace(first_rsc, 
"Applying ordering constraint %d (first: %s)",
  1289                  order->
id, first_rsc->
id);
  1291     if (first_action != NULL) {
  1292         first_actions = g_list_prepend(NULL, first_action);
  1295         first_actions = find_actions_by_task(first_rsc, order->
lh_action_task);
  1298     if ((first_actions == NULL) && (first_rsc == then_rsc)) {
  1300                      "Ignoring constraint %d: first (%s for %s) not found",
  1303     } 
else if (first_actions == NULL) {
  1305         char *op_type = NULL;
  1306         guint interval_ms = 0;
  1315                          "Ignoring constraint %d: first (%s for %s) not found",
  1322                          "Ignoring constraint %d: first (%s for %s) not found",
  1327                          "Creating first (%s for %s) for constraint %d ",
  1329             first_action = 
custom_action(first_rsc, key, op_type, NULL, TRUE,
  1331             first_actions = g_list_prepend(NULL, first_action);
  1337     if (then_rsc == NULL) {
  1339             pe_rsc_trace(first_rsc, 
"Ignoring constraint %d: then not found",
  1345     for (GList *gIter = first_actions; gIter != NULL; gIter = gIter->next) {
  1348         if (then_rsc == NULL) {
  1352             order_resource_actions_after(first_action, then_rsc, order);
  1356     g_list_free(first_actions);
  1362     crm_trace(
"Applying ordering constraints");
  1379          gIter != NULL; gIter = gIter->next) {
  1385             rsc_order_first(rsc, order, 
data_set);
  1391             order_resource_actions_after(order->
lh_action, rsc, order);
  1394             crm_trace(
"Applying ordering constraint %d (non-resource actions)",
  1423     const char *after_desc = (after->
task == NULL)? after->
uuid : after->
task;
  1425     for (GList *iter = list; iter != NULL; iter = iter->next) {
  1427         const char *before_desc = before->
task? before->
task : before->
uuid;
  1429         crm_debug(
"Ordering %s on %s before %s on %s",
  1430                   before_desc, pe__node_name(before->
node),
  1431                   after_desc, pe__node_name(after->
node));
 
#define CRM_CHECK(expr, failure_action)
 
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
 
void pcmk__unpack_ordering(xmlNode *xml_obj, pe_working_set_t *data_set)
 
#define pe_rsc_debug(rsc, fmt, args...)
 
#define XML_ORDER_ATTR_THEN_ACTION
 
#define pe__set_action_flags(action, flags_to_set)
 
int pcmk__scan_min_int(const char *text, int *result, int minimum)
 
void pcmk__order_after_each(pe_action_t *after, GList *list)
 
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
 
#define XML_ORDER_ATTR_THEN
 
#define CRM_OP_RELAXED_SET
 
#define pcmk__config_warn(fmt...)
 
G_GNUC_INTERNAL bool pcmk__rsc_corresponds_to_guest(pe_resource_t *rsc, pe_node_t *node)
 
#define XML_RULE_ATTR_SCORE
 
GList * find_actions(GList *input, const char *key, const pe_node_t *on_node)
 
xmlNode * first_named_child(const xmlNode *parent, const char *name)
 
int char2score(const char *score)
Get the integer value of a score string. 
 
#define pcmk__config_err(fmt...)
 
resource_object_functions_t * fns
 
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value. 
 
int order_id
Deprecated (will be removed in a future release) 
 
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
 
G_GNUC_INTERNAL void pcmk__order_probes(pe_working_set_t *data_set)
 
void pcmk__new_ordering(pe_resource_t *first_rsc, char *first_action_task, pe_action_t *first_action, pe_resource_t *then_rsc, char *then_action_task, pe_action_t *then_action, uint32_t flags, pe_working_set_t *data_set)
 
#define XML_ORDER_ATTR_FIRST_INSTANCE
 
#define XML_CONS_TAG_RSC_SET
 
pe_working_set_t * data_set
Cluster that this node is part of. 
 
#define XML_RSC_ATTR_INCARNATION_MIN
 
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, pe_working_set_t *data_set)
 
xmlNode * copy_xml(xmlNode *src_node)
 
#define XML_ORDER_ATTR_FIRST
 
#define crm_warn(fmt, args...)
 
pe_action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
 
#define crm_debug(fmt, args...)
 
#define pe__clear_order_flags(order_flags, flags_to_clear)
 
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute. 
 
void pcmk__apply_orderings(pe_working_set_t *data_set)
 
#define pe_warn_once(pe_wo_bit, fmt...)
 
#define pe__clear_action_flags(action, flags_to_clear)
 
#define crm_trace(fmt, args...)
 
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag. 
 
struct pe_node_shared_s * details
 
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
 
pe_resource_t * find_clone_instance(pe_resource_t *rsc, const char *sub_id, pe_working_set_t *data_set)
 
int pcmk__xe_get_bool_attr(const xmlNode *node, const char *name, bool *value)
 
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
 
pe_working_set_t * data_set
 
void pcmk__order_stops_before_shutdown(pe_node_t *node, pe_action_t *shutdown_op)
 
#define XML_TAG_RESOURCE_REF
 
#define handle_restart_type(rsc, kind, flag, flags)
 
void free_xml(xmlNode *child)
 
G_GNUC_INTERNAL bool pcmk__graph_has_loop(pe_action_t *init_action, pe_action_t *action, pe_action_wrapper_t *input)
 
G_GNUC_INTERNAL pe_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
 
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL) 
 
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
 
#define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name)
 
void pcmk__promotable_restart_ordering(pe_resource_t *rsc)
 
#define XML_ORDER_ATTR_THEN_INSTANCE
 
void pcmk__disable_invalid_orderings(pe_working_set_t *data_set)
 
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
 
G_GNUC_INTERNAL void pcmk__update_action_for_orderings(pe_action_t *action, pe_working_set_t *data_set)
 
GList * ordering_constraints
 
#define XML_ORDER_ATTR_KIND
 
#define crm_err(fmt, args...)
 
void xml_remove_prop(xmlNode *obj, const char *name)
 
#define CRM_OP_RELAXED_CLONE
 
enum pe_action_flags flags
 
#define pe_rsc_maintenance
 
#define crm_log_xml_trace(xml, text)
 
gboolean crm_is_true(const char *s)
 
#define pe_rsc_trace(rsc, fmt, args...)
 
#define pe__set_order_flags(order_flags, flags_to_set)
 
G_GNUC_INTERNAL void pcmk__block_colocation_dependents(pe_action_t *action, pe_working_set_t *data_set)
 
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object. 
 
#define XML_CONS_ATTR_SYMMETRICAL
 
#define XML_ORDER_ATTR_FIRST_ACTION
 
void pcmk__order_migration_equivalents(pe__ordering_t *order)
 
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(pe_working_set_t *data_set, const char *id, pe_resource_t **rsc, pe_tag_t **tag)
 
int required_runnable_before
 
G_GNUC_INTERNAL bool pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr, bool convert_rsc, pe_working_set_t *data_set)
 
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.