Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1842213
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
53 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/crm/pengine/pengine.h b/crm/pengine/pengine.h
index 4bc251e875..bba4da1f9b 100644
--- a/crm/pengine/pengine.h
+++ b/crm/pengine/pengine.h
@@ -1,180 +1,164 @@
/* $Id: pengine.h,v 1.115 2006/06/09 06:42:16 andrew Exp $ */
/*
* 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__H
#define PENGINE__H
#include <clplumbing/ipc.h>
typedef struct rsc_to_node_s rsc_to_node_t;
typedef struct rsc_colocation_s rsc_colocation_t;
typedef struct lrm_agent_s lrm_agent_t;
typedef struct order_constraint_s order_constraint_t;
#include <glib.h>
#include <crm/crm.h>
#include <crm/common/msg.h>
#include <crm/common/iso8601.h>
#include <crm/pengine/rules.h>
#include <crm/pengine/common.h>
#include <crm/pengine/status.h>
#include <linux-ha/config.h>
#include <crm/pengine/complex.h>
enum con_strength {
pecs_ignore,
pecs_must,
pecs_must_not,
pecs_startstop
};
enum pe_stop_fail {
pesf_block,
pesf_stonith,
pesf_ignore
};
-struct color_shared_s {
- int id;
- int highest_priority;
- GListPtr candidate_nodes; /* node_t* */
- GListPtr allocated_resources; /* resources_t* */
- node_t *chosen_node;
- gboolean pending;
- int num_resources;
-};
-
-struct color_s {
- int id;
- struct color_shared_s *details;
- int local_weight;
-};
-
struct rsc_colocation_s {
const char *id;
resource_t *rsc_lh;
resource_t *rsc_rh;
const char *state_lh;
const char *state_rh;
enum con_strength strength;
};
struct rsc_to_node_s {
const char *id;
resource_t *rsc_lh;
enum rsc_role_e role_filter;
GListPtr node_list_rh; /* node_t* */
};
struct order_constraint_s
{
int id;
enum pe_ordering type;
void *lh_opaque;
resource_t *lh_rsc;
action_t *lh_action;
char *lh_action_task;
void *rh_opaque;
resource_t *rh_rsc;
action_t *rh_action;
char *rh_action_task;
/* (soon to be) variant specific */
/* int lh_rsc_incarnation; */
/* int rh_rsc_incarnation; */
};
extern gboolean stage0(pe_working_set_t *data_set);
extern gboolean stage1(pe_working_set_t *data_set);
extern gboolean stage2(pe_working_set_t *data_set);
extern gboolean stage3(pe_working_set_t *data_set);
extern gboolean stage4(pe_working_set_t *data_set);
extern gboolean stage5(pe_working_set_t *data_set);
extern gboolean stage6(pe_working_set_t *data_set);
extern gboolean stage7(pe_working_set_t *data_set);
extern gboolean stage8(pe_working_set_t *data_set);
extern gboolean summary(GListPtr resources);
extern gboolean pe_msg_dispatch(IPC_Channel *sender, void *user_data);
extern gboolean process_pe_message(
HA_Message *msg, crm_data_t *xml_data, IPC_Channel *sender);
extern gboolean unpack_constraints(
crm_data_t *xml_constraints, pe_working_set_t *data_set);
extern gboolean apply_placement_constraints(pe_working_set_t *data_set);
extern gboolean choose_node_from_list(color_t *color);
extern gboolean update_action_states(GListPtr actions);
extern gboolean shutdown_constraints(
node_t *node, action_t *shutdown_op, pe_working_set_t *data_set);
extern gboolean stonith_constraints(
node_t *node, action_t *stonith_op, pe_working_set_t *data_set);
extern gboolean custom_action_order(
resource_t *lh_rsc, char *lh_task, action_t *lh_action,
resource_t *rh_rsc, char *rh_task, action_t *rh_action,
enum pe_ordering type, pe_working_set_t *data_set);
#define order_start_start(rsc1,rsc2, type) \
custom_action_order(rsc1, start_key(rsc1), NULL, \
rsc2, start_key(rsc2) ,NULL, \
type, data_set)
#define order_stop_stop(rsc1, rsc2, type) \
custom_action_order(rsc1, stop_key(rsc1), NULL, \
rsc2, stop_key(rsc2) ,NULL, \
type, data_set)
#define order_restart(rsc1) \
custom_action_order(rsc1, stop_key(rsc1), NULL, \
rsc1, start_key(rsc1), NULL, \
pe_ordering_restart, data_set)
#define order_stop_start(rsc1, rsc2, type) \
custom_action_order(rsc1, stop_key(rsc1), NULL, \
rsc2, start_key(rsc2) ,NULL, \
type, data_set)
#define order_start_stop(rsc1, rsc2, type) \
custom_action_order(rsc1, start_key(rsc1), NULL, \
rsc2, stop_key(rsc2) ,NULL, \
type, data_set)
extern gboolean process_colored_constraints(resource_t *rsc);
extern void graph_element_from_action(
action_t *action, pe_working_set_t *data_set);
extern const char* transition_idle_timeout;
#endif
diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
index 7ad2c8c44b..b9324d1536 100644
--- a/include/crm/pengine/status.h
+++ b/include/crm/pengine/status.h
@@ -1,222 +1,215 @@
/* $Id: status.h,v 1.3 2006/06/21 14:48:01 andrew Exp $ */
/*
* 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_STATUS__H
#define PENGINE_STATUS__H
#include <glib.h>
#include <crm/common/iso8601.h>
#include <crm/pengine/common.h>
typedef struct node_s node_t;
-typedef struct color_s color_t;
typedef struct action_s action_t;
typedef struct resource_s resource_t;
typedef struct action_wrapper_s action_wrapper_t;
typedef enum no_quorum_policy_e {
no_quorum_freeze,
no_quorum_stop,
no_quorum_ignore
} no_quorum_policy_t;
enum node_type {
node_ping,
node_member
};
enum pe_restart {
pe_restart_restart,
pe_restart_ignore
};
typedef struct pe_working_set_s
{
crm_data_t *input;
ha_time_t *now;
/* options extracted from the input */
char *transition_idle_timeout;
char *dc_uuid;
node_t *dc_node;
gboolean have_quorum;
gboolean stonith_enabled;
const char *stonith_action;
gboolean symmetric_cluster;
gboolean is_managed_default;
gboolean remove_after_stop;
gboolean stop_rsc_orphans;
gboolean stop_action_orphans;
int default_resource_stickiness;
int default_resource_fail_stickiness;
no_quorum_policy_t no_quorum_policy;
GHashTable *config_hash;
- /* intermediate steps */
- color_t *no_color;
-
GListPtr nodes;
GListPtr resources;
GListPtr placement_constraints;
GListPtr ordering_constraints;
GListPtr colors;
GListPtr actions;
/* stats */
int num_synapse;
int max_valid_nodes;
int order_id;
int action_id;
int color_id;
/* final output */
crm_data_t *graph;
} pe_working_set_t;
struct node_shared_s {
const char *id;
const char *uname;
gboolean online;
gboolean standby;
gboolean unclean;
gboolean shutdown;
gboolean expected_up;
gboolean is_dc;
int num_resources;
GListPtr running_rsc; /* resource_t* */
GHashTable *attrs; /* char* => char* */
enum node_type type;
};
struct node_s {
int weight;
gboolean fixed;
struct node_shared_s *details;
};
#include <crm/pengine/complex.h>
struct resource_s {
char *id;
char *clone_name;
char *long_name;
crm_data_t *xml;
crm_data_t *ops_xml;
resource_t *parent;
void *variant_opaque;
enum pe_obj_types variant;
resource_object_functions_t *fns;
resource_alloc_functions_t *cmds;
enum rsc_recovery_type recovery_type;
enum pe_restart restart_type;
int priority;
int stickiness;
int fail_stickiness;
int effective_priority;
gboolean notify;
gboolean is_managed;
gboolean starting;
gboolean stopping;
gboolean runnable;
gboolean provisional;
gboolean globally_unique;
gboolean failed;
gboolean start_pending;
gboolean orphan;
- GListPtr candidate_colors; /* color_t* */
GListPtr rsc_cons; /* rsc_colocation_t* */
GListPtr rsc_location; /* rsc_to_node_t* */
GListPtr actions; /* action_t* */
- color_t *color;
- GListPtr colors; /* color_t* */
GListPtr running_on; /* node_t* */
GListPtr known_on; /* node_t* */
GListPtr allowed_nodes; /* node_t* */
enum rsc_role_e role;
enum rsc_role_e next_role;
GHashTable *meta;
GHashTable *parameters;
};
struct action_s
{
int id;
int priority;
resource_t *rsc;
void *rsc_opaque;
node_t *node;
const char *task;
char *uuid;
crm_data_t *op_entry;
gboolean pseudo;
gboolean runnable;
gboolean optional;
gboolean failure_is_fatal;
enum rsc_start_requirement needs;
enum action_fail_response on_fail;
enum rsc_role_e fail_role;
gboolean dumped;
gboolean processed;
action_t *pre_notify;
action_t *pre_notified;
action_t *post_notify;
action_t *post_notified;
int seen_count;
GHashTable *meta;
GHashTable *extra;
GHashTable *notify_keys; /* do NOT free */
GListPtr actions_before; /* action_warpper_t* */
GListPtr actions_after; /* action_warpper_t* */
};
struct action_wrapper_s
{
enum pe_ordering type;
action_t *action;
};
gboolean cluster_status(pe_working_set_t *data_set);
extern void set_working_set_defaults(pe_working_set_t *data_set);
extern void cleanup_calculations(pe_working_set_t *data_set);
extern resource_t *pe_find_resource(GListPtr rsc_list, const char *id_rh);
#endif
diff --git a/lib/crm/pengine/complex.c b/lib/crm/pengine/complex.c
index 1f4cbb0265..7fceada9c6 100644
--- a/lib/crm/pengine/complex.c
+++ b/lib/crm/pengine/complex.c
@@ -1,332 +1,330 @@
/* $Id: complex.c,v 1.7 2006/08/14 16:32:21 andrew Exp $ */
/*
* 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 <portability.h>
#include <crm/cib.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_free
},
{
group_unpack,
group_find_child,
group_children,
native_parameter,
group_print,
group_active,
group_resource_state,
group_free
},
{
clone_unpack,
clone_find_child,
clone_children,
native_parameter,
clone_print,
clone_active,
clone_resource_state,
clone_free
},
{
master_unpack,
clone_find_child,
clone_children,
native_parameter,
clone_print,
clone_active,
clone_resource_state,
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);
}
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...");
/* meta attributes */
xml_prop_iter(
xml_obj, prop_name, prop_value,
add_hash_param((*rsc)->meta, prop_name, prop_value);
);
unpack_instance_attributes(
xml_obj, XML_TAG_META_SETS, NULL, (*rsc)->meta,
NULL, data_set->now);
/* populate from the regular attributes until the GUI can create
* meta attributes
*/
unpack_instance_attributes(
xml_obj, XML_TAG_ATTR_SETS, NULL, (*rsc)->meta,
NULL, data_set->now);
if(parent != NULL) {
g_hash_table_foreach(parent->meta, dup_attr, (*rsc)->meta);
g_hash_table_foreach(
parent->parameters, dup_attr, (*rsc)->parameters);
}
if((*rsc)->fns->unpack(*rsc, data_set) == FALSE) {
return FALSE;
}
(*rsc)->runnable = TRUE;
(*rsc)->provisional = TRUE;
(*rsc)->starting = FALSE;
(*rsc)->stopping = FALSE;
- (*rsc)->candidate_colors = NULL;
(*rsc)->rsc_cons = NULL;
(*rsc)->actions = NULL;
(*rsc)->failed = FALSE;
(*rsc)->start_pending = FALSE;
(*rsc)->globally_unique = TRUE;
(*rsc)->role = RSC_ROLE_STOPPED;
(*rsc)->next_role = RSC_ROLE_UNKNOWN;
(*rsc)->is_managed = data_set->is_managed_default;
(*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);
(*rsc)->notify = crm_is_true(value);
value = g_hash_table_lookup((*rsc)->meta, "is_managed");
if(value != NULL && safe_str_neq("default", value)) {
cl_str_to_boolean(value, &((*rsc)->is_managed));
}
crm_debug_2("Options for %s", (*rsc)->id);
value = g_hash_table_lookup((*rsc)->meta, "globally_unique");
if(value != NULL) {
cl_str_to_boolean(value, &((*rsc)->globally_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);
}
if((*rsc)->stickiness > 0) {
crm_debug_2("\tPlacement: prefer current location%s",
value == NULL?" (default)":"");
} else if((*rsc)->stickiness < 0) {
crm_warn("\tPlacement: always move from the current location%s",
value == NULL?" (default)":"");
} else {
crm_debug_2("\tPlacement: optimal%s",
value == NULL?" (default)":"");
}
value = g_hash_table_lookup(
(*rsc)->meta, XML_RSC_ATTR_FAIL_STICKINESS);
if(value != NULL) {
(*rsc)->fail_stickiness = char2score(value);
}
crm_debug_2("\tNode score per failure: %d%s",
(*rsc)->fail_stickiness, value == NULL?" (default)":"");
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)->variant == pe_native && (*rsc)->next_role == RSC_ROLE_STOPPED) {
crm_debug_2("Making sure %s doesn't get colored", (*rsc)->id);
/* make sure it doesnt come up again */
resource_location(*rsc, NULL, -INFINITY, "target_role", data_set);
}
if((*rsc)->is_managed == FALSE) {
crm_warn("Resource %s is currently not managed", (*rsc)->id);
} else if((*rsc)->variant == pe_native && data_set->symmetric_cluster) {
resource_location(*rsc, NULL, 0, "symmetric_default", data_set);
}
crm_debug_2("\tAction notification: %s",
(*rsc)->notify?"required":"not required");
/* data_set->resources = g_list_append(data_set->resources, (*rsc)); */
return TRUE;
}
void common_free(resource_t *rsc)
{
if(rsc == NULL) {
return;
}
crm_debug_5("Freeing %s", rsc->id);
pe_free_shallow(rsc->rsc_cons);
if(rsc->parameters != NULL) {
g_hash_table_destroy(rsc->parameters);
}
if(rsc->meta != NULL) {
g_hash_table_destroy(rsc->meta);
}
if(rsc->orphan) {
free_xml(rsc->xml);
}
pe_free_shallow_adv(rsc->running_on, FALSE);
pe_free_shallow_adv(rsc->known_on, FALSE);
- pe_free_shallow_adv(rsc->candidate_colors, TRUE);
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->variant_opaque);
crm_free(rsc);
crm_debug_5("Resource freed");
}
diff --git a/lib/crm/pengine/group.c b/lib/crm/pengine/group.c
index aaeb83f0ce..4eae5f9750 100644
--- a/lib/crm/pengine/group.c
+++ b/lib/crm/pengine/group.c
@@ -1,262 +1,260 @@
/* $Id: group.c,v 1.6 2006/08/14 09:06:32 andrew Exp $ */
/*
* 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 <portability.h>
#include <crm/pengine/status.h>
#include <utils.h>
#include <crm/msg_xml.h>
#include <clplumbing/cl_misc.h>
typedef struct group_variant_data_s
{
int num_children;
GListPtr child_list; /* resource_t* */
resource_t *self;
resource_t *first_child;
resource_t *last_child;
gboolean colocated;
gboolean ordered;
gboolean child_starting;
gboolean child_stopping;
} group_variant_data_t;
#define get_group_variant_data(data, rsc) \
CRM_ASSERT(rsc != NULL); \
CRM_ASSERT(rsc->variant == pe_group); \
CRM_ASSERT(rsc->variant_opaque != NULL); \
data = (group_variant_data_t *)rsc->variant_opaque; \
-void group_assign_color(resource_t *rsc, color_t *group_color);
-
gboolean group_unpack(resource_t *rsc, pe_working_set_t *data_set)
{
resource_t *self = NULL;
crm_data_t *xml_obj = rsc->xml;
crm_data_t *xml_self = copy_xml(rsc->xml);
group_variant_data_t *group_data = NULL;
const char *group_ordered = g_hash_table_lookup(
rsc->meta, XML_RSC_ATTR_ORDERED);
const char *group_colocated = g_hash_table_lookup(
rsc->meta, "collocated");
const char *clone_id = NULL;
crm_debug_3("Processing resource %s...", rsc->id);
crm_malloc0(group_data, sizeof(group_variant_data_t));
group_data->num_children = 0;
group_data->self = NULL;
group_data->child_list = NULL;
group_data->first_child = NULL;
group_data->last_child = NULL;
rsc->variant_opaque = group_data;
group_data->ordered = TRUE;
group_data->colocated = TRUE;
if(group_ordered != NULL) {
cl_str_to_boolean(group_ordered, &(group_data->ordered));
}
if(group_colocated != NULL) {
cl_str_to_boolean(group_colocated, &(group_data->colocated));
}
/* this is a bit of a hack - but simplifies everything else */
ha_msg_mod(xml_self, F_XML_TAGNAME, XML_CIB_TAG_RESOURCE);
if(common_unpack(xml_self, &self, NULL, data_set)) {
group_data->self = self;
self->restart_type = pe_restart_restart;
} else {
crm_log_xml_err(xml_self, "Couldnt unpack dummy child");
return FALSE;
}
clone_id = crm_element_value(rsc->xml, XML_RSC_ATTR_INCARNATION);
xml_child_iter_filter(
xml_obj, xml_native_rsc, XML_CIB_TAG_RESOURCE,
resource_t *new_rsc = NULL;
crm_xml_add(xml_native_rsc, XML_RSC_ATTR_INCARNATION, clone_id);
if(common_unpack(xml_native_rsc, &new_rsc,
rsc, data_set) == FALSE) {
pe_err("Failed unpacking resource %s",
crm_element_value(xml_obj, XML_ATTR_ID));
if(new_rsc != NULL && new_rsc->fns != NULL) {
new_rsc->fns->free(new_rsc);
}
}
group_data->num_children++;
group_data->child_list = g_list_append(
group_data->child_list, new_rsc);
if(group_data->first_child == NULL) {
group_data->first_child = new_rsc;
}
group_data->last_child = new_rsc;
print_resource(LOG_DEBUG_3, "Added", new_rsc, FALSE);
);
if(group_data->num_children == 0) {
#if 0
/* Bug #1287 */
crm_config_err("Group %s did not have any children", rsc->id);
return FALSE;
#else
crm_config_warn("Group %s did not have any children", rsc->id);
return TRUE;
#endif
}
crm_debug_3("Added %d children to resource %s...",
group_data->num_children, rsc->id);
return TRUE;
}
resource_t *
group_find_child(resource_t *rsc, const char *id)
{
group_variant_data_t *group_data = NULL;
get_group_variant_data(group_data, rsc);
return pe_find_resource(group_data->child_list, id);
}
GListPtr group_children(resource_t *rsc)
{
group_variant_data_t *group_data = NULL;
get_group_variant_data(group_data, rsc);
return group_data->child_list;
}
gboolean group_active(resource_t *rsc, gboolean all)
{
group_variant_data_t *group_data = NULL;
get_group_variant_data(group_data, rsc);
slist_iter(
child_rsc, resource_t, group_data->child_list, lpc,
gboolean child_active = child_rsc->fns->active(child_rsc, all);
if(all == FALSE && child_active) {
return TRUE;
} else if(child_active == FALSE) {
return FALSE;
}
);
if(all) {
return TRUE;
} else {
return FALSE;
}
}
void group_print(
resource_t *rsc, const char *pre_text, long options, void *print_data)
{
const char *child_text = NULL;
group_variant_data_t *group_data = NULL;
get_group_variant_data(group_data, rsc);
if(pre_text != NULL) {
child_text = " ";
} else {
child_text = " ";
}
status_print("%sResource Group: %s",
pre_text?pre_text:"", rsc->id);
if(options & pe_print_html) {
status_print("\n<ul>\n");
} else if((options & pe_print_log) == 0) {
status_print("\n");
}
slist_iter(
child_rsc, resource_t, group_data->child_list, lpc,
if(options & pe_print_html) {
status_print("<li>\n");
}
child_rsc->fns->print(
child_rsc, child_text, options, print_data);
if(options & pe_print_html) {
status_print("</li>\n");
}
);
if(options & pe_print_html) {
status_print("</ul>\n");
}
}
void group_free(resource_t *rsc)
{
group_variant_data_t *group_data = NULL;
CRM_CHECK(rsc != NULL, return);
get_group_variant_data(group_data, rsc);
crm_debug_3("Freeing %s", rsc->id);
slist_iter(
child_rsc, resource_t, group_data->child_list, lpc,
crm_debug_3("Freeing child %s", child_rsc->id);
child_rsc->fns->free(child_rsc);
);
crm_debug_3("Freeing child list");
pe_free_shallow_adv(group_data->child_list, FALSE);
if(group_data->self != NULL) {
free_xml(group_data->self->xml);
group_data->self->fns->free(group_data->self);
}
common_free(rsc);
}
enum rsc_role_e
group_resource_state(resource_t *rsc)
{
enum rsc_role_e group_role = RSC_ROLE_UNKNOWN;
group_variant_data_t *group_data = NULL;
get_group_variant_data(group_data, rsc);
slist_iter(
child_rsc, resource_t, group_data->child_list, lpc,
if(child_rsc->next_role > group_role) {
group_role = rsc->next_role;
}
if(child_rsc->failed) {
rsc->failed = TRUE;
}
);
return group_role;
}
diff --git a/lib/crm/pengine/native.c b/lib/crm/pengine/native.c
index 9b2c6f1529..17d3ca0b01 100644
--- a/lib/crm/pengine/native.c
+++ b/lib/crm/pengine/native.c
@@ -1,449 +1,442 @@
/* $Id: native.c,v 1.5 2006/07/12 15:41:46 andrew Exp $ */
/*
* 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 <portability.h>
#include <crm/pengine/status.h>
#include <crm/pengine/rules.h>
#include <crm/pengine/complex.h>
#include <utils.h>
#include <crm/msg_xml.h>
#define DELETE_THEN_REFRESH 1
typedef struct native_variant_data_s
{
/* GListPtr allowed_nodes; /\* node_t* *\/ */
} native_variant_data_t;
gboolean DeleteRsc(resource_t *rsc, node_t *node, pe_working_set_t *data_set);
#define get_native_variant_data(data, rsc) \
CRM_ASSERT(rsc->variant == pe_native); \
CRM_ASSERT(rsc->variant_opaque != NULL); \
data = (native_variant_data_t *)rsc->variant_opaque;
void
native_add_running(resource_t *rsc, node_t *node, pe_working_set_t *data_set)
{
CRM_CHECK(node != NULL, return);
slist_iter(
a_node, node_t, rsc->running_on, lpc,
CRM_CHECK(a_node != NULL, return);
if(safe_str_eq(a_node->details->id, node->details->id)) {
return;
}
);
rsc->running_on = g_list_append(rsc->running_on, node);
if(rsc->variant == pe_native) {
node->details->running_rsc = g_list_append(
node->details->running_rsc, rsc);
}
if(rsc->variant != pe_native) {
} else if(rsc->is_managed == FALSE) {
crm_info("resource %s isnt managed", rsc->id);
resource_location(rsc, node, INFINITY,
"not_managed_default", data_set);
return;
#if 0
} else if(rsc->failed) {
crm_info("Skipping resource stickiness for failed resource %s",
rsc->id);
#endif
} else if(rsc->stickiness > 0 || rsc->stickiness < 0) {
resource_location(rsc, node, rsc->stickiness,
"stickiness", data_set);
crm_debug("Resource %s: preferring current location (node=%s, weight=%d)",
rsc->id, node->details->uname, rsc->stickiness);
}
if(rsc->variant == pe_native && g_list_length(rsc->running_on) > 1) {
const char *type = crm_element_value(rsc->xml, XML_ATTR_TYPE);
const char *class = crm_element_value(
rsc->xml, XML_AGENT_ATTR_CLASS);
/* these are errors because hardly any gets it right
* at the moment and this way the might notice
*/
pe_proc_err("Resource %s::%s:%s appears to be active on %d nodes.",
class, type, rsc->id, g_list_length(rsc->running_on));
cl_log(LOG_ERR, "See %s for more information.",
HAURL("v2/faq/resource_too_active"));
if(rsc->recovery_type == recovery_stop_only) {
crm_debug("Making sure %s doesn't come up again", rsc->id);
/* make sure it doesnt come up again */
pe_free_shallow_adv(rsc->allowed_nodes, TRUE);
rsc->allowed_nodes = node_list_dup(
data_set->nodes, FALSE, FALSE);
slist_iter(
node, node_t, rsc->allowed_nodes, lpc,
node->weight = -INFINITY;
);
} else if(rsc->recovery_type == recovery_block) {
rsc->is_managed = FALSE;
}
} else {
crm_debug_2("Resource %s is active on: %s",
rsc->id, node->details->uname);
}
if(rsc->parent != NULL) {
native_add_running(rsc->parent, node, data_set);
}
}
gboolean native_unpack(resource_t *rsc, pe_working_set_t *data_set)
{
native_variant_data_t *native_data = NULL;
crm_debug_3("Processing resource %s...", rsc->id);
crm_malloc0(native_data, sizeof(native_variant_data_t));
rsc->allowed_nodes = NULL;
rsc->running_on = NULL;
rsc->variant_opaque = native_data;
return TRUE;
}
resource_t *
native_find_child(resource_t *rsc, const char *id)
{
return NULL;
}
GListPtr native_children(resource_t *rsc)
{
return NULL;
}
static void
hash_copy_field(gpointer key, gpointer value, gpointer user_data)
{
const char *name = key;
const char *s_value = value;
GHashTable *hash_copy = user_data;
g_hash_table_insert(hash_copy, crm_strdup(name), crm_strdup(s_value));
}
char *
native_parameter(
resource_t *rsc, node_t *node, gboolean create, const char *name,
pe_working_set_t *data_set)
{
char *value_copy = NULL;
const char *value = NULL;
GHashTable *hash = rsc->parameters;
GHashTable *local_hash = NULL;
CRM_CHECK(rsc != NULL, return NULL);
CRM_CHECK(name != NULL && strlen(name) != 0, return NULL);
crm_debug_2("Looking up %s in %s", name, rsc->id);
if(create) {
if(node != NULL) {
crm_debug_2("Creating hash with node %s",
node->details->uname);
} else {
crm_debug_2("Creating default hash");
}
local_hash = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
g_hash_table_foreach(
rsc->parameters, hash_copy_field, local_hash);
unpack_instance_attributes(
rsc->xml, XML_TAG_ATTR_SETS,
node?node->details->attrs:NULL,
local_hash, NULL, data_set->now);
hash = local_hash;
}
value = g_hash_table_lookup(hash, name);
if(value == NULL) {
/* try meta attributes instead */
value = g_hash_table_lookup(rsc->meta, name);
}
if(value != NULL) {
value_copy = crm_strdup(value);
}
if(local_hash != NULL) {
g_hash_table_destroy(local_hash);
}
return value_copy;
}
gboolean native_active(resource_t *rsc, gboolean all)
{
slist_iter(
a_node, node_t, rsc->running_on, lpc,
if(a_node->details->online == FALSE) {
crm_debug("Resource %s: node %s is offline",
rsc->id, a_node->details->uname);
} else if(a_node->details->unclean) {
crm_debug("Resource %s: node %s is unclean",
rsc->id, a_node->details->uname);
} else {
crm_debug("Resource %s active on %s",
rsc->id, a_node->details->uname);
return TRUE;
}
);
return FALSE;
}
struct print_data_s
{
long options;
void *print_data;
};
static void native_print_attr(gpointer key, gpointer value, gpointer user_data)
{
long options = ((struct print_data_s*)user_data)->options;
void *print_data = ((struct print_data_s*)user_data)->print_data;
status_print("Option: %s = %s\n", (char*)key, (char*)value);
}
void
native_print(
resource_t *rsc, const char *pre_text, long options, void *print_data)
{
node_t *node = NULL;
const char *prov = NULL;
const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
if(safe_str_eq(class, "ocf")) {
prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
}
if(rsc->running_on != NULL) {
node = rsc->running_on->data;
}
if(options & pe_print_html) {
if(rsc->is_managed == FALSE) {
status_print("<font color=\"yellow\">");
} else if(rsc->failed) {
status_print("<font color=\"red\">");
} else if(rsc->variant == pe_native
&& g_list_length(rsc->running_on) == 0) {
status_print("<font color=\"red\">");
} else if(g_list_length(rsc->running_on) > 1) {
status_print("<font color=\"orange\">");
} else {
status_print("<font color=\"green\">");
}
}
if((options & pe_print_rsconly) || g_list_length(rsc->running_on) > 1) {
const char *desc = NULL;
desc = crm_element_value(rsc->xml, XML_ATTR_DESC);
status_print("%s%s\t(%s%s%s:%s)%s%s",
pre_text?pre_text:"", rsc->id,
prov?prov:"", prov?"::":"",
class, crm_element_value(rsc->xml, XML_ATTR_TYPE),
desc?": ":"", desc?desc:"");
} else {
status_print("%s%s\t(%s%s%s:%s):\t%s %s%s%s",
pre_text?pre_text:"", rsc->id,
prov?prov:"", prov?"::":"",
class, crm_element_value(rsc->xml, XML_ATTR_TYPE),
(rsc->variant!=pe_native)?"":role2text(rsc->role),
(rsc->variant!=pe_native)?"":node!=NULL?node->details->uname:"",
rsc->is_managed?"":" (unmanaged)", rsc->failed?" FAILED":"");
#if CURSES_ENABLED
if(options & pe_print_ncurses) {
move(-1, 0);
}
#endif
}
if(options & pe_print_html) {
status_print(" </font> ");
}
if((options & pe_print_rsconly)) {
} else if(g_list_length(rsc->running_on) > 1) {
if(options & pe_print_html) {
status_print("<ul>\n");
} else if((options & pe_print_printf)
|| (options & pe_print_ncurses)) {
status_print("[");
}
slist_iter(node, node_t, rsc->running_on, lpc,
if(options & pe_print_html) {
status_print("<li>\n%s",
node->details->uname);
} else if((options & pe_print_printf)
|| (options & pe_print_ncurses)) {
status_print("\t%s", node->details->uname);
} else if((options & pe_print_log)) {
status_print("\t%d : %s",
lpc, node->details->uname);
} else {
status_print("%s", node->details->uname);
}
if(options & pe_print_html) {
status_print("</li>\n");
}
);
if(options & pe_print_html) {
status_print("</ul>\n");
} else if((options & pe_print_printf)
|| (options & pe_print_ncurses)) {
status_print(" ]");
}
}
if(options & pe_print_html) {
status_print("<br/>\n");
} else if((options & pe_print_printf) || (options & pe_print_ncurses)) {
status_print("\n");
}
if(options & pe_print_details) {
struct print_data_s pdata;
pdata.options = options;
pdata.print_data = print_data;
g_hash_table_foreach(rsc->parameters, native_print_attr, &pdata);
}
if(options & pe_print_dev) {
status_print("%s\t(%s%svariant=%s, priority=%f)",
pre_text, rsc->provisional?"provisional, ":"",
rsc->runnable?"":"non-startable, ",
crm_element_name(rsc->xml),
(double)rsc->priority);
-
- status_print("%s\t%d candidate colors, %d allowed nodes,"
- " %d rsc_cons",
- pre_text, g_list_length(rsc->candidate_colors),
- g_list_length(rsc->allowed_nodes),
- g_list_length(rsc->rsc_cons));
}
if(options & pe_print_max_details) {
status_print("%s\t=== Actions.\n", pre_text);
slist_iter(
action, action_t, rsc->actions, lpc,
log_action(LOG_DEBUG_4, "\trsc action: ", action, FALSE);
);
status_print("%s\t=== Allowed Nodes\n", pre_text);
slist_iter(
node, node_t, rsc->allowed_nodes, lpc,
print_node("\t", node, FALSE);
);
}
}
void native_free(resource_t *rsc)
{
crm_debug_4("Freeing Allowed Nodes");
- crm_free(rsc->color);
common_free(rsc);
}
enum rsc_role_e
native_resource_state(resource_t *rsc)
{
if(rsc->next_role != RSC_ROLE_UNKNOWN) {
return rsc->next_role;
}
if(rsc->role != RSC_ROLE_UNKNOWN) {
return rsc->role;
}
return RSC_ROLE_STOPPED;
}
gboolean
DeleteRsc(resource_t *rsc, node_t *node, pe_working_set_t *data_set)
{
action_t *delete = NULL;
action_t *refresh = NULL;
if(rsc->failed) {
crm_debug_2("Resource %s not deleted from %s: failed",
rsc->id, node->details->uname);
return FALSE;
} else if(node == NULL) {
crm_debug_2("Resource %s not deleted: NULL node", rsc->id);
return FALSE;
} else if(node->details->unclean || node->details->online == FALSE) {
crm_debug_2("Resource %s not deleted from %s: unrunnable",
rsc->id, node->details->uname);
return FALSE;
}
crm_notice("Removing %s from %s",
rsc->id, node->details->uname);
delete = delete_action(rsc, node);
#if DELETE_THEN_REFRESH
refresh = custom_action(
NULL, crm_strdup(CRM_OP_LRM_REFRESH), CRM_OP_LRM_REFRESH,
node, FALSE, TRUE, data_set);
add_hash_param(refresh->meta, XML_ATTR_TE_NOWAIT, XML_BOOLEAN_TRUE);
order_actions(delete, refresh, pe_ordering_optional);
#endif
return TRUE;
}
diff --git a/lib/crm/pengine/pengine.h b/lib/crm/pengine/pengine.h
index 49a0652288..119b2f5166 100644
--- a/lib/crm/pengine/pengine.h
+++ b/lib/crm/pengine/pengine.h
@@ -1,246 +1,227 @@
/* $Id: pengine.h,v 1.1 2006/06/07 12:46:56 andrew Exp $ */
/*
* 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__H
#define PENGINE__H
#include <clplumbing/ipc.h>
typedef struct rsc_to_node_s rsc_to_node_t;
typedef struct rsc_colocation_s rsc_colocation_t;
typedef struct lrm_agent_s lrm_agent_t;
typedef struct order_constraint_s order_constraint_t;
typedef struct action_s action_t;
typedef struct action_wrapper_s action_wrapper_t;
#include <glib.h>
#include <crm/crm.h>
#include <crm/common/msg.h>
#include <crm/common/iso8601.h>
#include <crm/pengine/rules.h>
#include <crm/pengine/common.h>
#include <crm/pengine/status.h>
#include <linux-ha/config.h>
#include <crm/pengine/complex.h>
enum con_strength {
pecs_ignore,
pecs_must,
pecs_must_not,
pecs_startstop
};
enum pe_stop_fail {
pesf_block,
pesf_stonith,
pesf_ignore
};
enum pe_ordering {
pe_ordering_manditory,
pe_ordering_restart,
pe_ordering_recover,
pe_ordering_postnotify,
pe_ordering_optional
};
-
-struct color_shared_s {
- int id;
- int highest_priority;
- GListPtr candidate_nodes; /* node_t* */
- GListPtr allocated_resources; /* resources_t* */
- node_t *chosen_node;
- gboolean pending;
- int num_resources;
-};
-
-struct color_s {
- int id;
- struct color_shared_s *details;
- int local_weight;
-};
-
struct rsc_colocation_s {
const char *id;
resource_t *rsc_lh;
resource_t *rsc_rh;
const char *state_lh;
const char *state_rh;
enum con_strength strength;
};
struct rsc_to_node_s {
const char *id;
resource_t *rsc_lh;
enum rsc_role_e role_filter;
GListPtr node_list_rh; /* node_t* */
};
struct action_wrapper_s
{
enum pe_ordering type;
action_t *action;
};
struct action_s
{
int id;
int priority;
resource_t *rsc;
void *rsc_opaque;
node_t *node;
const char *task;
char *uuid;
crm_data_t *op_entry;
gboolean pseudo;
gboolean runnable;
gboolean optional;
gboolean failure_is_fatal;
enum rsc_start_requirement needs;
enum action_fail_response on_fail;
enum rsc_role_e fail_role;
gboolean dumped;
gboolean processed;
action_t *pre_notify;
action_t *pre_notified;
action_t *post_notify;
action_t *post_notified;
int seen_count;
GHashTable *meta;
GHashTable *extra;
GHashTable *notify_keys; /* do NOT free */
GListPtr actions_before; /* action_warpper_t* */
GListPtr actions_after; /* action_warpper_t* */
};
struct order_constraint_s
{
int id;
enum pe_ordering type;
void *lh_opaque;
resource_t *lh_rsc;
action_t *lh_action;
char *lh_action_task;
void *rh_opaque;
resource_t *rh_rsc;
action_t *rh_action;
char *rh_action_task;
/* (soon to be) variant specific */
/* int lh_rsc_incarnation; */
/* int rh_rsc_incarnation; */
};
extern gboolean stage0(pe_working_set_t *data_set);
extern gboolean stage1(pe_working_set_t *data_set);
extern gboolean stage2(pe_working_set_t *data_set);
extern gboolean stage3(pe_working_set_t *data_set);
extern gboolean stage4(pe_working_set_t *data_set);
extern gboolean stage5(pe_working_set_t *data_set);
extern gboolean stage6(pe_working_set_t *data_set);
extern gboolean stage7(pe_working_set_t *data_set);
extern gboolean stage8(pe_working_set_t *data_set);
extern gboolean summary(GListPtr resources);
extern gboolean pe_msg_dispatch(IPC_Channel *sender, void *user_data);
extern gboolean process_pe_message(
HA_Message *msg, crm_data_t *xml_data, IPC_Channel *sender);
extern gboolean unpack_constraints(
crm_data_t *xml_constraints, pe_working_set_t *data_set);
extern gboolean unpack_resources(
crm_data_t *xml_resources, pe_working_set_t *data_set);
extern gboolean unpack_config(crm_data_t *config, pe_working_set_t *data_set);
extern gboolean unpack_nodes(crm_data_t *xml_nodes, pe_working_set_t *data_set);
extern gboolean unpack_status(crm_data_t *status, pe_working_set_t *data_set);
extern gboolean apply_placement_constraints(pe_working_set_t *data_set);
-extern gboolean choose_node_from_list(color_t *color);
-
extern gboolean update_action_states(GListPtr actions);
extern gboolean shutdown_constraints(
node_t *node, action_t *shutdown_op, pe_working_set_t *data_set);
extern gboolean stonith_constraints(
node_t *node, action_t *stonith_op, pe_working_set_t *data_set);
extern gboolean custom_action_order(
resource_t *lh_rsc, char *lh_task, action_t *lh_action,
resource_t *rh_rsc, char *rh_task, action_t *rh_action,
enum pe_ordering type, pe_working_set_t *data_set);
#define order_start_start(rsc1,rsc2, type) \
custom_action_order(rsc1, start_key(rsc1), NULL, \
rsc2, start_key(rsc2) ,NULL, \
type, data_set)
#define order_stop_stop(rsc1, rsc2, type) \
custom_action_order(rsc1, stop_key(rsc1), NULL, \
rsc2, stop_key(rsc2) ,NULL, \
type, data_set)
#define order_restart(rsc1) \
custom_action_order(rsc1, stop_key(rsc1), NULL, \
rsc1, start_key(rsc1), NULL, \
pe_ordering_restart, data_set)
#define order_stop_start(rsc1, rsc2, type) \
custom_action_order(rsc1, stop_key(rsc1), NULL, \
rsc2, start_key(rsc2) ,NULL, \
type, data_set)
#define order_start_stop(rsc1, rsc2, type) \
custom_action_order(rsc1, start_key(rsc1), NULL, \
rsc2, stop_key(rsc2) ,NULL, \
type, data_set)
extern gboolean process_colored_constraints(resource_t *rsc);
extern void graph_element_from_action(
action_t *action, pe_working_set_t *data_set);
extern void order_actions(action_t *lh_action, action_t *rh_action, enum pe_ordering order);
extern const char* transition_idle_timeout;
#endif
diff --git a/lib/crm/pengine/status.c b/lib/crm/pengine/status.c
index 0074d40cf1..72bdeb9e5b 100644
--- a/lib/crm/pengine/status.c
+++ b/lib/crm/pengine/status.c
@@ -1,281 +1,279 @@
/* $Id: status.c,v 1.8 2006/08/14 09:00:57 andrew Exp $ */
/*
* 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 <portability.h>
#include <sys/param.h>
#include <crm/crm.h>
#include <crm/cib.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crm/common/msg.h>
#include <clplumbing/cl_misc.h>
#include <glib.h>
#include <crm/pengine/status.h>
#include <utils.h>
#include <unpack.h>
crm_data_t * do_calculations(
pe_working_set_t *data_set, crm_data_t *xml_input, ha_time_t *now);
unsigned int pengine_input_loglevel = LOG_INFO;
#define PE_WORKING_DIR HA_VARLIBDIR"/heartbeat/pengine"
#define MEMCHECK_STAGE_0 0
#define check_and_exit(stage) cleanup_calculations(data_set); \
crm_mem_stats(NULL); \
crm_err("Exiting: stage %d", stage); \
exit(1);
/*
* Unpack everything
* At the end you'll have:
* - A list of nodes
* - A list of resources (each with any dependencies on other resources)
* - A list of constraints between resources and nodes
* - A list of constraints between start/stop actions
* - A list of nodes that need to be stonith'd
* - A list of nodes that need to be shutdown
* - A list of the possible stop/start actions (without dependencies)
*/
gboolean
cluster_status(pe_working_set_t *data_set)
{
crm_data_t * config = get_object_root(
XML_CIB_TAG_CRMCONFIG, data_set->input);
crm_data_t * cib_nodes = get_object_root(
XML_CIB_TAG_NODES, data_set->input);
crm_data_t * cib_resources = get_object_root(
XML_CIB_TAG_RESOURCES, data_set->input);
crm_data_t * cib_status = get_object_root(
XML_CIB_TAG_STATUS, data_set->input);
const char *value = crm_element_value(
data_set->input, XML_ATTR_HAVE_QUORUM);
crm_debug_3("Beginning unpack");
/* reset remaining global variables */
if(data_set->input == NULL) {
return FALSE;
}
if(data_set->input != NULL
&& crm_element_value(data_set->input, XML_ATTR_DC_UUID) != NULL) {
/* this should always be present */
data_set->dc_uuid = crm_element_value_copy(
data_set->input, XML_ATTR_DC_UUID);
}
unpack_config(config, data_set);
if(value != NULL) {
cl_str_to_boolean(value, &data_set->have_quorum);
}
if(data_set->have_quorum == FALSE
&& data_set->no_quorum_policy != no_quorum_ignore) {
crm_warn("We do not have quorum"
" - fencing and resource management disabled");
}
unpack_nodes(cib_nodes, data_set);
unpack_resources(cib_resources, data_set);
unpack_status(cib_status, data_set);
return TRUE;
}
static void
pe_free_resources(GListPtr resources)
{
resource_t *rsc = NULL;
GListPtr iterator = resources;
while(iterator != NULL) {
iterator = iterator;
rsc = (resource_t *)iterator->data;
iterator = iterator->next;
rsc->fns->free(rsc);
}
if(resources != NULL) {
g_list_free(resources);
}
}
static void
pe_free_actions(GListPtr actions)
{
GListPtr iterator = actions;
while(iterator != NULL) {
pe_free_action(iterator->data);
iterator = iterator->next;
}
if(actions != NULL) {
g_list_free(actions);
}
}
static void
pe_free_nodes(GListPtr nodes)
{
GListPtr iterator = nodes;
while(iterator != NULL) {
node_t *node = (node_t*)iterator->data;
struct node_shared_s *details = node->details;
iterator = iterator->next;
crm_debug_5("deleting node");
crm_debug_5("%s is being deleted", details->uname);
print_node("delete", node, FALSE);
if(details != NULL) {
if(details->attrs != NULL) {
g_hash_table_destroy(details->attrs);
}
pe_free_shallow_adv(details->running_rsc, FALSE);
crm_free(details);
}
crm_free(node);
}
if(nodes != NULL) {
g_list_free(nodes);
}
}
void
cleanup_calculations(pe_working_set_t *data_set)
{
if(data_set == NULL) {
return;
}
if(data_set->config_hash != NULL) {
g_hash_table_destroy(data_set->config_hash);
}
crm_free(data_set->dc_uuid);
crm_free(data_set->transition_idle_timeout);
crm_debug_3("deleting actions");
pe_free_actions(data_set->actions);
crm_debug_3("deleting resources");
pe_free_resources(data_set->resources);
crm_debug_3("deleting nodes");
pe_free_nodes(data_set->nodes);
free_xml(data_set->graph);
free_ha_date(data_set->now);
free_xml(data_set->input);
data_set->stonith_action = NULL;
CRM_CHECK(data_set->colors == NULL, ;);
CRM_CHECK(data_set->ordering_constraints == NULL, ;);
CRM_CHECK(data_set->placement_constraints == NULL, ;);
}
void
set_working_set_defaults(pe_working_set_t *data_set)
{
data_set->input = NULL;
data_set->now = NULL;
data_set->graph = NULL;
data_set->transition_idle_timeout = NULL;
data_set->dc_uuid = NULL;
data_set->dc_node = NULL;
data_set->have_quorum = FALSE;
data_set->stonith_enabled = FALSE;
data_set->stonith_action = NULL;
data_set->symmetric_cluster = TRUE;
data_set->is_managed_default = TRUE;
data_set->no_quorum_policy = no_quorum_freeze;
data_set->remove_after_stop = FALSE;
data_set->stop_action_orphans = TRUE;
data_set->stop_rsc_orphans = TRUE;
data_set->config_hash = NULL;
data_set->nodes = NULL;
data_set->resources = NULL;
data_set->ordering_constraints = NULL;
data_set->placement_constraints = NULL;
- data_set->no_color = NULL;
- data_set->colors = NULL;
data_set->actions = NULL;
data_set->num_synapse = 0;
data_set->max_valid_nodes = 0;
data_set->order_id = 1;
data_set->action_id = 1;
data_set->color_id = 0;
data_set->default_resource_stickiness = 0;
data_set->default_resource_fail_stickiness = 0;
}
resource_t *
pe_find_resource(GListPtr rsc_list, const char *id)
{
unsigned lpc = 0;
resource_t *rsc = NULL;
resource_t *child_rsc = NULL;
if(id == NULL) {
return NULL;
}
crm_debug_4("Looking for %s in %d objects", id, g_list_length(rsc_list));
for(lpc = 0; lpc < g_list_length(rsc_list); lpc++) {
rsc = g_list_nth_data(rsc_list, lpc);
if(rsc == NULL) {
} else if(rsc->id && strcmp(rsc->id, id) == 0){
crm_debug_4("Found a match for %s", id);
return rsc;
} else if(rsc->long_name && strcmp(rsc->long_name, id) == 0) {
crm_debug_4("Found a match for %s", id);
return rsc;
} else if(rsc->clone_name && strcmp(rsc->clone_name, id) == 0) {
crm_debug_4("Found a match for %s", id);
return rsc;
}
}
for(lpc = 0; lpc < g_list_length(rsc_list); lpc++) {
rsc = g_list_nth_data(rsc_list, lpc);
child_rsc = rsc->fns->find_child(rsc, id);
if(child_rsc != NULL) {
return child_rsc;
}
}
crm_debug_2("No match for %s", id);
return NULL;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 2:24 PM (18 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1012330
Default Alt Text
(53 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment