summaryrefslogtreecommitdiffstats
path: root/tools/crm_resource_runtime.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/crm_resource_runtime.c540
1 files changed, 303 insertions, 237 deletions
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index f25dbbc..da360fd 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -16,22 +16,22 @@
#include <crm/services_internal.h>
static GList *
-build_node_info_list(const pe_resource_t *rsc)
+build_node_info_list(const pcmk_resource_t *rsc)
{
GList *retval = NULL;
for (const GList *iter = rsc->children; iter != NULL; iter = iter->next) {
- const pe_resource_t *child = (const pe_resource_t *) iter->data;
+ const pcmk_resource_t *child = (const pcmk_resource_t *) iter->data;
for (const GList *iter2 = child->running_on;
iter2 != NULL; iter2 = iter2->next) {
- const pe_node_t *node = (const pe_node_t *) iter2->data;
+ const pcmk_node_t *node = (const pcmk_node_t *) iter2->data;
node_info_t *ni = calloc(1, sizeof(node_info_t));
ni->node_name = node->details->uname;
- ni->promoted = pcmk_is_set(rsc->flags, pe_rsc_promotable) &&
- child->fns->state(child, TRUE) == RSC_ROLE_PROMOTED;
+ ni->promoted = pcmk_is_set(rsc->flags, pcmk_rsc_promotable) &&
+ child->fns->state(child, TRUE) == pcmk_role_promoted;
retval = g_list_prepend(retval, ni);
}
@@ -41,18 +41,18 @@ build_node_info_list(const pe_resource_t *rsc)
}
GList *
-cli_resource_search(pe_resource_t *rsc, const char *requested_name,
- pe_working_set_t *data_set)
+cli_resource_search(pcmk_resource_t *rsc, const char *requested_name,
+ pcmk_scheduler_t *scheduler)
{
GList *retval = NULL;
- const pe_resource_t *parent = pe__const_top_resource(rsc, false);
+ const pcmk_resource_t *parent = pe__const_top_resource(rsc, false);
if (pe_rsc_is_clone(rsc)) {
retval = build_node_info_list(rsc);
/* The anonymous clone children's common ID is supplied */
} else if (pe_rsc_is_clone(parent)
- && !pcmk_is_set(rsc->flags, pe_rsc_unique)
+ && !pcmk_is_set(rsc->flags, pcmk_rsc_unique)
&& rsc->clone_name
&& pcmk__str_eq(requested_name, rsc->clone_name, pcmk__str_casei)
&& !pcmk__str_eq(requested_name, rsc->id, pcmk__str_casei)) {
@@ -61,10 +61,10 @@ cli_resource_search(pe_resource_t *rsc, const char *requested_name,
} else if (rsc->running_on != NULL) {
for (GList *iter = rsc->running_on; iter != NULL; iter = iter->next) {
- pe_node_t *node = (pe_node_t *) iter->data;
+ pcmk_node_t *node = (pcmk_node_t *) iter->data;
node_info_t *ni = calloc(1, sizeof(node_info_t));
ni->node_name = node->details->uname;
- ni->promoted = (rsc->fns->state(rsc, TRUE) == RSC_ROLE_PROMOTED);
+ ni->promoted = (rsc->fns->state(rsc, TRUE) == pcmk_role_promoted);
retval = g_list_prepend(retval, ni);
}
@@ -133,7 +133,7 @@ find_resource_attr(pcmk__output_t *out, cib_t * the_cib, const char *attr,
}
crm_log_xml_debug(xml_search, "Match");
- if (xml_has_children(xml_search)) {
+ if (xml_search->children != NULL) {
xmlNode *child = NULL;
rc = ENOTUNIQ;
@@ -159,8 +159,9 @@ find_resource_attr(pcmk__output_t *out, cib_t * the_cib, const char *attr,
/* PRIVATE. Use the find_matching_attr_resources instead. */
static void
-find_matching_attr_resources_recursive(pcmk__output_t *out, GList/* <pe_resource_t*> */ ** result,
- pe_resource_t * rsc, const char * rsc_id,
+find_matching_attr_resources_recursive(pcmk__output_t *out,
+ GList /* <pcmk_resource_t*> */ **result,
+ pcmk_resource_t *rsc, const char *rsc_id,
const char * attr_set, const char * attr_set_type,
const char * attr_id, const char * attr_name,
cib_t * cib, const char * cmd, int depth)
@@ -171,18 +172,19 @@ find_matching_attr_resources_recursive(pcmk__output_t *out, GList/* <pe_resource
/* visit the children */
for(GList *gIter = rsc->children; gIter; gIter = gIter->next) {
- find_matching_attr_resources_recursive(out, result, (pe_resource_t*)gIter->data,
+ find_matching_attr_resources_recursive(out, result,
+ (pcmk_resource_t *) gIter->data,
rsc_id, attr_set, attr_set_type,
attr_id, attr_name, cib, cmd, depth+1);
/* do it only once for clones */
- if(pe_clone == rsc->variant) {
+ if (rsc->variant == pcmk_rsc_variant_clone) {
break;
}
}
rc = find_resource_attr(out, cib, XML_ATTR_ID, lookup_id, attr_set_type,
attr_set, attr_id, attr_name, &local_attr_id);
- /* Post-order traversal.
+ /* Post-order traversal.
* The root is always on the list and it is the last item. */
if((0 == depth) || (pcmk_rc_ok == rc)) {
/* push the head */
@@ -195,8 +197,8 @@ find_matching_attr_resources_recursive(pcmk__output_t *out, GList/* <pe_resource
/* The result is a linearized pre-ordered tree of resources. */
-static GList/*<pe_resource_t*>*/ *
-find_matching_attr_resources(pcmk__output_t *out, pe_resource_t * rsc,
+static GList/*<pcmk_resource_t*>*/ *
+find_matching_attr_resources(pcmk__output_t *out, pcmk_resource_t *rsc,
const char * rsc_id, const char * attr_set,
const char * attr_set_type, const char * attr_id,
const char * attr_name, cib_t * cib, const char * cmd,
@@ -212,7 +214,8 @@ find_matching_attr_resources(pcmk__output_t *out, pe_resource_t * rsc,
if(force == TRUE) {
return g_list_append(result, rsc);
}
- if(rsc->parent && pe_clone == rsc->parent->variant) {
+ if ((rsc->parent != NULL)
+ && (rsc->parent->variant == pcmk_rsc_variant_clone)) {
int rc = pcmk_rc_ok;
char *local_attr_id = NULL;
rc = find_resource_attr(out, cib, XML_ATTR_ID, rsc_id, attr_set_type,
@@ -225,10 +228,12 @@ find_matching_attr_resources(pcmk__output_t *out, pe_resource_t * rsc,
cmd, attr_name, rsc->id, rsc_id);
}
return g_list_append(result, rsc);
- } else if(rsc->parent == NULL && rsc->children && pe_clone == rsc->variant) {
- pe_resource_t *child = rsc->children->data;
- if(child->variant == pe_native) {
+ } else if ((rsc->parent == NULL) && (rsc->children != NULL)
+ && (rsc->variant == pcmk_rsc_variant_clone)) {
+ pcmk_resource_t *child = rsc->children->data;
+
+ if (child->variant == pcmk_rsc_variant_primitive) {
lookup_id = clone_strip(child->id); /* Could be a cloned group! */
rc = find_resource_attr(out, cib, XML_ATTR_ID, lookup_id, attr_set_type,
attr_set, attr_id, attr_name, &local_attr_id);
@@ -253,7 +258,7 @@ find_matching_attr_resources(pcmk__output_t *out, pe_resource_t * rsc,
// \return Standard Pacemaker return code
int
-cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
+cli_resource_update_attribute(pcmk_resource_t *rsc, const char *requested_name,
const char *attr_set, const char *attr_set_type,
const char *attr_id, const char *attr_name,
const char *attr_value, gboolean recursive,
@@ -264,7 +269,7 @@ cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
char *found_attr_id = NULL;
- GList/*<pe_resource_t*>*/ *resources = NULL;
+ GList/*<pcmk_resource_t*>*/ *resources = NULL;
const char *top_id = pe__const_top_resource(rsc, false)->id;
if ((attr_id == NULL) && !force) {
@@ -333,7 +338,7 @@ cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
xmlNode *xml_obj = NULL;
found_attr_id = NULL;
- rsc = (pe_resource_t *) iter->data;
+ rsc = (pcmk_resource_t *) iter->data;
lookup_id = clone_strip(rsc->id); /* Could be a cloned group! */
rc = find_resource_attr(out, cib, XML_ATTR_ID, lookup_id, attr_set_type,
@@ -358,7 +363,7 @@ cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
rsc_attr_id = found_attr_id;
}
- xml_top = create_xml_node(NULL, crm_element_name(rsc->xml));
+ xml_top = create_xml_node(NULL, (const char *) rsc->xml->name);
crm_xml_add(xml_top, XML_ATTR_ID, lookup_id);
xml_obj = create_xml_node(xml_top, attr_set_type);
@@ -408,19 +413,19 @@ cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
need_init = false;
pcmk__unpack_constraints(rsc->cluster);
pe__clear_resource_flags_on_all(rsc->cluster,
- pe_rsc_detect_loop);
+ pcmk_rsc_detect_loop);
}
/* We want to set the attribute only on resources explicitly
* colocated with this one, so we use rsc->rsc_cons_lhs directly
* rather than the with_this_colocations() method.
*/
- pe__set_resource_flags(rsc, pe_rsc_detect_loop);
+ pe__set_resource_flags(rsc, pcmk_rsc_detect_loop);
for (lpc = rsc->rsc_cons_lhs; lpc != NULL; lpc = lpc->next) {
pcmk__colocation_t *cons = (pcmk__colocation_t *) lpc->data;
crm_debug("Checking %s %d", cons->id, cons->score);
- if (!pcmk_is_set(cons->dependent->flags, pe_rsc_detect_loop)
+ if (!pcmk_is_set(cons->dependent->flags, pcmk_rsc_detect_loop)
&& (cons->score > 0)) {
crm_debug("Setting %s=%s for dependent resource %s",
attr_name, attr_value, cons->dependent->id);
@@ -440,14 +445,14 @@ cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
// \return Standard Pacemaker return code
int
-cli_resource_delete_attribute(pe_resource_t *rsc, const char *requested_name,
+cli_resource_delete_attribute(pcmk_resource_t *rsc, const char *requested_name,
const char *attr_set, const char *attr_set_type,
const char *attr_id, const char *attr_name,
cib_t *cib, int cib_options, gboolean force)
{
pcmk__output_t *out = rsc->cluster->priv;
int rc = pcmk_rc_ok;
- GList/*<pe_resource_t*>*/ *resources = NULL;
+ GList/*<pcmk_resource_t*>*/ *resources = NULL;
if ((attr_id == NULL) && !force) {
find_resource_attr(out, cib, XML_ATTR_ID,
@@ -482,7 +487,7 @@ cli_resource_delete_attribute(pe_resource_t *rsc, const char *requested_name,
char *found_attr_id = NULL;
const char *rsc_attr_id = attr_id;
- rsc = (pe_resource_t *) iter->data;
+ rsc = (pcmk_resource_t *) iter->data;
lookup_id = clone_strip(rsc->id);
rc = find_resource_attr(out, cib, XML_ATTR_ID, lookup_id, attr_set_type,
@@ -534,9 +539,10 @@ cli_resource_delete_attribute(pe_resource_t *rsc, const char *requested_name,
// \return Standard Pacemaker return code
static int
send_lrm_rsc_op(pcmk_ipc_api_t *controld_api, bool do_fail_resource,
- const char *host_uname, const char *rsc_id, pe_working_set_t *data_set)
+ const char *host_uname, const char *rsc_id,
+ pcmk_scheduler_t *scheduler)
{
- pcmk__output_t *out = data_set->priv;
+ pcmk__output_t *out = scheduler->priv;
const char *router_node = host_uname;
const char *rsc_api_id = NULL;
const char *rsc_long_id = NULL;
@@ -544,13 +550,13 @@ send_lrm_rsc_op(pcmk_ipc_api_t *controld_api, bool do_fail_resource,
const char *rsc_provider = NULL;
const char *rsc_type = NULL;
bool cib_only = false;
- pe_resource_t *rsc = pe_find_resource(data_set->resources, rsc_id);
+ pcmk_resource_t *rsc = pe_find_resource(scheduler->resources, rsc_id);
if (rsc == NULL) {
out->err(out, "Resource %s not found", rsc_id);
return ENXIO;
- } else if (rsc->variant != pe_native) {
+ } else if (rsc->variant != pcmk_rsc_variant_primitive) {
out->err(out, "We can only process primitive resources, not %s", rsc_id);
return EINVAL;
}
@@ -564,7 +570,7 @@ send_lrm_rsc_op(pcmk_ipc_api_t *controld_api, bool do_fail_resource,
}
{
- pe_node_t *node = pe_find_node(data_set->nodes, host_uname);
+ pcmk_node_t *node = pe_find_node(scheduler->nodes, host_uname);
if (node == NULL) {
out->err(out, "Node %s not found", host_uname);
@@ -617,17 +623,20 @@ send_lrm_rsc_op(pcmk_ipc_api_t *controld_api, bool do_fail_resource,
* \note The caller is responsible for freeing the result.
*/
static inline char *
-rsc_fail_name(const pe_resource_t *rsc)
+rsc_fail_name(const pcmk_resource_t *rsc)
{
const char *name = (rsc->clone_name? rsc->clone_name : rsc->id);
- return pcmk_is_set(rsc->flags, pe_rsc_unique)? strdup(name) : clone_strip(name);
+ if (pcmk_is_set(rsc->flags, pcmk_rsc_unique)) {
+ return strdup(name);
+ }
+ return clone_strip(name);
}
// \return Standard Pacemaker return code
static int
clear_rsc_history(pcmk_ipc_api_t *controld_api, const char *host_uname,
- const char *rsc_id, pe_working_set_t *data_set)
+ const char *rsc_id, pcmk_scheduler_t *scheduler)
{
int rc = pcmk_rc_ok;
@@ -636,7 +645,7 @@ clear_rsc_history(pcmk_ipc_api_t *controld_api, const char *host_uname,
* single operation, we might wind up with a wrong idea of the current
* resource state, and we might not re-probe the resource.
*/
- rc = send_lrm_rsc_op(controld_api, false, host_uname, rsc_id, data_set);
+ rc = send_lrm_rsc_op(controld_api, false, host_uname, rsc_id, scheduler);
if (rc != pcmk_rc_ok) {
return rc;
}
@@ -654,7 +663,7 @@ clear_rsc_history(pcmk_ipc_api_t *controld_api, const char *host_uname,
static int
clear_rsc_failures(pcmk__output_t *out, pcmk_ipc_api_t *controld_api,
const char *node_name, const char *rsc_id, const char *operation,
- const char *interval_spec, pe_working_set_t *data_set)
+ const char *interval_spec, pcmk_scheduler_t *scheduler)
{
int rc = pcmk_rc_ok;
const char *failed_value = NULL;
@@ -675,7 +684,7 @@ clear_rsc_failures(pcmk__output_t *out, pcmk_ipc_api_t *controld_api,
crm_parse_interval_spec(interval_spec));
}
- for (xmlNode *xml_op = pcmk__xml_first_child(data_set->failed);
+ for (xmlNode *xml_op = pcmk__xml_first_child(scheduler->failed);
xml_op != NULL;
xml_op = pcmk__xml_next(xml_op)) {
@@ -687,10 +696,12 @@ clear_rsc_failures(pcmk__output_t *out, pcmk_ipc_api_t *controld_api,
// No resource specified means all resources match
if (rsc_id) {
- pe_resource_t *fail_rsc = pe_find_resource_with_flags(data_set->resources,
- failed_id,
- pe_find_renamed|pe_find_anon);
+ pcmk_resource_t *fail_rsc = NULL;
+ fail_rsc = pe_find_resource_with_flags(scheduler->resources,
+ failed_id,
+ pcmk_rsc_match_history
+ |pcmk_rsc_match_anon_basename);
if (!fail_rsc || !pcmk__str_eq(rsc_id, fail_rsc->id, pcmk__str_casei)) {
continue;
}
@@ -722,7 +733,7 @@ clear_rsc_failures(pcmk__output_t *out, pcmk_ipc_api_t *controld_api,
g_hash_table_iter_init(&iter, rscs);
while (g_hash_table_iter_next(&iter, (gpointer *) &failed_id, NULL)) {
crm_debug("Erasing failures of %s on %s", failed_id, node_name);
- rc = clear_rsc_history(controld_api, node_name, failed_id, data_set);
+ rc = clear_rsc_history(controld_api, node_name, failed_id, scheduler);
if (rc != pcmk_rc_ok) {
return rc;
}
@@ -733,8 +744,8 @@ clear_rsc_failures(pcmk__output_t *out, pcmk_ipc_api_t *controld_api,
// \return Standard Pacemaker return code
static int
-clear_rsc_fail_attrs(const pe_resource_t *rsc, const char *operation,
- const char *interval_spec, const pe_node_t *node)
+clear_rsc_fail_attrs(const pcmk_resource_t *rsc, const char *operation,
+ const char *interval_spec, const pcmk_node_t *node)
{
int rc = pcmk_rc_ok;
int attr_options = pcmk__node_attr_none;
@@ -754,13 +765,13 @@ clear_rsc_fail_attrs(const pe_resource_t *rsc, const char *operation,
// \return Standard Pacemaker return code
int
cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
- const pe_resource_t *rsc, const char *operation,
+ const pcmk_resource_t *rsc, const char *operation,
const char *interval_spec, bool just_failures,
- pe_working_set_t *data_set, gboolean force)
+ pcmk_scheduler_t *scheduler, gboolean force)
{
- pcmk__output_t *out = data_set->priv;
+ pcmk__output_t *out = scheduler->priv;
int rc = pcmk_rc_ok;
- pe_node_t *node = NULL;
+ pcmk_node_t *node = NULL;
if (rsc == NULL) {
return ENXIO;
@@ -768,10 +779,11 @@ cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
} else if (rsc->children) {
for (const GList *lpc = rsc->children; lpc != NULL; lpc = lpc->next) {
- const pe_resource_t *child = (const pe_resource_t *) lpc->data;
+ const pcmk_resource_t *child = (const pcmk_resource_t *) lpc->data;
rc = cli_resource_delete(controld_api, host_uname, child, operation,
- interval_spec, just_failures, data_set, force);
+ interval_spec, just_failures, scheduler,
+ force);
if (rc != pcmk_rc_ok) {
return rc;
}
@@ -783,11 +795,11 @@ cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
GList *nodes = g_hash_table_get_values(rsc->known_on);
if(nodes == NULL && force) {
- nodes = pcmk__copy_node_list(data_set->nodes, false);
+ nodes = pcmk__copy_node_list(scheduler->nodes, false);
} else if(nodes == NULL && rsc->exclusive_discover) {
GHashTableIter iter;
- pe_node_t *node = NULL;
+ pcmk_node_t *node = NULL;
g_hash_table_iter_init(&iter, rsc->allowed_nodes);
while (g_hash_table_iter_next(&iter, NULL, (void**)&node)) {
@@ -801,12 +813,12 @@ cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
}
for (lpc = nodes; lpc != NULL; lpc = lpc->next) {
- node = (pe_node_t *) lpc->data;
+ node = (pcmk_node_t *) lpc->data;
if (node->details->online) {
rc = cli_resource_delete(controld_api, node->details->uname, rsc,
operation, interval_spec, just_failures,
- data_set, force);
+ scheduler, force);
}
if (rc != pcmk_rc_ok) {
g_list_free(nodes);
@@ -818,7 +830,7 @@ cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
return pcmk_rc_ok;
}
- node = pe_find_node(data_set->nodes, host_uname);
+ node = pe_find_node(scheduler->nodes, host_uname);
if (node == NULL) {
out->err(out, "Unable to clean up %s because node %s not found",
@@ -847,13 +859,13 @@ cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
if (just_failures) {
rc = clear_rsc_failures(out, controld_api, host_uname, rsc->id, operation,
- interval_spec, data_set);
+ interval_spec, scheduler);
} else {
- rc = clear_rsc_history(controld_api, host_uname, rsc->id, data_set);
+ rc = clear_rsc_history(controld_api, host_uname, rsc->id, scheduler);
}
if (rc != pcmk_rc_ok) {
out->err(out, "Cleaned %s failures on %s, but unable to clean history: %s",
- rsc->id, host_uname, pcmk_strerror(rc));
+ rsc->id, host_uname, pcmk_rc_str(rc));
} else {
out->info(out, "Cleaned up %s on %s", rsc->id, host_uname);
}
@@ -864,9 +876,9 @@ cli_resource_delete(pcmk_ipc_api_t *controld_api, const char *host_uname,
int
cli_cleanup_all(pcmk_ipc_api_t *controld_api, const char *node_name,
const char *operation, const char *interval_spec,
- pe_working_set_t *data_set)
+ pcmk_scheduler_t *scheduler)
{
- pcmk__output_t *out = data_set->priv;
+ pcmk__output_t *out = scheduler->priv;
int rc = pcmk_rc_ok;
int attr_options = pcmk__node_attr_none;
const char *display_name = node_name? node_name : "all nodes";
@@ -878,7 +890,7 @@ cli_cleanup_all(pcmk_ipc_api_t *controld_api, const char *node_name,
}
if (node_name) {
- pe_node_t *node = pe_find_node(data_set->nodes, node_name);
+ pcmk_node_t *node = pe_find_node(scheduler->nodes, node_name);
if (node == NULL) {
out->err(out, "Unknown node: %s", node_name);
@@ -899,21 +911,21 @@ cli_cleanup_all(pcmk_ipc_api_t *controld_api, const char *node_name,
if (node_name) {
rc = clear_rsc_failures(out, controld_api, node_name, NULL,
- operation, interval_spec, data_set);
+ operation, interval_spec, scheduler);
if (rc != pcmk_rc_ok) {
out->err(out, "Cleaned all resource failures on %s, but unable to clean history: %s",
- node_name, pcmk_strerror(rc));
+ node_name, pcmk_rc_str(rc));
return rc;
}
} else {
- for (GList *iter = data_set->nodes; iter; iter = iter->next) {
- pe_node_t *node = (pe_node_t *) iter->data;
+ for (GList *iter = scheduler->nodes; iter; iter = iter->next) {
+ pcmk_node_t *node = (pcmk_node_t *) iter->data;
rc = clear_rsc_failures(out, controld_api, node->details->uname, NULL,
- operation, interval_spec, data_set);
+ operation, interval_spec, scheduler);
if (rc != pcmk_rc_ok) {
out->err(out, "Cleaned all resource failures on all nodes, but unable to clean history: %s",
- pcmk_strerror(rc));
+ pcmk_rc_str(rc));
return rc;
}
}
@@ -933,13 +945,13 @@ check_role(resource_checks_t *checks)
return;
}
switch (text2role(role_s)) {
- case RSC_ROLE_STOPPED:
+ case pcmk_role_stopped:
checks->flags |= rsc_remain_stopped;
break;
- case RSC_ROLE_UNPROMOTED:
+ case pcmk_role_unpromoted:
if (pcmk_is_set(pe__const_top_resource(checks->rsc, false)->flags,
- pe_rsc_promotable)) {
+ pcmk_rsc_promotable)) {
checks->flags |= rsc_unpromotable;
}
break;
@@ -970,7 +982,7 @@ check_locked(resource_checks_t *checks)
}
static bool
-node_is_unhealthy(pe_node_t *node)
+node_is_unhealthy(pcmk_node_t *node)
{
switch (pe__health_strategy(node->details->data_set)) {
case pcmk__health_strategy_none:
@@ -1000,7 +1012,7 @@ node_is_unhealthy(pe_node_t *node)
}
static void
-check_node_health(resource_checks_t *checks, pe_node_t *node)
+check_node_health(resource_checks_t *checks, pcmk_node_t *node)
{
if (node == NULL) {
GHashTableIter iter;
@@ -1025,7 +1037,7 @@ check_node_health(resource_checks_t *checks, pe_node_t *node)
}
int
-cli_resource_check(pcmk__output_t *out, pe_resource_t *rsc, pe_node_t *node)
+cli_resource_check(pcmk__output_t *out, pcmk_resource_t *rsc, pcmk_node_t *node)
{
resource_checks_t checks = { .rsc = rsc };
@@ -1040,15 +1052,15 @@ cli_resource_check(pcmk__output_t *out, pe_resource_t *rsc, pe_node_t *node)
// \return Standard Pacemaker return code
int
cli_resource_fail(pcmk_ipc_api_t *controld_api, const char *host_uname,
- const char *rsc_id, pe_working_set_t *data_set)
+ const char *rsc_id, pcmk_scheduler_t *scheduler)
{
crm_notice("Failing %s on %s", rsc_id, host_uname);
- return send_lrm_rsc_op(controld_api, true, host_uname, rsc_id, data_set);
+ return send_lrm_rsc_op(controld_api, true, host_uname, rsc_id, scheduler);
}
static GHashTable *
-generate_resource_params(pe_resource_t *rsc, pe_node_t *node,
- pe_working_set_t *data_set)
+generate_resource_params(pcmk_resource_t *rsc, pcmk_node_t *node,
+ pcmk_scheduler_t *scheduler)
{
GHashTable *params = NULL;
GHashTable *meta = NULL;
@@ -1059,7 +1071,7 @@ generate_resource_params(pe_resource_t *rsc, pe_node_t *node,
combined = pcmk__strkey_table(free, free);
- params = pe_rsc_params(rsc, node, data_set);
+ params = pe_rsc_params(rsc, node, scheduler);
if (params != NULL) {
g_hash_table_iter_init(&iter, params);
while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value)) {
@@ -1068,7 +1080,7 @@ generate_resource_params(pe_resource_t *rsc, pe_node_t *node,
}
meta = pcmk__strkey_table(free, free);
- get_meta_attributes(meta, rsc, node, data_set);
+ get_meta_attributes(meta, rsc, node, scheduler);
if (meta != NULL) {
g_hash_table_iter_init(&iter, meta);
while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value)) {
@@ -1082,7 +1094,7 @@ generate_resource_params(pe_resource_t *rsc, pe_node_t *node,
return combined;
}
-bool resource_is_running_on(pe_resource_t *rsc, const char *host)
+bool resource_is_running_on(pcmk_resource_t *rsc, const char *host)
{
bool found = true;
GList *hIter = NULL;
@@ -1094,7 +1106,7 @@ bool resource_is_running_on(pe_resource_t *rsc, const char *host)
rsc->fns->location(rsc, &hosts, TRUE);
for (hIter = hosts; host != NULL && hIter != NULL; hIter = hIter->next) {
- pe_node_t *node = (pe_node_t *) hIter->data;
+ pcmk_node_t *node = (pcmk_node_t *) hIter->data;
if (pcmk__strcase_any_of(host, node->details->uname, node->details->id, NULL)) {
crm_trace("Resource %s is running on %s\n", rsc->id, host);
@@ -1132,13 +1144,13 @@ get_active_resources(const char *host, GList *rsc_list)
GList *active = NULL;
for (rIter = rsc_list; rIter != NULL; rIter = rIter->next) {
- pe_resource_t *rsc = (pe_resource_t *) rIter->data;
+ pcmk_resource_t *rsc = (pcmk_resource_t *) rIter->data;
/* Expand groups to their members, because if we're restarting a member
* other than the first, we can't otherwise tell which resources are
* stopping and starting.
*/
- if (rsc->variant == pe_group) {
+ if (rsc->variant == pcmk_rsc_variant_group) {
active = g_list_concat(active,
get_active_resources(host, rsc->children));
} else if (resource_is_running_on(rsc, host)) {
@@ -1148,7 +1160,7 @@ get_active_resources(const char *host, GList *rsc_list)
return active;
}
-static void dump_list(GList *items, const char *tag)
+static void dump_list(GList *items, const char *tag)
{
int lpc = 0;
GList *item = NULL;
@@ -1170,45 +1182,45 @@ static void display_list(pcmk__output_t *out, GList *items, const char *tag)
/*!
* \internal
- * \brief Upgrade XML to latest schema version and use it as working set input
+ * \brief Upgrade XML to latest schema version and use it as scheduler input
*
- * This also updates the working set timestamp to the current time.
+ * This also updates the scheduler timestamp to the current time.
*
- * \param[in,out] data_set Working set instance to update
- * \param[in,out] xml XML to use as input
+ * \param[in,out] scheduler Scheduler data to update
+ * \param[in,out] xml XML to use as input
*
* \return Standard Pacemaker return code
* \note On success, caller is responsible for freeing memory allocated for
- * data_set->now.
+ * scheduler->now.
* \todo This follows the example of other callers of cli_config_update()
* and returns ENOKEY ("Required key not available") if that fails,
* but perhaps pcmk_rc_schema_validation would be better in that case.
*/
int
-update_working_set_xml(pe_working_set_t *data_set, xmlNode **xml)
+update_scheduler_input(pcmk_scheduler_t *scheduler, xmlNode **xml)
{
if (cli_config_update(xml, NULL, FALSE) == FALSE) {
return ENOKEY;
}
- data_set->input = *xml;
- data_set->now = crm_time_new(NULL);
+ scheduler->input = *xml;
+ scheduler->now = crm_time_new(NULL);
return pcmk_rc_ok;
}
/*!
* \internal
- * \brief Update a working set's XML input based on a CIB query
+ * \brief Update scheduler XML input based on a CIB query
*
- * \param[in] data_set Data set instance to initialize
+ * \param[in] scheduler Scheduler data to initialize
* \param[in] cib Connection to the CIB manager
*
* \return Standard Pacemaker return code
* \note On success, caller is responsible for freeing memory allocated for
- * data_set->input and data_set->now.
+ * scheduler->input and scheduler->now.
*/
static int
-update_working_set_from_cib(pcmk__output_t *out, pe_working_set_t * data_set,
- cib_t *cib)
+update_scheduler_input_to_cib(pcmk__output_t *out, pcmk_scheduler_t *scheduler,
+ cib_t *cib)
{
xmlNode *cib_xml_copy = NULL;
int rc = pcmk_rc_ok;
@@ -1217,10 +1229,10 @@ update_working_set_from_cib(pcmk__output_t *out, pe_working_set_t * data_set,
rc = pcmk_legacy2rc(rc);
if (rc != pcmk_rc_ok) {
- out->err(out, "Could not obtain the current CIB: %s (%d)", pcmk_strerror(rc), rc);
+ out->err(out, "Could not obtain the current CIB: %s (%d)", pcmk_rc_str(rc), rc);
return rc;
}
- rc = update_working_set_xml(data_set, &cib_xml_copy);
+ rc = update_scheduler_input(scheduler, &cib_xml_copy);
if (rc != pcmk_rc_ok) {
out->err(out, "Could not upgrade the current CIB XML");
free_xml(cib_xml_copy);
@@ -1232,18 +1244,19 @@ update_working_set_from_cib(pcmk__output_t *out, pe_working_set_t * data_set,
// \return Standard Pacemaker return code
static int
-update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate)
+update_dataset(cib_t *cib, pcmk_scheduler_t *scheduler, bool simulate)
{
char *pid = NULL;
char *shadow_file = NULL;
cib_t *shadow_cib = NULL;
int rc = pcmk_rc_ok;
- pcmk__output_t *out = data_set->priv;
+ pcmk__output_t *out = scheduler->priv;
- pe_reset_working_set(data_set);
- pe__set_working_set_flags(data_set, pe_flag_no_counts|pe_flag_no_compat);
- rc = update_working_set_from_cib(out, data_set, cib);
+ pe_reset_working_set(scheduler);
+ pe__set_working_set_flags(scheduler,
+ pcmk_sched_no_counts|pcmk_sched_no_compat);
+ rc = update_scheduler_input_to_cib(out, scheduler, cib);
if (rc != pcmk_rc_ok) {
return rc;
}
@@ -1261,7 +1274,7 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate)
goto done;
}
- rc = write_xml_file(data_set->input, shadow_file, FALSE);
+ rc = write_xml_file(scheduler->input, shadow_file, FALSE);
if (rc < 0) {
out->err(out, "Could not populate shadow cib: %s (%d)", pcmk_strerror(rc), rc);
@@ -1272,26 +1285,27 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate)
rc = pcmk_legacy2rc(rc);
if (rc != pcmk_rc_ok) {
- out->err(out, "Could not connect to shadow cib: %s (%d)", pcmk_strerror(rc), rc);
+ out->err(out, "Could not connect to shadow cib: %s (%d)", pcmk_rc_str(rc), rc);
goto done;
}
- pcmk__schedule_actions(data_set->input,
- pe_flag_no_counts|pe_flag_no_compat, data_set);
+ pcmk__schedule_actions(scheduler->input,
+ pcmk_sched_no_counts|pcmk_sched_no_compat,
+ scheduler);
prev_quiet = out->is_quiet(out);
out->quiet = true;
- pcmk__simulate_transition(data_set, shadow_cib, NULL);
+ pcmk__simulate_transition(scheduler, shadow_cib, NULL);
out->quiet = prev_quiet;
- rc = update_dataset(shadow_cib, data_set, false);
+ rc = update_dataset(shadow_cib, scheduler, false);
} else {
- cluster_status(data_set);
+ cluster_status(scheduler);
}
done:
- /* Do not free data_set->input here, we need rsc->xml to be valid later on */
+ // Do not free scheduler->input here, we need rsc->xml to be valid later on
cib_delete(shadow_cib);
free(pid);
@@ -1303,64 +1317,96 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate)
return rc;
}
+/*!
+ * \internal
+ * \brief Find the maximum stop timeout of a resource and its children (if any)
+ *
+ * \param[in,out] rsc Resource to get timeout for
+ *
+ * \return Maximum stop timeout for \p rsc (in milliseconds)
+ */
static int
-max_delay_for_resource(pe_working_set_t * data_set, pe_resource_t *rsc)
+max_rsc_stop_timeout(pcmk_resource_t *rsc)
{
- int delay = 0;
+ long long result_ll;
int max_delay = 0;
+ xmlNode *config = NULL;
+ GHashTable *meta = NULL;
- if(rsc && rsc->children) {
- GList *iter = NULL;
+ if (rsc == NULL) {
+ return 0;
+ }
- for(iter = rsc->children; iter; iter = iter->next) {
- pe_resource_t *child = (pe_resource_t *)iter->data;
+ // If resource is collective, use maximum of its children's stop timeouts
+ if (rsc->children != NULL) {
+ for (GList *iter = rsc->children; iter; iter = iter->next) {
+ pcmk_resource_t *child = iter->data;
+ int delay = max_rsc_stop_timeout(child);
- delay = max_delay_for_resource(data_set, child);
- if(delay > max_delay) {
- double seconds = delay / 1000.0;
- crm_trace("Calculated new delay of %.1fs due to %s", seconds, child->id);
+ if (delay > max_delay) {
+ pe_rsc_trace(rsc,
+ "Maximum stop timeout for %s is now %s due to %s",
+ rsc->id, pcmk__readable_interval(delay), child->id);
max_delay = delay;
}
}
+ return max_delay;
+ }
- } else if(rsc) {
- char *key = crm_strdup_printf("%s_%s_0", rsc->id, RSC_STOP);
- pe_action_t *stop = custom_action(rsc, key, RSC_STOP, NULL, TRUE, FALSE, data_set);
- const char *value = g_hash_table_lookup(stop->meta, XML_ATTR_TIMEOUT);
- long long result_ll;
+ // Get resource's stop action configuration from CIB
+ config = pcmk__find_action_config(rsc, PCMK_ACTION_STOP, 0, true);
- if ((pcmk__scan_ll(value, &result_ll, -1LL) == pcmk_rc_ok)
- && (result_ll >= 0) && (result_ll <= INT_MAX)) {
- max_delay = (int) result_ll;
- } else {
- max_delay = -1;
- }
- pe_free_action(stop);
+ /* Get configured timeout for stop action (fully evaluated for rules,
+ * defaults, etc.).
+ *
+ * @TODO This currently ignores node (which might matter for rules)
+ */
+ meta = pcmk__unpack_action_meta(rsc, NULL, PCMK_ACTION_STOP, 0, config);
+ if ((pcmk__scan_ll(g_hash_table_lookup(meta, XML_ATTR_TIMEOUT),
+ &result_ll, -1LL) == pcmk_rc_ok)
+ && (result_ll >= 0) && (result_ll <= INT_MAX)) {
+ max_delay = (int) result_ll;
}
+ g_hash_table_destroy(meta);
return max_delay;
}
+/*!
+ * \internal
+ * \brief Find a reasonable waiting time for stopping any one resource in a list
+ *
+ * \param[in,out] scheduler Scheduler data
+ * \param[in] resources List of names of resources that will be stopped
+ *
+ * \return Rough estimate of a reasonable time to wait (in seconds) to stop any
+ * one resource in \p resources
+ * \note This estimate is very rough, simply the maximum stop timeout of all
+ * given resources and their children, plus a small fudge factor. It does
+ * not account for children that must be stopped in sequence, action
+ * throttling, or any demotions needed. It checks the stop timeout, even
+ * if the resources in question are actually being started.
+ */
static int
-max_delay_in(pe_working_set_t * data_set, GList *resources)
+wait_time_estimate(pcmk_scheduler_t *scheduler, const GList *resources)
{
int max_delay = 0;
- GList *item = NULL;
-
- for (item = resources; item != NULL; item = item->next) {
- int delay = 0;
- pe_resource_t *rsc = pe_find_resource(data_set->resources, (const char *)item->data);
- delay = max_delay_for_resource(data_set, rsc);
+ // Find maximum stop timeout in milliseconds
+ for (const GList *item = resources; item != NULL; item = item->next) {
+ pcmk_resource_t *rsc = pe_find_resource(scheduler->resources,
+ (const char *) item->data);
+ int delay = max_rsc_stop_timeout(rsc);
- if(delay > max_delay) {
- double seconds = delay / 1000.0;
- crm_trace("Calculated new delay of %.1fs due to %s", seconds, rsc->id);
+ if (delay > max_delay) {
+ pe_rsc_trace(rsc,
+ "Wait time is now %s due to %s",
+ pcmk__readable_interval(delay), rsc->id);
max_delay = delay;
}
}
- return 5 + (max_delay / 1000);
+ return (max_delay / 1000) + 5;
}
#define waiting_for_starts(d, r, h) ((d != NULL) || \
@@ -1390,8 +1436,8 @@ max_delay_in(pe_working_set_t * data_set, GList *resources)
* \return Standard Pacemaker return code (exits on certain failures)
*/
int
-cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
- const pe_node_t *node, const char *move_lifetime,
+cli_resource_restart(pcmk__output_t *out, pcmk_resource_t *rsc,
+ const pcmk_node_t *node, const char *move_lifetime,
int timeout_ms, cib_t *cib, int cib_options,
gboolean promoted_role_only, gboolean force)
{
@@ -1412,8 +1458,8 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
GList *current_active = NULL;
GList *restart_target_active = NULL;
- pe_working_set_t *data_set = NULL;
- pe_resource_t *parent = uber_parent(rsc);
+ pcmk_scheduler_t *scheduler = NULL;
+ pcmk_resource_t *parent = uber_parent(rsc);
bool running = false;
const char *id = rsc->clone_name ? rsc->clone_name : rsc->id;
@@ -1435,7 +1481,9 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
lookup_id = clone_strip(rsc->id);
}
- rsc = parent->fns->find_rsc(parent, lookup_id, node, pe_find_any|pe_find_current);
+ rsc = parent->fns->find_rsc(parent, lookup_id, node,
+ pcmk_rsc_match_basename
+ |pcmk_rsc_match_current_node);
free(lookup_id);
running = resource_is_running_on(rsc, host);
}
@@ -1449,6 +1497,11 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
return ENXIO;
}
+ if (!pcmk_is_set(rsc->flags, pcmk_rsc_managed)) {
+ out->err(out, "Unmanaged resources cannot be restarted.");
+ return EAGAIN;
+ }
+
rsc_id = strdup(rsc->id);
if (pe_rsc_is_unique_clone(parent)) {
@@ -1485,32 +1538,32 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
- Allow a --no-deps option (aka. --force-restart)
*/
- data_set = pe_new_working_set();
- if (data_set == NULL) {
- crm_perror(LOG_ERR, "Could not allocate working set");
- rc = ENOMEM;
+ scheduler = pe_new_working_set();
+ if (scheduler == NULL) {
+ rc = errno;
+ out->err(out, "Could not allocate scheduler data: %s", pcmk_rc_str(rc));
goto done;
}
- data_set->priv = out;
- rc = update_dataset(cib, data_set, false);
+ scheduler->priv = out;
+ rc = update_dataset(cib, scheduler, false);
if(rc != pcmk_rc_ok) {
- out->err(out, "Could not get new resource list: %s (%d)", pcmk_strerror(rc), rc);
+ out->err(out, "Could not get new resource list: %s (%d)", pcmk_rc_str(rc), rc);
goto done;
}
- restart_target_active = get_active_resources(host, data_set->resources);
- current_active = get_active_resources(host, data_set->resources);
+ restart_target_active = get_active_resources(host, scheduler->resources);
+ current_active = get_active_resources(host, scheduler->resources);
dump_list(current_active, "Origin");
if (stop_via_ban) {
/* Stop the clone or bundle instance by banning it from the host */
out->quiet = true;
- rc = cli_resource_ban(out, lookup_id, host, move_lifetime, NULL, cib,
- cib_options, promoted_role_only);
-
+ rc = cli_resource_ban(out, lookup_id, host, move_lifetime, cib,
+ cib_options, promoted_role_only,
+ PCMK__ROLE_PROMOTED);
} else {
/* Stop the resource by setting target-role to Stopped.
* Remember any existing target-role so we can restore it later
@@ -1521,11 +1574,11 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
NULL, XML_RSC_ATTR_TARGET_ROLE, &orig_target_role);
rc = cli_resource_update_attribute(rsc, rsc_id, NULL, XML_TAG_META_SETS,
NULL, XML_RSC_ATTR_TARGET_ROLE,
- RSC_STOPPED, FALSE, cib, cib_options,
- force);
+ PCMK_ACTION_STOPPED, FALSE, cib,
+ cib_options, force);
}
if(rc != pcmk_rc_ok) {
- out->err(out, "Could not set target-role for %s: %s (%d)", rsc_id, pcmk_strerror(rc), rc);
+ out->err(out, "Could not set target-role for %s: %s (%d)", rsc_id, pcmk_rc_str(rc), rc);
if (current_active != NULL) {
g_list_free_full(current_active, free);
current_active = NULL;
@@ -1537,13 +1590,13 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
goto done;
}
- rc = update_dataset(cib, data_set, true);
+ rc = update_dataset(cib, scheduler, true);
if(rc != pcmk_rc_ok) {
out->err(out, "Could not determine which resources would be stopped");
goto failure;
}
- target_active = get_active_resources(host, data_set->resources);
+ target_active = get_active_resources(host, scheduler->resources);
dump_list(target_active, "Target");
list_delta = pcmk__subtract_lists(current_active, target_active, (GCompareFunc) strcmp);
@@ -1554,7 +1607,8 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
while (list_delta != NULL) {
before = g_list_length(list_delta);
if(timeout_ms == 0) {
- step_timeout_s = max_delay_in(data_set, list_delta) / sleep_interval;
+ step_timeout_s = wait_time_estimate(scheduler, list_delta)
+ / sleep_interval;
}
/* We probably don't need the entire step timeout */
@@ -1564,7 +1618,7 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
timeout -= sleep_interval;
crm_trace("%ds remaining", timeout);
}
- rc = update_dataset(cib, data_set, FALSE);
+ rc = update_dataset(cib, scheduler, FALSE);
if(rc != pcmk_rc_ok) {
out->err(out, "Could not determine which resources were stopped");
goto failure;
@@ -1572,12 +1626,12 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
if (current_active != NULL) {
g_list_free_full(current_active, free);
- current_active = NULL;
}
- current_active = get_active_resources(host, data_set->resources);
+ current_active = get_active_resources(host, scheduler->resources);
+
g_list_free(list_delta);
- list_delta = NULL;
list_delta = pcmk__subtract_lists(current_active, target_active, (GCompareFunc) strcmp);
+
dump_list(current_active, "Current");
dump_list(list_delta, "Delta");
}
@@ -1610,15 +1664,15 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
}
if(rc != pcmk_rc_ok) {
- out->err(out, "Could not unset target-role for %s: %s (%d)", rsc_id, pcmk_strerror(rc), rc);
+ out->err(out, "Could not unset target-role for %s: %s (%d)", rsc_id, pcmk_rc_str(rc), rc);
goto done;
}
if (target_active != NULL) {
g_list_free_full(target_active, free);
- target_active = NULL;
}
target_active = restart_target_active;
+
list_delta = pcmk__subtract_lists(target_active, current_active, (GCompareFunc) strcmp);
out->info(out, "Waiting for %d resources to start again:", g_list_length(list_delta));
display_list(out, list_delta, " * ");
@@ -1627,7 +1681,8 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
while (waiting_for_starts(list_delta, rsc, host)) {
before = g_list_length(list_delta);
if(timeout_ms == 0) {
- step_timeout_s = max_delay_in(data_set, list_delta) / sleep_interval;
+ step_timeout_s = wait_time_estimate(scheduler, list_delta)
+ / sleep_interval;
}
/* We probably don't need the entire step timeout */
@@ -1639,21 +1694,20 @@ cli_resource_restart(pcmk__output_t *out, pe_resource_t *rsc,
crm_trace("%ds remaining", timeout);
}
- rc = update_dataset(cib, data_set, false);
+ rc = update_dataset(cib, scheduler, false);
if(rc != pcmk_rc_ok) {
out->err(out, "Could not determine which resources were started");
goto failure;
}
+ /* It's OK if dependent resources moved to a different node,
+ * so we check active resources on all nodes.
+ */
if (current_active != NULL) {
g_list_free_full(current_active, free);
- current_active = NULL;
}
+ current_active = get_active_resources(NULL, scheduler->resources);
- /* It's OK if dependent resources moved to a different node,
- * so we check active resources on all nodes.
- */
- current_active = get_active_resources(NULL, data_set->resources);
g_list_free(list_delta);
list_delta = pcmk__subtract_lists(target_active, current_active, (GCompareFunc) strcmp);
dump_list(current_active, "Current");
@@ -1702,16 +1756,17 @@ done:
}
free(rsc_id);
free(lookup_id);
- pe_free_working_set(data_set);
+ pe_free_working_set(scheduler);
return rc;
}
static inline bool
-action_is_pending(const pe_action_t *action)
+action_is_pending(const pcmk_action_t *action)
{
- if (pcmk_any_flags_set(action->flags, pe_action_optional|pe_action_pseudo)
- || !pcmk_is_set(action->flags, pe_action_runnable)
- || pcmk__str_eq("notify", action->task, pcmk__str_casei)) {
+ if (pcmk_any_flags_set(action->flags,
+ pcmk_action_optional|pcmk_action_pseudo)
+ || !pcmk_is_set(action->flags, pcmk_action_runnable)
+ || pcmk__str_eq(PCMK_ACTION_NOTIFY, action->task, pcmk__str_casei)) {
return false;
}
return true;
@@ -1729,7 +1784,7 @@ static bool
actions_are_pending(const GList *actions)
{
for (const GList *action = actions; action != NULL; action = action->next) {
- const pe_action_t *a = (const pe_action_t *) action->data;
+ const pcmk_action_t *a = (const pcmk_action_t *) action->data;
if (action_is_pending(a)) {
crm_notice("Waiting for %s (flags=%#.8x)", a->uuid, a->flags);
@@ -1746,7 +1801,7 @@ print_pending_actions(pcmk__output_t *out, GList *actions)
out->info(out, "Pending actions:");
for (action = actions; action != NULL; action = action->next) {
- pe_action_t *a = (pe_action_t *) action->data;
+ pcmk_action_t *a = (pcmk_action_t *) action->data;
if (!action_is_pending(a)) {
continue;
@@ -1786,27 +1841,28 @@ print_pending_actions(pcmk__output_t *out, GList *actions)
int
wait_till_stable(pcmk__output_t *out, int timeout_ms, cib_t * cib)
{
- pe_working_set_t *data_set = NULL;
+ pcmk_scheduler_t *scheduler = NULL;
+ xmlXPathObjectPtr search;
int rc = pcmk_rc_ok;
+ bool pending_unknown_state_resources;
int timeout_s = timeout_ms? ((timeout_ms + 999) / 1000) : WAIT_DEFAULT_TIMEOUT_S;
time_t expire_time = time(NULL) + timeout_s;
time_t time_diff;
bool printed_version_warning = out->is_quiet(out); // i.e. don't print if quiet
- data_set = pe_new_working_set();
- if (data_set == NULL) {
+ scheduler = pe_new_working_set();
+ if (scheduler == NULL) {
return ENOMEM;
}
do {
-
/* Abort if timeout is reached */
time_diff = expire_time - time(NULL);
if (time_diff > 0) {
crm_info("Waiting up to %lld seconds for cluster actions to complete", (long long) time_diff);
} else {
- print_pending_actions(out, data_set->actions);
- pe_free_working_set(data_set);
+ print_pending_actions(out, scheduler->actions);
+ pe_free_working_set(scheduler);
return ETIME;
}
if (rc == pcmk_rc_ok) { /* this avoids sleep on first loop iteration */
@@ -1814,14 +1870,15 @@ wait_till_stable(pcmk__output_t *out, int timeout_ms, cib_t * cib)
}
/* Get latest transition graph */
- pe_reset_working_set(data_set);
- rc = update_working_set_from_cib(out, data_set, cib);
+ pe_reset_working_set(scheduler);
+ rc = update_scheduler_input_to_cib(out, scheduler, cib);
if (rc != pcmk_rc_ok) {
- pe_free_working_set(data_set);
+ pe_free_working_set(scheduler);
return rc;
}
- pcmk__schedule_actions(data_set->input,
- pe_flag_no_counts|pe_flag_no_compat, data_set);
+ pcmk__schedule_actions(scheduler->input,
+ pcmk_sched_no_counts|pcmk_sched_no_compat,
+ scheduler);
if (!printed_version_warning) {
/* If the DC has a different version than the local node, the two
@@ -1832,7 +1889,7 @@ wait_till_stable(pcmk__output_t *out, int timeout_ms, cib_t * cib)
* wait as a new controller operation that would be forwarded to the
* DC. However, that would have potential problems of its own.
*/
- const char *dc_version = g_hash_table_lookup(data_set->config_hash,
+ const char *dc_version = g_hash_table_lookup(scheduler->config_hash,
"dc-version");
if (!pcmk__str_eq(dc_version, PACEMAKER_VERSION "-" BUILD_VERSION, pcmk__str_casei)) {
@@ -1842,9 +1899,13 @@ wait_till_stable(pcmk__output_t *out, int timeout_ms, cib_t * cib)
}
}
- } while (actions_are_pending(data_set->actions));
+ search = xpath_search(scheduler->input, "/cib/status/node_state/lrm/lrm_resources/lrm_resource/"
+ XML_LRM_TAG_RSC_OP "[@" XML_LRM_ATTR_RC "='193']");
+ pending_unknown_state_resources = (numXpathResults(search) > 0);
+ freeXpathObject(search);
+ } while (actions_are_pending(scheduler->actions) || pending_unknown_state_resources);
- pe_free_working_set(data_set);
+ pe_free_working_set(scheduler);
return rc;
}
@@ -1853,10 +1914,10 @@ get_action(const char *rsc_action) {
const char *action = NULL;
if (pcmk__str_eq(rsc_action, "validate", pcmk__str_casei)) {
- action = "validate-all";
+ action = PCMK_ACTION_VALIDATE_ALL;
} else if (pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) {
- action = "monitor";
+ action = PCMK_ACTION_MONITOR;
} else if (pcmk__strcase_any_of(rsc_action, "force-start", "force-stop",
"force-demote", "force-promote", NULL)) {
@@ -1898,7 +1959,7 @@ set_agent_environment(GHashTable *params, int timeout_ms, int check_level,
free(level);
}
- setenv("HA_debug", (verbosity > 0)? "1" : "0", 1);
+ pcmk__set_env_option(PCMK__ENV_DEBUG, ((verbosity > 0)? "1" : "0"), true);
if (verbosity > 1) {
setenv("OCF_TRACE_RA", "1", 1);
}
@@ -1948,7 +2009,7 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
// If no timeout was provided, use the same default as the cluster
if (timeout_ms == 0) {
- timeout_ms = crm_get_msec(CRM_DEFAULT_OP_TIMEOUT_S);
+ timeout_ms = PCMK_DEFAULT_ACTION_TIMEOUT_MS;
}
set_agent_environment(params, timeout_ms, check_level, resource_verbose);
@@ -2000,12 +2061,12 @@ done:
}
crm_exit_t
-cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
+cli_resource_execute(pcmk_resource_t *rsc, const char *requested_name,
const char *rsc_action, GHashTable *override_hash,
- int timeout_ms, cib_t * cib, pe_working_set_t *data_set,
+ int timeout_ms, cib_t *cib, pcmk_scheduler_t *scheduler,
int resource_verbose, gboolean force, int check_level)
{
- pcmk__output_t *out = data_set->priv;
+ pcmk__output_t *out = scheduler->priv;
crm_exit_t exit_code = CRM_EX_OK;
const char *rid = NULL;
const char *rtype = NULL;
@@ -2016,7 +2077,7 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
if (pcmk__strcase_any_of(rsc_action, "force-start", "force-demote",
"force-promote", NULL)) {
if(pe_rsc_is_clone(rsc)) {
- GList *nodes = cli_resource_search(rsc, requested_name, data_set);
+ GList *nodes = cli_resource_search(rsc, requested_name, scheduler);
if(nodes != NULL && force == FALSE) {
out->err(out, "It is not safe to %s %s here: the cluster claims it is already active",
rsc_action, rsc->id);
@@ -2034,10 +2095,10 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
rsc = rsc->children->data;
}
- if(rsc->variant == pe_group) {
+ if (rsc->variant == pcmk_rsc_variant_group) {
out->err(out, "Sorry, the %s option doesn't support group resources", rsc_action);
return CRM_EX_UNIMPLEMENT_FEATURE;
- } else if (rsc->variant == pe_container || pe_rsc_is_bundled(rsc)) {
+ } else if (pe_rsc_is_bundled(rsc)) {
out->err(out, "Sorry, the %s option doesn't support bundled resources", rsc_action);
return CRM_EX_UNIMPLEMENT_FEATURE;
}
@@ -2047,10 +2108,11 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
params = generate_resource_params(rsc, NULL /* @TODO use local node */,
- data_set);
+ scheduler);
if (timeout_ms == 0) {
- timeout_ms = pe_get_configured_timeout(rsc, get_action(rsc_action), data_set);
+ timeout_ms = pe_get_configured_timeout(rsc, get_action(rsc_action),
+ scheduler);
}
rid = pe_rsc_is_anon_clone(rsc->parent)? requested_name : rsc->id;
@@ -2063,26 +2125,28 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
// \return Standard Pacemaker return code
int
-cli_resource_move(const pe_resource_t *rsc, const char *rsc_id,
+cli_resource_move(const pcmk_resource_t *rsc, const char *rsc_id,
const char *host_name, const char *move_lifetime, cib_t *cib,
- int cib_options, pe_working_set_t *data_set,
+ int cib_options, pcmk_scheduler_t *scheduler,
gboolean promoted_role_only, gboolean force)
{
- pcmk__output_t *out = data_set->priv;
+ pcmk__output_t *out = scheduler->priv;
int rc = pcmk_rc_ok;
unsigned int count = 0;
- pe_node_t *current = NULL;
- pe_node_t *dest = pe_find_node(data_set->nodes, host_name);
+ pcmk_node_t *current = NULL;
+ pcmk_node_t *dest = pe_find_node(scheduler->nodes, host_name);
bool cur_is_dest = false;
if (dest == NULL) {
return pcmk_rc_node_unknown;
}
- if (promoted_role_only && !pcmk_is_set(rsc->flags, pe_rsc_promotable)) {
- const pe_resource_t *p = pe__const_top_resource(rsc, false);
+ if (promoted_role_only
+ && !pcmk_is_set(rsc->flags, pcmk_rsc_promotable)) {
- if (pcmk_is_set(p->flags, pe_rsc_promotable)) {
+ const pcmk_resource_t *p = pe__const_top_resource(rsc, false);
+
+ if (pcmk_is_set(p->flags, pcmk_rsc_promotable)) {
out->info(out, "Using parent '%s' for move instead of '%s'.", rsc->id, rsc_id);
rsc_id = p->id;
rsc = p;
@@ -2096,15 +2160,15 @@ cli_resource_move(const pe_resource_t *rsc, const char *rsc_id,
current = pe__find_active_requires(rsc, &count);
- if (pcmk_is_set(rsc->flags, pe_rsc_promotable)) {
+ if (pcmk_is_set(rsc->flags, pcmk_rsc_promotable)) {
unsigned int promoted_count = 0;
- pe_node_t *promoted_node = NULL;
+ pcmk_node_t *promoted_node = NULL;
for (const GList *iter = rsc->children; iter; iter = iter->next) {
- const pe_resource_t *child = (const pe_resource_t *) iter->data;
+ const pcmk_resource_t *child = (const pcmk_resource_t *) iter->data;
enum rsc_role_e child_role = child->fns->state(child, TRUE);
- if (child_role == RSC_ROLE_PROMOTED) {
+ if (child_role == pcmk_role_promoted) {
rsc = child;
promoted_node = pe__current_node(child);
promoted_count++;
@@ -2137,15 +2201,17 @@ cli_resource_move(const pe_resource_t *rsc, const char *rsc_id,
}
/* Clear any previous prefer constraints across all nodes. */
- cli_resource_clear(rsc_id, NULL, data_set->nodes, cib, cib_options, false, force);
+ cli_resource_clear(rsc_id, NULL, scheduler->nodes, cib, cib_options, false,
+ force);
/* Clear any previous ban constraints on 'dest'. */
- cli_resource_clear(rsc_id, dest->details->uname, data_set->nodes, cib,
+ cli_resource_clear(rsc_id, dest->details->uname, scheduler->nodes, cib,
cib_options, TRUE, force);
/* Record an explicit preference for 'dest' */
rc = cli_resource_prefer(out, rsc_id, dest->details->uname, move_lifetime,
- cib, cib_options, promoted_role_only);
+ cib, cib_options, promoted_role_only,
+ PCMK__ROLE_PROMOTED);
crm_trace("%s%s now prefers %s%s",
rsc->id, (promoted_role_only? " (promoted)" : ""),
@@ -2158,8 +2224,8 @@ cli_resource_move(const pe_resource_t *rsc, const char *rsc_id,
/* Ban the original location if possible */
if(current) {
(void)cli_resource_ban(out, rsc_id, current->details->uname, move_lifetime,
- NULL, cib, cib_options, promoted_role_only);
-
+ cib, cib_options, promoted_role_only,
+ PCMK__ROLE_PROMOTED);
} else if(count > 1) {
out->info(out, "Resource '%s' is currently %s in %d locations. "
"One may now move to %s",