Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/include/crm/pengine/complex.h b/include/crm/pengine/complex.h
index edf525dce6..e57674d940 100644
--- a/include/crm/pengine/complex.h
+++ b/include/crm/pengine/complex.h
@@ -1,120 +1,121 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PENGINE_COMPLEX__H
#define PENGINE_COMPLEX__H
#define n_object_classes 3
/*#define PE_OBJ_F_ ""*/
#define PE_OBJ_T_NATIVE "native"
#define PE_OBJ_T_GROUP "group"
#define PE_OBJ_T_INCARNATION "clone"
#define PE_OBJ_T_MASTER "master"
enum pe_obj_types
{
pe_unknown = -1,
pe_native = 0,
pe_group = 1,
pe_clone = 2,
pe_master = 3
};
extern int get_resource_type(const char *name);
typedef struct resource_object_functions_s
{
gboolean (*unpack)(resource_t *, pe_working_set_t *);
resource_t *(*find_child)(resource_t *, const char *);
GListPtr (*children)(resource_t *);
/* parameter result must be free'd */
char *(*parameter)(
resource_t *, node_t *, gboolean, const char *,
pe_working_set_t *);
void (*print)(resource_t *, const char *, long, void *);
gboolean (*active)(resource_t *,gboolean);
enum rsc_role_e (*state)(const resource_t *, gboolean);
node_t *(*location)(resource_t *, GListPtr*, gboolean);
void (*free)(resource_t *);
} resource_object_functions_t;
extern void common_update_score(resource_t *rsc, const char *id, int score);
extern void common_apply_stickiness(resource_t *rsc, node_t *node, pe_working_set_t *data_set);
extern char *native_parameter(
resource_t *rsc, node_t *node, gboolean create, const char *name,
pe_working_set_t *data_set);
extern gboolean native_unpack(resource_t *rsc, pe_working_set_t *data_set);
extern gboolean group_unpack(resource_t *rsc, pe_working_set_t *data_set);
extern gboolean clone_unpack(resource_t *rsc, pe_working_set_t *data_set);
extern gboolean master_unpack(resource_t *rsc, pe_working_set_t *data_set);
extern GListPtr native_children(resource_t *rsc);
extern GListPtr group_children(resource_t *rsc);
extern GListPtr clone_children(resource_t *rsc);
extern GListPtr master_children(resource_t *rsc);
extern resource_t *native_find_child(resource_t *rsc, const char *id);
extern resource_t *group_find_child(resource_t *rsc, const char *id);
extern resource_t *clone_find_child(resource_t *rsc, const char *id);
extern resource_t *master_find_child(resource_t *rsc, const char *id);
extern gboolean native_active(resource_t *rsc, gboolean all);
extern gboolean group_active(resource_t *rsc, gboolean all);
extern gboolean clone_active(resource_t *rsc, gboolean all);
extern gboolean master_active(resource_t *rsc, gboolean all);
extern void native_print(
resource_t *rsc, const char *pre_text, long options, void *print_data);
extern void group_print(
resource_t *rsc, const char *pre_text, long options, void *print_data);
extern void clone_print(
resource_t *rsc, const char *pre_text, long options, void *print_data);
extern void master_print(
resource_t *rsc, const char *pre_text, long options, void *print_data);
extern void native_free(resource_t *rsc);
extern void group_free(resource_t *rsc);
extern void clone_free(resource_t *rsc);
extern void master_free(resource_t *rsc);
extern enum rsc_role_e native_resource_state(const resource_t *rsc, gboolean current);
extern enum rsc_role_e group_resource_state(const resource_t *rsc, gboolean current);
extern enum rsc_role_e clone_resource_state(const resource_t *rsc, gboolean current);
extern enum rsc_role_e master_resource_state(const resource_t *rsc, gboolean current);
extern node_t *native_location(resource_t *rsc, GListPtr *list, gboolean current);
extern resource_object_functions_t resource_class_functions[];
extern gboolean common_unpack(crm_data_t * xml_obj, resource_t **rsc,
resource_t *parent, pe_working_set_t *data_set);
extern void common_print(resource_t *rsc, const char *pre_text, long options, void *print_data);
extern void common_free(resource_t *rsc);
extern void native_add_running(
resource_t *rsc, node_t *node, pe_working_set_t *data_set);
extern void get_meta_attributes(GHashTable *meta_hash, resource_t *rsc,
node_t *node, pe_working_set_t *data_set);
typedef struct resource_alloc_functions_s resource_alloc_functions_t;
+extern resource_t *uber_parent(resource_t *rsc);
#endif
diff --git a/lib/crm/pengine/complex.c b/lib/crm/pengine/complex.c
index 77e323a51e..5d81cfa3e4 100644
--- a/lib/crm/pengine/complex.c
+++ b/lib/crm/pengine/complex.c
@@ -1,416 +1,429 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <crm_internal.h>
#include <utils.h>
#include <crm/pengine/rules.h>
#include <crm/msg_xml.h>
#include <clplumbing/cl_misc.h>
void populate_hash(crm_data_t *nvpair_list, GHashTable *hash,
const char **attrs, int attrs_length);
resource_object_functions_t resource_class_functions[] = {
{
native_unpack,
native_find_child,
native_children,
native_parameter,
native_print,
native_active,
native_resource_state,
native_location,
native_free
},
{
group_unpack,
native_find_child,
native_children,
native_parameter,
group_print,
group_active,
group_resource_state,
native_location,
group_free
},
{
clone_unpack,
native_find_child,
native_children,
native_parameter,
clone_print,
clone_active,
clone_resource_state,
native_location,
clone_free
},
{
master_unpack,
native_find_child,
native_children,
native_parameter,
clone_print,
clone_active,
clone_resource_state,
native_location,
clone_free
}
};
int get_resource_type(const char *name)
{
if(safe_str_eq(name, XML_CIB_TAG_RESOURCE)) {
return pe_native;
} else if(safe_str_eq(name, XML_CIB_TAG_GROUP)) {
return pe_group;
} else if(safe_str_eq(name, XML_CIB_TAG_INCARNATION)) {
return pe_clone;
} else if(safe_str_eq(name, XML_CIB_TAG_MASTER)) {
return pe_master;
}
return pe_unknown;
}
static void dup_attr(gpointer key, gpointer value, gpointer user_data)
{
add_hash_param(user_data, key, value);
}
void
get_meta_attributes(GHashTable *meta_hash, resource_t *rsc,
node_t *node, pe_working_set_t *data_set)
{
GHashTable *node_hash = NULL;
if(node) {
node_hash = node->details->attrs;
}
xml_prop_iter(rsc->xml, prop_name, prop_value,
add_hash_param(meta_hash, prop_name, prop_value);
);
unpack_instance_attributes(rsc->xml, XML_TAG_META_SETS, node_hash,
meta_hash, NULL, data_set->now);
/* populate from the regular attributes until the GUI can create
* meta attributes
*/
unpack_instance_attributes(rsc->xml, XML_TAG_ATTR_SETS, node_hash,
meta_hash, NULL, data_set->now);
/* set anything else based on the parent */
if(rsc->parent != NULL) {
g_hash_table_foreach(rsc->parent->meta, dup_attr, meta_hash);
}
}
gboolean
common_unpack(crm_data_t * xml_obj, resource_t **rsc,
resource_t *parent, pe_working_set_t *data_set)
{
const char *value = NULL;
const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
crm_log_xml_debug_3(xml_obj, "Processing resource input...");
if(id == NULL) {
pe_err("Must specify id tag in <resource>");
return FALSE;
} else if(rsc == NULL) {
pe_err("Nowhere to unpack resource into");
return FALSE;
}
crm_malloc0(*rsc, sizeof(resource_t));
if(*rsc == NULL) {
return FALSE;
}
(*rsc)->xml = xml_obj;
(*rsc)->parent = parent;
(*rsc)->ops_xml = find_xml_node(xml_obj, "operations", FALSE);
(*rsc)->variant = get_resource_type(crm_element_name(xml_obj));
if((*rsc)->variant == pe_unknown) {
pe_err("Unknown resource type: %s", crm_element_name(xml_obj));
crm_free(*rsc);
return FALSE;
}
(*rsc)->parameters = g_hash_table_new_full(
g_str_hash,g_str_equal, g_hash_destroy_str,g_hash_destroy_str);
(*rsc)->meta = g_hash_table_new_full(
g_str_hash,g_str_equal, g_hash_destroy_str,g_hash_destroy_str);
value = crm_element_value(xml_obj, XML_RSC_ATTR_INCARNATION);
if(value) {
(*rsc)->id = crm_concat(id, value, ':');
add_hash_param((*rsc)->meta, XML_RSC_ATTR_INCARNATION, value);
} else {
(*rsc)->id = crm_strdup(id);
}
if(parent) {
(*rsc)->long_name = crm_concat(parent->long_name, (*rsc)->id, ':');
} else {
(*rsc)->long_name = crm_strdup((*rsc)->id);
}
(*rsc)->fns = &resource_class_functions[(*rsc)->variant];
crm_debug_3("Unpacking resource...");
get_meta_attributes((*rsc)->meta, *rsc, NULL, data_set);
if(parent != NULL) {
g_hash_table_foreach(
parent->parameters, dup_attr, (*rsc)->parameters);
}
(*rsc)->flags = 0;
set_bit((*rsc)->flags, pe_rsc_runnable);
set_bit((*rsc)->flags, pe_rsc_provisional);
if(data_set->is_managed_default) {
set_bit((*rsc)->flags, pe_rsc_managed);
}
(*rsc)->rsc_cons = NULL;
(*rsc)->actions = NULL;
(*rsc)->role = RSC_ROLE_STOPPED;
(*rsc)->next_role = RSC_ROLE_UNKNOWN;
(*rsc)->recovery_type = recovery_stop_start;
(*rsc)->stickiness = data_set->default_resource_stickiness;
(*rsc)->fail_stickiness = data_set->default_resource_fail_stickiness;
value = g_hash_table_lookup((*rsc)->meta, XML_CIB_ATTR_PRIORITY);
(*rsc)->priority = crm_parse_int(value, "0");
(*rsc)->effective_priority = (*rsc)->priority;
value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_NOTIFY);
if(crm_is_true(value)) {
set_bit((*rsc)->flags, pe_rsc_notify);
}
value = g_hash_table_lookup((*rsc)->meta, "is_managed");
if(value != NULL && safe_str_neq("default", value)) {
gboolean bool_value = TRUE;
cl_str_to_boolean(value, &bool_value);
if(bool_value == FALSE) {
clear_bit((*rsc)->flags, pe_rsc_managed);
} else {
set_bit((*rsc)->flags, pe_rsc_managed);
}
}
crm_debug_2("Options for %s", (*rsc)->id);
value = g_hash_table_lookup((*rsc)->meta, "globally_unique");
if(value == NULL || crm_is_true(value)) {
set_bit((*rsc)->flags, pe_rsc_unique);
}
value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_RESTART);
if(safe_str_eq(value, "restart")) {
(*rsc)->restart_type = pe_restart_restart;
crm_debug_2("\tDependancy restart handling: restart");
} else {
(*rsc)->restart_type = pe_restart_ignore;
crm_debug_2("\tDependancy restart handling: ignore");
}
value = g_hash_table_lookup((*rsc)->meta, "multiple_active");
if(safe_str_eq(value, "stop_only")) {
(*rsc)->recovery_type = recovery_stop_only;
crm_debug_2("\tMultiple running resource recovery: stop only");
} else if(safe_str_eq(value, "block")) {
(*rsc)->recovery_type = recovery_block;
crm_debug_2("\tMultiple running resource recovery: block");
} else {
(*rsc)->recovery_type = recovery_stop_start;
crm_debug_2("\tMultiple running resource recovery: stop/start");
}
value = g_hash_table_lookup((*rsc)->meta, "resource_stickiness");
if(value != NULL && safe_str_neq("default", value)) {
(*rsc)->stickiness = char2score(value);
}
value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_FAIL_STICKINESS);
if(value != NULL) {
(*rsc)->fail_stickiness = char2score(value);
}
value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_TARGET_ROLE);
if(value != NULL && safe_str_neq("default", value)) {
(*rsc)->next_role = text2role(value);
if((*rsc)->next_role == RSC_ROLE_UNKNOWN) {
crm_config_err("%s: Unknown value for "
XML_RSC_ATTR_TARGET_ROLE": %s",
(*rsc)->id, value);
}
}
crm_debug_2("\tDesired next state: %s",
(*rsc)->next_role!=RSC_ROLE_UNKNOWN?role2text((*rsc)->next_role):"default");
if((*rsc)->fns->unpack(*rsc, data_set) == FALSE) {
return FALSE;
}
if(is_not_set((*rsc)->flags, pe_rsc_managed)) {
crm_warn("Resource %s is currently not managed", (*rsc)->id);
} else if(data_set->symmetric_cluster) {
resource_location(*rsc, NULL, 0, "symmetric_default", data_set);
}
crm_debug_2("\tAction notification: %s",
is_set((*rsc)->flags, pe_rsc_notify)?"required":"not required");
/* data_set->resources = g_list_append(data_set->resources, (*rsc)); */
return TRUE;
}
void common_update_score(resource_t *rsc, const char *id, int score)
{
node_t *node = NULL;
node = pe_find_node_id(rsc->allowed_nodes, id);
if(node != NULL) {
crm_debug_2("Updating score for %s on %s: %d + %d",
rsc->id, id, node->weight, score);
node->weight = merge_weights(node->weight, score);
}
if(rsc->children) {
slist_iter(
child_rsc, resource_t, rsc->children, lpc,
common_update_score(child_rsc, id, score);
);
}
}
+resource_t *uber_parent(resource_t *rsc)
+{
+ resource_t *parent = rsc;
+ while(parent != NULL && parent->parent != NULL) {
+ parent = parent->parent;
+ }
+ return parent;
+}
+
void
common_apply_stickiness(resource_t *rsc, node_t *node, pe_working_set_t *data_set)
{
int fail_count = 0;
char *fail_attr = NULL;
const char *value = NULL;
GHashTable *meta_hash = NULL;
if(rsc->children) {
slist_iter(
child_rsc, resource_t, rsc->children, lpc,
common_apply_stickiness(child_rsc, node, data_set);
);
return;
}
meta_hash = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
get_meta_attributes(meta_hash, rsc, node, data_set);
/* update resource preferences that relate to the current node */
value = g_hash_table_lookup(meta_hash, "resource_stickiness");
if(value != NULL && safe_str_neq("default", value)) {
rsc->stickiness = char2score(value);
} else {
rsc->stickiness = data_set->default_resource_stickiness;
}
value = g_hash_table_lookup(meta_hash, XML_RSC_ATTR_FAIL_STICKINESS);
if(value != NULL && safe_str_neq("default", value)) {
rsc->fail_stickiness = char2score(value);
} else {
rsc->fail_stickiness = data_set->default_resource_fail_stickiness;
}
/* process failure stickiness */
fail_attr = crm_concat("fail-count", rsc->id, '-');
value = g_hash_table_lookup(node->details->attrs, fail_attr);
if(value != NULL) {
crm_debug("%s: %s", fail_attr, value);
fail_count = char2score(value);
}
crm_free(fail_attr);
if(fail_count > 0 && rsc->fail_stickiness != 0) {
- resource_location(rsc, node, fail_count * rsc->fail_stickiness,
+ resource_t *failed = rsc;
+ if(is_not_set(rsc->flags, pe_rsc_unique)) {
+ failed = uber_parent(rsc);
+ }
+ resource_location(failed, node, fail_count * rsc->fail_stickiness,
"fail_stickiness", data_set);
crm_info("Setting failure stickiness for %s on %s: %d",
- rsc->id, node->details->uname,
+ failed->id, node->details->uname,
fail_count * rsc->fail_stickiness);
}
g_hash_table_destroy(meta_hash);
}
void common_free(resource_t *rsc)
{
if(rsc == NULL) {
return;
}
crm_debug_5("Freeing %s %d", rsc->id, rsc->variant);
g_list_free(rsc->rsc_cons);
g_list_free(rsc->rsc_cons_lhs);
if(rsc->parameters != NULL) {
g_hash_table_destroy(rsc->parameters);
}
if(rsc->meta != NULL) {
g_hash_table_destroy(rsc->meta);
}
if(is_set(rsc->flags, pe_rsc_orphan)) {
free_xml(rsc->xml);
}
if(rsc->running_on) {
g_list_free(rsc->running_on);
rsc->running_on = NULL;
}
if(rsc->known_on) {
g_list_free(rsc->known_on);
rsc->known_on = NULL;
}
if(rsc->actions) {
g_list_free(rsc->actions);
rsc->actions = NULL;
}
pe_free_shallow_adv(rsc->rsc_location, FALSE);
pe_free_shallow_adv(rsc->allowed_nodes, TRUE);
crm_free(rsc->id);
crm_free(rsc->long_name);
crm_free(rsc->clone_name);
crm_free(rsc->allocated_to);
crm_free(rsc->variant_opaque);
crm_free(rsc);
crm_debug_5("Resource freed");
}
diff --git a/pengine/testcases/stonith-2.dot b/pengine/testcases/stonith-2.dot
index abc0fc7f5b..f41858ec09 100644
--- a/pengine/testcases/stonith-2.dot
+++ b/pengine/testcases/stonith-2.dot
@@ -1,39 +1,11 @@
digraph "g" {
-"DoFencing_running_0" [ style=bold color="green" fontcolor="orange" ]
-"DoFencing_start_0" -> "DoFencing_running_0" [ style = bold]
-"DoFencing_start_0" -> "child_DoFencing:2_start_0 sles-4" [ style = bold]
-"DoFencing_start_0" -> "child_DoFencing:3_start_0 sles-3" [ style = bold]
-"DoFencing_start_0" [ style=bold color="green" fontcolor="orange" ]
-"DoFencing_stop_0" -> "DoFencing_start_0" [ style = bold]
-"DoFencing_stop_0" -> "DoFencing_stopped_0" [ style = bold]
-"DoFencing_stop_0" -> "child_DoFencing:2_stop_0 sles-3" [ style = bold]
-"DoFencing_stop_0" -> "child_DoFencing:3_stop_0 sles-4" [ style = bold]
-"DoFencing_stop_0" [ style=bold color="green" fontcolor="orange" ]
-"DoFencing_stopped_0" -> "DoFencing_start_0" [ style = bold]
-"DoFencing_stopped_0" [ style=bold color="green" fontcolor="orange" ]
"all_stopped" -> "rsc_sles-5_start_0 sles-6" [ style = bold]
"all_stopped" [ style=bold color="green" fontcolor="orange" ]
-"child_DoFencing:2_monitor_120000 sles-4" [ style=bold color="green" fontcolor="black" ]
-"child_DoFencing:2_start_0 sles-4" -> "DoFencing_running_0" [ style = bold]
-"child_DoFencing:2_start_0 sles-4" -> "child_DoFencing:2_monitor_120000 sles-4" [ style = bold]
-"child_DoFencing:2_start_0 sles-4" -> "stonith_up" [ style = bold]
-"child_DoFencing:2_start_0 sles-4" [ style=bold color="green" fontcolor="black" ]
-"child_DoFencing:2_stop_0 sles-3" -> "DoFencing_stopped_0" [ style = bold]
-"child_DoFencing:2_stop_0 sles-3" -> "child_DoFencing:2_start_0 sles-4" [ style = bold]
-"child_DoFencing:2_stop_0 sles-3" [ style=bold color="green" fontcolor="black" ]
-"child_DoFencing:3_monitor_120000 sles-3" [ style=bold color="green" fontcolor="black" ]
-"child_DoFencing:3_start_0 sles-3" -> "DoFencing_running_0" [ style = bold]
-"child_DoFencing:3_start_0 sles-3" -> "child_DoFencing:3_monitor_120000 sles-3" [ style = bold]
-"child_DoFencing:3_start_0 sles-3" -> "stonith_up" [ style = bold]
-"child_DoFencing:3_start_0 sles-3" [ style=bold color="green" fontcolor="black" ]
-"child_DoFencing:3_stop_0 sles-4" -> "DoFencing_stopped_0" [ style = bold]
-"child_DoFencing:3_stop_0 sles-4" -> "child_DoFencing:3_start_0 sles-3" [ style = bold]
-"child_DoFencing:3_stop_0 sles-4" [ style=bold color="green" fontcolor="black" ]
"rsc_sles-5_monitor_5000 sles-6" [ style=bold color="green" fontcolor="black" ]
"rsc_sles-5_start_0 sles-6" -> "rsc_sles-5_monitor_5000 sles-6" [ style = bold]
"rsc_sles-5_start_0 sles-6" [ style=bold color="green" fontcolor="black" ]
"stonith sles-5" -> "all_stopped" [ style = bold]
"stonith sles-5" [ style=bold color="green" fontcolor="black" ]
"stonith_up" -> "stonith sles-5" [ style = bold]
"stonith_up" [ style=bold color="green" fontcolor="orange" ]
}
diff --git a/pengine/testcases/stonith-2.exp b/pengine/testcases/stonith-2.exp
index ee193b01bf..de4794ff06 100644
--- a/pengine/testcases/stonith-2.exp
+++ b/pengine/testcases/stonith-2.exp
@@ -1,211 +1,61 @@
<transition_graph cluster-delay="60s" batch-limit="30" transition_id="0">
<synapse id="0">
<action_set>
<rsc_op id="55" operation="start" operation_key="rsc_sles-5_start_0" on_node="sles-6" on_node_uuid="e7840e57-67e1-44dc-9804-edd22d282394">
<primitive id="rsc_sles-5" long-id="rsc_sles-5" class="ocf" provider="heartbeat" type="IPaddr"/>
<attributes crm_feature_set="2.1" ip="192.168.100.188" CRM_meta_timeout="20000"/>
</rsc_op>
</action_set>
<inputs>
<trigger>
<pseudo_event id="26" operation="all_stopped" operation_key="all_stopped"/>
</trigger>
</inputs>
</synapse>
<synapse id="1">
<action_set>
<rsc_op id="56" operation="monitor" operation_key="rsc_sles-5_monitor_5000" on_node="sles-6" on_node_uuid="e7840e57-67e1-44dc-9804-edd22d282394">
<primitive id="rsc_sles-5" long-id="rsc_sles-5" class="ocf" provider="heartbeat" type="IPaddr"/>
<attributes crm_feature_set="2.1" ip="192.168.100.188" CRM_meta_id="rsc_sles-5-mon" CRM_meta_timeout="20000" CRM_meta_name="monitor" CRM_meta_interval="5000"/>
</rsc_op>
</action_set>
<inputs>
<trigger>
<rsc_op id="55" operation="start" operation_key="rsc_sles-5_start_0" on_node="sles-6" on_node_uuid="e7840e57-67e1-44dc-9804-edd22d282394"/>
</trigger>
</inputs>
</synapse>
<synapse id="2">
- <action_set>
- <rsc_op id="63" operation="stop" operation_key="child_DoFencing:2_stop_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700">
- <primitive id="child_DoFencing:2" long-id="DoFencing:child_DoFencing:2" class="stonith" type="external/vmware"/>
- <attributes crm_feature_set="2.1" CRM_meta_id="DoFencing-3" CRM_meta_timeout="180000" CRM_meta_name="stop" CRM_meta_globally_unique="false" CRM_meta_clone="2" CRM_meta_clone_max="6"/>
- </rsc_op>
- </action_set>
- <inputs>
- <trigger>
- <pseudo_event id="73" operation="stop" operation_key="DoFencing_stop_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="3">
- <action_set>
- <rsc_op id="64" operation="start" operation_key="child_DoFencing:2_start_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065">
- <primitive id="child_DoFencing:2" long-id="DoFencing:child_DoFencing:2" class="stonith" type="external/vmware"/>
- <attributes crm_feature_set="2.1" device_host="vmhost" CRM_meta_id="DoFencing-2" CRM_meta_timeout="180000" CRM_meta_name="start" CRM_meta_prereq="nothing" CRM_meta_globally_unique="false" CRM_meta_clone="2" CRM_meta_clone_max="6"/>
- </rsc_op>
- </action_set>
- <inputs>
- <trigger>
- <rsc_op id="63" operation="stop" operation_key="child_DoFencing:2_stop_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700"/>
- </trigger>
- <trigger>
- <pseudo_event id="71" operation="start" operation_key="DoFencing_start_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="4">
- <action_set>
- <rsc_op id="65" operation="monitor" operation_key="child_DoFencing:2_monitor_120000" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065">
- <primitive id="child_DoFencing:2" long-id="DoFencing:child_DoFencing:2" class="stonith" type="external/vmware"/>
- <attributes crm_feature_set="2.1" device_host="vmhost" CRM_meta_id="DoFencing-1" CRM_meta_timeout="300000" CRM_meta_name="monitor" CRM_meta_interval="120000" CRM_meta_prereq="nothing" CRM_meta_globally_unique="false" CRM_meta_clone="2" CRM_meta_clone_max="6"/>
- </rsc_op>
- </action_set>
- <inputs>
- <trigger>
- <rsc_op id="64" operation="start" operation_key="child_DoFencing:2_start_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="5">
- <action_set>
- <rsc_op id="66" operation="stop" operation_key="child_DoFencing:3_stop_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065">
- <primitive id="child_DoFencing:3" long-id="DoFencing:child_DoFencing:3" class="stonith" type="external/vmware"/>
- <attributes crm_feature_set="2.1" CRM_meta_id="DoFencing-3" CRM_meta_timeout="180000" CRM_meta_name="stop" CRM_meta_globally_unique="false" CRM_meta_clone="3" CRM_meta_clone_max="6"/>
- </rsc_op>
- </action_set>
- <inputs>
- <trigger>
- <pseudo_event id="73" operation="stop" operation_key="DoFencing_stop_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="6">
- <action_set>
- <rsc_op id="67" operation="start" operation_key="child_DoFencing:3_start_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700">
- <primitive id="child_DoFencing:3" long-id="DoFencing:child_DoFencing:3" class="stonith" type="external/vmware"/>
- <attributes crm_feature_set="2.1" device_host="vmhost" CRM_meta_id="DoFencing-2" CRM_meta_timeout="180000" CRM_meta_name="start" CRM_meta_prereq="nothing" CRM_meta_globally_unique="false" CRM_meta_clone="3" CRM_meta_clone_max="6"/>
- </rsc_op>
- </action_set>
- <inputs>
- <trigger>
- <rsc_op id="66" operation="stop" operation_key="child_DoFencing:3_stop_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065"/>
- </trigger>
- <trigger>
- <pseudo_event id="71" operation="start" operation_key="DoFencing_start_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="7">
- <action_set>
- <rsc_op id="68" operation="monitor" operation_key="child_DoFencing:3_monitor_120000" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700">
- <primitive id="child_DoFencing:3" long-id="DoFencing:child_DoFencing:3" class="stonith" type="external/vmware"/>
- <attributes crm_feature_set="2.1" device_host="vmhost" CRM_meta_id="DoFencing-1" CRM_meta_timeout="300000" CRM_meta_name="monitor" CRM_meta_interval="120000" CRM_meta_prereq="nothing" CRM_meta_globally_unique="false" CRM_meta_clone="3" CRM_meta_clone_max="6"/>
- </rsc_op>
- </action_set>
- <inputs>
- <trigger>
- <rsc_op id="67" operation="start" operation_key="child_DoFencing:3_start_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="8">
- <action_set>
- <pseudo_event id="71" operation="start" operation_key="DoFencing_start_0">
- <attributes crm_feature_set="2.1" CRM_meta_timeout="20000" CRM_meta_globally_unique="false"/>
- </pseudo_event>
- </action_set>
- <inputs>
- <trigger>
- <pseudo_event id="73" operation="stop" operation_key="DoFencing_stop_0"/>
- </trigger>
- <trigger>
- <pseudo_event id="74" operation="stopped" operation_key="DoFencing_stopped_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="9" priority="1000000">
- <action_set>
- <pseudo_event id="72" operation="running" operation_key="DoFencing_running_0">
- <attributes crm_feature_set="2.1" CRM_meta_timeout="20000" CRM_meta_globally_unique="false"/>
- </pseudo_event>
- </action_set>
- <inputs>
- <trigger>
- <rsc_op id="64" operation="start" operation_key="child_DoFencing:2_start_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065"/>
- </trigger>
- <trigger>
- <rsc_op id="67" operation="start" operation_key="child_DoFencing:3_start_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700"/>
- </trigger>
- <trigger>
- <pseudo_event id="71" operation="start" operation_key="DoFencing_start_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="10">
- <action_set>
- <pseudo_event id="73" operation="stop" operation_key="DoFencing_stop_0">
- <attributes crm_feature_set="2.1" CRM_meta_timeout="20000" CRM_meta_globally_unique="false"/>
- </pseudo_event>
- </action_set>
- <inputs/>
- </synapse>
- <synapse id="11" priority="1000000">
- <action_set>
- <pseudo_event id="74" operation="stopped" operation_key="DoFencing_stopped_0">
- <attributes crm_feature_set="2.1" CRM_meta_timeout="20000" CRM_meta_globally_unique="false"/>
- </pseudo_event>
- </action_set>
- <inputs>
- <trigger>
- <rsc_op id="63" operation="stop" operation_key="child_DoFencing:2_stop_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700"/>
- </trigger>
- <trigger>
- <rsc_op id="66" operation="stop" operation_key="child_DoFencing:3_stop_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065"/>
- </trigger>
- <trigger>
- <pseudo_event id="73" operation="stop" operation_key="DoFencing_stop_0"/>
- </trigger>
- </inputs>
- </synapse>
- <synapse id="12">
<action_set>
<pseudo_event id="26" operation="all_stopped" operation_key="all_stopped">
<attributes crm_feature_set="2.1"/>
</pseudo_event>
</action_set>
<inputs>
<trigger>
- <crm_event id="114" operation="stonith" operation_key="stonith" on_node="sles-5" on_node_uuid="434915c6-7b40-4d30-95ff-dc0ff3dc005a"/>
+ <crm_event id="112" operation="stonith" operation_key="stonith" on_node="sles-5" on_node_uuid="434915c6-7b40-4d30-95ff-dc0ff3dc005a"/>
</trigger>
</inputs>
</synapse>
- <synapse id="13">
+ <synapse id="3">
<action_set>
- <pseudo_event id="113" operation="stonith_up" operation_key="stonith_up">
+ <pseudo_event id="111" operation="stonith_up" operation_key="stonith_up">
<attributes crm_feature_set="2.1"/>
</pseudo_event>
</action_set>
- <inputs>
- <trigger>
- <rsc_op id="64" operation="start" operation_key="child_DoFencing:2_start_0" on_node="sles-4" on_node_uuid="6b218012-be71-4249-a8ad-332247f79065"/>
- </trigger>
- <trigger>
- <rsc_op id="67" operation="start" operation_key="child_DoFencing:3_start_0" on_node="sles-3" on_node_uuid="d38d7afa-de9e-4ef2-b4a0-fd58a7c67700"/>
- </trigger>
- </inputs>
+ <inputs/>
</synapse>
- <synapse id="14">
+ <synapse id="4">
<action_set>
- <crm_event id="114" operation="stonith" operation_key="stonith" on_node="sles-5" on_node_uuid="434915c6-7b40-4d30-95ff-dc0ff3dc005a">
+ <crm_event id="112" operation="stonith" operation_key="stonith" on_node="sles-5" on_node_uuid="434915c6-7b40-4d30-95ff-dc0ff3dc005a">
<attributes crm_feature_set="2.1" CRM_meta_on_node="sles-5" CRM_meta_stonith_action="reboot" CRM_meta_on_node_uuid="434915c6-7b40-4d30-95ff-dc0ff3dc005a"/>
</crm_event>
</action_set>
<inputs>
<trigger>
- <pseudo_event id="113" operation="stonith_up" operation_key="stonith_up"/>
+ <pseudo_event id="111" operation="stonith_up" operation_key="stonith_up"/>
</trigger>
</inputs>
</synapse>
</transition_graph>
diff --git a/pengine/utils.c b/pengine/utils.c
index ce333df928..a750f0eddf 100644
--- a/pengine/utils.c
+++ b/pengine/utils.c
@@ -1,557 +1,547 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <crm_internal.h>
#include <crm/msg_xml.h>
#include <allocate.h>
#include <utils.h>
#include <lib/crm/pengine/utils.h>
void
print_rsc_to_node(const char *pre_text, rsc_to_node_t *cons, gboolean details)
{
if(cons == NULL) {
crm_debug_4("%s%s: <NULL>",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ");
return;
}
crm_debug_4("%s%s%s Constraint %s (%p) - %d nodes:",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ",
"rsc_to_node",
cons->id, cons,
g_list_length(cons->node_list_rh));
if(details == FALSE) {
crm_debug_4("\t%s (node placement rule)",
safe_val3(NULL, cons, rsc_lh, id));
slist_iter(
node, node_t, cons->node_list_rh, lpc,
print_node("\t\t-->", node, FALSE)
);
}
}
void
print_rsc_colocation(const char *pre_text, rsc_colocation_t *cons, gboolean details)
{
if(cons == NULL) {
crm_debug_4("%s%s: <NULL>",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ");
return;
}
crm_debug_4("%s%s%s Constraint %s (%p):",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ",
XML_CONS_TAG_RSC_DEPEND, cons->id, cons);
if(details == FALSE) {
crm_debug_4("\t%s --> %s, %d",
safe_val3(NULL, cons, rsc_lh, id),
safe_val3(NULL, cons, rsc_rh, id),
cons->score);
}
}
void
pe_free_ordering(GListPtr constraints)
{
GListPtr iterator = constraints;
while(iterator != NULL) {
order_constraint_t *order = iterator->data;
iterator = iterator->next;
crm_free(order->lh_action_task);
crm_free(order->rh_action_task);
crm_free(order);
}
if(constraints != NULL) {
g_list_free(constraints);
}
}
void
pe_free_rsc_to_node(GListPtr constraints)
{
GListPtr iterator = constraints;
while(iterator != NULL) {
rsc_to_node_t *cons = iterator->data;
iterator = iterator->next;
pe_free_shallow(cons->node_list_rh);
crm_free(cons);
}
if(constraints != NULL) {
g_list_free(constraints);
}
}
rsc_to_node_t *
rsc2node_new(const char *id, resource_t *rsc,
int node_weight, node_t *foo_node, pe_working_set_t *data_set)
{
rsc_to_node_t *new_con = NULL;
if(rsc == NULL || id == NULL) {
pe_err("Invalid constraint %s for rsc=%p", crm_str(id), rsc);
return NULL;
} else if(foo_node == NULL) {
CRM_CHECK(node_weight == 0, return NULL);
}
crm_malloc0(new_con, sizeof(rsc_to_node_t));
if(new_con != NULL) {
new_con->id = id;
new_con->rsc_lh = rsc;
new_con->node_list_rh = NULL;
new_con->role_filter = RSC_ROLE_UNKNOWN;
if(foo_node != NULL) {
node_t *copy = node_copy(foo_node);
copy->weight = node_weight;
new_con->node_list_rh = g_list_append(NULL, copy);
}
data_set->placement_constraints = g_list_append(
data_set->placement_constraints, new_con);
rsc->rsc_location = g_list_append(rsc->rsc_location, new_con);
}
return new_con;
}
const char *
ordering_type2text(enum pe_ordering type)
{
const char *result = "<unknown>";
if(type & pe_order_implies_left) {
/* was: mandatory */
result = "right_implies_left";
} else if(type & pe_order_implies_right) {
/* was: recover */
result = "left_implies_right";
} else if(type & pe_order_optional) {
/* pure ordering, nothing implied */
result = "optional";
} else if(type & pe_order_runnable_left) {
result = "runnable";
} else {
crm_err("Unknown ordering type: %.3x", type);
}
return result;
}
gboolean
can_run_resources(const node_t *node)
{
if(node == NULL) {
return FALSE;
}
if(node->details->online == FALSE
|| node->details->shutdown
|| node->details->unclean
|| node->details->standby) {
crm_debug_2("%s: online=%d, unclean=%d, standby=%d",
node->details->uname, node->details->online,
node->details->unclean, node->details->standby);
return FALSE;
}
return TRUE;
}
/* return -1 if 'a' is more preferred
* return 1 if 'b' is more preferred
*/
gint sort_node_weight(gconstpointer a, gconstpointer b)
{
int level = LOG_DEBUG_3;
const node_t *node1 = (const node_t*)a;
const node_t *node2 = (const node_t*)b;
int node1_weight = 0;
int node2_weight = 0;
if(a == NULL) { return 1; }
if(b == NULL) { return -1; }
node1_weight = node1->weight;
node2_weight = node2->weight;
if(can_run_resources(node1) == FALSE) {
node1_weight = -INFINITY;
}
if(can_run_resources(node2) == FALSE) {
node2_weight = -INFINITY;
}
if(node1_weight > node2_weight) {
do_crm_log(level, "%s (%d) > %s (%d) : weight",
node1->details->uname, node1_weight,
node2->details->uname, node2_weight);
return -1;
}
if(node1_weight < node2_weight) {
do_crm_log(level, "%s (%d) < %s (%d) : weight",
node1->details->uname, node1_weight,
node2->details->uname, node2_weight);
return 1;
}
do_crm_log(level, "%s (%d) == %s (%d) : weight",
node1->details->uname, node1_weight,
node2->details->uname, node2_weight);
/* now try to balance resources across the cluster */
if(node1->details->num_resources
< node2->details->num_resources) {
do_crm_log(level, "%s (%d) < %s (%d) : resources",
node1->details->uname, node1->details->num_resources,
node2->details->uname, node2->details->num_resources);
return -1;
} else if(node1->details->num_resources
> node2->details->num_resources) {
do_crm_log(level, "%s (%d) > %s (%d) : resources",
node1->details->uname, node1->details->num_resources,
node2->details->uname, node2->details->num_resources);
return 1;
}
do_crm_log(level, "%s = %s", node1->details->uname, node2->details->uname);
return 0;
}
gboolean
native_assign_node(resource_t *rsc, GListPtr nodes, node_t *chosen)
{
int multiple = 0;
CRM_ASSERT(rsc->variant == pe_native);
clear_bit(rsc->flags, pe_rsc_provisional);
slist_iter(candidate, node_t, nodes, lpc,
crm_debug("Color %s, Node[%d] %s: %d", rsc->id, lpc,
candidate->details->uname, candidate->weight);
if(chosen->weight > 0
&& candidate->details->unclean == FALSE
&& candidate->weight == chosen->weight) {
multiple++;
}
);
if(chosen == NULL) {
crm_debug("Could not allocate a node for %s", rsc->id);
rsc->next_role = RSC_ROLE_STOPPED;
return FALSE;
} else if(can_run_resources(chosen) == FALSE || chosen->weight < 0) {
crm_debug("All nodes for resource %s are unavailable"
", unclean or shutting down", rsc->id);
rsc->next_role = RSC_ROLE_STOPPED;
return FALSE;
}
if(rsc->next_role == RSC_ROLE_UNKNOWN) {
rsc->next_role = RSC_ROLE_STARTED;
}
if(multiple > 1) {
int log_level = LOG_INFO;
char *score = score2char(chosen->weight);
if(chosen->weight >= INFINITY) {
log_level = LOG_WARNING;
}
do_crm_log(log_level, "%d nodes with equal score (%s) for"
" running the listed resources (chose %s):",
multiple, score, chosen->details->uname);
crm_free(score);
}
/* todo: update the old node for each resource to reflect its
* new resource count
*/
if(rsc->allocated_to) {
node_t *old = rsc->allocated_to;
old->details->allocated_rsc = g_list_remove(
old->details->allocated_rsc, rsc);
old->details->num_resources--;
old->count--;
}
crm_debug("Assigning %s to %s", chosen->details->uname, rsc->id);
crm_free(rsc->allocated_to);
rsc->allocated_to = node_copy(chosen);
chosen->details->allocated_rsc = g_list_append(chosen->details->allocated_rsc, rsc);
chosen->details->num_resources++;
chosen->count++;
return TRUE;
}
void
convert_non_atomic_task(resource_t *rsc, order_constraint_t *order)
{
int interval = 0;
char *rid = NULL;
char *raw_task = NULL;
int task = no_action;
char *old_uuid = order->lh_action_task;
crm_debug_3("Processing %s", old_uuid);
if(order->lh_action_task == NULL
|| strstr(order->lh_action_task, "notify") != NULL) {
/* no conversion */
return;
}
CRM_ASSERT(parse_op_key(old_uuid, &rid, &raw_task, &interval));
task = text2task(raw_task);
switch(task) {
case stop_rsc:
case start_rsc:
case action_notify:
case action_promote:
case action_demote:
break;
case stopped_rsc:
case started_rsc:
case action_notified:
case action_promoted:
case action_demoted:
task--;
break;
case monitor_rsc:
case shutdown_crm:
case stonith_node:
task = no_action;
break;
default:
crm_err("Unknown action: %s", raw_task);
task = no_action;
break;
}
if(task != no_action) {
if(is_set(rsc->flags, pe_rsc_notify)) {
order->lh_action_task = generate_notify_key(
rsc->id, "confirmed-post",
task2text(task));
} else {
order->lh_action_task = generate_op_key(
rsc->id, task2text(task+1), 0);
}
crm_debug_2("Converted %s -> %s",
old_uuid, order->lh_action_task);
crm_free(old_uuid);
}
crm_free(raw_task);
crm_free(rid);
}
void
order_actions(
action_t *lh_action, action_t *rh_action, enum pe_ordering order)
{
action_wrapper_t *wrapper = NULL;
GListPtr list = NULL;
crm_debug_2("Ordering Action %s before %s",
lh_action->uuid, rh_action->uuid);
log_action(LOG_DEBUG_4, "LH (order_actions)", lh_action, FALSE);
log_action(LOG_DEBUG_4, "RH (order_actions)", rh_action, FALSE);
crm_malloc0(wrapper, sizeof(action_wrapper_t));
wrapper->action = rh_action;
wrapper->type = order;
list = lh_action->actions_after;
list = g_list_append(list, wrapper);
lh_action->actions_after = list;
wrapper = NULL;
/* order |= pe_order_implies_right; */
/* order ^= pe_order_implies_right; */
crm_malloc0(wrapper, sizeof(action_wrapper_t));
wrapper->action = lh_action;
wrapper->type = order;
list = rh_action->actions_before;
list = g_list_append(list, wrapper);
rh_action->actions_before = list;
}
void
log_action(unsigned int log_level, const char *pre_text, action_t *action, gboolean details)
{
const char *node_uname = NULL;
const char *node_uuid = NULL;
if(action == NULL) {
do_crm_log(log_level, "%s%s: <NULL>",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ");
return;
}
if(action->pseudo) {
node_uname = NULL;
node_uuid = NULL;
} else if(action->node != NULL) {
node_uname = action->node->details->uname;
node_uuid = action->node->details->id;
} else {
node_uname = "<none>";
node_uuid = NULL;
}
switch(text2task(action->task)) {
case stonith_node:
case shutdown_crm:
do_crm_log(log_level,
"%s%s%sAction %d: %s%s%s%s%s%s",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ",
action->pseudo?"Pseduo ":action->optional?"Optional ":action->runnable?action->processed?"":"(Provisional) ":"!!Non-Startable!! ",
action->id, action->uuid,
node_uname?"\ton ":"",
node_uname?node_uname:"",
node_uuid?"\t\t(":"",
node_uuid?node_uuid:"",
node_uuid?")":"");
break;
default:
do_crm_log(log_level,
"%s%s%sAction %d: %s %s%s%s%s%s%s",
pre_text==NULL?"":pre_text,
pre_text==NULL?"":": ",
action->optional?"Optional ":action->pseudo?"Pseduo ":action->runnable?action->processed?"":"(Provisional) ":"!!Non-Startable!! ",
action->id, action->uuid,
safe_val3("<none>", action, rsc, id),
node_uname?"\ton ":"",
node_uname?node_uname:"",
node_uuid?"\t\t(":"",
node_uuid?node_uuid:"",
node_uuid?")":"");
break;
}
if(details) {
do_crm_log(log_level+1, "\t\t====== Preceeding Actions");
slist_iter(
other, action_wrapper_t, action->actions_before, lpc,
log_action(log_level+1, "\t\t", other->action, FALSE);
);
do_crm_log(log_level+1, "\t\t====== Subsequent Actions");
slist_iter(
other, action_wrapper_t, action->actions_after, lpc,
log_action(log_level+1, "\t\t", other->action, FALSE);
);
do_crm_log(log_level+1, "\t\t====== End");
} else {
do_crm_log(log_level, "\t\t(seen=%d, before=%d, after=%d)",
action->seen_count,
g_list_length(action->actions_before),
g_list_length(action->actions_after));
}
}
-resource_t *uber_parent(resource_t *rsc)
-{
- resource_t *parent = rsc;
- while(parent != NULL && parent->parent != NULL) {
- parent = parent->parent;
- }
- return parent;
-}
-
-
action_t *get_pseudo_op(const char *name, pe_working_set_t *data_set)
{
action_t *op = NULL;
const char *op_s = name;
GListPtr possible_matches = NULL;
possible_matches = find_actions(data_set->actions, name, NULL);
if(possible_matches != NULL) {
if(g_list_length(possible_matches) > 1) {
pe_warn("Action %s exists %d times",
name, g_list_length(possible_matches));
}
op = g_list_nth_data(possible_matches, 0);
g_list_free(possible_matches);
} else {
op = custom_action(NULL, crm_strdup(op_s), op_s,
NULL, TRUE, TRUE, data_set);
op->pseudo = TRUE;
op->runnable = TRUE;
}
return op;
}
gboolean can_run_any(GListPtr nodes)
{
if(nodes == NULL) {
return FALSE;
}
slist_iter(
node, node_t, nodes, lpc,
if(can_run_resources(node) && node->weight >= 0) {
return TRUE;
}
);
return FALSE;
}
diff --git a/pengine/utils.h b/pengine/utils.h
index 1aaf4d6cab..d4e45718e0 100644
--- a/pengine/utils.h
+++ b/pengine/utils.h
@@ -1,69 +1,68 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PENGINE_AUTILS__H
#define PENGINE_AUTILS__H
/* Constraint helper functions */
extern rsc_colocation_t *invert_constraint(rsc_colocation_t *constraint);
extern rsc_to_node_t *copy_constraint(rsc_to_node_t *constraint);
extern void print_rsc_to_node(
const char *pre_text, rsc_to_node_t *cons, gboolean details);
extern void print_rsc_colocation(
const char *pre_text, rsc_colocation_t *cons, gboolean details);
extern rsc_to_node_t *rsc2node_new(
const char *id, resource_t *rsc, int weight, node_t *node,
pe_working_set_t *data_set);
extern void pe_free_rsc_to_node(GListPtr constraints);
extern void pe_free_ordering(GListPtr constraints);
extern const char *ordering_type2text(enum pe_ordering type);
extern gboolean rsc_colocation_new(
const char *id, const char *node_attr, int score,
resource_t *rsc_lh, resource_t *rsc_rh,
const char *state_lh, const char *state_rh,
pe_working_set_t *data_set);
extern rsc_to_node_t *generate_location_rule(
resource_t *rsc, crm_data_t *location_rule, pe_working_set_t *data_set);
extern gint sort_node_weight(gconstpointer a, gconstpointer b);
extern gboolean can_run_resources(const node_t *node);
extern gboolean native_assign_node(resource_t *rsc, GListPtr candidates, node_t *chosen);
extern void convert_non_atomic_task(resource_t *rsc, order_constraint_t *order);
extern void order_actions(
action_t *lh_action, action_t *rh_action, enum pe_ordering order);
extern void log_action(unsigned int log_level, const char *pre_text,
action_t *action, gboolean details);
-extern resource_t *uber_parent(resource_t *rsc);
extern action_t *get_pseudo_op(const char *name, pe_working_set_t *data_set);
extern gboolean can_run_any(GListPtr nodes);
#define STONITH_UP "stonith_up"
#define ALL_STOPPED "all_stopped"
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 26, 5:41 PM (22 h, 36 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1959263
Default Alt Text
(48 KB)

Event Timeline