12#include <libxml/tree.h>
21void populate_hash(xmlNode * nvpair_list, GHashTable * hash,
const char **attrs,
int attrs_length);
24 unsigned int *count_all,
25 unsigned int *count_clean);
79get_resource_type(
const char *
name)
109dup_attr(gpointer key, gpointer value, gpointer user_data)
111 GHashTable *table = user_data;
113 CRM_CHECK((key != NULL) && (table != NULL),
return);
117 "the explicit value '#default' is deprecated and "
118 "will be removed in a future release",
120 }
else if ((value != NULL) && (g_hash_table_lookup(table, key) == NULL)) {
145 rule_input, parent_orig_meta, NULL,
150 if (parent_orig_meta != NULL) {
152 g_hash_table_foreach(parent_orig_meta, dup_attr, meta_hash);
155 if (parent_orig_meta != NULL) {
156 g_hash_table_destroy(parent_orig_meta);
182 for (xmlAttrPtr a = pcmk__xe_first_attr(rsc->
priv->
xml);
183 a != NULL; a = a->next) {
185 if (a->children != NULL) {
186 dup_attr((gpointer) a->name, (gpointer) a->children->content,
192 &rule_input, meta_hash, NULL,
scheduler);
199 expand_parents_fixed_nvpairs(rsc, &rule_input, meta_hash,
scheduler);
243 &rule_input, instance_attrs, NULL,
scheduler);
250template_op_key(xmlNode * op)
267unpack_template(xmlNode *xml_obj, xmlNode **expanded_xml,
270 xmlNode *cib_resources = NULL;
271 xmlNode *
template = NULL;
272 xmlNode *new_xml = NULL;
273 xmlNode *child_xml = NULL;
274 xmlNode *rsc_ops = NULL;
275 xmlNode *template_ops = NULL;
276 const char *template_ref = NULL;
277 const char *
id = NULL;
279 if (xml_obj == NULL) {
285 if (template_ref == NULL) {
289 id = pcmk__xe_id(xml_obj);
303 if (cib_resources == NULL) {
310 if (
template == NULL) {
316 xmlNodeSetName(new_xml, xml_obj->name);
325 child_xml != NULL; child_xml =
pcmk__xe_next(child_xml, NULL)) {
334 if (template_ops && rsc_ops) {
341 char *key = template_op_key(op);
343 g_hash_table_insert(rsc_ops_hash, key, op);
349 char *key = template_op_key(op);
351 if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) {
359 g_hash_table_destroy(rsc_ops_hash);
366 *expanded_xml = new_xml;
369 if (!unpack_template(new_xml, expanded_xml,
scheduler)) {
371 *expanded_xml = NULL;
382 const char *template_ref = NULL;
383 const char *
id = NULL;
385 if (xml_obj == NULL) {
392 if (template_ref == NULL) {
396 id = pcmk__xe_id(xml_obj);
424 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
428 value = g_hash_table_lookup(rsc->
priv->
meta,
444free_params_table(gpointer
data)
446 g_hash_table_destroy((GHashTable *)
data);
465 GHashTable *params_on_node = NULL;
471 const char *node_name =
"";
474 if ((rsc == NULL) || (
scheduler == NULL)) {
477 if ((node != NULL) && (node->
priv->
name != NULL)) {
491 if (params_on_node == NULL) {
497 return params_on_node;
509unpack_requires(
pcmk_resource_t *rsc,
const char *value,
bool is_default)
529 "devices cannot require unfencing", rsc->
id);
536 "disabled", rsc->
id);
546 const char *orig_value = value;
551 }
else if (pcmk__is_primitive(rsc)
568 if (orig_value != NULL) {
570 "to '%s' because '%s' is not valid",
571 rsc->
id, value, orig_value);
573 unpack_requires(rsc, value,
true);
578 (is_default?
" (default)" :
""));
590 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
597 " because '%s' is not a valid value: %s",
611 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
619 "' is deprecated and will be removed in a "
620 "future release (just leave it unset)");
627 " because '%s' is not a valid value: %s",
642 const char *value = g_hash_table_lookup(rsc->
priv->
meta,
650 "' is deprecated and will be removed in a "
651 "future release (just leave it unset)");
659 ") for resource %s meta-attribute "
661 " because '%s' is not a valid value: %s",
689 xmlNode *expanded_xml = NULL;
691 const char *value = NULL;
692 const char *
id = NULL;
693 bool guest_node =
false;
694 bool remote_node =
false;
717 if (unpack_template(xml_obj, &expanded_xml,
scheduler) == FALSE) {
724 "Unable to allocate memory for resource '%s'",
id);
729 if ((*rsc)->priv == NULL) {
731 "Unable to allocate memory for resource '%s'",
id);
735 rsc_private = (*rsc)->priv;
741 rsc_private->
xml = expanded_xml;
745 rsc_private->
xml = xml_obj;
757 rsc_private->
variant = get_resource_type((
const char *)
758 rsc_private->
xml->name);
761 id, rsc_private->
xml->name);
778 (*rsc)->id = strdup(
id);
781 rsc_private->
fns = &resource_class_functions[rsc_private->
variant];
795 unpack_priority(*rsc);
819 }
else if ((value == NULL) && remote_node) {
836 "' is deprecated and will be removed in a "
837 "future release (just leave it unset)");
856 if (detect_unique(*rsc)) {
859 if (
crm_is_true(g_hash_table_lookup((*rsc)->priv->meta,
870 pcmk__rsc_trace(*rsc,
"%s multiple running resource recovery: stop only",
882 "%s multiple running resource recovery: "
883 "stop unexpected instances",
891 ", using default of "
897 "%s multiple running resource recovery: stop/start",
901 unpack_stickiness(*rsc);
902 unpack_migration_threshold(*rsc);
911 unpack_requires(*rsc, value,
false);
956 }
else if (guest_node) {
972 if (add_template_rsc(xml_obj,
scheduler) == FALSE) {
986 if (
parent == NULL || rsc == NULL) {
989 while (
parent->priv->parent != NULL) {
990 if (
parent->priv->parent == rsc) {
1006 while ((
parent->priv->parent != NULL)
1007 && !pcmk__is_bundle(
parent->priv->parent)) {
1032 while (
parent->priv->parent != NULL) {
1033 if (!include_bundle && pcmk__is_bundle(
parent->priv->parent)) {
1084 g_hash_table_destroy(rsc->
priv->
meta);
1118 unsigned int *count_clean)
1120 bool keep_looking =
false;
1121 bool is_happy =
false;
1123 CRM_CHECK((rsc != NULL) && (node != NULL) && (active != NULL),
1128 if (count_all != NULL) {
1131 if ((count_clean != NULL) && is_happy) {
1134 if ((count_all != NULL) || (count_clean != NULL)) {
1135 keep_looking =
true;
1142 keep_looking =
true;
1145 if (is_happy && ((*active == NULL) || !(*active)->details->online
1146 || (*active)->details->unclean)) {
1149 keep_looking =
true;
1152 if (*active == NULL) {
1155 return keep_looking;
1161 unsigned int *count_clean)
1165 if (count_all != NULL) {
1168 if (count_clean != NULL) {
1175 iter != NULL; iter = iter->next) {
1178 count_all, count_clean)) {
1202 if (count != NULL) {
1220 item != NULL; item = item->next) {
#define PCMK_RESOURCE_CLASS_STONITH
unsigned int pe__bundle_max_per_node(const pcmk_resource_t *rsc)
pcmk_node_t * pe__bundle_active_node(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
unsigned int pe__clone_max_per_node(const pcmk_resource_t *rsc)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
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.
pcmk_node_t * pe__find_active_requires(const pcmk_resource_t *rsc, unsigned int *count)
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
gboolean is_parent(pcmk_resource_t *child, pcmk_resource_t *rsc)
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
void populate_hash(xmlNode *nvpair_list, GHashTable *hash, const char **attrs, int attrs_length)
void get_meta_attributes(GHashTable *meta_hash, pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_scheduler_t *scheduler)
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)
int pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, pcmk_resource_t *parent, pcmk_scheduler_t *scheduler)
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
void common_free(pcmk_resource_t *rsc)
void pe__count_common(pcmk_resource_t *rsc)
unsigned int pe__group_max_per_node(const pcmk_resource_t *rsc)
#define CRM_CHECK(expr, failure_action)
#define crm_log_xml_trace(xml, text)
#define pcmk__config_warn(fmt...)
#define pcmk__config_err(fmt...)
unsigned int pe__primitive_max_per_node(const pcmk_resource_t *rsc)
pcmk_scheduler_t * scheduler
void pcmk__free_node_copy(void *data)
#define pcmk__insert_meta(obj, name, value)
#define PCMK_META_PRIORITY
#define PCMK_META_PROMOTABLE
#define PCMK_VALUE_STOP_UNEXPECTED
#define PCMK_META_RESOURCE_STICKINESS
#define PCMK_META_MIGRATION_THRESHOLD
#define PCMK_META_REQUIRES
#define PCMK_META_CLONE_NODE_MAX
#define PCMK_VALUE_STOP_START
#define PCMK_VALUE_FENCING
#define PCMK_META_CRITICAL
#define PCMK_REMOTE_RA_RECONNECT_INTERVAL
#define PCMK_META_FAILURE_TIMEOUT
#define PCMK_VALUE_QUORUM
#define PCMK_META_IS_MANAGED
#define PCMK_META_ALLOW_MIGRATE
#define PCMK_META_GLOBALLY_UNIQUE
#define PCMK_VALUE_STOP_ONLY
#define PCMK_VALUE_DEFAULT
#define PCMK_META_MAINTENANCE
#define PCMK_VALUE_UNFENCING
#define PCMK_VALUE_INFINITY
#define PCMK_VALUE_NOTHING
#define PCMK_META_MULTIPLE_ACTIVE
#define PCMK__META_CONTAINER
bool clone_active(const pcmk_resource_t *rsc, bool all)
enum rsc_role_e pe__bundle_resource_state(const pcmk_resource_t *rsc, bool current)
gboolean get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role)
bool pe__bundle_is_filtered(const pcmk_resource_t *rsc, const GList *only_rsc, bool check_parent)
void group_free(pcmk_resource_t *rsc)
bool native_unpack(pcmk_resource_t *rsc)
bool group_active(const pcmk_resource_t *rsc, bool all)
void pe__count_bundle(pcmk_resource_t *rsc)
bool native_active(const pcmk_resource_t *rsc, bool all)
void native_free(pcmk_resource_t *rsc)
bool pe__group_is_filtered(const pcmk_resource_t *rsc, const GList *only_rsc, bool check_parent)
enum rsc_role_e group_resource_state(const pcmk_resource_t *rsc, bool current)
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
void clone_free(pcmk_resource_t *rsc)
void pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name, const pcmk_rule_input_t *rule_input, GHashTable *hash, const char *always_first, pcmk_scheduler_t *scheduler)
bool clone_unpack(pcmk_resource_t *rsc)
bool pe__native_is_filtered(const pcmk_resource_t *rsc, const GList *only_rsc, bool check_parent)
pcmk_node_t * native_location(const pcmk_resource_t *rsc, GList **list, uint32_t target)
pcmk_resource_t * native_find_rsc(pcmk_resource_t *rsc, const char *id, const pcmk_node_t *node, uint32_t flags)
bool pe__unpack_bundle(pcmk_resource_t *rsc)
bool pe__bundle_active(const pcmk_resource_t *rsc, bool all)
bool pe__resource_is_disabled(const pcmk_resource_t *rsc)
bool pe__clone_is_filtered(const pcmk_resource_t *rsc, const GList *only_rsc, bool check_parent)
bool group_unpack(pcmk_resource_t *rsc)
enum rsc_role_e clone_resource_state(const pcmk_resource_t *rsc, bool current)
enum rsc_role_e native_resource_state(const pcmk_resource_t *rsc, bool current)
void pe__free_bundle(pcmk_resource_t *rsc)
bool xml_contains_remote_node(xmlNode *xml)
@ pcmk__rsc_needs_unfencing
@ pcmk__rsc_needs_fencing
@ pcmk__rsc_is_remote_connection
#define pcmk__set_rsc_flags(resource, flags_to_set)
pcmk__rsc_variant
Resource variants supported by Pacemaker.
@ pcmk__rsc_variant_group
Group resource.
@ pcmk__rsc_variant_clone
Clone resource.
@ pcmk__rsc_variant_unknown
Unknown resource variant.
@ pcmk__rsc_variant_primitive
Primitive resource.
@ pcmk__rsc_variant_bundle
Bundle resource.
void pcmk__free_resource(gpointer user_data)
@ pcmk__multiply_active_restart
Stop on all, start on desired.
@ pcmk__multiply_active_block
Do nothing to resource.
@ pcmk__multiply_active_stop
Stop on all and leave stopped.
@ pcmk__multiply_active_unexpected
Stop unexpected instances.
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
#define pcmk__assert(expr)
#define PCMK_ROLE_STARTED
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
@ pcmk_role_unknown
Resource role is unknown.
@ pcmk_role_stopped
Stopped.
#define PCMK_ROLE_UNPROMOTED
#define PCMK__ROLE_UNPROMOTED_LEGACY
#define PCMK__ROLE_UNKNOWN
@ pcmk_no_quorum_ignore
Act as if partition still holds quorum.
#define pcmk__sched_err(scheduler, fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
#define pcmk__set_scheduler_flags(scheduler, flags_to_set)
@ pcmk__sched_in_maintenance
@ pcmk__sched_enable_unfencing
@ pcmk__sched_fencing_enabled
@ pcmk__sched_symmetric_cluster
@ pcmk__sched_have_fencing
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string.
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
int pcmk_parse_interval_spec(const char *input, guint *result_ms)
Parse milliseconds from a Pacemaker interval specification.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
gboolean crm_is_true(const char *s)
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
int pcmk__scan_min_int(const char *text, int *result, int minimum)
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
GHashTable * pcmk__strikey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk_node_t * assigned_node
guint failure_expiration_ms
GHashTable * probed_nodes
GList * ticket_constraints
GList * this_with_colocations
GList * with_this_colocations
pcmk_scheduler_t * scheduler
pcmk_node_t * partial_migration_source
GList * dangling_migration_sources
enum pcmk__multiply_active multiply_active_policy
enum pcmk__rsc_variant variant
enum rsc_role_e orig_role
enum rsc_role_e next_role
GHashTable * parameter_cache
const pcmk__rsc_methods_t * fns
GHashTable * allowed_nodes
guint remote_reconnect_ms
GList * location_constraints
pcmk__resource_private_t * priv
bool(* unpack)(pcmk_resource_t *rsc)
pcmk_node_t *(* active_node)(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
void(* count)(pcmk_resource_t *rsc)
pcmk__scheduler_private_t * priv
enum pe_quorum_policy no_quorum_policy
pcmk__node_private_t * priv
struct pcmk__node_details * details
Wrappers for and extensions to libxml2.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
xmlNode * pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
void pcmk__add_idref(GHashTable *table, const char *id, const char *referrer)
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
void pcmk__xml_free(xmlNode *xml)
#define PCMK_XE_UTILIZATION
#define PCMK_XE_RESOURCES
#define PCMK_XE_INSTANCE_ATTRIBUTES
#define PCMK_XE_META_ATTRIBUTES
#define PCMK_XE_PRIMITIVE
#define PCMK_XE_OPERATIONS
xmlNode * pcmk__xpath_find_one(xmlDoc *doc, const char *path, uint8_t level)