diff --git a/crm/pengine/complex.c b/crm/pengine/complex.c index d6fbd1d433..e314393c38 100644 --- a/crm/pengine/complex.c +++ b/crm/pengine/complex.c @@ -1,483 +1,497 @@ -/* $Id: complex.c,v 1.44 2005/07/05 13:56:46 andrew Exp $ */ +/* $Id: complex.c,v 1.45 2005/07/06 09:30:21 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * 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 #include #include #include gboolean update_node_weight(rsc_to_node_t *cons,const char *id,GListPtr nodes); gboolean is_active(rsc_to_node_t *cons); gboolean constraint_violated( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint); void order_actions(action_t *lh, action_t *rh, order_constraint_t *order); gboolean has_agent(node_t *a_node, lrm_agent_t *an_agent); extern gboolean rsc_colocation_new(const char *id, enum con_strength strength, resource_t *rsc_lh, resource_t *rsc_rh); extern rsc_to_node_t *rsc2node_new( const char *id, resource_t *rsc, double weight, node_t *node, pe_working_set_t *data_set); resource_object_functions_t resource_class_functions[] = { { native_unpack, native_find_child, native_num_allowed_nodes, native_color, native_create_actions, native_internal_constraints, native_agent_constraints, native_rsc_colocation_lh, native_rsc_colocation_rh, native_rsc_order_lh, native_rsc_order_rh, native_rsc_location, native_expand, native_dump, native_printw, + native_html, native_free }, { group_unpack, group_find_child, group_num_allowed_nodes, group_color, group_create_actions, group_internal_constraints, group_agent_constraints, group_rsc_colocation_lh, group_rsc_colocation_rh, group_rsc_order_lh, group_rsc_order_rh, group_rsc_location, group_expand, group_dump, group_printw, + group_html, group_free }, { - incarnation_unpack, - incarnation_find_child, - incarnation_num_allowed_nodes, - incarnation_color, - incarnation_create_actions, - incarnation_internal_constraints, - incarnation_agent_constraints, - incarnation_rsc_colocation_lh, - incarnation_rsc_colocation_rh, - incarnation_rsc_order_lh, - incarnation_rsc_order_rh, - incarnation_rsc_location, - incarnation_expand, - incarnation_dump, - incarnation_printw, - incarnation_free + clone_unpack, + clone_find_child, + clone_num_allowed_nodes, + clone_color, + clone_create_actions, + clone_internal_constraints, + clone_agent_constraints, + clone_rsc_colocation_lh, + clone_rsc_colocation_rh, + clone_rsc_order_lh, + clone_rsc_order_rh, + clone_rsc_location, + clone_expand, + clone_dump, + clone_printw, + clone_html, + clone_free } }; /* resource_object_functions_t resource_variants[] = resource_class_functions; */ 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_incarnation; + return pe_clone; } return pe_unknown; } gboolean is_active(rsc_to_node_t *cons) { /* todo: check constraint lifetime */ return TRUE; } void inherit_parent_attributes( crm_data_t *parent, crm_data_t *child, gboolean overwrite) { int lpc = 0; const char *attributes[] = { XML_RSC_ATTR_STOPFAIL, XML_RSC_ATTR_RESTART, "multiple_active", "start_prereq", "resource_stickiness", "is_managed" }; for(lpc = 0; lpc < DIMOF(attributes); lpc++) { const char *attr_p = crm_element_value(parent, attributes[lpc]); const char *attr_c = crm_element_value(child, attributes[lpc]); if(attr_c != NULL && safe_str_neq(attr_p, attr_c)) { if(overwrite == FALSE) { crm_debug_2("Resource %s: ignoring parent value for %s", ID(child), attributes[lpc]); continue; } pe_warn("Resource %s: Overwriting attribute %s: %s->%s", ID(child), attributes[lpc], attr_c, attr_p); } if(attr_p != NULL) { crm_xml_add(child, attributes[lpc], attr_p); } } } gboolean common_unpack( crm_data_t * xml_obj, resource_t **rsc, pe_working_set_t *data_set) { const char *id = crm_element_value(xml_obj, XML_ATTR_ID); const char *restart = crm_element_value(xml_obj, XML_RSC_ATTR_RESTART); const char *multiple = crm_element_value(xml_obj, "multiple_active"); const char *placement= crm_element_value(xml_obj, "resource_stickiness"); const char *priority = NULL; const char *is_managed = NULL; crm_log_xml_debug_2(xml_obj, "Processing resource input..."); if(id == NULL) { pe_err("Must specify id tag in "); 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)->id = id; (*rsc)->xml = xml_obj; (*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)->fns = &resource_class_functions[(*rsc)->variant]; crm_debug_3("Unpacking resource..."); (*rsc)->parameters = g_hash_table_new_full( g_str_hash,g_str_equal, g_hash_destroy_str,g_hash_destroy_str); unpack_instance_attributes(xml_obj, (*rsc)->parameters); priority = get_rsc_param(*rsc, XML_CIB_ATTR_PRIORITY); (*rsc)->priority = atoi(priority?priority:"0"); (*rsc)->effective_priority = (*rsc)->priority; (*rsc)->recovery_type = recovery_stop_start; (*rsc)->runnable = TRUE; (*rsc)->provisional = TRUE; (*rsc)->start_pending = FALSE; (*rsc)->starting = FALSE; (*rsc)->stopping = FALSE; (*rsc)->candidate_colors = NULL; (*rsc)->rsc_cons = NULL; (*rsc)->actions = NULL; (*rsc)->is_managed = TRUE; (*rsc)->stickiness = data_set->default_resource_stickiness; is_managed = crm_element_value((*rsc)->xml, "is_managed"); if(is_managed != NULL && crm_is_true(is_managed) == FALSE) { (*rsc)->is_managed = FALSE; crm_warn("Resource %s is currently not managed", (*rsc)->id); #if 0 rsc_to_node_t *new_con = NULL; /* prevent this resource from running anywhere */ new_con = rsc2node_new( "is_managed_default", *rsc, -INFINITY, NULL, data_set); new_con->node_list_rh = node_list_dup(data_set->nodes, FALSE); #endif } else if((*rsc)->is_managed && data_set->symmetric_cluster) { rsc_to_node_t *new_con = rsc2node_new( "symmetric_default", *rsc, 0, NULL, data_set); new_con->node_list_rh = node_list_dup(data_set->nodes, FALSE); } crm_debug_2("Options for %s", id); if(safe_str_eq(restart, "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"); } if(safe_str_eq(multiple, "stop_only")) { (*rsc)->recovery_type = recovery_stop_only; crm_debug_2("\tMultiple running resource recovery: stop only"); } else if(safe_str_eq(multiple, "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"); } if(placement != NULL) { if(safe_str_eq(placement, "INFINITY")) { (*rsc)->stickiness = INFINITY; } else if(safe_str_eq(placement, "-INFINITY")) { (*rsc)->stickiness = -INFINITY; } else { (*rsc)->stickiness = atoi(placement); } } if((*rsc)->stickiness > 0) { crm_debug_2("\tPlacement: prefer current location%s", placement == NULL?" (default)":""); } else if((*rsc)->stickiness < 0) { crm_warn("\tPlacement: always move from the current location%s", placement == NULL?" (default)":""); } else { crm_debug_2("\tPlacement: optimal%s", placement == NULL?" (default)":""); } (*rsc)->fns->unpack(*rsc, data_set); return TRUE; } void order_actions(action_t *lh_action, action_t *rh_action, order_constraint_t *order) { action_wrapper_t *wrapper = NULL; GListPtr list = NULL; crm_debug_2("Ordering %d: Action %d before %d", order?order->id:-1, lh_action->id, rh_action->id); 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)); if(wrapper != NULL) { wrapper->action = rh_action; wrapper->type = order->type; list = lh_action->actions_after; list = g_list_append(list, wrapper); lh_action->actions_after = list; wrapper = NULL; } if(order->type != pe_ordering_recover) { crm_malloc0(wrapper, sizeof(action_wrapper_t)); if(wrapper != NULL) { wrapper->action = lh_action; wrapper->type = order->type; list = rh_action->actions_before; list = g_list_append(list, wrapper); rh_action->actions_before = list; } } } +void common_html(resource_t *rsc, const char *pre_text, FILE *stream) +{ + const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); + + fprintf(stream, "%s%s %s (%s%s%s:%s):\t", + pre_text?pre_text:"", crm_element_name(rsc->xml), rsc->id, + prov?prov:"", prov?"::":"", + crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS), + crm_element_value(rsc->xml, XML_ATTR_TYPE)); +} + void common_printw(resource_t *rsc, const char *pre_text, int *index) { #if CURSES_ENABLED const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); move(*index, 0); printw("%s%s %s (%s%s%s:%s):\t", pre_text?pre_text:"", crm_element_name(rsc->xml), rsc->id, prov?prov:"", prov?"::":"", crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS), crm_element_value(rsc->xml, XML_ATTR_TYPE)); #else crm_err("printw support requires ncurses to be available during configure"); #endif } void common_dump(resource_t *rsc, const char *pre_text, gboolean details) { crm_debug_4("%s%s%s%sResource %s: (variant=%s, priority=%f)", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", rsc->provisional?"Provisional ":"", rsc->runnable?"":"(Non-Startable) ", rsc->id, crm_element_name(rsc->xml), (double)rsc->priority); } void common_free(resource_t *rsc) { if(rsc == NULL) { return; } crm_debug_5("Freeing %s", rsc->id); while(rsc->rsc_cons) { pe_free_rsc_colocation( (rsc_colocation_t*)rsc->rsc_cons->data); rsc->rsc_cons = rsc->rsc_cons->next; } if(rsc->rsc_cons != NULL) { g_list_free(rsc->rsc_cons); } if(rsc->parameters != NULL) { g_hash_table_destroy(rsc->parameters); } pe_free_shallow_adv(rsc->candidate_colors, TRUE); crm_free(rsc->variant_opaque); crm_free(rsc); crm_debug_5("Resource freed"); } void common_agent_constraints( GListPtr node_list, lrm_agent_t *agent, const char *id) { #if 0 slist_iter( node, node_t, node_list, lpc, crm_debug_5("Checking if %s supports %s/%s (%s)", node->details->uname, agent->class, agent->type, agent->version); if(has_agent(node, agent) == FALSE) { /* remove node from contention */ crm_debug_5("Marking node %s unavailable for %s", node->details->uname, id); node->weight = -1.0; node->fixed = TRUE; } ); #endif } void unpack_instance_attributes(crm_data_t *xml_obj, GHashTable *hash) { const char *name = NULL; const char *value = NULL; if(xml_obj == NULL) { crm_debug_4("No instance attributes"); return; } xml_child_iter( xml_obj, attr_set, XML_TAG_ATTR_SETS, xml_child_iter( attr_set, attrs, XML_TAG_ATTRS, /* todo: check any rules */ xml_child_iter( attrs, an_attr, XML_CIB_TAG_NVPAIR, name = crm_element_value( an_attr, XML_NVPAIR_ATTR_NAME); value = crm_element_value( an_attr, XML_NVPAIR_ATTR_VALUE); add_hash_param(hash, name, value); ); ); ); } void add_rsc_param(resource_t *rsc, const char *name, const char *value) { CRM_DEV_ASSERT(rsc != NULL); if(crm_assert_failed) { return; } add_hash_param(rsc->parameters, name, value); } void add_hash_param(GHashTable *hash, const char *name, const char *value) { CRM_DEV_ASSERT(hash != NULL); if(crm_assert_failed) { return; } crm_debug_3("adding: name=%s value=%s", crm_str(name), crm_str(value)); if(name == NULL || value == NULL) { return; } else if(g_hash_table_lookup(hash, name) == NULL) { g_hash_table_insert(hash, crm_strdup(name), crm_strdup(value)); } } const char * get_rsc_param(resource_t *rsc, const char *name) { CRM_DEV_ASSERT(rsc != NULL); if(crm_assert_failed) { return NULL; } return g_hash_table_lookup(rsc->parameters, name); } void hash2nvpair(gpointer key, gpointer value, gpointer user_data) { const char *name = key; const char *s_value = value; crm_data_t *xml_node = user_data; crm_data_t *xml_child = create_xml_node(xml_node, XML_CIB_TAG_NVPAIR); crm_xml_add(xml_child, XML_NVPAIR_ATTR_NAME, name); crm_xml_add(xml_child, XML_NVPAIR_ATTR_VALUE, s_value); crm_debug_3("dumped: name=%s value=%s", name, s_value); } diff --git a/crm/pengine/complex.h b/crm/pengine/complex.h index 13cdfb1e6b..1786d1914c 100644 --- a/crm/pengine/complex.h +++ b/crm/pengine/complex.h @@ -1,165 +1,169 @@ -/* $Id: complex.h,v 1.14 2005/06/29 16:43:12 andrew Exp $ */ +/* $Id: complex.h,v 1.15 2005/07/06 09:30:21 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * 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 CRM_PENGINE_COMPLEX__H #define CRM_PENGINE_COMPLEX__H #include #include #include #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 "incarnation" enum pe_obj_types { pe_native = 0, pe_group = 1, - pe_incarnation = 2, + pe_clone = 2, pe_unknown = -1 }; extern int get_resource_type(const char *name); typedef struct resource_object_functions_s { void (*unpack)(resource_t *, pe_working_set_t *); resource_t *(*find_child)(resource_t *, const char *); int (*num_allowed_nodes)(resource_t *); void (*color)(resource_t *, pe_working_set_t *); void (*create_actions)(resource_t *, pe_working_set_t *); void (*internal_constraints)(resource_t *, pe_working_set_t *); void (*agent_constraints)(resource_t *); void (*rsc_colocation_lh)(rsc_colocation_t *); void (*rsc_colocation_rh)(resource_t *, rsc_colocation_t *); void (*rsc_order_lh)(resource_t *, order_constraint_t *); void (*rsc_order_rh)( action_t *, resource_t *, order_constraint_t *); void (*rsc_location)(resource_t *, rsc_to_node_t *); void (*expand)(resource_t *, pe_working_set_t *); void (*dump)(resource_t *, const char *, gboolean); void (*printw)(resource_t *, const char *, int*); + void (*html)(resource_t *, const char *, FILE*); void (*free)(resource_t *); } resource_object_functions_t; extern void native_unpack(resource_t *rsc, pe_working_set_t *data_set); extern resource_t *native_find_child(resource_t *rsc, const char *id); extern int native_num_allowed_nodes(resource_t *rsc); extern void native_color(resource_t *rsc, pe_working_set_t *data_set); extern void native_create_actions( resource_t *rsc, pe_working_set_t *data_set); extern void native_internal_constraints( resource_t *rsc, pe_working_set_t *data_set); extern void native_agent_constraints(resource_t *rsc); extern void native_rsc_colocation_lh(rsc_colocation_t *constraint); extern void native_rsc_colocation_rh( resource_t *rsc, rsc_colocation_t *constraint); extern void native_rsc_order_lh(resource_t *rsc, order_constraint_t *order); extern void native_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order); extern void native_rsc_location(resource_t *rsc, rsc_to_node_t *constraint); extern void native_expand(resource_t *rsc, pe_working_set_t *data_set); extern void native_dump(resource_t *rsc, const char *pre_text, gboolean details); extern void native_printw(resource_t *rsc, const char *pre_text, int *index); +extern void native_html(resource_t *rsc, const char *pre_text, FILE *stream); extern void native_free(resource_t *rsc); extern void group_unpack(resource_t *rsc, pe_working_set_t *data_set); extern resource_t *group_find_child(resource_t *rsc, const char *id); extern int group_num_allowed_nodes(resource_t *rsc); extern void group_color(resource_t *rsc, pe_working_set_t *data_set); extern void group_create_actions( resource_t *rsc, pe_working_set_t *data_set); extern void group_internal_constraints( resource_t *rsc, pe_working_set_t *data_set); extern void group_agent_constraints(resource_t *rsc); extern void group_rsc_colocation_lh(rsc_colocation_t *constraint); extern void group_rsc_colocation_rh( resource_t *rsc, rsc_colocation_t *constraint); extern void group_rsc_order_lh(resource_t *rsc, order_constraint_t *order); extern void group_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order); extern void group_rsc_location(resource_t *rsc, rsc_to_node_t *constraint); extern void group_expand(resource_t *rsc, pe_working_set_t *data_set); extern void group_dump(resource_t *rsc, const char *pre_text, gboolean details); extern void group_printw(resource_t *rsc, const char *pre_text, int *index); +extern void group_html(resource_t *rsc, const char *pre_text, FILE *stream); extern void group_free(resource_t *rsc); -extern void incarnation_unpack(resource_t *rsc, pe_working_set_t *data_set); -extern resource_t *incarnation_find_child(resource_t *rsc, const char *id); -extern int incarnation_num_allowed_nodes(resource_t *rsc); -extern void incarnation_color(resource_t *rsc, pe_working_set_t *data_set); -extern void incarnation_create_actions( +extern void clone_unpack(resource_t *rsc, pe_working_set_t *data_set); +extern resource_t *clone_find_child(resource_t *rsc, const char *id); +extern int clone_num_allowed_nodes(resource_t *rsc); +extern void clone_color(resource_t *rsc, pe_working_set_t *data_set); +extern void clone_create_actions(resource_t *rsc, pe_working_set_t *data_set); +extern void clone_internal_constraints( resource_t *rsc, pe_working_set_t *data_set); -extern void incarnation_internal_constraints( - resource_t *rsc, pe_working_set_t *data_set); -extern void incarnation_agent_constraints(resource_t *rsc); -extern void incarnation_rsc_colocation_lh(rsc_colocation_t *constraint); -extern void incarnation_rsc_colocation_rh( +extern void clone_agent_constraints(resource_t *rsc); +extern void clone_rsc_colocation_lh(rsc_colocation_t *constraint); +extern void clone_rsc_colocation_rh( resource_t *rsc, rsc_colocation_t *constraint); -extern void incarnation_rsc_order_lh(resource_t *rsc, order_constraint_t *order); -extern void incarnation_rsc_order_rh( +extern void clone_rsc_order_lh(resource_t *rsc, order_constraint_t *order); +extern void clone_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order); -extern void incarnation_rsc_location(resource_t *rsc, rsc_to_node_t *constraint); -extern void incarnation_expand(resource_t *rsc, pe_working_set_t *data_set); -extern void incarnation_dump(resource_t *rsc, const char *pre_text, gboolean details); -extern void incarnation_printw(resource_t *rsc, const char *pre_text, int *index); -extern void incarnation_free(resource_t *rsc); +extern void clone_rsc_location(resource_t *rsc, rsc_to_node_t *constraint); +extern void clone_expand(resource_t *rsc, pe_working_set_t *data_set); +extern void clone_dump(resource_t *rsc, const char *pre_text, gboolean details); +extern void clone_printw(resource_t *rsc, const char *pre_text, int *index); +extern void clone_html(resource_t *rsc, const char *pre_text, FILE *stream); +extern void clone_free(resource_t *rsc); /* extern resource_object_functions_t resource_variants[]; */ extern resource_object_functions_t resource_class_functions[]; extern gboolean common_unpack( crm_data_t *xml_obj, resource_t **rsc, pe_working_set_t *data_set); extern void common_dump( resource_t *rsc, const char *pre_text, gboolean details); extern void common_printw(resource_t *rsc, const char *pre_text, int *index); +extern void common_html(resource_t *rsc, const char *pre_text, FILE *stream); 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 gboolean is_active(rsc_to_node_t *cons); extern gboolean native_constraint_violated( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint); extern void order_actions(action_t *lh, action_t *rh, order_constraint_t *order); extern void common_agent_constraints( GListPtr node_list, lrm_agent_t *agent, const char *id); extern void unpack_instance_attributes(crm_data_t *xml_obj, GHashTable *hash); extern const char *get_rsc_param(resource_t *rsc, const char *prop); extern void add_rsc_param(resource_t *rsc, const char *name, const char *value); extern void add_hash_param(GHashTable *hash, const char *name, const char *value); extern void hash2nvpair(gpointer key, gpointer value, gpointer user_data); extern void inherit_parent_attributes( crm_data_t *parent, crm_data_t *child, gboolean overwrite); #endif diff --git a/crm/pengine/incarnation.c b/crm/pengine/incarnation.c index 434f0f0ae0..a6a4971a56 100644 --- a/crm/pengine/incarnation.c +++ b/crm/pengine/incarnation.c @@ -1,739 +1,764 @@ -/* $Id: incarnation.c,v 1.35 2005/07/05 13:56:46 andrew Exp $ */ +/* $Id: incarnation.c,v 1.36 2005/07/06 09:30:21 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * 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 #include #include #include extern gboolean rsc_colocation_new( const char *id, enum con_strength strength, resource_t *rsc_lh, resource_t *rsc_rh); -typedef struct incarnation_variant_data_s +typedef struct clone_variant_data_s { resource_t *self; - int incarnation_max; - int incarnation_max_node; + int clone_max; + int clone_max_node; - int active_incarnation; + int active_clones; gboolean interleave; gboolean ordered; GListPtr child_list; /* resource_t* */ gboolean child_starting; gboolean child_stopping; -} incarnation_variant_data_t; +} clone_variant_data_t; void child_stopping_constraints( - incarnation_variant_data_t *incarnation_data, enum pe_ordering type, + clone_variant_data_t *clone_data, enum pe_ordering type, resource_t *child, resource_t *last, pe_working_set_t *data_set); void child_starting_constraints( - incarnation_variant_data_t *incarnation_data, enum pe_ordering type, + clone_variant_data_t *clone_data, enum pe_ordering type, resource_t *child, resource_t *last, pe_working_set_t *data_set); -#define get_incarnation_variant_data(data, rsc) \ - if(rsc->variant == pe_incarnation) { \ - data = (incarnation_variant_data_t *)rsc->variant_opaque; \ +#define get_clone_variant_data(data, rsc) \ + if(rsc->variant == pe_clone) { \ + data = (clone_variant_data_t *)rsc->variant_opaque; \ } else { \ - pe_err("Resource %s was not an \"incarnation\" variant", \ + pe_err("Resource %s was not an \"" XML_CIB_TAG_INCARNATION "\" variant", \ rsc->id); \ return; \ } -void incarnation_unpack(resource_t *rsc, pe_working_set_t *data_set) +void clone_unpack(resource_t *rsc, pe_working_set_t *data_set) { int lpc = 0; crm_data_t * xml_obj_child = NULL; crm_data_t * xml_obj = rsc->xml; crm_data_t * xml_self = create_xml_node(NULL, XML_CIB_TAG_RESOURCE); - incarnation_variant_data_t *incarnation_data = NULL; + clone_variant_data_t *clone_data = NULL; resource_t *self = NULL; char *inc_max = NULL; const char *ordered = crm_element_value(xml_obj, XML_RSC_ATTR_ORDERED); const char *interleave = crm_element_value(xml_obj, XML_RSC_ATTR_INTERLEAVE); - const char *max_incarn = + const char *max_clones = get_rsc_param(rsc, XML_RSC_ATTR_INCARNATION_MAX); - const char *max_incarn_node = + const char *max_clones_node = get_rsc_param(rsc, XML_RSC_ATTR_INCARNATION_NODEMAX); crm_debug_3("Processing resource %s...", rsc->id); - crm_malloc0(incarnation_data, sizeof(incarnation_variant_data_t)); - incarnation_data->child_list = NULL; - incarnation_data->interleave = FALSE; - incarnation_data->ordered = FALSE; - incarnation_data->active_incarnation = 0; - incarnation_data->incarnation_max = crm_atoi(max_incarn, "1"); - incarnation_data->incarnation_max_node = crm_atoi(max_incarn_node,"1"); + crm_malloc0(clone_data, sizeof(clone_variant_data_t)); + clone_data->child_list = NULL; + clone_data->interleave = FALSE; + clone_data->ordered = FALSE; + clone_data->active_clones = 0; + clone_data->clone_max = crm_atoi(max_clones, "1"); + clone_data->clone_max_node = crm_atoi(max_clones_node,"1"); /* this is a bit of a hack - but simplifies everything else */ copy_in_properties(xml_self, xml_obj); xml_obj_child = find_xml_node(xml_obj, XML_CIB_TAG_GROUP, FALSE); if(xml_obj_child == NULL) { xml_obj_child = find_xml_node( xml_obj, XML_CIB_TAG_RESOURCE, TRUE); } CRM_DEV_ASSERT(xml_obj_child != NULL); if(crm_assert_failed) { return; } xml_obj_child = copy_xml(xml_obj_child); if(common_unpack(xml_self, &self, data_set)) { - incarnation_data->self = self; + clone_data->self = self; } else { crm_log_xml_err(xml_self, "Couldnt unpack dummy child"); return; } if(crm_is_true(interleave)) { - incarnation_data->interleave = TRUE; + clone_data->interleave = TRUE; } if(crm_is_true(ordered)) { - incarnation_data->ordered = TRUE; + clone_data->ordered = TRUE; } inherit_parent_attributes(xml_self, xml_obj_child, FALSE); - inc_max = crm_itoa(incarnation_data->incarnation_max); - for(lpc = 0; lpc < incarnation_data->incarnation_max; lpc++) { + inc_max = crm_itoa(clone_data->clone_max); + for(lpc = 0; lpc < clone_data->clone_max; lpc++) { resource_t *child_rsc = NULL; crm_data_t * child_copy = copy_xml(xml_obj_child); set_id(child_copy, rsc->id, lpc); if(common_unpack(child_copy, &child_rsc, data_set)) { char *inc_num = crm_itoa(lpc); - incarnation_data->child_list = g_list_append( - incarnation_data->child_list, child_rsc); + clone_data->child_list = g_list_append( + clone_data->child_list, child_rsc); add_rsc_param( child_rsc, XML_RSC_ATTR_INCARNATION, inc_num); add_rsc_param( child_rsc, XML_RSC_ATTR_INCARNATION_MAX, inc_max); crm_action_debug_3( print_resource("Added", child_rsc, FALSE)); crm_free(inc_num); } else { pe_err("Failed unpacking resource %s", crm_element_value(child_copy, XML_ATTR_ID)); } } crm_free(inc_max); free_xml(xml_obj_child); crm_debug_3("Added %d children to resource %s...", - incarnation_data->incarnation_max, rsc->id); + clone_data->clone_max, rsc->id); - rsc->variant_opaque = incarnation_data; + rsc->variant_opaque = clone_data; } resource_t * -incarnation_find_child(resource_t *rsc, const char *id) +clone_find_child(resource_t *rsc, const char *id) { - incarnation_variant_data_t *incarnation_data = NULL; - if(rsc->variant == pe_incarnation) { - incarnation_data = (incarnation_variant_data_t *)rsc->variant_opaque; + clone_variant_data_t *clone_data = NULL; + if(rsc->variant == pe_clone) { + clone_data = (clone_variant_data_t *)rsc->variant_opaque; } else { - pe_err("Resource %s was not a \"incarnation\" variant", rsc->id); + pe_err("Resource %s was not a \"" XML_CIB_TAG_INCARNATION "\" variant", rsc->id); return NULL; } - return pe_find_resource(incarnation_data->child_list, id); + return pe_find_resource(clone_data->child_list, id); } -int incarnation_num_allowed_nodes(resource_t *rsc) +int clone_num_allowed_nodes(resource_t *rsc) { int num_nodes = 0; - incarnation_variant_data_t *incarnation_data = NULL; - if(rsc->variant == pe_incarnation) { - incarnation_data = (incarnation_variant_data_t *)rsc->variant_opaque; + clone_variant_data_t *clone_data = NULL; + if(rsc->variant == pe_clone) { + clone_data = (clone_variant_data_t *)rsc->variant_opaque; } else { - pe_err("Resource %s was not an \"incarnation\" variant", + pe_err("Resource %s was not an \"" XML_CIB_TAG_INCARNATION "\" variant", rsc->id); return 0; } /* what *should* we return here? */ slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, int tmp_num_nodes = child_rsc->fns->num_allowed_nodes(child_rsc); if(tmp_num_nodes > num_nodes) { num_nodes = tmp_num_nodes; } ); return num_nodes; } -void incarnation_color(resource_t *rsc, pe_working_set_t *data_set) +void clone_color(resource_t *rsc, pe_working_set_t *data_set) { int lpc = 0, lpc2 = 0, max_nodes = 0; resource_t *child_0 = NULL; resource_t *child_lh = NULL; resource_t *child_rh = NULL; - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); - if(incarnation_data->self->is_managed == FALSE) { + if(clone_data->self->is_managed == FALSE) { return; } - child_0 = g_list_nth_data(incarnation_data->child_list, 0); + child_0 = g_list_nth_data(clone_data->child_list, 0); max_nodes = rsc->fns->num_allowed_nodes(rsc); - /* generate up to max_nodes * incarnation_node_max constraints */ + /* generate up to max_nodes * clone_node_max constraints */ lpc = 0; crm_info("Distributing %d incarnations over %d nodes", - incarnation_data->incarnation_max, max_nodes); + clone_data->clone_max, max_nodes); - for(; lpc < max_nodes && lpc < incarnation_data->incarnation_max; lpc++) { + for(; lpc < max_nodes && lpc < clone_data->clone_max; lpc++) { child_lh = child_0; - incarnation_data->active_incarnation++; + clone_data->active_clones++; if(lpc != 0) { - child_rh = g_list_nth_data(incarnation_data->child_list, lpc); + child_rh = g_list_nth_data(clone_data->child_list, lpc); - crm_debug_4("Incarnation %d will run on a differnt node to 0", + crm_debug_4("Clone %d will run on a differnt node to 0", lpc); - rsc_colocation_new("pe_incarnation_internal_must_not", + rsc_colocation_new("pe_clone_internal_must_not", pecs_must_not, child_lh, child_rh); } else { child_rh = child_0; } child_lh = child_rh; - for(lpc2 = 1; lpc2 < incarnation_data->incarnation_max_node; lpc2++) { + for(lpc2 = 1; lpc2 < clone_data->clone_max_node; lpc2++) { int offset = lpc + (lpc2 * max_nodes); - if(offset >= incarnation_data->incarnation_max) { + if(offset >= clone_data->clone_max) { break; } - crm_debug_4("Incarnation %d will run on the same node as %d", + crm_debug_4("Clone %d will run on the same node as %d", offset, lpc); - incarnation_data->active_incarnation++; + clone_data->active_clones++; child_rh = g_list_nth_data( - incarnation_data->child_list, offset); + clone_data->child_list, offset); - rsc_colocation_new("pe_incarnation_internal_must", + rsc_colocation_new("pe_clone_internal_must", pecs_must, child_lh, child_rh); } } slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, - if(lpc < incarnation_data->active_incarnation) { - crm_debug_4("Coloring Incarnation %d", lpc); + child_rsc, resource_t, clone_data->child_list, lpc, + if(lpc < clone_data->active_clones) { + crm_debug_4("Coloring Clone %d", lpc); child_rsc->fns->color(child_rsc, data_set); } else { /* TODO: assign "no color"? Doesnt seem to need it */ - pe_warn("Incarnation %d cannot be started", lpc+1); + pe_warn("Clone %d cannot be started", lpc+1); /* native_assign_color(child_rsc, data_set->no_color); */ } ); - crm_info("%d Incarnations are active", incarnation_data->active_incarnation); + crm_info("%d Clones are active", clone_data->active_clones); } -void incarnation_update_pseudo_status(resource_t *parent, resource_t *child); +void clone_update_pseudo_status(resource_t *parent, resource_t *child); -void incarnation_create_actions(resource_t *rsc, pe_working_set_t *data_set) +void clone_create_actions(resource_t *rsc, pe_working_set_t *data_set) { action_t *op = NULL; resource_t *last_start_rsc = NULL; resource_t *last_stop_rsc = NULL; - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, child_rsc->fns->create_actions(child_rsc, data_set); - incarnation_update_pseudo_status(rsc, child_rsc); + clone_update_pseudo_status(rsc, child_rsc); if(child_rsc->starting) { last_start_rsc = child_rsc; } if(child_rsc->stopping) { last_stop_rsc = child_rsc; } ); - op = start_action(incarnation_data->self, NULL, - !incarnation_data->child_starting); + op = start_action(clone_data->self, NULL, + !clone_data->child_starting); op->pseudo = TRUE; - op = custom_action(incarnation_data->self, started_key(rsc), + op = custom_action(clone_data->self, started_key(rsc), CRMD_ACTION_STARTED, NULL, - !incarnation_data->child_starting, data_set); + !clone_data->child_starting, data_set); op->pseudo = TRUE; child_starting_constraints( - incarnation_data, pe_ordering_optional, + clone_data, pe_ordering_optional, NULL, last_start_rsc, data_set); - op = stop_action(incarnation_data->self, NULL, - !incarnation_data->child_stopping); + op = stop_action(clone_data->self, NULL, + !clone_data->child_stopping); op->pseudo = TRUE; - op = custom_action(incarnation_data->self, stopped_key(rsc), + op = custom_action(clone_data->self, stopped_key(rsc), CRMD_ACTION_STOPPED, NULL, - !incarnation_data->child_stopping, data_set); + !clone_data->child_stopping, data_set); op->pseudo = TRUE; child_stopping_constraints( - incarnation_data, pe_ordering_optional, + clone_data, pe_ordering_optional, NULL, last_stop_rsc, data_set); } void -incarnation_update_pseudo_status(resource_t *parent, resource_t *child) +clone_update_pseudo_status(resource_t *parent, resource_t *child) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, parent); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, parent); - if(incarnation_data->child_stopping - && incarnation_data->child_starting) { + if(clone_data->child_stopping + && clone_data->child_starting) { return; } slist_iter( action, action_t, child->actions, lpc, if(action->optional) { continue; } if(safe_str_eq(CRMD_ACTION_STOP, action->task)) { - incarnation_data->child_stopping = TRUE; + clone_data->child_stopping = TRUE; } else if(safe_str_eq(CRMD_ACTION_START, action->task)) { - incarnation_data->child_starting = TRUE; + clone_data->child_starting = TRUE; } ); } void child_starting_constraints( - incarnation_variant_data_t *incarnation_data, enum pe_ordering type, + clone_variant_data_t *clone_data, enum pe_ordering type, resource_t *child, resource_t *last, pe_working_set_t *data_set) { - if(incarnation_data->ordered - || incarnation_data->self->restart_type == pe_restart_restart) { + if(clone_data->ordered + || clone_data->self->restart_type == pe_restart_restart) { type = pe_ordering_manditory; } if(child == NULL) { - if(incarnation_data->ordered && last != NULL) { + if(clone_data->ordered && last != NULL) { crm_debug_4("Ordered version (last node)"); /* last child start before global started */ custom_action_order( last, start_key(last), NULL, - incarnation_data->self, started_key(incarnation_data->self), NULL, + clone_data->self, started_key(clone_data->self), NULL, type, data_set); } - } else if(incarnation_data->ordered) { + } else if(clone_data->ordered) { crm_debug_4("Ordered version"); if(last == NULL) { /* global start before first child start */ - last = incarnation_data->self; + last = clone_data->self; } /* else: child/child relative start */ order_start_start(last, child, type); } else { crm_debug_4("Un-ordered version"); /* child start before global started */ custom_action_order( child, start_key(child), NULL, - incarnation_data->self, started_key(incarnation_data->self), NULL, + clone_data->self, started_key(clone_data->self), NULL, type, data_set); /* global start before child start */ -/* order_start_start(incarnation_data->self, child, type); */ +/* order_start_start(clone_data->self, child, type); */ order_start_start( - incarnation_data->self, child, pe_ordering_manditory); + clone_data->self, child, pe_ordering_manditory); } } void child_stopping_constraints( - incarnation_variant_data_t *incarnation_data, enum pe_ordering type, + clone_variant_data_t *clone_data, enum pe_ordering type, resource_t *child, resource_t *last, pe_working_set_t *data_set) { - if(incarnation_data->ordered - || incarnation_data->self->restart_type == pe_restart_restart) { + if(clone_data->ordered + || clone_data->self->restart_type == pe_restart_restart) { type = pe_ordering_manditory; } if(child == NULL) { - if(incarnation_data->ordered && last != NULL) { + if(clone_data->ordered && last != NULL) { crm_debug_4("Ordered version (last node)"); /* global stop before first child stop */ - order_stop_stop(incarnation_data->self, last, + order_stop_stop(clone_data->self, last, pe_ordering_manditory); } - } else if(incarnation_data->ordered && last != NULL) { + } else if(clone_data->ordered && last != NULL) { crm_debug_4("Ordered version"); /* child/child relative stop */ order_stop_stop(child, last, type); - } else if(incarnation_data->ordered) { + } else if(clone_data->ordered) { crm_debug_4("Ordered version (1st node)"); /* first child stop before global stopped */ custom_action_order( child, stop_key(child), NULL, - incarnation_data->self, stopped_key(incarnation_data->self), NULL, + clone_data->self, stopped_key(clone_data->self), NULL, type, data_set); } else { crm_debug_4("Un-ordered version"); /* child stop before global stopped */ custom_action_order( child, stop_key(child), NULL, - incarnation_data->self, stopped_key(incarnation_data->self), NULL, + clone_data->self, stopped_key(clone_data->self), NULL, type, data_set); /* global stop before child stop */ - order_stop_stop(incarnation_data->self, child, type); + order_stop_stop(clone_data->self, child, type); } } void -incarnation_internal_constraints(resource_t *rsc, pe_working_set_t *data_set) +clone_internal_constraints(resource_t *rsc, pe_working_set_t *data_set) { resource_t *last_rsc = NULL; - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); /* global stopped before start */ custom_action_order( - incarnation_data->self, stopped_key(incarnation_data->self), NULL, - incarnation_data->self, start_key(incarnation_data->self), NULL, + clone_data->self, stopped_key(clone_data->self), NULL, + clone_data->self, start_key(clone_data->self), NULL, pe_ordering_manditory, data_set); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, /* child stop before start */ order_restart(child_rsc); child_starting_constraints( - incarnation_data, pe_ordering_optional, + clone_data, pe_ordering_optional, child_rsc, last_rsc, data_set); child_stopping_constraints( - incarnation_data, pe_ordering_optional, + clone_data, pe_ordering_optional, child_rsc, last_rsc, data_set); last_rsc = child_rsc; ); } -void incarnation_rsc_colocation_lh(rsc_colocation_t *constraint) +void clone_rsc_colocation_lh(rsc_colocation_t *constraint) { gboolean do_interleave = FALSE; resource_t *rsc = constraint->rsc_lh; - incarnation_variant_data_t *incarnation_data = NULL; - incarnation_variant_data_t *incarnation_data_rh = NULL; + clone_variant_data_t *clone_data = NULL; + clone_variant_data_t *clone_data_rh = NULL; if(rsc == NULL) { pe_err("rsc_lh was NULL for %s", constraint->id); return; } else if(constraint->rsc_rh == NULL) { pe_err("rsc_rh was NULL for %s", constraint->id); return; } else { crm_debug_4("Processing constraints from %s", rsc->id); } - get_incarnation_variant_data(incarnation_data, rsc); - - if(constraint->rsc_rh->variant == pe_incarnation) { - get_incarnation_variant_data( - incarnation_data_rh, constraint->rsc_rh); - if(incarnation_data->incarnation_max_node - != incarnation_data_rh->incarnation_max_node) { - pe_err("Cannot interleave incarnation %s and %s because" + get_clone_variant_data(clone_data, rsc); + + if(constraint->rsc_rh->variant == pe_clone) { + get_clone_variant_data( + clone_data_rh, constraint->rsc_rh); + if(clone_data->clone_max_node + != clone_data_rh->clone_max_node) { + pe_err("Cannot interleave "XML_CIB_TAG_INCARNATION" %s and %s because" " they do not support the same number of" " resources per node", constraint->rsc_lh->id, constraint->rsc_rh->id); /* only the LHS side needs to be labeled as interleave */ - } else if(incarnation_data->interleave) { + } else if(clone_data->interleave) { do_interleave = TRUE; } } if(do_interleave) { resource_t *child_lh = NULL; resource_t *child_rh = NULL; resource_t *parent_rh = constraint->rsc_rh; - GListPtr iter_lh = incarnation_data->child_list; - GListPtr iter_rh = incarnation_data_rh->child_list; + GListPtr iter_lh = clone_data->child_list; + GListPtr iter_rh = clone_data_rh->child_list; crm_debug_2("Interleaving %s with %s", constraint->rsc_lh->id, constraint->rsc_rh->id); /* If the resource have different numbers of incarnations, * then just do as many as are available */ while(iter_lh != NULL && iter_rh != NULL) { child_lh = iter_lh->data; child_rh = iter_rh->data; iter_lh = iter_lh->next; iter_rh = iter_rh->next; constraint->rsc_rh = child_rh; crm_debug_3("Colocating %s with %s", child_lh->id, child_rh->id); child_rh->fns->rsc_colocation_rh(child_lh, constraint); } /* restore the original RHS of the constraint */ constraint->rsc_rh = parent_rh; return; } else if(constraint->strength != pecs_must_not) { pe_warn("rsc_colocations other than \"-INFINITY\"" " are not supported for non-interleaved" - " incarnation resources"); + " "XML_CIB_TAG_INCARNATION" resources"); return; } slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, crm_action_debug_3(print_resource("LHS", child_rsc, TRUE)); child_rsc->fns->rsc_colocation_rh(child_rsc, constraint); ); } -void incarnation_rsc_colocation_rh(resource_t *rsc, rsc_colocation_t *constraint) +void clone_rsc_colocation_rh(resource_t *rsc, rsc_colocation_t *constraint) { - incarnation_variant_data_t *incarnation_data = NULL; + clone_variant_data_t *clone_data = NULL; crm_debug_3("Processing RH of constraint %s", constraint->id); if(rsc == NULL) { pe_err("rsc_lh was NULL for %s", constraint->id); return; } else if(constraint->rsc_rh == NULL) { pe_err("rsc_rh was NULL for %s", constraint->id); return; } else if(constraint->strength != pecs_must_not) { pe_warn("rsc_dependencies other than \"must_not\" " "are not supported for incarnation resources"); return; } else { crm_action_debug_3(print_resource("LHS", rsc, FALSE)); } - get_incarnation_variant_data(incarnation_data, rsc); + get_clone_variant_data(clone_data, rsc); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, crm_action_debug_3(print_resource("RHS", child_rsc, FALSE)); child_rsc->fns->rsc_colocation_rh(child_rsc, constraint); ); } -void incarnation_rsc_order_lh(resource_t *rsc, order_constraint_t *order) +void clone_rsc_order_lh(resource_t *rsc, order_constraint_t *order) { char *stop_id = NULL; char *start_id = NULL; - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); crm_debug_3("Processing LH of ordering constraint %d", order->id); stop_id = stop_key(rsc); start_id = start_key(rsc); if(safe_str_eq(order->lh_action_task, start_id)) { crm_free(order->lh_action_task); order->lh_action_task = started_key(rsc); } else if(safe_str_eq(order->lh_action_task, stop_id)) { crm_free(order->lh_action_task); order->lh_action_task = stopped_key(rsc); } crm_free(start_id); crm_free(stop_id); - incarnation_data->self->fns->rsc_order_lh(incarnation_data->self, order); + clone_data->self->fns->rsc_order_lh(clone_data->self, order); } -void incarnation_rsc_order_rh( +void clone_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); crm_debug_3("Processing RH of ordering constraint %d", order->id); - incarnation_data->self->fns->rsc_order_rh(lh_action, incarnation_data->self, order); + clone_data->self->fns->rsc_order_rh(lh_action, clone_data->self, order); } -void incarnation_rsc_location(resource_t *rsc, rsc_to_node_t *constraint) +void clone_rsc_location(resource_t *rsc, rsc_to_node_t *constraint) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); crm_debug_3("Processing actions from %s", rsc->id); - incarnation_data->self->fns->rsc_location(incarnation_data->self, constraint); + clone_data->self->fns->rsc_location(clone_data->self, constraint); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, child_rsc->fns->rsc_location(child_rsc, constraint); ); } -void incarnation_expand(resource_t *rsc, pe_working_set_t *data_set) +void clone_expand(resource_t *rsc, pe_working_set_t *data_set) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); crm_debug_3("Processing actions from %s", rsc->id); - incarnation_data->self->fns->expand(incarnation_data->self, data_set); + clone_data->self->fns->expand(clone_data->self, data_set); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, child_rsc->fns->expand(child_rsc, data_set); ); } -void incarnation_printw(resource_t *rsc, const char *pre_text, int *index) +void clone_printw(resource_t *rsc, const char *pre_text, int *index) { #if CURSES_ENABLED const char *child_text = NULL; - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); if(pre_text != NULL) { child_text = " "; } else { child_text = " "; } move(*index, 0); - printw("Incarnation: %s\n", rsc->id); + printw("Clone: %s\n", rsc->id); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, (*index)++; child_rsc->fns->printw(child_rsc, child_text, index); ); #else crm_err("printw support requires ncurses to be available during configure"); #endif } -void incarnation_dump(resource_t *rsc, const char *pre_text, gboolean details) +void clone_html(resource_t *rsc, const char *pre_text, FILE *stream) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + const char *child_text = NULL; + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); + if(pre_text != NULL) { + child_text = " "; + } else { + child_text = " "; + } + + fprintf(stream, "Clone: %s\n", rsc->id); + fprintf(stream, "
    \n"); + + slist_iter( + child_rsc, resource_t, clone_data->child_list, lpc, + + fprintf(stream, "
  • \n"); + child_rsc->fns->html(child_rsc, child_text, stream); + fprintf(stream, "
  • \n"); + ); + fprintf(stream, "
\n"); +} + + +void clone_dump(resource_t *rsc, const char *pre_text, gboolean details) +{ + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); common_dump(rsc, pre_text, details); - incarnation_data->self->fns->dump( - incarnation_data->self, pre_text, details); + clone_data->self->fns->dump( + clone_data->self, pre_text, details); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, child_rsc->fns->dump(child_rsc, pre_text, details); ); } -void incarnation_free(resource_t *rsc) +void clone_free(resource_t *rsc) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); crm_debug_3("Freeing %s", rsc->id); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, crm_debug_3("Freeing child %s", child_rsc->id); free_xml(child_rsc->xml); child_rsc->fns->free(child_rsc); ); crm_debug_3("Freeing child list"); - pe_free_shallow_adv(incarnation_data->child_list, FALSE); + pe_free_shallow_adv(clone_data->child_list, FALSE); - free_xml(incarnation_data->self->xml); - incarnation_data->self->fns->free(incarnation_data->self); + free_xml(clone_data->self->xml); + clone_data->self->fns->free(clone_data->self); common_free(rsc); } void -incarnation_agent_constraints(resource_t *rsc) +clone_agent_constraints(resource_t *rsc) { - incarnation_variant_data_t *incarnation_data = NULL; - get_incarnation_variant_data(incarnation_data, rsc); + clone_variant_data_t *clone_data = NULL; + get_clone_variant_data(clone_data, rsc); slist_iter( - child_rsc, resource_t, incarnation_data->child_list, lpc, + child_rsc, resource_t, clone_data->child_list, lpc, child_rsc->fns->agent_constraints(child_rsc); ); } diff --git a/cts/CM_LinuxHAv2.py.in b/cts/CM_LinuxHAv2.py.in index 483441f850..72bf3236b5 100755 --- a/cts/CM_LinuxHAv2.py.in +++ b/cts/CM_LinuxHAv2.py.in @@ -1,603 +1,602 @@ #!@PYTHON@ '''CTS: Cluster Testing System: LinuxHA v2 dependent modules... ''' __copyright__=''' Author: Huang Zhen Copyright (C) 2004 International Business Machines Additional Audits, Revised Start action, Default Configuration: Copyright (C) 2004 Andrew Beekhof ''' # # 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 # of the License, or (at your option) any later version. # # This program 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 program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import os,sys,CTS,CTSaudits,CTStests from CTS import * from CM_hb import HeartbeatCM from xml.dom.minidom import * from CTSaudits import ClusterAudit from CTStests import * ####################################################################### # # LinuxHA v2 dependent modules # ####################################################################### class LinuxHAv2(HeartbeatCM): ''' The linux-ha version 2 cluster manager class. It implements the things we need to talk to and manipulate linux-ha version 2 clusters ''' def __init__(self, Environment, randseed=None): HeartbeatCM.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "linux-ha-v2", "DeadTime" : 300, "StartTime" : 300, # Max time to start up "StableTime" : 30, "StartCmd" : "@libdir@/heartbeat/ha_logd -d >/dev/null 2>&1; @libdir@/heartbeat/heartbeat >/dev/null 2>&1", "StopCmd" : "@libdir@/heartbeat/heartbeat -k", "ElectionCmd" : "@libdir@/heartbeat/crmadmin -E %s", "StatusCmd" : "@libdir@/heartbeat/crmadmin -S %s 2>/dev/null", "EpocheCmd" : "@libdir@/heartbeat/ccm_tool -e", "QuorumCmd" : "@libdir@/heartbeat/ccm_tool -q", "ParitionCmd" : "@libdir@/heartbeat/ccm_tool -p", "IsRscRunning" : "@libdir@/heartbeat/lrmadmin -E %s monitor 0 0 EVERYTIME 2>/dev/null|grep return", "ExecuteRscOp" : "@libdir@/heartbeat/lrmadmin -E %s %s 0 0 EVERYTIME 2>/dev/null", "CIBfile" : "%s:@HA_VARLIBDIR@/heartbeat/crm/cib.xml", "TmpDir" : "/tmp", "BreakCommCmd2" : "/usr/lib/heartbeat/TestHeartbeatComm break-communication %s>/dev/null 2>&1", "IsIPAddrRscRunning" : "", "StandbyOnCmd" : "@libdir@/heartbeat/crmadmin -s %s", "StandbyOffCmd" : "@libdir@/heartbeat/crmadmin -a %s", "UUIDQueryCmd" : "@libdir@/heartbeat/crmadmin -N", "CIBQueryCmd" : "@libdir@/heartbeat/cibadmin -Ql -h %s", # Patterns to look for in the log files for various occasions... "Pat:DC_IDLE" : "crmd:.*State transition.*-> S_IDLE", # This wont work if we have multiple partitions # Use: "Pat:They_started" : "%s crmd:.*State transition.*-> S_NOT_DC", "Pat:They_started" : "Updating node state to member for %s", "Pat:We_started" : "%s crmd:.*State transition.*-> S_IDLE", "Pat:We_stopped" : "%s heartbeat.*Heartbeat shutdown complete", "Pat:They_stopped" : "%s crmd:.*LOST:.* %s ", "Pat:All_stopped" : "%s .*heartbeat.*Heartbeat shutdown complete", "Pat:They_dead" : "node %s.*: is dead", "Pat:TransitionComplete" : "Transition status: Complete: complete", # Bad news Regexes. Should never occur. "BadRegexes" : ( r"Shutting down\.", r"Forcing shutdown\.", r"Timer I_TERMINATE just popped", r"input=I_ERROR", r"input=I_FAIL", r"input=I_INTEGRATED cause=C_TIMER_POPPED", r"input=I_FINALIZED cause=C_TIMER_POPPED", r"input=I_ERROR", r", exiting\.", r"WARN.*Ignoring HA message.*vote.*not in our membership list", r"pengine:.*Attempting recovery of resource", r"pengine:.*Handling failed ", r"tengine:.*is taking more than 2x its timeout", r"Confirm not received from", r"Welcome reply not received from", r"ERROR:", r"CRIT:", ), }) del self["Standby"] self.check_transitions = 0 self.check_elections = 0 self.CIBsync = {} cib_prefix=''' ''' cib_options=''' - - + ''' cib_glue_1=''' ''' cib_glue_2=''' ''' cib_suffix=''' ''' resources=''' ''' constraints=''' ''' cib_fencing = "" if self.Env["CIBResource"] == 1: self.log("Enabling DC resource") resources=''' - + - ''' % self.Env["IPBase"] + ''' % self.Env["IPBase"] # DcIPaddr cant run anywhere but the DC constraints=''' ''' fields = string.split(self.Env["IPBase"], '.') for node in self.Env["nodes"]: # These resources prefer to run on the node with the same name fields[3] = str(int(fields[3])+1) ip = string.join(fields, '.') node_resource=(""" - + - """ %("rsc_"+node, ip)) + """ %("rsc_"+node, ip)) resources = resources + node_resource node_constraint=(""" """ % ("rsc_"+node, "rsc_"+node, "rsc_"+node, node)) constraints = constraints + node_constraint # always add the fencing resource so that we test incarnations nodelist = "" for node in self.Env["nodes"]: nodelist += node + " " stonith_resource=(""" - + - - + + - + - - """ %(len(self.Env["nodes"]), nodelist)) + + """ %(len(self.Env["nodes"]), nodelist)) resources = resources + stonith_resource if self.Env["DoFencing"] == 1: cib_options=cib_options + ''' ''' self.default_cts_cib=cib_prefix + cib_options + cib_glue_1 + \ resources + cib_glue_2 + constraints + cib_suffix self.debug(self.default_cts_cib) def errorstoignore(self): # At some point implement a more elegant solution that # also produces a report at the end '''Return list of errors which are known and very noisey should be ignored''' if 1: return [ "crmadmin:" ] return [] def install_config(self, node): if not self.CIBsync.has_key(node) and self.Env["ClobberCIB"] == 1: self.CIBsync[node] = 1 if self.Env["CIBfilename"] == None: self.debug("Installing Generated CIB on node %s" %(node)) os.system("rm -f /tmp/cts.default.cib") os.system("echo \'" + self.default_cts_cib + "\' > /tmp/cts.default.cib") if 0!=self.rsh.cp("/tmp/cts.default.cib", "root@" + (self["CIBfile"]%node)): raise ValueError("Can not scp file to %s "%node) os.system("rm -f /tmp/cts.default.cib") else: self.debug("Installing CIB (%s) on node %s" %(self.Env["CIBfilename"], node)) if 0!=self.rsh.cp(self.Env["CIBfilename"], "root@" + (self["CIBfile"]%node)): raise ValueError("Can not scp file to %s "%node) def prepare(self): '''Finish the Initialization process. Prepare to test...''' for node in self.Env["nodes"]: self.ShouldBeStatus[node] = "" self.StataCM(node) def test_node_CM(self, node): '''Report the status of the cluster manager on a given node''' watchpats = [ ] watchpats.append("Current state: (S_IDLE|S_NOT_DC)") watchpats.append(self["Pat:They_started"]%node) idle_watch = CTS.LogWatcher(self["LogFileName"], watchpats) idle_watch.setwatch() out=self.rsh.readaline(node, self["StatusCmd"]%node) ret= (string.find(out, 'ok') != -1) self.debug("Node %s status: %s" %(node, out)) if not ret: if self.ShouldBeStatus[node] == self["up"]: self.log( "Node status for %s is %s but we think it should be %s" %(node, self["down"], self.ShouldBeStatus[node])) self.ShouldBeStatus[node]=self["down"] return 0 if self.ShouldBeStatus[node] == self["down"]: self.log( "Node status for %s is %s but we think it should be %s: %s" %(node, self["up"], self.ShouldBeStatus[node], out)) self.ShouldBeStatus[node]=self["up"] # check the output first - because syslog-ng looses messages if string.find(out, 'S_NOT_DC') != -1: # Up and stable return 2 if string.find(out, 'S_IDLE') != -1: # Up and stable return 2 # fall back to syslog-ng and wait if not idle_watch.look(): # just up self.debug("Warn: Node %s is unstable: %s" %(node, out)) return 1 # Up and stable return 2 # Is the node up or is the node down def StataCM(self, node): '''Report the status of the cluster manager on a given node''' if self.test_node_CM(node) > 0: return 1 return None # Being up and being stable is not the same question... def node_stable(self, node): '''Report the status of the cluster manager on a given node''' if self.test_node_CM(node) == 2: return 1 self.log("Warn: Node %s not stable" %(node)) return None def cluster_stable(self, timeout=None): watchpats = [ ] watchpats.append("Current state: S_IDLE") watchpats.append(self["Pat:DC_IDLE"]) if timeout == None: timeout = self["DeadTime"] idle_watch = CTS.LogWatcher(self["LogFileName"], watchpats, timeout) idle_watch.setwatch() any_up = 0 for node in self.Env["nodes"]: # have each node dump its current state if self.ShouldBeStatus[node] == self["up"]: self.rsh.readaline(node, (self["StatusCmd"] %node) ) any_up = 1 if any_up == 0 or idle_watch.look(): return 1 self.log("Warn: Cluster Master not IDLE") return None def is_node_dc(self, node, status_line=None): rc = 0 if not status_line: status_line = self.rsh.readaline(node, self["StatusCmd"]%node) if not status_line: rc = 0 elif string.find(status_line, 'S_IDLE') != -1: rc = 1 elif string.find(status_line, 'S_INTEGRATION') != -1: rc = 1 elif string.find(status_line, 'S_FINALIZE_JOIN') != -1: rc = 1 elif string.find(status_line, 'S_POLICY_ENGINE') != -1: rc = 1 elif string.find(status_line, 'S_TRANSITION_ENGINE') != -1: rc = 1 if rc == 1: self.debug("%s _is_ the DC" % node) return rc def isolate_node(self, node, allowlist): '''isolate the communication between the nodes''' rc = self.rsh(node, self["BreakCommCmd2"]%allowlist) if rc == 0: return 1 else: self.log("Could not break the communication from node: %s",node) return None def Configuration(self): if self.Env["ClobberCIB"] == 1: if self.Env["CIBfilename"] == None: os.system("rm -f /tmp/cts.default.cib") os.system("echo \'" + self.default_cts_cib + "\' > /tmp/cts.default.cib") cib=parse("/tmp/cts.default.cib") # os.system("rm -f /tmp/cts.default.cib") else: cib=parse(self.Env["CIBfilename"]) else: local_cib = "%s/cts_cib_%s.xml"%(self["TmpDir"],str(os.getpid())) if 0!=self.rsh.cp("root@"+self["CIBfile"]%self.Env["nodes"][0],local_cib): raise ValueError("Can not copy file to %s, maybe permission denied"%self["TmpDir"]) cib=parse(local_cib) os.remove(local_cib) return cib.getElementsByTagName('configuration')[0] def Resources(self): ResourceList = [] #read resources in cib configuration = self.Configuration() resources = configuration.getElementsByTagName('resources')[0] - rscs = configuration.getElementsByTagName('resource') + rscs = configuration.getElementsByTagName('primative') for rsc in rscs: if rsc in resources.childNodes: ResourceList.append(HAResource(self,rsc)) - incs = configuration.getElementsByTagName('incarnation') + incs = configuration.getElementsByTagName('clone') for inc in incs: max = 0 inc_name = inc.getAttribute("id") instance_attributes = inc.getElementsByTagName('instance_attributes')[0] attributes = instance_attributes.getElementsByTagName('attributes')[0] nvpairs = attributes.getElementsByTagName('nvpair') for nvpair in nvpairs: - if nvpair.getAttribute("name") == "incarnation_max": + if nvpair.getAttribute("name") == "clone_max": max = int(nvpair.getAttribute("value")) - inc_rsc = inc.getElementsByTagName('resource')[0] + inc_rsc = inc.getElementsByTagName('primative')[0] for i in range(0,max): rsc = HAResource(self,inc_rsc) rsc.inc_no = i rsc.inc_name = inc_name rsc.inc_max = max rsc.rid = inc_name+":"+rsc.rid + ":%d"%i rsc.Instance = rsc.rid ResourceList.append(rsc) return ResourceList def Dependancies(self): DependancyList = [] #read dependancy in cib configuration=self.Configuration() constraints=configuration.getElementsByTagName('constraints')[0] rsc_to_rscs=configuration.getElementsByTagName('rsc_to_rsc') for node in rsc_to_rscs: dependancy = {} dependancy["id"]=node.getAttribute('id') dependancy["from"]=node.getAttribute('from') dependancy["to"]=node.getAttribute('to') dependancy["type"]=node.getAttribute('type') dependancy["strength"]=node.getAttribute('strength') DependancyList.append(dependancy) return DependancyList def find_partitions(self): ccm_partitions = [] for node in self.Env["nodes"]: if self.ShouldBeStatus[node] == self["up"]: partition = self.rsh.readaline(node, self["ParitionCmd"]) if not partition: self.log("no partition details for %s" %node) elif len(partition) > 2: partition = partition[:-1] for a_partition in ccm_partitions: if partition != a_partition: ccm_partitions.append(partition) else: self.log("bad partition details for %s" %node) return ccm_partitions def HasQuorum(self, node_list): # If we are auditing a partition, then one side will # have quorum and the other not. # So the caller needs to tell us which we are checking # If no value for node_list is specified... assume all nodes if not node_list: node_list = self.Env["nodes"] for node in node_list: if self.ShouldBeStatus[node] == self["up"]: quorum = self.rsh.readaline(node, self["QuorumCmd"]) return string.find(quorum,"1") != -1 return 0 def Components(self): complist = [Process("lrmd",self),Process("crmd",self)] if self.Env["DoFencing"] == 1 : complist.append(Process("stonithd",self)) complist.append(Process("heartbeat",self)) return complist def NodeUUID(self, node): lines = self.rsh.readlines(node, self["UUIDQueryCmd"]) for line in lines: m = re.search(r'%s.+\((.+)\)' % node, line) if m: return m.group(1) return "" def StandbyStatus(self, node): check_cib_cmd = self["CIBQueryCmd"] % node; lines = self.rsh.readlines(node, check_cib_cmd); if not lines: return "" cib_data = "".join(lines) try: cib = parseString(cib_data) except xml.parsers.expat.ExpatError: return "" standby_status = "off" nodes = cib.getElementsByTagName('node') for ha_node in nodes: if ha_node.getAttribute("uname") == node: nvpairs = ha_node.getElementsByTagName('nvpair') for nvpair in nvpairs: if nvpair.getAttribute('name') == 'standby': if nvpair.getAttribute('value') == 'on': standby_status = "on" break return standby_status # status == "on" : Enter Standby mode # status == "off": Enter Active mode def SetStandbyMode(self, node, status): current_status = self.StandbyStatus(node) if current_status == status: return True if status == "on": cmd = self["StandbyOnCmd"] % self.NodeUUID(node) elif status == "off": cmd = self["StandbyOffCmd"] % self.NodeUUID(node) else: return False ret = self.rsh(node, cmd) return True class HAResource(Resource): def __init__(self, cm, node): ''' Get information from xml node ''' self.rid = str(node.getAttribute('id')) self.rclass = str(node.getAttribute('class')) self.rtype = str(node.getAttribute('type')) self.inc_name = None self.inc_no = -1 self.inc_max = -1 self.rparameters = {} list = node.getElementsByTagName('instance_attributes') if len(list) > 0: attributes = list[0] list = attributes.getElementsByTagName('attributes') if len(list) > 0: parameters = list[0] nvpairs = parameters.getElementsByTagName('nvpair') for nvpair in nvpairs: name=nvpair.getAttribute('name') value=nvpair.getAttribute('value') self.rparameters[name]=value Resource.__init__(self, cm, self.rtype, self.rid) def IsRunningOn(self, nodename): ''' This member function returns true if our resource is running on the given node in the cluster. We call the status operation for the resource script. ''' out=self.CM.rsh.readaline(nodename, self.CM["IsRscRunning"]%self.rid) return re.search("0",out) def RunningNodes(self): ResourceNodes = [] for node in self.CM.Env["nodes"]: if self.CM.ShouldBeStatus[node] == self.CM["up"]: if self.IsRunningOn(node): ResourceNodes.append(node) return ResourceNodes def _ResourceOperation(self, operation, nodename): ''' Execute an operation on the resource ''' self.CM.rsh.readaline(nodename, self.CM["ExecuteRscOp"]%(self.rid,operation)) return self.CM.rsh.lastrc == 0 def Start(self, nodename): ''' This member function starts or activates the resource. ''' return self._ResourceOperation("start", nodename) def Stop(self, nodename): ''' This member function stops or deactivates the resource. ''' return self._ResourceOperation("stop", nodename) def IsWorkingCorrectly(self, nodename): return self._ResourceOperation("monitor", nodename) ####################################################################### # # A little test code... # # Which you are advised to completely ignore... # ####################################################################### if __name__ == '__main__': pass diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h index 2263ded33b..24c963049d 100644 --- a/include/crm/msg_xml.h +++ b/include/crm/msg_xml.h @@ -1,219 +1,219 @@ -/* $Id: msg_xml.h,v 1.35 2005/07/05 13:56:46 andrew Exp $ */ +/* $Id: msg_xml.h,v 1.36 2005/07/06 09:30:21 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * 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 XML_TAGS__H #define XML_TAGS__H #define F_CRM_TASK "crm_task" #define F_CRM_HOST_TO "crm_host_to" #define F_CRM_MSG_TYPE F_SUBTYPE #define F_CRM_SYS_TO "crm_sys_to" #define F_CRM_SYS_FROM "crm_sys_from" #define F_CRM_HOST_FROM F_ORIG #define F_CRM_REFERENCE XML_ATTR_REFERENCE #define F_CRM_VERSION XML_ATTR_VERSION #define F_CRM_ORIGIN "origin" #define F_CRM_JOIN_ID "join_id" /*---- Common tags/attrs */ #define XML_ATTR_TAGNAME F_XML_TAGNAME #define XML_ATTR_PARENT F_XML_PARENT #define XML_TAG_CIB "cib" #define XML_TAG_FAILED "failed" #define XML_ATTR_NUMPEERS "num_peers" #define XML_ATTR_HAVE_QUORUM "have_quorum" #define XML_ATTR_CCM_TRANSITION "ccm_transition" #define XML_ATTR_GENERATION "epoche" #define XML_ATTR_GENERATION_ADMIN "admin_epoche" #define XML_ATTR_NUMUPDATES "num_updates" #define XML_ATTR_TIMEOUT "timeout" #define XML_ATTR_TSTAMP "timestamp" #define XML_ATTR_VERSION "version" #define XML_ATTR_DESC "description" #define XML_ATTR_ID "id" #define XML_ATTR_TYPE "type" #define XML_ATTR_FILTER_TYPE "type_filter" #define XML_ATTR_FILTER_ID "id_filter" #define XML_ATTR_FILTER_PRIORITY "priority_filter" #define XML_ATTR_VERBOSE "verbose" #define XML_ATTR_OP "op" #define XML_ATTR_DC "is_dc" #define XML_ATTR_DC_UUID "dc_uuid" #define XML_ATTR_CIB_REVISION "cib_feature_revision" #define XML_ATTR_CIB_REVISION_MAX "cib_feature_revision_max" #define XML_BOOLEAN_TRUE "true" #define XML_BOOLEAN_FALSE "false" #define XML_BOOLEAN_YES XML_BOOLEAN_TRUE #define XML_BOOLEAN_NO XML_BOOLEAN_FALSE #define XML_TAG_OPTIONS "options" /*---- top level tags/attrs */ #define XML_MSG_TAG "crm_message" #define XML_MSG_TAG_DATA "msg_data" #define XML_ATTR_REQUEST "request" #define XML_ATTR_RESPONSE "response" #define XML_ATTR_UNAME "uname" #define XML_ATTR_UUID "id" #define XML_ATTR_REFERENCE "reference" #define XML_FAIL_TAG_RESOURCE "failed_resource" #define XML_FAILRES_ATTR_RESID "resource_id" #define XML_FAILRES_ATTR_REASON "reason" #define XML_FAILRES_ATTR_RESSTATUS "resource_status" #define XML_CRM_TAG_PING "ping_response" #define XML_PING_ATTR_STATUS "result" #define XML_PING_ATTR_SYSFROM "crm_subsystem" #define XML_TAG_FRAGMENT "cib_fragment" #define XML_ATTR_RESULT "result" #define XML_ATTR_SECTION "section" #define XML_FAIL_TAG_CIB "failed_update" #define XML_FAILCIB_ATTR_ID "id" #define XML_FAILCIB_ATTR_OBJTYPE "object_type" #define XML_FAILCIB_ATTR_OP "operation" #define XML_FAILCIB_ATTR_REASON "reason" /*---- CIB specific tags/attrs */ #define XML_CIB_TAG_SECTION_ALL "all" #define XML_CIB_TAG_CONFIGURATION "configuration" #define XML_CIB_TAG_STATUS "status" #define XML_CIB_TAG_RESOURCES "resources" #define XML_CIB_TAG_NODES "nodes" #define XML_CIB_TAG_CONSTRAINTS "constraints" #define XML_CIB_TAG_CRMCONFIG "crm_config" #define XML_CIB_TAG_STATE "node_state" #define XML_CIB_TAG_NODE "node" #define XML_CIB_TAG_CONSTRAINT "constraint" #define XML_CIB_TAG_NVPAIR "nvpair" #define XML_TAG_ATTR_SETS "instance_attributes" #define XML_TAG_ATTRS "attributes" -#define XML_CIB_TAG_RESOURCE "resource" -#define XML_CIB_TAG_GROUP "resource_group" -#define XML_CIB_TAG_INCARNATION "incarnation" +#define XML_CIB_TAG_RESOURCE "primative" +#define XML_CIB_TAG_GROUP "group" +#define XML_CIB_TAG_INCARNATION "clone" #define XML_RSC_ATTR_STOPFAIL "on_stopfail" #define XML_RSC_ATTR_RESTART "restart_type" #define XML_RSC_ATTR_START_TIMEOUT "start_timeout" #define XML_RSC_ATTR_STOP_TIMEOUT "stop_timeout" #define XML_RSC_ATTR_ORDERED "ordered" #define XML_RSC_ATTR_INTERLEAVE "interleave" -#define XML_RSC_ATTR_INCARNATION "incarnation" -#define XML_RSC_ATTR_INCARNATION_MAX "incarnation_max" -#define XML_RSC_ATTR_INCARNATION_NODEMAX "incarnation_node_max" +#define XML_RSC_ATTR_INCARNATION "clone" +#define XML_RSC_ATTR_INCARNATION_MAX "clone_max" +#define XML_RSC_ATTR_INCARNATION_NODEMAX "clone_node_max" #define XML_CIB_TAG_LRM "lrm" #define XML_LRM_TAG_RESOURCES "lrm_resources" #define XML_LRM_TAG_RESOURCE "lrm_resource" #define XML_LRM_TAG_AGENTS "lrm_agents" #define XML_LRM_TAG_AGENT "lrm_agent" #define XML_LRM_TAG_RSC_OP "lrm_rsc_op" #define XML_AGENT_ATTR_CLASS "class" #define XML_AGENT_ATTR_PROVIDER "provider" #define XML_LRM_TAG_ATTRIBUTES "attributes" #define XML_CIB_ATTR_REPLACE "replace" #define XML_CIB_ATTR_SOURCE "source" #define XML_CIB_ATTR_HEALTH "health" #define XML_CIB_ATTR_WEIGHT "weight" #define XML_CIB_ATTR_PRIORITY "priority" #define XML_CIB_ATTR_CLEAR "clear_on" #define XML_CIB_ATTR_SOURCE "source" #define XML_CIB_ATTR_JOINSTATE "join" #define XML_CIB_ATTR_EXPSTATE "expected" #define XML_CIB_ATTR_INCCM "in_ccm" #define XML_CIB_ATTR_CRMDSTATE "crmd" #define XML_CIB_ATTR_HASTATE "ha" #define XML_CIB_ATTR_SHUTDOWN "shutdown" #define XML_CIB_ATTR_CLEAR_SHUTDOWN "clear_shutdown" #define XML_CIB_ATTR_STONITH "stonith" #define XML_CIB_ATTR_CLEAR_STONITH "clear_stonith" #define XML_LRM_ATTR_TASK "operation" #define XML_LRM_ATTR_TARGET "on_node" #define XML_LRM_ATTR_TARGET_UUID "on_node_uuid" #define XML_LRM_ATTR_RSCSTATE "rsc_state" #define XML_LRM_ATTR_RSCID "rsc_id" #define XML_LRM_ATTR_LASTOP "last_op" #define XML_LRM_ATTR_OPSTATUS "op_status" #define XML_LRM_ATTR_RC "rc_code" #define XML_LRM_ATTR_CALLID "call_id" #define XML_TAG_GRAPH "transition_graph" #define XML_GRAPH_TAG_RSC_OP "rsc_op" #define XML_GRAPH_TAG_PSEUDO_EVENT "pseudo_event" #define XML_GRAPH_TAG_CRM_EVENT "crm_event" #define XML_TAG_RULE "rule" #define XML_RULE_ATTR_SCORE "score" #define XML_RULE_ATTR_RESULT "result" #define XML_RULE_ATTR_BOOLEAN_OP "boolean_op" #define XML_TAG_EXPRESSION "expression" #define XML_EXPR_ATTR_ATTRIBUTE "attribute" #define XML_EXPR_ATTR_OPERATION "operation" #define XML_EXPR_ATTR_VALUE "value" #define XML_EXPR_ATTR_TYPE "type" #define XML_CONS_TAG_RSC_DEPEND "rsc_colocation" #define XML_CONS_TAG_RSC_ORDER "rsc_order" #define XML_CONS_TAG_RSC_LOCATION "rsc_location" #define XML_CONS_ATTR_FROM "from" #define XML_CONS_ATTR_TO "to" #define XML_CONS_ATTR_ACTION "action" #define XML_CONS_ATTR_SYMMETRICAL "symmetrical" #define XML_NVPAIR_ATTR_NAME "name" #define XML_NVPAIR_ATTR_VALUE "value" #define XML_STRENGTH_VAL_MUST "must" #define XML_STRENGTH_VAL_SHOULD "should" #define XML_STRENGTH_VAL_SHOULDNOT "should_not" #define XML_STRENGTH_VAL_MUSTNOT "must_not" #define XML_NODE_ATTR_STATE "state" #define XML_CONFIG_ATTR_DC_BEAT "dc_heartbeat" #define XML_CONFIG_ATTR_DC_DEADTIME "dc_deadtime" #define XML_CONFIG_ATTR_FORCE_QUIT "shutdown_escalation" #define XML_CONFIG_ATTR_REANNOUNCE "join_reannouce" #define XML_CIB_TAG_GENERATION_TUPPLE "generation_tuple" #include #define ID(x) crm_element_value(x, XML_ATTR_ID) #define INSTANCE(x) crm_element_value(x, XML_CIB_ATTR_INSTANCE) #define TSTAMP(x) crm_element_value(x, XML_ATTR_TSTAMP) #define TYPE(x) crm_element_name(x) #endif