Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4525084
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
48 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment