diff --git a/pengine/allocate.h b/pengine/allocate.h index 847cb328a8..2f5974017c 100644 --- a/pengine/allocate.h +++ b/pengine/allocate.h @@ -1,196 +1,220 @@ /* * 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CRM_PENGINE_COMPLEX_ALLOC__H #define CRM_PENGINE_COMPLEX_ALLOC__H #include #include #include #include #include typedef struct notify_entry_s { resource_t *rsc; node_t *node; } notify_entry_t; struct resource_alloc_functions_s { GHashTable *(*merge_weights)(resource_t*, const char*, GHashTable*, const char*, int, gboolean, gboolean); node_t *(*allocate)(resource_t *, pe_working_set_t *); void (*create_actions)(resource_t *, pe_working_set_t *); gboolean (*create_probe)( resource_t *, node_t *, action_t *, gboolean, pe_working_set_t *); void (*internal_constraints)(resource_t *, pe_working_set_t *); void (*rsc_colocation_lh)(resource_t *, resource_t *, rsc_colocation_t *); void (*rsc_colocation_rh)(resource_t *, resource_t *, rsc_colocation_t *); void (*rsc_location)(resource_t *, rsc_to_node_t *); enum pe_action_flags (*action_flags)(action_t *, node_t*); enum pe_graph_flags (*update_actions)(action_t *, action_t *, node_t*, enum pe_action_flags, enum pe_action_flags, enum pe_ordering); void (*expand)(resource_t *, pe_working_set_t *); void (*append_meta)(resource_t *rsc, xmlNode *xml); }; extern GHashTable *rsc_merge_weights( resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, int factor, gboolean allow_rollback, gboolean only_positive); extern GHashTable *group_merge_weights( resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, int factor, gboolean allow_rollback, gboolean only_positive); extern node_t * 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_rsc_colocation_lh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern void native_rsc_colocation_rh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern enum pe_action_flags native_action_flags(action_t *action, node_t *node); 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 create_notify_element( resource_t *rsc, action_t *op, notify_data_t *n_data, pe_working_set_t *data_set); extern void native_assign_color(resource_t *rsc, node_t *node); extern gboolean native_create_probe( resource_t *rsc, node_t *node, action_t *complete, gboolean force, pe_working_set_t *data_set); extern void native_append_meta(resource_t *rsc, xmlNode *xml); extern int group_num_allowed_nodes(resource_t *rsc); extern node_t *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_rsc_colocation_lh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern void group_rsc_colocation_rh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern enum pe_action_flags group_action_flags(action_t *action, node_t *node); 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_append_meta(resource_t *rsc, xmlNode *xml); extern int clone_num_allowed_nodes(resource_t *rsc); extern node_t *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 clone_rsc_colocation_lh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern void clone_rsc_colocation_rh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern void clone_rsc_location(resource_t *rsc, rsc_to_node_t *constraint); extern enum pe_action_flags clone_action_flags(action_t *action, node_t *node); extern void clone_expand(resource_t *rsc, pe_working_set_t *data_set); extern gboolean clone_create_probe( resource_t *rsc, node_t *node, action_t *complete, gboolean force, pe_working_set_t *data_set); extern void clone_append_meta(resource_t *rsc, xmlNode *xml); extern gboolean master_unpack(resource_t *rsc, pe_working_set_t *data_set); extern node_t *master_color(resource_t *rsc, pe_working_set_t *data_set); extern void master_create_actions(resource_t *rsc, pe_working_set_t *data_set); extern void master_internal_constraints( resource_t *rsc, pe_working_set_t *data_set); extern void master_rsc_colocation_rh( resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint); extern void master_append_meta(resource_t *rsc, xmlNode *xml); /* extern resource_object_functions_t resource_variants[]; */ extern resource_alloc_functions_t resource_class_alloc_functions[]; 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 gboolean unpack_rsc_to_attr(xmlNode *xml_obj, pe_working_set_t *data_set); extern gboolean unpack_rsc_to_node(xmlNode *xml_obj, pe_working_set_t *data_set); extern gboolean unpack_rsc_order(xmlNode *xml_obj, pe_working_set_t *data_set); extern gboolean unpack_rsc_colocation(xmlNode *xml_obj, pe_working_set_t *data_set); extern gboolean unpack_rsc_location(xmlNode *xml_obj, pe_working_set_t *data_set); extern void LogActions(resource_t *rsc, pe_working_set_t *data_set); extern void cleanup_alloc_calculations(pe_working_set_t *data_set); extern notify_data_t *create_notification_boundaries( resource_t *rsc, const char *action, action_t *start, action_t *end, pe_working_set_t *data_set); extern void collect_notification_data(resource_t *rsc, gboolean state, gboolean activity, notify_data_t *n_data); extern gboolean expand_notification_data(notify_data_t *n_data); extern void create_notifications(resource_t *rsc, notify_data_t *n_data, pe_working_set_t *data_set); extern void free_notification_data(notify_data_t *n_data); extern void rsc_migrate_reload(resource_t *rsc, pe_working_set_t *data_set); extern void rsc_stonith_ordering(resource_t *rsc, action_t *stonith_op, pe_working_set_t *data_set); extern enum pe_graph_flags native_update_actions( action_t *first, action_t *then, node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type); extern enum pe_graph_flags group_update_actions( action_t *first, action_t *then, node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type); extern enum pe_graph_flags clone_update_actions( action_t *first, action_t *then, node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type); static inline enum pe_action_flags get_action_flags(action_t *action, node_t *node) { + enum pe_action_flags flags = action->flags; if(action->rsc) { - return action->rsc->cmds->action_flags(action, action->rsc->variant >= pe_clone?node:NULL); + flags = action->rsc->cmds->action_flags(action, NULL); + + if(action->rsc->variant >= pe_clone && node) { + + /* We only care about activity on $node */ + enum pe_action_flags clone_flags = action->rsc->cmds->action_flags(action, node); + + /* Go to great lengths to ensure the correct value for pe_action_runnable... + * + * If we are a clone, then for _ordering_ constraints, its only relevant + * if we are runnable _anywhere_. + * + * This only applies to _runnable_ though, and only for ordering constraints. + * If this function is ever used during colocation, then we'll need additional logic + * + * Not very satisfying, but its logical and appears to work well. + */ + if(is_not_set(clone_flags, pe_action_runnable) + && is_set(flags, pe_action_runnable)) { + crm_trace("Fixing up runnable flag for %s", action->uuid); + set_bit_inplace(clone_flags, pe_action_runnable); + } + flags = clone_flags; + } } - return action->flags; + return flags; } static inline gboolean update_action_flags(action_t *action, enum pe_action_flags flags) { gboolean changed = FALSE; gboolean clear = is_set(flags, pe_action_clear); enum pe_action_flags last = action->flags; if(clear) { clear_bit_inplace(action->flags, flags); } else { set_bit_inplace(action->flags, flags); } if(last != action->flags) { changed = TRUE; clear_bit_inplace(flags, pe_action_clear); crm_trace("%sset flags 0x%.6x (was 0x%.6x, now 0x%.6x) for %s on %s", clear?"un-":"", flags, last, action->flags, action->uuid, action->node?action->node->details->uname:"[none]"); } return changed; } #endif