31 #define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name) do {                      \    32         __rsc = pcmk__find_constraint_resource(data_set->resources, __name);    \    33         if (__rsc == NULL) {                                                    \    34             pcmk__config_err("%s: No resource found for %s", __set, __name);    \    35             return pcmk_rc_schema_validation;                                   \    40 invert_action(
const char *
action)
    66     crm_warn(
"Unknown action '%s' specified in order constraint", 
action);
    71 get_ordering_type(xmlNode *xml_obj)
    89                          "Support for 'score' in rsc_order is deprecated "    90                          "and will be removed in a future release "    91                          "(use 'kind' instead)");
   105                          "'%s' to Mandatory because '%s' is not valid",
   123 get_ordering_symmetry(xmlNode *xml_obj, 
enum pe_order_kind parent_kind,
   124                       const char *parent_symmetrical_s)
   126     const char *symmetrical_s = NULL;
   132         kind = get_ordering_type(xml_obj);
   137     if (symmetrical_s == NULL) {
   138         symmetrical_s = parent_symmetrical_s;
   140     if (symmetrical_s != NULL) {
   144                                   " for '%s' because not valid with "   172 ordering_flags_for_kind(
enum pe_order_kind kind, 
const char *first,
   222 get_ordering_resource(xmlNode *xml, 
const char *resource_attr,
   229     if (rsc_id == NULL) {
   231                          ID(xml), resource_attr);
   238                          "does not exist", 
ID(xml), rsc_id);
   242     if (instance_id != NULL) {
   243         if (!pe_rsc_is_clone(rsc)) {
   245                              "is not a clone but instance '%s' was requested",
   246                              ID(xml), rsc_id, instance_id);
   252                              "does not have an instance '%s'",
   253                              "'%s'", 
ID(xml), rsc_id, instance_id);
   270 get_minimum_first_instances(
pe_resource_t *rsc, xmlNode *xml)
   272     if (pe_rsc_is_clone(rsc)) {
   273         const char *clone_min = NULL;
   275         clone_min = g_hash_table_lookup(rsc->
meta,
   277         if (clone_min != NULL) {
   278             int clone_min_int = 0;
   281             return clone_min_int;
   288         if (clone_min != NULL) {
   290                          "Support for require-all in ordering constraints "   291                          "is deprecated and will be removed in a future release"   292                          " (use clone-min clone meta-attribute instead)");
   315 clone_min_ordering(
const char *
id,
   334     for (GList *rIter = rsc_first->
children; rIter != NULL;
   335          rIter = rIter->next) {
   340                            NULL, NULL, NULL, clone_min_met,
   364 #define handle_restart_type(rsc, kind, flag, flags) do {        \   365         if (((kind) == pe_order_kind_optional)                  \   366             && ((rsc)->restart_type == pe_restart_restart)) {   \   367             pe__set_order_flags((flags), (flag));               \   389     action_then = invert_action(action_then);
   390     action_first = invert_action(action_first);
   391     if ((action_then == NULL) || (action_first == NULL)) {
   393                           "(please specify inverse manually)", 
id);
   400                                      action_first, 
flags, data_set);
   409     int min_required_before = 0;
   414     const char *action_then = NULL;
   415     const char *action_first = NULL;
   416     const char *
id = NULL;
   423                          crm_element_name(xml_obj));
   430     if (rsc_first == NULL) {
   437     if (rsc_then == NULL) {
   442     if (action_first == NULL) {
   447     if (action_then == NULL) {
   448         action_then = action_first;
   451     kind = get_ordering_type(xml_obj);
   453     symmetry = get_ordering_symmetry(xml_obj, kind, NULL);
   454     cons_weight = ordering_flags_for_kind(kind, action_first, symmetry);
   463     min_required_before = get_minimum_first_instances(rsc_first, xml_obj);
   464     if (min_required_before > 0) {
   465         clone_min_ordering(
id, rsc_first, action_first, rsc_then, action_then,
   466                            cons_weight, min_required_before, data_set);
   469                                      action_then, cons_weight, data_set);
   473         inverse_ordering(
id, kind, rsc_first, action_first,
   474                          rsc_then, action_then, data_set);
   484         res = strdup(
action->task);
   485     } 
else if (key != NULL) {
   505     char *lh_task = NULL;
   506     char *rh_task = NULL;
   525     if (!lh_migratable && !rh_migratable) {
   532     if ((lh_task == NULL) || (rh_task == NULL)) {
   541         if (lh_migratable && rh_migratable) {
   548                                NULL, 
flags, data_set);
   564                                NULL, 
flags, data_set);
   583                            NULL, 
flags, data_set);
   591                                NULL, 
flags, data_set);
   606                                NULL, 
flags, data_set);
   621                                NULL, 
flags, data_set);
   629                                    NULL, 
flags, data_set);
   674     CRM_CHECK(((lh_action != NULL) || (lh_rsc != NULL))
   675               && ((rh_action != NULL) || (rh_rsc != NULL)),
   676               free(lh_action_task); free(rh_action_task); 
return);
   678     if ((lh_rsc == NULL) && (lh_action != NULL)) {
   679         lh_rsc = lh_action->
rsc;
   681     if ((rh_rsc == NULL) && (rh_action != NULL)) {
   682         rh_rsc = rh_action->
rsc;
   704     if ((order->
lh_rsc == NULL) && (lh_action != NULL)) {
   708     if ((order->
rh_rsc == NULL) && (rh_action != NULL)) {
   712     pe_rsc_trace(lh_rsc, 
"Created ordering %d for %s then %s",
   714                  ((lh_action_task == NULL)? 
"?" : lh_action_task),
   715                  ((rh_action_task == NULL)? 
"?" : rh_action_task));
   719     handle_migration_ordering(order, data_set);
   733 unpack_order_set(xmlNode *
set, 
enum pe_order_kind parent_kind,
   736     xmlNode *xml_rsc = NULL;
   737     GList *set_iter = NULL;
   738     GList *resources = NULL;
   743     int local_kind = parent_kind;
   744     bool sequential = 
false;
   749     const char *
id = 
ID(
set);
   759         local_kind = get_ordering_type(
set);
   761     if (sequential_s == NULL) {
   767     symmetry = get_ordering_symmetry(
set, parent_kind, parent_symmetrical_s);
   768     flags = ordering_flags_for_kind(local_kind, 
action, symmetry);
   774         resources = g_list_append(resources, resource);
   777     if (pcmk__list_of_1(resources)) {
   782     set_iter = resources;
   783     while (set_iter != NULL) {
   785         set_iter = set_iter->next;
   792             for (GList *gIter = set_iter; gIter != NULL; gIter = gIter->next) {
   797                                    then_key, NULL, 
flags, data_set);
   800         } 
else if (sequential) {
   817     flags = ordering_flags_for_kind(local_kind, 
action,
   820     set_iter = resources;
   821     while (set_iter != NULL) {
   823         set_iter = set_iter->next;
   835     g_list_free(resources);
   852 order_rsc_sets(
const char *
id, xmlNode *set1, xmlNode *set2,
   857     xmlNode *xml_rsc = NULL;
   858     xmlNode *xml_rsc_2 = NULL;
   870     bool require_all = require_all_s? 
crm_is_true(require_all_s) : true;
   874     if (action_1 == NULL) {
   878     if (action_2 == NULL) {
   883         action_1 = invert_action(action_1);
   884         action_2 = invert_action(action_2);
   898     flags = ordering_flags_for_kind(kind, action_2, symmetry);
   920                                NULL, NULL, NULL, unordered_action,
   945             if (xml_rsc != NULL) {
   951             const char *rid = NULL;
   965             const char *rid = NULL;
   977             if (xml_rsc != NULL) {
   983     if ((rsc_1 != NULL) && (rsc_2 != NULL)) {
   987     } 
else if (rsc_1 != NULL) {
   996     } 
else if (rsc_2 != NULL) {
  1016                                              action_2, 
flags, data_set);
  1036 unpack_order_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
  1039     const char *id_first = NULL;
  1040     const char *id_then = NULL;
  1041     const char *action_first = NULL;
  1042     const char *action_then = NULL;
  1049     xmlNode *rsc_set_first = NULL;
  1050     xmlNode *rsc_set_then = NULL;
  1051     bool any_sets = 
false;
  1055     if (*expanded_xml != NULL) {
  1062     if ((id_first == NULL) || (id_then == NULL)) {
  1069                          "valid resource or tag", 
ID(xml_obj), id_first);
  1075                          "valid resource or tag", 
ID(xml_obj), id_then);
  1079     if ((rsc_first != NULL) && (rsc_then != NULL)) {
  1093         *expanded_xml = NULL;
  1097     if (rsc_set_first != NULL) {
  1098         if (action_first != NULL) {
  1100             crm_xml_add(rsc_set_first, 
"action", action_first);
  1110         *expanded_xml = NULL;
  1114     if (rsc_set_then != NULL) {
  1115         if (action_then != NULL) {
  1127         *expanded_xml = NULL;
  1143     xmlNode *
set = NULL;
  1144     xmlNode *last = NULL;
  1146     xmlNode *orig_xml = NULL;
  1147     xmlNode *expanded_xml = NULL;
  1157     if (unpack_order_tags(xml_obj, &expanded_xml, data_set) != 
pcmk_rc_ok) {
  1160     if (expanded_xml != NULL) {
  1162         xml_obj = expanded_xml;
  1171             || (unpack_order_set(
set, kind, invert, data_set) != 
pcmk_rc_ok)) {
  1173             if (expanded_xml != NULL) {
  1181             if (order_rsc_sets(
id, last, 
set, kind, data_set,
  1183                 if (expanded_xml != NULL) {
  1190                 && (order_rsc_sets(
id, 
set, last, kind, data_set,
  1192                 if (expanded_xml != NULL) {
  1209         return unpack_simple_rsc_order(xml_obj, data_set);
  1223         crm_warn(
"Invalid ordering constraint between %s and %s",
  1247     for (GList *iter = data_set->
actions; iter != NULL; iter = iter->next) {
  1251         for (GList *input_iter = 
action->actions_before;
  1252              input_iter != NULL; input_iter = input_iter->next) {
  1255             if (ordering_is_invalid(
action, input)) {
  1274     for (GList *iter = data_set->
actions; iter != NULL; iter = iter->next) {
  1288                          "Not ordering %s before %s shutdown because "  1289                          "resource in maintenance mode",
  1295                          "Not ordering %s before %s shutdown because "  1296                          "node in maintenance mode",
  1305         if (!pcmk_any_flags_set(
action->rsc->flags,
  1308                          "Not ordering %s before %s shutdown because "  1309                          "resource is unmanaged or blocked",
  1334 find_actions_by_task(
pe_resource_t *rsc, 
const char *original_key)
  1343         guint interval_ms = 0;
  1345         if (
parse_op_key(original_key, NULL, &task, &interval_ms)) {
  1351             crm_err(
"Invalid operation key (bug?): %s", original_key);
  1361     GList *rh_actions = NULL;
  1370     crm_trace(
"Applying ordering constraint %d (then: %s)", order->
id, rsc->
id);
  1372     if (rh_action != NULL) {
  1373         rh_actions = g_list_prepend(NULL, rh_action);
  1375     } 
else if (rsc != NULL) {
  1379     if (rh_actions == NULL) {
  1381                      "Ignoring constraint %d: then (%s for %s) not found",
  1386     if ((lh_action != NULL) && (lh_action->
rsc == rsc)
  1389         pe_rsc_trace(rsc, 
"Detected dangling operation %s -> %s",
  1394     for (GList *gIter = rh_actions; gIter != NULL; gIter = gIter->next) {
  1408     g_list_free(rh_actions);
  1415     GList *lh_actions = NULL;
  1420     pe_rsc_trace(lh_rsc, 
"Applying ordering constraint %d (first: %s)",
  1421                  order->
id, lh_rsc->
id);
  1423     if (lh_action != NULL) {
  1424         lh_actions = g_list_prepend(NULL, lh_action);
  1427         lh_actions = find_actions_by_task(lh_rsc, order->
lh_action_task);
  1430     if ((lh_actions == NULL) && (lh_rsc == rh_rsc)) {
  1432                      "Ignoring constraint %d: first (%s for %s) not found",
  1435     } 
else if (lh_actions == NULL) {
  1437         char *op_type = NULL;
  1438         guint interval_ms = 0;
  1447                          "Ignoring constraint %d: first (%s for %s) not found",
  1454                          "Ignoring constraint %d: first (%s for %s) not found",
  1459                          "Creating first (%s for %s) for constraint %d ",
  1461             lh_action = 
custom_action(lh_rsc, key, op_type, NULL, TRUE, TRUE, data_set);
  1462             lh_actions = g_list_prepend(NULL, lh_action);
  1468     if (rh_rsc == NULL) {
  1470             pe_rsc_trace(lh_rsc, 
"Ignoring constraint %d: then not found",
  1476     for (GList *gIter = lh_actions; gIter != NULL; gIter = gIter->next) {
  1479         if (rh_rsc == NULL) {
  1483             rsc_order_then(lh_action, rh_rsc, order);
  1487     g_list_free(lh_actions);
  1493     crm_trace(
"Applying ordering constraints");
  1504          gIter != NULL; gIter = gIter->next) {
  1510             rsc_order_first(rsc, order, data_set);
  1516             rsc_order_then(order->
lh_action, rsc, order);
  1519             crm_trace(
"Applying ordering constraint %d (non-resource actions)",
 
#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 XML_ORDER_ATTR_THEN_ACTION
 
#define pe__set_action_flags(action, flags_to_set)
 
gboolean is_parent(pe_resource_t *child, pe_resource_t *rsc)
 
int pcmk__scan_min_int(const char *text, int *result, int minimum)
 
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)
 
#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) 
 
enum crm_ais_msg_types type
 
G_GNUC_INTERNAL void pcmk__order_probes(pe_working_set_t *data_set)
 
pe_node_t * partial_migration_target
 
#define XML_ORDER_ATTR_FIRST_INSTANCE
 
#define XML_CONS_TAG_RSC_SET
 
#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...)
 
#define pe_rsc_allow_migrate
 
pe_action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
 
#define pe__clear_order_flags(order_flags, flags_to_clear)
 
G_GNUC_INTERNAL void pcmk__block_colocated_starts(pe_action_t *action, pe_working_set_t *data_set)
 
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)
 
void pcmk__new_ordering(pe_resource_t *lh_rsc, char *lh_action_task, pe_action_t *lh_action, pe_resource_t *rh_rsc, char *rh_action_task, pe_action_t *rh_action, enum pe_ordering type, pe_working_set_t *data_set)
 
#define pe_warn_once(pe_wo_bit, fmt...)
 
gboolean update_action(pe_action_t *action, pe_working_set_t *data_set)
 
#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)
 
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
 
#define pcmk__order_resource_actions(lh_rsc, lh_task, rh_rsc, rh_task, flags, data_set)
 
#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 EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name)
 
#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)
 
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)
 
#define XML_CONS_ATTR_SYMMETRICAL
 
void pcmk__order_stops_before_shutdown(pe_node_t *node, pe_action_t *shutdown_op, pe_working_set_t *data_set)
 
#define XML_ORDER_ATTR_FIRST_ACTION
 
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)
 
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. 
 
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.