20 void populate_hash(xmlNode * nvpair_list, GHashTable * hash,
const char **attrs,
int attrs_length);
23 unsigned int *count_all,
24 unsigned int *count_clean);
86 get_resource_type(
const char *
name)
109 dup_attr(gpointer key, gpointer value, gpointer user_data)
131 parent_orig_meta, NULL, FALSE,
scheduler);
136 if (parent_orig_meta != NULL) {
141 g_hash_table_iter_init(&iter, parent_orig_meta);
142 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
145 dup_attr(key, value, meta_hash);
149 if (parent_orig_meta != NULL) {
150 g_hash_table_destroy(parent_orig_meta);
171 .rsc_data = &rsc_rule_data,
179 for (xmlAttrPtr a = pcmk__xe_first_attr(rsc->
xml); a != NULL; a = a->next) {
180 const char *prop_name = (
const char *) a->name;
181 const char *prop_value = pcmk__xml_attr_value(a);
191 if (rsc->
parent != NULL) {
192 expand_parents_fixed_nvpairs(rsc, &rule_data, meta_hash,
scheduler);
197 &rule_data, meta_hash, NULL, FALSE,
scheduler);
202 g_hash_table_foreach(rsc->
parent->
meta, dup_attr, meta_hash);
227 if (rsc->
parent != NULL) {
233 &rule_data, meta_hash, NULL, FALSE,
239 template_op_key(xmlNode * op)
256 unpack_template(xmlNode *xml_obj, xmlNode **expanded_xml,
259 xmlNode *cib_resources = NULL;
260 xmlNode *
template = NULL;
261 xmlNode *new_xml = NULL;
262 xmlNode *child_xml = NULL;
263 xmlNode *rsc_ops = NULL;
264 xmlNode *template_ops = NULL;
265 const char *template_ref = NULL;
266 const char *clone = NULL;
267 const char *
id = NULL;
269 if (xml_obj == NULL) {
270 pe_err(
"No resource object for template unpacking");
275 if (template_ref == NULL) {
281 pe_err(
"'%s' object must have a id", xml_obj->name);
286 pe_err(
"The resource object '%s' should not reference itself",
id);
292 if (cib_resources == NULL) {
293 pe_err(
"No resources configured");
299 if (
template == NULL) {
300 pe_err(
"No template named '%s'", template_ref);
305 xmlNodeSetName(new_xml, xml_obj->name);
315 for (child_xml = pcmk__xe_first_child(xml_obj); child_xml != NULL;
316 child_xml = pcmk__xe_next(child_xml)) {
317 xmlNode *new_child = NULL;
321 if (pcmk__str_eq((
const char *)new_child->name,
"operations",
pcmk__str_none)) {
326 if (template_ops && rsc_ops) {
330 for (op = pcmk__xe_first_child(rsc_ops); op != NULL;
331 op = pcmk__xe_next(op)) {
333 char *key = template_op_key(op);
335 g_hash_table_insert(rsc_ops_hash, key, op);
338 for (op = pcmk__xe_first_child(template_ops); op != NULL;
339 op = pcmk__xe_next(op)) {
341 char *key = template_op_key(op);
343 if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) {
351 g_hash_table_destroy(rsc_ops_hash);
358 *expanded_xml = new_xml;
361 if (!unpack_template(new_xml, expanded_xml,
scheduler)) {
363 *expanded_xml = NULL;
374 const char *template_ref = NULL;
375 const char *
id = NULL;
377 if (xml_obj == NULL) {
378 pe_err(
"No resource object for processing resource list of template");
383 if (template_ref == NULL) {
389 pe_err(
"'%s' object must have a id", xml_obj->name);
394 pe_err(
"The resource object '%s' should not reference itself",
id);
408 const char *promotable = g_hash_table_lookup(rsc->
meta,
428 free_params_table(gpointer
data)
430 g_hash_table_destroy((GHashTable *)
data);
449 GHashTable *params_on_node = NULL;
455 const char *node_name =
"";
458 if ((rsc == NULL) || (
scheduler == NULL)) {
473 if (params_on_node == NULL) {
479 return params_on_node;
491 unpack_requires(
pcmk_resource_t *rsc,
const char *value,
bool is_default)
509 "devices cannot require unfencing", rsc->
id);
517 "is disabled", rsc->
id);
527 const char *orig_value = value;
551 if (orig_value != NULL) {
553 "to '%s' because '%s' is not valid",
554 rsc->
id, value, orig_value);
556 unpack_requires(rsc, value,
true);
561 (is_default?
" (default)" :
""));
564 #ifndef PCMK__COMPAT_2_0 572 "Support for Upstart resources (such as %s) is deprecated " 573 "and will be removed in a future release of Pacemaker",
578 "Support for Nagios resources (such as %s) is deprecated " 579 "and will be removed in a future release of Pacemaker",
606 xmlNode *expanded_xml = NULL;
608 const char *value = NULL;
609 const char *
id = NULL;
610 bool guest_node =
false;
611 bool remote_node =
false;
638 if (unpack_template(xml_obj, &expanded_xml,
scheduler) == FALSE) {
644 crm_crit(
"Unable to allocate memory for resource '%s'",
id);
651 (*rsc)->xml = expanded_xml;
652 (*rsc)->orig_xml = xml_obj;
655 (*rsc)->xml = xml_obj;
656 (*rsc)->orig_xml = NULL;
666 (*rsc)->variant = get_resource_type((
const char *) (*rsc)->xml->name);
668 pe_err(
"Ignoring resource '%s' of unknown type '%s'",
669 id, (*rsc)->xml->name);
675 #ifndef PCMK__COMPAT_2_0 676 warn_about_deprecated_classes(*rsc);
689 (*rsc)->id = strdup(
id);
704 (*rsc)->rsc_cons = NULL;
705 (*rsc)->rsc_tickets = NULL;
706 (*rsc)->actions = NULL;
711 (*rsc)->stickiness = 0;
712 (*rsc)->migration_threshold =
INFINITY;
713 (*rsc)->failure_timeout = 0;
729 (*rsc)->is_remote_node = TRUE;
740 }
else if ((value == NULL) && remote_node) {
752 if (value != NULL && !pcmk__str_eq(
"default", value,
pcmk__str_casei)) {
775 if (detect_promotable(*rsc)) {
785 pe_rsc_trace((*rsc),
"%s dependency restart handling: restart",
788 "Support for restart-type is deprecated and will be removed in a future release");
792 pe_rsc_trace((*rsc),
"%s dependency restart handling: ignore",
799 pe_rsc_trace((*rsc),
"%s multiple running resource recovery: stop only",
804 pe_rsc_trace((*rsc),
"%s multiple running resource recovery: block",
809 pe_rsc_trace((*rsc),
"%s multiple running resource recovery: " 810 "stop unexpected instances",
814 if (!pcmk__str_eq(value,
"stop_start",
817 ", using default of \"stop_start\"", value);
820 pe_rsc_trace((*rsc),
"%s multiple running resource recovery: " 821 "stop/start", (*rsc)->id);
825 if (value != NULL && !pcmk__str_eq(
"default", value,
pcmk__str_casei)) {
830 if (value != NULL && !pcmk__str_eq(
"default", value,
pcmk__str_casei)) {
831 (*rsc)->migration_threshold =
char2score(value);
832 if ((*rsc)->migration_threshold < 0) {
839 " must be non-negative, using 1 instead");
840 (*rsc)->migration_threshold = 1;
851 unpack_requires(*rsc, value,
false);
875 (*rsc)->failure_timeout = (*rsc)->remote_reconnect_ms / 1000;
880 pe_rsc_trace((*rsc),
"%s desired next state: %s", (*rsc)->id,
883 if ((*rsc)->fns->unpack(*rsc,
scheduler) == FALSE) {
884 (*rsc)->fns->free(*rsc);
892 }
else if (guest_node) {
900 pe_rsc_trace((*rsc),
"%s action notification: %s", (*rsc)->id,
906 (*rsc)->utilization, NULL, FALSE,
scheduler);
909 if (add_template_rsc(xml_obj,
scheduler) == FALSE) {
910 (*rsc)->fns->free(*rsc);
923 if (
parent == NULL || rsc == NULL) {
926 while (
parent->parent != NULL) {
927 if (
parent->parent == rsc) {
943 while ((
parent->parent != NULL)
969 while (
parent->parent != NULL) {
996 if (rsc->
meta != NULL) {
997 g_hash_table_destroy(rsc->
meta);
1003 if ((rsc->
parent == NULL)
1021 g_hash_table_destroy(rsc->
known_on);
1060 unsigned int *count_clean)
1062 bool keep_looking =
false;
1063 bool is_happy =
false;
1065 CRM_CHECK((rsc != NULL) && (node != NULL) && (active != NULL),
1070 if (count_all != NULL) {
1073 if ((count_clean != NULL) && is_happy) {
1076 if ((count_all != NULL) || (count_clean != NULL)) {
1077 keep_looking =
true;
1084 keep_looking =
true;
1087 if (is_happy && ((*active == NULL) || !(*active)->details->online
1088 || (*active)->details->unclean)) {
1091 keep_looking =
true;
1094 if (*active == NULL) {
1097 return keep_looking;
1103 unsigned int *count_clean)
1107 if (count_all != NULL) {
1110 if (count_clean != NULL) {
1116 for (GList *iter = rsc->
running_on; iter != NULL; iter = iter->next) {
1118 count_all, count_clean)) {
1142 if (count != NULL) {
1159 for (GList *item = rsc->
children; item != NULL; item = item->next) {
1188 pe_rsc_trace(rsc,
"Resetting next role for %s from %s to %s (%s)",
gboolean native_active(pcmk_resource_t *rsc, gboolean all)
void pe__count_bundle(pcmk_resource_t *rsc)
#define CRM_CHECK(expr, failure_action)
Whether resource has clone notifications enabled.
xmlNode * orig_xml
Original resource configuration, if using template.
enum pe_quorum_policy no_quorum_policy
Response to loss of quorum.
GHashTable * known_on
Nodes where resource has been probed (key is node ID, not name)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
GHashTable * attrs
Node attributes.
unsigned int pe__clone_max_per_node(const pcmk_resource_t *rsc)
#define crm_crit(fmt, args...)
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
#define PCMK__VALUE_FENCING
xmlNode * pcmk__xe_match(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
void pe__free_bundle(pcmk_resource_t *rsc)
#define XML_EXPR_ATTR_TYPE
#define XML_CIB_TAG_CONTAINER
#define PCMK__ROLE_STARTED
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Whether cluster is symmetric (via symmetric-cluster property)
enum rsc_role_e role
Resource's current role.
#define XML_TAG_UTILIZATION
#define pcmk__config_warn(fmt...)
GList * children
Resource's child resources, if any.
Whether resource can be started or promoted only on quorate nodes.
xmlNode * xml
Resource configuration (possibly expanded from template)
#define XML_RSC_ATTR_INCARNATION
enum rsc_role_e next_role
Resource's scheduled next role.
gboolean get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role)
int char2score(const char *score)
Get the integer value of a score string.
#define pcmk__config_err(fmt...)
xmlNode * find_xml_node(const xmlNode *root, const char *search_path, gboolean must_find)
pcmk_node_t * pe__find_active_requires(const pcmk_resource_t *rsc, unsigned int *count)
GHashTable * meta
Resource's meta-attributes.
#define PCMK__VALUE_QUORUM
gboolean is_parent(pcmk_resource_t *child, pcmk_resource_t *rsc)
Whether resource, its node, or entire cluster is in maintenance mode.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define pe__set_working_set_flags(scheduler, flags_to_set)
#define PCMK__VALUE_UNFENCING
enum rsc_role_e native_resource_state(const pcmk_resource_t *rsc, gboolean current)
#define XML_CIB_TAG_RSC_TEMPLATE
#define XML_RSC_ATTR_STICKINESS
unsigned int pe__bundle_max_per_node(const pcmk_resource_t *rsc)
#define PCMK_META_FAILURE_TIMEOUT
bool pe__count_active_node(const pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_node_t **active, unsigned int *count_all, unsigned int *count_clean)
Implementation of pcmk_scheduler_t.
char * pending_task
Pending action in history, if any.
int pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, pcmk_resource_t *parent, pcmk_scheduler_t *scheduler)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
unsigned int pe__group_max_per_node(const pcmk_resource_t *rsc)
gboolean clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
int ninstances
Total number of resource instances.
#define pe__set_resource_flags(resource, flags_to_set)
#define XML_CIB_ATTR_PRIORITY
xmlNode * copy_xml(xmlNode *src_node)
#define XML_TAG_ATTR_SETS
gboolean native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
#define XML_CIB_TAG_RESOURCES
void pe__print_bundle(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
#define XML_RSC_ATTR_PROMOTABLE
const char * role2text(enum rsc_role_e role)
gboolean group_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
Stop on all and leave stopped.
pcmk_resource_t * parent
Resource's parent resource, if any.
GList * dangling_migrations
Whether any resource provides or requires unfencing (via CIB resources)
#define PCMK_RESOURCE_CLASS_UPSTART
gboolean clone_active(pcmk_resource_t *rsc, gboolean all)
#define XML_RSC_ATTR_REQUIRES
#define XML_RSC_ATTR_CRITICAL
Implementation of pcmk_resource_t.
gboolean pe__bundle_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
gboolean pe__clone_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
#define XML_RSC_ATTR_CONTAINER
#define PCMK__ROLE_UNPROMOTED_LEGACY
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
xmlNode * rsc_defaults
Configured resource defaults.
unsigned int pe__primitive_max_per_node(const pcmk_resource_t *rsc)
#define pe_warn_once(pe_wo_bit, fmt...)
#define PCMK__ROLE_UNPROMOTED
#define PCMK_RESOURCE_CLASS_STONITH
bool xml_contains_remote_node(xmlNode *xml)
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
int blocked_resources
Number of blocked resources in cluster.
enum rsc_role_e clone_resource_state(const pcmk_resource_t *rsc, gboolean current)
struct pe_node_shared_s * details
Basic node information.
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
#define XML_AGENT_ATTR_PROVIDER
pe_obj_types
Resource variants supported by Pacemaker.
unsigned long long flags
Group of enum pcmk_rsc_flags.
const char * uname
Node name in cluster.
#define XML_TAG_META_SETS
char * clone_name
Resource instance ID in history.
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
void group_free(pcmk_resource_t *rsc)
void native_free(pcmk_resource_t *rsc)
#define XML_RSC_ATTR_MANAGED
void pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name, const pe_rule_eval_data_t *rule_data, GHashTable *hash, const char *always_first, gboolean overwrite, pcmk_scheduler_t *scheduler)
void get_meta_attributes(GHashTable *meta_hash, pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_scheduler_t *scheduler)
void common_free(pcmk_resource_t *rsc)
GHashTable * utilization
Resource's utilization attributes.
enum rsc_role_e pe__bundle_resource_state(const pcmk_resource_t *rsc, gboolean current)
void pe__count_common(pcmk_resource_t *rsc)
void group_print(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
void free_xml(xmlNode *child)
Whether resource is blocked from further action.
Implementation of pcmk_node_t.
enum pe_obj_types variant
Resource variant.
gboolean group_active(pcmk_resource_t *rsc, gboolean all)
#define XML_REMOTE_ATTR_RECONNECT_INTERVAL
Stop unexpected instances.
#define XML_RSC_ATTR_NOTIFY
void populate_hash(xmlNode *nvpair_list, GHashTable *hash, const char **attrs, int attrs_length)
#define XML_RSC_ATTR_UNIQUE
Whether resource has "critical" meta-attribute enabled.
GList * fillers
Resources contained by this one, if any.
char * native_parameter(pcmk_resource_t *rsc, pcmk_node_t *node, gboolean create, const char *name, pcmk_scheduler_t *scheduler)
pcmk_resource_t * native_find_rsc(pcmk_resource_t *rsc, const char *id, const pcmk_node_t *node, int flags)
Whether resource has not yet been assigned to a node.
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
gboolean pe__native_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
void clone_print(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
pcmk_rsc_methods_t resource_class_functions[]
#define XML_CIB_TAG_INCARNATION
Whether resource requires fencing before recovery if on unclean node.
gboolean pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
Whether resource's class is "stonith".
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
#define PCMK__ROLE_UNKNOWN
#define XML_RSC_ATTR_MAINTENANCE
gboolean pe__bundle_active(pcmk_resource_t *rsc, gboolean all)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
pcmk_rsc_methods_t * fns
Resource object methods.
#define PCMK_META_MIGRATION_THRESHOLD
Whether fencing is enabled (via stonith-enabled property)
void * variant_opaque
Variant-specific (and private) data.
pcmk_scheduler_t * scheduler
char guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
int disabled_resources
Number of disabled resources in cluster.
Whether resource is allowed to live-migrate.
#define PCMK_XE_PROMOTABLE_LEGACY
Stop on all, start on desired.
pcmk_node_t *(* active_node)(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
Find a node (and optionally count all) where resource is active.
bool pe__resource_is_disabled(const pcmk_resource_t *rsc)
pcmk_node_t * allocated_to
Node resource is assigned to.
#define XML_RSC_ATTR_MULTIPLE
#define pe__clear_resource_flags(resource, flags_to_clear)
GList * running_on
Nodes where resource may be active.
#define XML_RSC_ATTR_RESTART
#define PCMK__VALUE_NOTHING
void clone_free(pcmk_resource_t *rsc)
#define crm_log_xml_trace(xml, text)
GHashTable * parameter_cache
enum rsc_role_e group_resource_state(const pcmk_resource_t *rsc, gboolean current)
gboolean crm_is_true(const char *s)
Whether resource can be promoted and demoted.
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
Whether cluster has a fencing resource (via CIB resources)
#define XML_CIB_TAG_GROUP
Resource role is unknown.
pcmk_node_t * pe__bundle_active_node(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
#define pe_rsc_trace(rsc, fmt, args...)
#define PCMK_RESOURCE_CLASS_NAGIOS
unsigned long long flags
Group of enum pcmk_scheduler_flags.
pcmk_node_t * native_location(const pcmk_resource_t *rsc, GList **list, int current)
Whether resource is managed.
Whether resource can be started or promoted only on unfenced nodes.
gboolean pe__group_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
gboolean unclean
Whether node requires fencing.
void get_rsc_attributes(GHashTable *meta_hash, const pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Whether cluster is in maintenance mode (via maintenance-mode property)
Whether resource has been removed from the configuration.
crm_time_t * now
Current time for evaluation purposes.
GHashTable * template_rsc_sets
Mappings of template ID to resource ID.
gboolean online
Whether online.
#define XML_OP_ATTR_ALLOW_MIGRATE
Whether resource is not an anonymous clone instance.
void native_print(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
Unknown resource variant.
pcmk_node_t * partial_migration_source
The source node, if migrate_to completed but migrate_from has not.
GHashTable * pcmk__strikey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
#define XML_AGENT_ATTR_CLASS
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)