diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h index d5ac418..b66ab90 100644 --- a/include/crm/msg_xml.h +++ b/include/crm/msg_xml.h @@ -328,6 +328,7 @@ extern "C" { # define XML_COLOC_ATTR_NODE_ATTR "node-attribute" # define XML_COLOC_ATTR_SOURCE_INSTANCE "rsc-instance" # define XML_COLOC_ATTR_TARGET_INSTANCE "with-rsc-instance" +# define XML_COLOC_ATTR_INFLUENCE "influence" # define XML_LOC_ATTR_SOURCE "rsc" # define XML_LOC_ATTR_SOURCE_PATTERN "rsc-pattern" diff --git a/include/pcmki/pcmki_sched_utils.h b/include/pcmki/pcmki_sched_utils.h index c7ae1b8..bed64da 100644 --- a/include/pcmki/pcmki_sched_utils.h +++ b/include/pcmki/pcmki_sched_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2020 the Pacemaker project contributors + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -31,7 +31,7 @@ pe__location_t *rsc2node_new(const char *id, pe_resource_t *rsc, int weight, void pcmk__new_colocation(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); + bool influence, pe_working_set_t *data_set); extern gboolean rsc_ticket_new(const char *id, pe_resource_t * rsc_lh, pe_ticket_t * ticket, const char *state_lh, const char *loss_policy, diff --git a/include/pcmki/pcmki_scheduler.h b/include/pcmki/pcmki_scheduler.h index b24e994..c604a32 100644 --- a/include/pcmki/pcmki_scheduler.h +++ b/include/pcmki/pcmki_scheduler.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2020 the Pacemaker project contributors + * Copyright 2014-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -46,6 +46,7 @@ typedef struct { int role_rh; int score; + bool influence; // Whether rsc_lh should influence active rsc_rh placement } pcmk__colocation_t; enum loss_ticket_policy_e { diff --git a/lib/pacemaker/pcmk_sched_bundle.c b/lib/pacemaker/pcmk_sched_bundle.c index 4f41b70..bc7009d 100644 --- a/lib/pacemaker/pcmk_sched_bundle.c +++ b/lib/pacemaker/pcmk_sched_bundle.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2020 the Pacemaker project contributors + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -143,7 +145,7 @@ pcmk__bundle_allocate(pe_resource_t *rsc, pe_node_t *prefer, pcmk__new_colocation("child-remote-with-docker-remote", NULL, INFINITY, replica->remote, container_host->details->remote_rsc, NULL, - NULL, data_set); + NULL, true, data_set); } if (replica->remote) { @@ -311,7 +313,8 @@ pcmk__bundle_internal_constraints(pe_resource_t *rsc, pe_order_implies_first|pe_order_preserve, data_set); pcmk__new_colocation("ip-with-docker", NULL, INFINITY, replica->ip, - replica->container, NULL, NULL, data_set); + replica->container, NULL, NULL, true, + data_set); } if (replica->remote) { diff --git a/lib/pacemaker/pcmk_sched_constraints.c b/lib/pacemaker/pcmk_sched_constraints.c index 92b9740..be93f0b 100644 --- a/lib/pacemaker/pcmk_sched_constraints.c +++ b/lib/pacemaker/pcmk_sched_constraints.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2020 the Pacemaker project contributors + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -1346,7 +1347,7 @@ void pcmk__new_colocation(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) + bool influence, pe_working_set_t *data_set) { pcmk__colocation_t *new_con = NULL; @@ -1376,6 +1377,7 @@ pcmk__new_colocation(const char *id, const char *node_attr, int score, new_con->role_lh = text2role(state_lh); new_con->role_rh = text2role(state_rh); new_con->node_attribute = node_attr; + new_con->influence = influence; if (node_attr == NULL) { node_attr = CRM_ATTR_UNAME; @@ -2279,8 +2281,38 @@ unpack_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) return TRUE; } +/*! + * \internal + * \brief Return the boolean influence corresponding to configuration + * + * \param[in] coloc_id Colocation XML ID (for error logging) + * \param[in] rsc Resource involved in constraint (for default) + * \param[in] influence_s String value of influence option + * + * \return true if string evaluates true, false if string evaluates false, + * or value of resource's critical option if string is NULL or invalid + */ +static bool +unpack_influence(const char *coloc_id, const pe_resource_t *rsc, + const char *influence_s) +{ + if (influence_s != NULL) { + int influence_i = 0; + + if (crm_str_to_boolean(influence_s, &influence_i) < 0) { + pcmk__config_err("Constraint '%s' has invalid value for " + XML_COLOC_ATTR_INFLUENCE " (using default)", + coloc_id); + } else { + return (influence_i == TRUE); + } + } + return pcmk_is_set(rsc->flags, pe_rsc_critical); +} + static gboolean -unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set) +unpack_colocation_set(xmlNode *set, int score, const char *coloc_id, + const char *influence_s, pe_working_set_t *data_set) { xmlNode *xml_rsc = NULL; pe_resource_t *with = NULL; @@ -2314,7 +2346,10 @@ unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set) if (with != NULL) { pe_rsc_trace(resource, "Colocating %s with %s", resource->id, with->id); pcmk__new_colocation(set_id, NULL, local_score, resource, - with, role, role, data_set); + with, role, role, + unpack_influence(coloc_id, resource, + influence_s), + data_set); } with = resource; @@ -2330,7 +2365,10 @@ unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set) if (last != NULL) { pe_rsc_trace(resource, "Colocating %s with %s", last->id, resource->id); pcmk__new_colocation(set_id, NULL, local_score, last, - resource, role, role, data_set); + resource, role, role, + unpack_influence(coloc_id, last, + influence_s), + data_set); } last = resource; @@ -2348,8 +2386,10 @@ unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set) if (pcmk__str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, pcmk__str_none)) { xmlNode *xml_rsc_with = NULL; + bool influence = true; EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc)); + influence = unpack_influence(coloc_id, resource, influence_s); for (xml_rsc_with = pcmk__xe_first_child(set); xml_rsc_with != NULL; @@ -2364,7 +2404,7 @@ unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set) with->id); pcmk__new_colocation(set_id, NULL, local_score, resource, with, role, role, - data_set); + influence, data_set); } } } @@ -2376,7 +2416,7 @@ unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set) static gboolean colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score, - pe_working_set_t * data_set) + const char *influence_s, pe_working_set_t *data_set) { xmlNode *xml_rsc = NULL; pe_resource_t *rsc_1 = NULL; @@ -2416,16 +2456,19 @@ colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score, if (rsc_1 != NULL && rsc_2 != NULL) { pcmk__new_colocation(id, NULL, score, rsc_1, rsc_2, role_1, role_2, + unpack_influence(id, rsc_1, influence_s), data_set); } else if (rsc_1 != NULL) { + bool influence = unpack_influence(id, rsc_1, influence_s); + for (xml_rsc = pcmk__xe_first_child(set2); xml_rsc != NULL; xml_rsc = pcmk__xe_next(xml_rsc)) { if (pcmk__str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, pcmk__str_none)) { EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc)); pcmk__new_colocation(id, NULL, score, rsc_1, rsc_2, role_1, - role_2, data_set); + role_2, influence, data_set); } } @@ -2436,7 +2479,9 @@ colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score, if (pcmk__str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, pcmk__str_none)) { EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc)); pcmk__new_colocation(id, NULL, score, rsc_1, rsc_2, role_1, - role_2, data_set); + role_2, + unpack_influence(id, rsc_1, influence_s), + data_set); } } @@ -2446,8 +2491,10 @@ colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score, if (pcmk__str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, pcmk__str_none)) { xmlNode *xml_rsc_2 = NULL; + bool influence = true; EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc)); + influence = unpack_influence(id, rsc_1, influence_s); for (xml_rsc_2 = pcmk__xe_first_child(set2); xml_rsc_2 != NULL; @@ -2456,7 +2503,8 @@ colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score, if (pcmk__str_eq((const char *)xml_rsc_2->name, XML_TAG_RESOURCE_REF, pcmk__str_none)) { EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc_2)); pcmk__new_colocation(id, NULL, score, rsc_1, rsc_2, - role_1, role_2, data_set); + role_1, role_2, influence, + data_set); } } } @@ -2467,13 +2515,12 @@ colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score, } static void -unpack_simple_colocation(xmlNode * xml_obj, pe_working_set_t * data_set) +unpack_simple_colocation(xmlNode *xml_obj, const char *id, + const char *influence_s, pe_working_set_t *data_set) { int score_i = 0; - const char *id = crm_element_value(xml_obj, XML_ATTR_ID); const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); - const char *id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE); const char *id_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET); const char *state_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE); @@ -2542,7 +2589,7 @@ unpack_simple_colocation(xmlNode * xml_obj, pe_working_set_t * data_set) } pcmk__new_colocation(id, attr, score_i, rsc_lh, rsc_rh, state_lh, state_rh, - data_set); + unpack_influence(id, rsc_lh, influence_s), data_set); } static gboolean @@ -2675,6 +2722,8 @@ unpack_rsc_colocation(xmlNode *xml_obj, pe_working_set_t *data_set) const char *id = crm_element_value(xml_obj, XML_ATTR_ID); const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); + const char *influence_s = crm_element_value(xml_obj, + XML_COLOC_ATTR_INFLUENCE); if (score) { score_i = char2score(score); @@ -2694,10 +2743,12 @@ unpack_rsc_colocation(xmlNode *xml_obj, pe_working_set_t *data_set) if (pcmk__str_eq((const char *)set->name, XML_CONS_TAG_RSC_SET, pcmk__str_none)) { any_sets = TRUE; set = expand_idref(set, data_set->input); - if (!unpack_colocation_set(set, score_i, data_set)) { + if (!unpack_colocation_set(set, score_i, id, influence_s, + data_set)) { return; } - if (last && !colocate_rsc_sets(id, last, set, score_i, data_set)) { + if ((last != NULL) && !colocate_rsc_sets(id, last, set, score_i, + influence_s, data_set)) { return; } last = set; @@ -2710,7 +2761,7 @@ unpack_rsc_colocation(xmlNode *xml_obj, pe_working_set_t *data_set) } if (!any_sets) { - unpack_simple_colocation(xml_obj, data_set); + unpack_simple_colocation(xml_obj, id, influence_s, data_set); } } diff --git a/lib/pacemaker/pcmk_sched_group.c b/lib/pacemaker/pcmk_sched_group.c index 5334f23..03df5e2 100644 --- a/lib/pacemaker/pcmk_sched_group.c +++ b/lib/pacemaker/pcmk_sched_group.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2020 the Pacemaker project contributors + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -193,7 +195,9 @@ group_internal_constraints(pe_resource_t * rsc, pe_working_set_t * data_set) } else if (group_data->colocated) { pcmk__new_colocation("group:internal_colocation", NULL, INFINITY, - child_rsc, last_rsc, NULL, NULL, data_set); + child_rsc, last_rsc, NULL, NULL, + pcmk_is_set(child_rsc->flags, pe_rsc_critical), + data_set); } if (pcmk_is_set(top->flags, pe_rsc_promotable)) { diff --git a/lib/pacemaker/pcmk_sched_native.c b/lib/pacemaker/pcmk_sched_native.c index 010c0fc..6675b23 100644 --- a/lib/pacemaker/pcmk_sched_native.c +++ b/lib/pacemaker/pcmk_sched_native.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2020 the Pacemaker project contributors + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -1690,7 +1692,7 @@ native_internal_constraints(pe_resource_t * rsc, pe_working_set_t * data_set) score = INFINITY; /* Force them to run on the same host */ } pcmk__new_colocation("resource-with-container", NULL, score, rsc, - rsc->container, NULL, NULL, data_set); + rsc->container, NULL, NULL, true, data_set); } }