|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* Copyright 2004-2019 the Pacemaker project contributors
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* The version control history for this file may have further details.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* This source code is licensed under the GNU General Public License version 2
|
|
rpm-build |
3ee90c |
* or later (GPLv2+) WITHOUT ANY WARRANTY.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm_resource.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#define XPATH_MAX 1024
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
char *move_lifetime = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static char *
|
|
rpm-build |
3ee90c |
parse_cli_lifetime(const char *input)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
char *later_s = NULL;
|
|
rpm-build |
3ee90c |
crm_time_t *now = NULL;
|
|
rpm-build |
3ee90c |
crm_time_t *later = NULL;
|
|
rpm-build |
3ee90c |
crm_time_t *duration = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (input == NULL) {
|
|
rpm-build |
3ee90c |
return NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
duration = crm_time_parse_duration(move_lifetime);
|
|
rpm-build |
3ee90c |
if (duration == NULL) {
|
|
rpm-build |
3ee90c |
CMD_ERR("Invalid duration specified: %s", move_lifetime);
|
|
rpm-build |
3ee90c |
CMD_ERR("Please refer to"
|
|
rpm-build |
3ee90c |
" https://en.wikipedia.org/wiki/ISO_8601#Durations"
|
|
rpm-build |
3ee90c |
" for examples of valid durations");
|
|
rpm-build |
3ee90c |
return NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
now = crm_time_new(NULL);
|
|
rpm-build |
3ee90c |
later = crm_time_add(now, duration);
|
|
rpm-build |
3ee90c |
if (later == NULL) {
|
|
rpm-build |
3ee90c |
CMD_ERR("Unable to add %s to current time", move_lifetime);
|
|
rpm-build |
3ee90c |
CMD_ERR("Please report to " PACKAGE_BUGREPORT " as possible bug");
|
|
rpm-build |
3ee90c |
crm_time_free(now);
|
|
rpm-build |
3ee90c |
crm_time_free(duration);
|
|
rpm-build |
3ee90c |
return NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_time_log(LOG_INFO, "now ", now,
|
|
rpm-build |
3ee90c |
crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone);
|
|
rpm-build |
3ee90c |
crm_time_log(LOG_INFO, "later ", later,
|
|
rpm-build |
3ee90c |
crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone);
|
|
rpm-build |
3ee90c |
crm_time_log(LOG_INFO, "duration", duration, crm_time_log_date | crm_time_log_timeofday);
|
|
rpm-build |
3ee90c |
later_s = crm_time_as_string(later, crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone);
|
|
rpm-build |
3ee90c |
printf("Migration will take effect until: %s\n", later_s);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_time_free(duration);
|
|
rpm-build |
3ee90c |
crm_time_free(later);
|
|
rpm-build |
3ee90c |
crm_time_free(now);
|
|
rpm-build |
3ee90c |
return later_s;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int
|
|
rpm-build |
3ee90c |
cli_resource_ban(const char *rsc_id, const char *host, GListPtr allnodes, cib_t * cib_conn)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
char *later_s = NULL;
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
xmlNode *fragment = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *location = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(host == NULL) {
|
|
rpm-build |
3ee90c |
GListPtr n = allnodes;
|
|
rpm-build |
3ee90c |
for(; n && rc == pcmk_ok; n = n->next) {
|
|
rpm-build |
3ee90c |
node_t *target = n->data;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = cli_resource_ban(rsc_id, target->details->uname, NULL, cib_conn);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
later_s = parse_cli_lifetime(move_lifetime);
|
|
rpm-build |
3ee90c |
if(move_lifetime && later_s == NULL) {
|
|
rpm-build |
3ee90c |
return -EINVAL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
fragment = create_xml_node(NULL, XML_CIB_TAG_CONSTRAINTS);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
location = create_xml_node(fragment, XML_CONS_TAG_RSC_LOCATION);
|
|
rpm-build |
3ee90c |
crm_xml_set_id(location, "cli-ban-%s-on-%s", rsc_id, host);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (BE_QUIET == FALSE) {
|
|
rpm-build |
3ee90c |
CMD_ERR("WARNING: Creating rsc_location constraint '%s'"
|
|
rpm-build |
3ee90c |
" with a score of -INFINITY for resource %s"
|
|
rpm-build |
3ee90c |
" on %s.", ID(location), rsc_id, host);
|
|
rpm-build |
3ee90c |
CMD_ERR("\tThis will prevent %s from %s on %s until the constraint "
|
|
rpm-build |
3ee90c |
"is removed using the clear option or by editing the CIB "
|
|
rpm-build |
3ee90c |
"with an appropriate tool",
|
|
rpm-build |
3ee90c |
rsc_id, (scope_master? "being promoted" : "running"), host);
|
|
rpm-build |
3ee90c |
CMD_ERR("\tThis will be the case even if %s is"
|
|
rpm-build |
3ee90c |
" the last node in the cluster", host);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_LOC_ATTR_SOURCE, rsc_id);
|
|
rpm-build |
3ee90c |
if(scope_master) {
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_MASTER_S);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_STARTED_S);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (later_s == NULL) {
|
|
rpm-build |
3ee90c |
/* Short form */
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_CIB_TAG_NODE, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_RULE_ATTR_SCORE, CRM_MINUS_INFINITY_S);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
xmlNode *rule = create_xml_node(location, XML_TAG_RULE);
|
|
rpm-build |
3ee90c |
xmlNode *expr = create_xml_node(rule, XML_TAG_EXPRESSION);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_set_id(rule, "cli-ban-%s-on-%s-rule", rsc_id, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(rule, XML_RULE_ATTR_SCORE, CRM_MINUS_INFINITY_S);
|
|
rpm-build |
3ee90c |
crm_xml_add(rule, XML_RULE_ATTR_BOOLEAN_OP, "and");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_set_id(expr, "cli-ban-%s-on-%s-expr", rsc_id, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_ATTRIBUTE, CRM_ATTR_UNAME);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_OPERATION, "eq");
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_VALUE, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_TYPE, "string");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
expr = create_xml_node(rule, "date_expression");
|
|
rpm-build |
3ee90c |
crm_xml_set_id(expr, "cli-ban-%s-on-%s-lifetime", rsc_id, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, "operation", "lt");
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, "end", later_s);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_log_xml_notice(fragment, "Modify");
|
|
rpm-build |
3ee90c |
rc = cib_conn->cmds->update(cib_conn, XML_CIB_TAG_CONSTRAINTS, fragment, cib_options);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free_xml(fragment);
|
|
rpm-build |
3ee90c |
free(later_s);
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int
|
|
rpm-build |
3ee90c |
cli_resource_prefer(const char *rsc_id, const char *host, cib_t * cib_conn)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
char *later_s = parse_cli_lifetime(move_lifetime);
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
xmlNode *location = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *fragment = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(move_lifetime && later_s == NULL) {
|
|
rpm-build |
3ee90c |
return -EINVAL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(cib_conn == NULL) {
|
|
rpm-build |
3ee90c |
free(later_s);
|
|
rpm-build |
3ee90c |
return -ENOTCONN;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
fragment = create_xml_node(NULL, XML_CIB_TAG_CONSTRAINTS);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
location = create_xml_node(fragment, XML_CONS_TAG_RSC_LOCATION);
|
|
rpm-build |
3ee90c |
crm_xml_set_id(location, "cli-prefer-%s", rsc_id);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_LOC_ATTR_SOURCE, rsc_id);
|
|
rpm-build |
3ee90c |
if(scope_master) {
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_MASTER_S);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_STARTED_S);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (later_s == NULL) {
|
|
rpm-build |
3ee90c |
/* Short form */
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_CIB_TAG_NODE, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_RULE_ATTR_SCORE, CRM_INFINITY_S);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
xmlNode *rule = create_xml_node(location, XML_TAG_RULE);
|
|
rpm-build |
3ee90c |
xmlNode *expr = create_xml_node(rule, XML_TAG_EXPRESSION);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_set_id(rule, "cli-prefer-rule-%s", rsc_id);
|
|
rpm-build |
3ee90c |
crm_xml_add(rule, XML_RULE_ATTR_SCORE, CRM_INFINITY_S);
|
|
rpm-build |
3ee90c |
crm_xml_add(rule, XML_RULE_ATTR_BOOLEAN_OP, "and");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_set_id(expr, "cli-prefer-expr-%s", rsc_id);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_ATTRIBUTE, CRM_ATTR_UNAME);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_OPERATION, "eq");
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_VALUE, host);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, XML_EXPR_ATTR_TYPE, "string");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
expr = create_xml_node(rule, "date_expression");
|
|
rpm-build |
3ee90c |
crm_xml_set_id(expr, "cli-prefer-lifetime-end-%s", rsc_id);
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, "operation", "lt");
|
|
rpm-build |
3ee90c |
crm_xml_add(expr, "end", later_s);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_log_xml_info(fragment, "Modify");
|
|
rpm-build |
3ee90c |
rc = cib_conn->cmds->update(cib_conn, XML_CIB_TAG_CONSTRAINTS, fragment, cib_options);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free_xml(fragment);
|
|
rpm-build |
3ee90c |
free(later_s);
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Nodes can be specified two different ways in the CIB, so we have two different
|
|
rpm-build |
3ee90c |
* functions to try clearing out any constraints on them:
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* (1) The node could be given by attribute=/value= in an expression XML node.
|
|
rpm-build |
3ee90c |
* That's what resource_clear_node_in_expr handles. That XML looks like this:
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* <rsc_location id="cli-prefer-dummy" rsc="dummy" role="Started">
|
|
rpm-build |
3ee90c |
* <rule id="cli-prefer-rule-dummy" score="INFINITY" boolean-op="and">
|
|
rpm-build |
3ee90c |
* <expression id="cli-prefer-expr-dummy" attribute="#uname" operation="eq" value="test02" type="string"/>
|
|
rpm-build |
3ee90c |
* <date_expression id="cli-prefer-lifetime-end-dummy" operation="lt" end="2018-12-12 14:05:37 -05:00"/>
|
|
rpm-build |
3ee90c |
* </rule>
|
|
rpm-build |
3ee90c |
* </rsc_location>
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* (2) The mode could be given by node= in an rsc_location XML node. That's
|
|
rpm-build |
3ee90c |
* what resource_clear_node_in_location handles. That XML looks like this:
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* <rsc_location id="cli-prefer-dummy" rsc="dummy" role="Started" node="node1" score="INFINITY"/>
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static int
|
|
rpm-build |
3ee90c |
resource_clear_node_in_expr(const char *rsc_id, const char *host, cib_t * cib_conn)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
char *xpath_string = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
xpath_string = crm_strdup_printf("//rsc_location[@id='cli-prefer-%s'][rule[@id='cli-prefer-rule-%s']/expression[@attribute='#uname' and @value='%s']]",
|
|
rpm-build |
3ee90c |
rsc_id, rsc_id, host);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = cib_conn->cmds->remove(cib_conn, xpath_string, NULL, cib_xpath | cib_options);
|
|
rpm-build |
3ee90c |
if (rc == -ENXIO) {
|
|
rpm-build |
3ee90c |
rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free(xpath_string);
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static int
|
|
rpm-build |
3ee90c |
resource_clear_node_in_location(const char *rsc_id, const char *host, cib_t * cib_conn,
|
|
rpm-build |
3ee90c |
bool clear_ban_constraints)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
xmlNode *fragment = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *location = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
fragment = create_xml_node(NULL, XML_CIB_TAG_CONSTRAINTS);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (clear_ban_constraints == TRUE) {
|
|
rpm-build |
3ee90c |
location = create_xml_node(fragment, XML_CONS_TAG_RSC_LOCATION);
|
|
rpm-build |
3ee90c |
crm_xml_set_id(location, "cli-ban-%s-on-%s", rsc_id, host);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
location = create_xml_node(fragment, XML_CONS_TAG_RSC_LOCATION);
|
|
rpm-build |
3ee90c |
crm_xml_set_id(location, "cli-prefer-%s", rsc_id);
|
|
rpm-build |
3ee90c |
if (do_force == FALSE) {
|
|
rpm-build |
3ee90c |
crm_xml_add(location, XML_CIB_TAG_NODE, host);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_log_xml_info(fragment, "Delete");
|
|
rpm-build |
3ee90c |
rc = cib_conn->cmds->remove(cib_conn, XML_CIB_TAG_CONSTRAINTS, fragment, cib_options);
|
|
rpm-build |
3ee90c |
if (rc == -ENXIO) {
|
|
rpm-build |
3ee90c |
rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free(fragment);
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int
|
|
rpm-build |
3ee90c |
cli_resource_clear(const char *rsc_id, const char *host, GListPtr allnodes, cib_t * cib_conn,
|
|
rpm-build |
3ee90c |
bool clear_ban_constraints)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(cib_conn == NULL) {
|
|
rpm-build |
3ee90c |
return -ENOTCONN;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (host) {
|
|
rpm-build |
3ee90c |
rc = resource_clear_node_in_expr(rsc_id, host, cib_conn);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* rc does not tell us whether the previous operation did anything, only
|
|
rpm-build |
3ee90c |
* whether it failed or not. Thus, as long as it did not fail, we need
|
|
rpm-build |
3ee90c |
* to try the second clear method.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
if (rc == pcmk_ok) {
|
|
rpm-build |
3ee90c |
rc = resource_clear_node_in_location(rsc_id, host, cib_conn, clear_ban_constraints);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
GListPtr n = allnodes;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Iterate over all nodes, attempting to clear the constraint from each.
|
|
rpm-build |
3ee90c |
* On the first error, abort.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
for(; n; n = n->next) {
|
|
rpm-build |
3ee90c |
node_t *target = n->data;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = cli_resource_clear(rsc_id, target->details->uname, NULL, cib_conn, clear_ban_constraints);
|
|
rpm-build |
3ee90c |
if (rc != pcmk_ok) {
|
|
rpm-build |
3ee90c |
break;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static char *
|
|
rpm-build |
3ee90c |
build_clear_xpath_string(xmlNode *constraint_node, const char *rsc, const char *node, bool scope_master)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int offset = 0;
|
|
rpm-build |
3ee90c |
char *xpath_string = NULL;
|
|
rpm-build |
3ee90c |
char *first_half = NULL;
|
|
rpm-build |
3ee90c |
char *rsc_role_substr = NULL;
|
|
rpm-build |
3ee90c |
char *date_substr = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (crm_starts_with(ID(constraint_node), "cli-ban-")) {
|
|
rpm-build |
3ee90c |
date_substr = crm_strdup_printf("//date_expression[@id='%s-lifetime']",
|
|
rpm-build |
3ee90c |
ID(constraint_node));
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (crm_starts_with(ID(constraint_node), "cli-prefer-")) {
|
|
rpm-build |
3ee90c |
date_substr = crm_strdup_printf("//date_expression[@id='cli-prefer-lifetime-end-%s']",
|
|
rpm-build |
3ee90c |
crm_element_value(constraint_node, "rsc"));
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
return NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
first_half = calloc(1, XPATH_MAX);
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "//rsc_location");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (node != NULL || rsc != NULL || scope_master == TRUE) {
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "[");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (node != NULL) {
|
|
rpm-build |
3ee90c |
if (rsc != NULL || scope_master == TRUE) {
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "@node='%s' and ", node);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "@node='%s'", node);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rsc != NULL && scope_master == TRUE) {
|
|
rpm-build |
3ee90c |
rsc_role_substr = crm_strdup_printf("@rsc='%s' and @role='%s'", rsc, RSC_ROLE_MASTER_S);
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "@rsc='%s' and @role='%s']", rsc, RSC_ROLE_MASTER_S);
|
|
rpm-build |
3ee90c |
} else if (rsc != NULL) {
|
|
rpm-build |
3ee90c |
rsc_role_substr = crm_strdup_printf("@rsc='%s'", rsc);
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "@rsc='%s']", rsc);
|
|
rpm-build |
3ee90c |
} else if (scope_master == TRUE) {
|
|
rpm-build |
3ee90c |
rsc_role_substr = crm_strdup_printf("@role='%s'", RSC_ROLE_MASTER_S);
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "@role='%s']", RSC_ROLE_MASTER_S);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
offset += snprintf(first_half + offset, XPATH_MAX - offset, "]");
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (node != NULL) {
|
|
rpm-build |
3ee90c |
if (rsc_role_substr != NULL) {
|
|
rpm-build |
3ee90c |
xpath_string = crm_strdup_printf("%s|//rsc_location[%s]/rule[expression[@attribute='#uname' and @value='%s']]%s",
|
|
rpm-build |
3ee90c |
first_half, rsc_role_substr, node, date_substr);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
xpath_string = crm_strdup_printf("%s|//rsc_location/rule[expression[@attribute='#uname' and @value='%s']]%s",
|
|
rpm-build |
3ee90c |
first_half, node, date_substr);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
xpath_string = crm_strdup_printf("%s%s", first_half, date_substr);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free(first_half);
|
|
rpm-build |
3ee90c |
free(date_substr);
|
|
rpm-build |
3ee90c |
free(rsc_role_substr);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
return xpath_string;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int
|
|
rpm-build |
3ee90c |
cli_resource_clear_all_expired(xmlNode *root, cib_t *cib_conn, const char *rsc, const char *node, bool scope_master)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlXPathObject *xpathObj = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *cib_constraints = NULL;
|
|
rpm-build |
3ee90c |
crm_time_t *now = crm_time_new(NULL);
|
|
rpm-build |
3ee90c |
int i;
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, root);
|
|
rpm-build |
3ee90c |
xpathObj = xpath_search(cib_constraints, "//" XML_CONS_TAG_RSC_LOCATION);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
for (i = 0; i < numXpathResults(xpathObj); i++) {
|
|
rpm-build |
3ee90c |
xmlNode *constraint_node = getXpathResult(xpathObj, i);
|
|
rpm-build |
3ee90c |
xmlNode *date_expr_node = NULL;
|
|
rpm-build |
3ee90c |
crm_time_t *end = NULL;
|
|
rpm-build |
3ee90c |
char *xpath_string = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
xpath_string = build_clear_xpath_string(constraint_node, rsc, node, scope_master);
|
|
rpm-build |
3ee90c |
if (xpath_string == NULL) {
|
|
rpm-build |
3ee90c |
continue;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
date_expr_node = get_xpath_object(xpath_string, constraint_node, LOG_DEBUG);
|
|
rpm-build |
3ee90c |
if (date_expr_node == NULL) {
|
|
rpm-build |
3ee90c |
free(xpath_string);
|
|
rpm-build |
3ee90c |
continue;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* And then finally, see if the date expression is expired. If so,
|
|
rpm-build |
3ee90c |
* clear the constraint.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
end = crm_time_new(crm_element_value(date_expr_node, "end"));
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (crm_time_compare(now, end) == 1) {
|
|
rpm-build |
3ee90c |
xmlNode *fragment = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *location = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
fragment = create_xml_node(NULL, XML_CIB_TAG_CONSTRAINTS);
|
|
rpm-build |
3ee90c |
location = create_xml_node(fragment, XML_CONS_TAG_RSC_LOCATION);
|
|
rpm-build |
3ee90c |
crm_xml_set_id(location, "%s", ID(constraint_node));
|
|
rpm-build |
3ee90c |
crm_log_xml_info(fragment, "Delete");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = cib_conn->cmds->remove(cib_conn, XML_CIB_TAG_CONSTRAINTS,
|
|
rpm-build |
3ee90c |
fragment, cib_options);
|
|
rpm-build |
3ee90c |
if (rc != pcmk_ok) {
|
|
rpm-build |
3ee90c |
free(xpath_string);
|
|
rpm-build |
3ee90c |
goto bail;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free_xml(fragment);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_time_free(end);
|
|
rpm-build |
3ee90c |
free(xpath_string);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
bail:
|
|
rpm-build |
3ee90c |
freeXpathObject(xpathObj);
|
|
rpm-build |
3ee90c |
crm_time_free(now);
|
|
rpm-build |
3ee90c |
return rc;
|
|
rpm-build |
3ee90c |
}
|