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);
82 get_resource_type(
const char *
name)
112 dup_attr(gpointer key, gpointer value, gpointer user_data)
114 GHashTable *table = user_data;
116 CRM_CHECK((key != NULL) && (table != NULL),
return);
120 "the explicit value '#default' is deprecated and " 121 "will be removed in a future release",
123 }
else if ((value != NULL) && (g_hash_table_lookup(table, key) == NULL)) {
148 rule_data, parent_orig_meta, NULL,
153 if (parent_orig_meta != NULL) {
155 g_hash_table_foreach(parent_orig_meta, dup_attr, meta_hash);
158 if (parent_orig_meta != NULL) {
159 g_hash_table_destroy(parent_orig_meta);
188 .rsc_data = &rsc_rule_data,
192 for (xmlAttrPtr a = pcmk__xe_first_attr(rsc->
priv->
xml);
193 a != NULL; a = a->next) {
195 if (a->children != NULL) {
196 dup_attr((gpointer) a->name, (gpointer) a->children->content,
209 expand_parents_fixed_nvpairs(rsc, &rule_data, meta_hash,
scheduler);
257 &rule_data, instance_attrs, NULL,
scheduler);
264 template_op_key(xmlNode * op)
281 unpack_template(xmlNode *xml_obj, xmlNode **expanded_xml,
284 xmlNode *cib_resources = NULL;
285 xmlNode *
template = NULL;
286 xmlNode *new_xml = NULL;
287 xmlNode *child_xml = NULL;
288 xmlNode *rsc_ops = NULL;
289 xmlNode *template_ops = NULL;
290 const char *template_ref = NULL;
291 const char *
id = NULL;
293 if (xml_obj == NULL) {
299 if (template_ref == NULL) {
303 id = pcmk__xe_id(xml_obj);
317 if (cib_resources == NULL) {
324 if (
template == NULL) {
330 xmlNodeSetName(new_xml, xml_obj->name);
339 child_xml != NULL; child_xml =
pcmk__xe_next(child_xml, NULL)) {
348 if (template_ops && rsc_ops) {
355 char *key = template_op_key(op);
357 g_hash_table_insert(rsc_ops_hash, key, op);
363 char *key = template_op_key(op);
365 if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) {
373 g_hash_table_destroy(rsc_ops_hash);
380 *expanded_xml = new_xml;
383 if (!unpack_template(new_xml, expanded_xml,
scheduler)) {
385 *expanded_xml = NULL;
396 const char *template_ref = NULL;
397 const char *
id = NULL;
399 if (xml_obj == NULL) {
406 if (template_ref == NULL) {
410 id = pcmk__xe_id(xml_obj);
438 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
442 value = g_hash_table_lookup(rsc->
priv->
meta,
458 free_params_table(gpointer
data)
460 g_hash_table_destroy((GHashTable *)
data);
479 GHashTable *params_on_node = NULL;
485 const char *node_name =
"";
488 if ((rsc == NULL) || (
scheduler == NULL)) {
491 if ((node != NULL) && (node->
priv->
name != NULL)) {
505 if (params_on_node == NULL) {
511 return params_on_node;
523 unpack_requires(
pcmk_resource_t *rsc,
const char *value,
bool is_default)
543 "devices cannot require unfencing", rsc->
id);
550 "disabled", rsc->
id);
560 const char *orig_value = value;
565 }
else if (pcmk__is_primitive(rsc)
582 if (orig_value != NULL) {
584 "to '%s' because '%s' is not valid",
585 rsc->
id, value, orig_value);
587 unpack_requires(rsc, value,
true);
592 (is_default?
" (default)" :
""));
604 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
611 " because '%s' is not a valid value: %s",
625 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
633 "' is deprecated and will be removed in a " 634 "future release (just leave it unset)");
641 " because '%s' is not a valid value: %s",
656 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
664 "' is deprecated and will be removed in a " 665 "future release (just leave it unset)");
673 ") for resource %s meta-attribute " 675 " because '%s' is not a valid value: %s",
703 xmlNode *expanded_xml = NULL;
705 const char *value = NULL;
706 const char *
id = NULL;
707 bool guest_node =
false;
708 bool remote_node =
false;
735 if (unpack_template(xml_obj, &expanded_xml,
scheduler) == FALSE) {
742 "Unable to allocate memory for resource '%s'",
id);
747 if ((*rsc)->priv == NULL) {
749 "Unable to allocate memory for resource '%s'",
id);
753 rsc_private = (*rsc)->priv;
759 rsc_private->
xml = expanded_xml;
763 rsc_private->
xml = xml_obj;
775 rsc_private->
variant = get_resource_type((
const char *)
776 rsc_private->
xml->name);
779 id, rsc_private->
xml->name);
796 (*rsc)->id = strdup(
id);
799 rsc_private->
fns = &resource_class_functions[rsc_private->
variant];
813 unpack_priority(*rsc);
837 }
else if ((value == NULL) && remote_node) {
854 "' is deprecated and will be removed in a " 855 "future release (just leave it unset)");
874 if (detect_unique(*rsc)) {
877 if (
crm_is_true(g_hash_table_lookup((*rsc)->priv->meta,
888 pcmk__rsc_trace(*rsc,
"%s multiple running resource recovery: stop only",
900 "%s multiple running resource recovery: " 901 "stop unexpected instances",
909 ", using default of " 915 "%s multiple running resource recovery: stop/start",
919 unpack_stickiness(*rsc);
920 unpack_migration_threshold(*rsc);
929 unpack_requires(*rsc, value,
false);
974 }
else if (guest_node) {
990 if (add_template_rsc(xml_obj,
scheduler) == FALSE) {
1004 if (
parent == NULL || rsc == NULL) {
1007 while (
parent->priv->parent != NULL) {
1008 if (
parent->priv->parent == rsc) {
1024 while ((
parent->priv->parent != NULL)
1025 && !pcmk__is_bundle(
parent->priv->parent)) {
1050 while (
parent->priv->parent != NULL) {
1051 if (!include_bundle && pcmk__is_bundle(
parent->priv->parent)) {
1102 g_hash_table_destroy(rsc->
priv->
meta);
1136 unsigned int *count_clean)
1138 bool keep_looking =
false;
1139 bool is_happy =
false;
1141 CRM_CHECK((rsc != NULL) && (node != NULL) && (active != NULL),
1146 if (count_all != NULL) {
1149 if ((count_clean != NULL) && is_happy) {
1152 if ((count_all != NULL) || (count_clean != NULL)) {
1153 keep_looking =
true;
1160 keep_looking =
true;
1163 if (is_happy && ((*active == NULL) || !(*active)->details->online
1164 || (*active)->details->unclean)) {
1167 keep_looking =
true;
1170 if (*active == NULL) {
1173 return keep_looking;
1179 unsigned int *count_clean)
1183 if (count_all != NULL) {
1186 if (count_clean != NULL) {
1193 iter != NULL; iter = iter->next) {
1196 count_all, count_clean)) {
1220 if (count != NULL) {
1238 item != NULL; item = item->next) {
gboolean native_active(pcmk_resource_t *rsc, gboolean all)
void get_rsc_attributes(GHashTable *instance_attrs, const pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get final values of a resource's instance attributes.
void pe__count_bundle(pcmk_resource_t *rsc)
#define CRM_CHECK(expr, failure_action)
xmlNode * pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
#define PCMK_VALUE_STOP_UNEXPECTED
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
#define pcmk__sched_err(scheduler, fmt...)
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
unsigned int pe__clone_max_per_node(const pcmk_resource_t *rsc)
#define PCMK_META_PROMOTABLE
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
void pe__free_bundle(pcmk_resource_t *rsc)
#define PCMK_META_MIGRATION_THRESHOLD
#define PCMK_META_REQUIRES
int pcmk__scan_min_int(const char *text, int *result, int minimum)
#define PCMK_REMOTE_RA_RECONNECT_INTERVAL
#define PCMK_VALUE_INFINITY
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
#define PCMK_XE_PRIMITIVE
#define pcmk__config_warn(fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
GHashTable * parameter_cache
#define pcmk__set_rsc_flags(resource, flags_to_set)
gboolean get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role)
#define pcmk__insert_meta(obj, name, value)
#define pcmk__config_err(fmt...)
#define PCMK_VALUE_STOP_START
pcmk_node_t * pe__find_active_requires(const pcmk_resource_t *rsc, unsigned int *count)
gboolean is_parent(pcmk_resource_t *child, pcmk_resource_t *rsc)
#define PCMK_VALUE_DEFAULT
void pcmk__add_idref(GHashTable *table, const char *id, const char *referrer)
#define PCMK_META_MULTIPLE_ACTIVE
pcmk__scheduler_private_t * priv
enum rsc_role_e native_resource_state(const pcmk_resource_t *rsc, gboolean current)
guint failure_expiration_ms
pcmk__rsc_variant
Resource variants supported by Pacemaker.
const pcmk__rsc_methods_t * fns
GList * ticket_constraints
unsigned int pe__bundle_max_per_node(const pcmk_resource_t *rsc)
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
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)
void pcmk__free_node_copy(void *data)
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)
enum pe_quorum_policy no_quorum_policy
#define PCMK_META_IS_MANAGED
pcmk_node_t * partial_migration_source
void pcmk__xml_free(xmlNode *xml)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define PCMK_VALUE_NOTHING
#define PCMK_VALUE_FENCING
gboolean native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
pcmk_node_t * native_location(const pcmk_resource_t *rsc, GList **list, uint32_t target)
gboolean group_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
pcmk__node_private_t * priv
#define PCMK_META_GLOBALLY_UNIQUE
gboolean clone_active(pcmk_resource_t *rsc, gboolean all)
gboolean pe__bundle_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
pcmk_scheduler_t * scheduler
void(* count)(pcmk_resource_t *rsc)
gboolean pe__clone_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
#define PCMK__ROLE_UNPROMOTED_LEGACY
#define PCMK_META_CLONE_NODE_MAX
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
#define PCMK_XE_UTILIZATION
gboolean(* unpack)(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
unsigned int pe__primitive_max_per_node(const pcmk_resource_t *rsc)
int pcmk_parse_interval_spec(const char *input, guint *result_ms)
Parse milliseconds from a Pacemaker interval specification.
enum pcmk__rsc_variant variant
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
enum pcmk__multiply_active multiply_active_policy
#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.
pcmk_node_t * assigned_node
GList * with_this_colocations
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
enum rsc_role_e clone_resource_state(const pcmk_resource_t *rsc, gboolean current)
Stop unexpected instances.
pcmk__resource_private_t * priv
#define PCMK_META_RESOURCE_STICKINESS
Wrappers for and extensions to libxml2.
void group_free(pcmk_resource_t *rsc)
void native_free(pcmk_resource_t *rsc)
enum rsc_role_e next_role
void get_meta_attributes(GHashTable *meta_hash, pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_scheduler_t *scheduler)
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
Act as if partition still holds quorum.
void common_free(pcmk_resource_t *rsc)
enum rsc_role_e pe__bundle_resource_state(const pcmk_resource_t *rsc, gboolean current)
#define PCMK_XE_OPERATIONS
void pe__count_common(pcmk_resource_t *rsc)
GList * location_constraints
#define PCMK_VALUE_QUORUM
gboolean group_active(pcmk_resource_t *rsc, gboolean all)
#define PCMK_XE_META_ATTRIBUTES
void populate_hash(xmlNode *nvpair_list, GHashTable *hash, const char **attrs, int attrs_length)
GHashTable * allowed_nodes
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
#define pcmk__assert(expr)
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)
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)
#define PCMK_META_MAINTENANCE
Stop on all, start on desired.
gboolean pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
#define PCMK__ROLE_UNKNOWN
gboolean pe__bundle_active(pcmk_resource_t *rsc, gboolean all)
#define PCMK_ROLE_STARTED
guint remote_reconnect_ms
pcmk_scheduler_t * scheduler
#define PCMK_VALUE_STOP_ONLY
enum rsc_role_e orig_role
#define PCMK_META_FAILURE_TIMEOUT
bool pe__resource_is_disabled(const pcmk_resource_t *rsc)
GList * this_with_colocations
#define PCMK_ROLE_UNPROMOTED
Unknown resource variant.
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string.
gboolean crm_is_true(const char *s)
Stop on all and leave stopped.
#define PCMK_META_CRITICAL
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, pcmk_scheduler_t *scheduler)
#define PCMK_META_PRIORITY
void clone_free(pcmk_resource_t *rsc)
GList * dangling_migration_sources
#define crm_log_xml_trace(xml, text)
enum rsc_role_e group_resource_state(const pcmk_resource_t *rsc, gboolean current)
#define PCMK_VALUE_UNFENCING
#define PCMK__META_CONTAINER
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
Resource role is unknown.
pcmk_node_t * pe__bundle_active_node(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
void(* free)(pcmk_resource_t *rsc)
struct pcmk__node_details * details
gboolean pe__group_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
#define PCMK_XE_INSTANCE_ATTRIBUTES
#define PCMK_XE_RESOURCES
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
#define pcmk__set_scheduler_flags(scheduler, flags_to_set)
GHashTable * probed_nodes
pcmk_node_t *(* active_node)(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
#define PCMK_META_ALLOW_MIGRATE
GHashTable * pcmk__strikey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1