16 void populate_hash(xmlNode * nvpair_list, GHashTable * hash,
const char **attrs,
int attrs_length);
66 get_resource_type(
const char *
name)
89 dup_attr(gpointer key, gpointer value, gpointer user_data)
98 GHashTable *node_hash = NULL;
105 xmlAttrPtr xIter = NULL;
107 for (xIter = rsc->
xml->properties; xIter; xIter = xIter->next) {
108 const char *prop_name = (
const char *)xIter->name;
116 meta_hash, NULL, FALSE, data_set);
119 if (rsc->
parent != NULL) {
120 g_hash_table_foreach(rsc->
parent->
meta, dup_attr, meta_hash);
125 node_hash, meta_hash, NULL, FALSE, data_set);
132 GHashTable *node_hash = NULL;
139 meta_hash, NULL, FALSE, data_set);
142 if (rsc->
parent != NULL) {
148 node_hash, meta_hash, NULL, FALSE, data_set);
152 #if ENABLE_VERSIONED_ATTRS
154 pe_get_versioned_attributes(xmlNode * meta_hash,
pe_resource_t * rsc,
157 GHashTable *node_hash = NULL;
164 meta_hash, data_set->
now, NULL);
167 if (rsc->
parent != NULL) {
168 pe_get_versioned_attributes(meta_hash, rsc->
parent, node, data_set);
173 node_hash, meta_hash, data_set->
now, NULL);
179 template_op_key(xmlNode * op)
195 unpack_template(xmlNode * xml_obj, xmlNode ** expanded_xml,
pe_working_set_t * data_set)
197 xmlNode *cib_resources = NULL;
198 xmlNode *
template = NULL;
199 xmlNode *new_xml = NULL;
200 xmlNode *child_xml = NULL;
201 xmlNode *rsc_ops = NULL;
202 xmlNode *template_ops = NULL;
203 const char *template_ref = NULL;
204 const char *clone = NULL;
205 const char *
id = NULL;
207 if (xml_obj == NULL) {
208 pe_err(
"No resource object for template unpacking");
213 if (template_ref == NULL) {
219 pe_err(
"'%s' object must have a id", crm_element_name(xml_obj));
224 pe_err(
"The resource object '%s' should not reference itself",
id);
229 if (cib_resources == NULL) {
230 pe_err(
"No resources configured");
235 if (
template == NULL) {
236 pe_err(
"No template named '%s'", template_ref);
241 xmlNodeSetName(new_xml, xml_obj->name);
251 for (child_xml = __xml_first_child_element(xml_obj); child_xml != NULL;
252 child_xml = __xml_next_element(child_xml)) {
253 xmlNode *new_child = NULL;
257 if (
crm_str_eq((
const char *)new_child->name,
"operations", TRUE)) {
262 if (template_ops && rsc_ops) {
264 GHashTable *rsc_ops_hash = g_hash_table_new_full(
crm_str_hash,
268 for (op = __xml_first_child_element(rsc_ops); op != NULL;
269 op = __xml_next_element(op)) {
271 char *key = template_op_key(op);
273 g_hash_table_insert(rsc_ops_hash, key, op);
276 for (op = __xml_first_child_element(template_ops); op != NULL;
277 op = __xml_next_element(op)) {
279 char *key = template_op_key(op);
281 if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) {
289 g_hash_table_destroy(rsc_ops_hash);
296 *expanded_xml = new_xml;
312 const char *template_ref = NULL;
313 const char *
id = NULL;
315 if (xml_obj == NULL) {
316 pe_err(
"No resource object for processing resource list of template");
321 if (template_ref == NULL) {
327 pe_err(
"'%s' object must have a id", crm_element_name(xml_obj));
332 pe_err(
"The resource object '%s' should not reference itself",
id);
346 const char *promotable = g_hash_table_lookup(rsc->
meta,
369 bool isdefault = FALSE;
370 xmlNode *expanded_xml = NULL;
372 const char *value = NULL;
373 const char *rclass = NULL;
375 bool guest_node = FALSE;
376 bool remote_node = FALSE;
377 bool has_versioned_params = FALSE;
382 pe_err(
"Must specify id tag in <resource>");
385 }
else if (rsc == NULL) {
386 pe_err(
"Nowhere to unpack resource into");
391 if (unpack_template(xml_obj, &expanded_xml, data_set) == FALSE) {
396 (*rsc)->cluster = data_set;
400 (*rsc)->xml = expanded_xml;
401 (*rsc)->orig_xml = xml_obj;
404 (*rsc)->xml = xml_obj;
405 (*rsc)->orig_xml = NULL;
410 (*rsc)->parent = parent;
415 (*rsc)->variant = get_resource_type(crm_element_name((*rsc)->xml));
417 pe_err(
"Unknown resource type: %s", crm_element_name((*rsc)->xml));
422 (*rsc)->parameters = crm_str_table_new();
424 #if ENABLE_VERSIONED_ATTRS
428 (*rsc)->meta = crm_str_table_new();
430 (*rsc)->allowed_nodes =
431 g_hash_table_new_full(
crm_str_hash, g_str_equal, NULL, free);
433 (*rsc)->known_on = g_hash_table_new_full(
crm_str_hash, g_str_equal, NULL,
442 (*rsc)->id = strdup(
id);
445 (*rsc)->fns = &resource_class_functions[(*rsc)->variant];
450 #if ENABLE_VERSIONED_ATTRS
451 pe_get_versioned_attributes((*rsc)->versioned_parameters, *rsc, NULL, data_set);
462 (*rsc)->rsc_cons = NULL;
463 (*rsc)->rsc_tickets = NULL;
464 (*rsc)->actions = NULL;
469 (*rsc)->stickiness = 0;
470 (*rsc)->migration_threshold =
INFINITY;
471 (*rsc)->failure_timeout = 0;
482 (*rsc)->is_remote_node = TRUE;
491 #if ENABLE_VERSIONED_ATTRS
495 pe_rsc_trace((*rsc),
"Migration is disabled for resources with versioned parameters");
498 }
else if ((value == NULL) && remote_node && !has_versioned_params) {
533 if (detect_promotable(*rsc)) {
545 pe_rsc_trace((*rsc),
"\tDependency restart handling: restart");
547 "Support for restart-type is deprecated and will be removed in a future release");
551 pe_rsc_trace((*rsc),
"\tDependency restart handling: ignore");
557 pe_rsc_trace((*rsc),
"\tMultiple running resource recovery: stop only");
561 pe_rsc_trace((*rsc),
"\tMultiple running resource recovery: block");
565 pe_rsc_trace((*rsc),
"\tMultiple running resource recovery: stop/start");
575 (*rsc)->migration_threshold =
char2score(value);
576 if ((*rsc)->migration_threshold < 0) {
583 " must be non-negative, using 1 instead");
584 (*rsc)->migration_threshold = 1;
595 handle_requires_pref:
604 "to 'quorum' because fencing devices cannot "
605 "require unfencing", (*rsc)->id);
608 goto handle_requires_pref;
612 "to 'quorum' because fencing is disabled",
616 goto handle_requires_pref;
631 const char *orig_value = value;
637 }
else if (((*rsc)->variant ==
pe_native)
658 if (orig_value != NULL) {
660 "to '%s' because '%s' is not valid",
661 (*rsc)->id, value, orig_value);
664 goto handle_requires_pref;
667 pe_rsc_trace((*rsc),
"\tRequired to start: %s%s", value, isdefault?
" (default)":
"");
682 (*rsc)->failure_timeout = (*rsc)->remote_reconnect_ms / 1000;
690 if ((*rsc)->fns->unpack(*rsc, data_set) == FALSE) {
697 }
else if (guest_node) {
705 is_set((*rsc)->flags,
pe_rsc_notify) ?
"required" :
"not required");
707 (*rsc)->utilization = crm_str_table_new();
710 (*rsc)->utilization, NULL, FALSE, data_set);
715 if (add_template_rsc(xml_obj, data_set) == FALSE) {
736 for (; gIter != NULL; gIter = gIter->next) {
749 if (parent == NULL || rsc == NULL) {
752 while (parent->
parent != NULL) {
753 if (parent->
parent == rsc) {
766 if (parent == NULL) {
792 #if ENABLE_VERSIONED_ATTRS
793 if (rsc->versioned_parameters != NULL) {
794 free_xml(rsc->versioned_parameters);
797 if (rsc->
meta != NULL) {
798 g_hash_table_destroy(rsc->
meta);
820 g_hash_table_destroy(rsc->
known_on);
859 unsigned int *count_clean)
863 bool keep_looking = FALSE;
864 bool is_happy = FALSE;
876 for (GList *node_iter = rsc->
running_on; node_iter != NULL;
877 node_iter = node_iter->next) {
879 node = node_iter->data;
880 keep_looking = FALSE;
887 if (count_clean && is_happy) {
890 if (count_all || count_clean) {
911 if (active == NULL) {
916 if (keep_looking == FALSE) {
950 for (GList *item = rsc->
children; item != NULL; item = item->next) {
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
enum pe_quorum_policy no_quorum_policy
void get_meta_attributes(GHashTable *meta_hash, pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
void group_free(pe_resource_t *rsc)
gboolean safe_str_neq(const char *a, const char *b)
gboolean is_parent(pe_resource_t *child, pe_resource_t *rsc)
void group_print(pe_resource_t *rsc, const char *pre_text, long options, void *print_data)
GListPtr dangling_migrations
#define XML_CIB_TAG_CONTAINER
pe_node_t * pe__find_active_on(const pe_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
pe_node_t * partial_migration_source
#define XML_TAG_UTILIZATION
#define RSC_ROLE_STARTED_S
void pe__free_bundle(pe_resource_t *rsc)
#define pe_flag_symmetric_cluster
enum rsc_role_e pe__bundle_resource_state(const pe_resource_t *rsc, gboolean current)
#define pcmk__config_err(fmt...)
void pe__count_common(pe_resource_t *rsc)
#define XML_RSC_ATTR_INCARNATION
#define pe_flag_maintenance_mode
gboolean group_active(pe_resource_t *rsc, gboolean all)
int char2score(const char *score)
pe_node_t * native_location(const pe_resource_t *rsc, GList **list, int current)
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
gboolean xml_contains_remote_node(xmlNode *xml)
#define XML_CIB_TAG_RSC_TEMPLATE
#define XML_RSC_ATTR_STICKINESS
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
#define clear_bit(word, bit)
guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
void pe__print_bundle(pe_resource_t *rsc, const char *pre_text, long options, void *print_data)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
gboolean pe__unpack_bundle(pe_resource_t *rsc, pe_working_set_t *data_set)
void native_free(pe_resource_t *rsc)
void clone_free(pe_resource_t *rsc)
#define XML_CIB_ATTR_PRIORITY
xmlNode * copy_xml(xmlNode *src_node)
enum rsc_role_e group_resource_state(const pe_resource_t *rsc, gboolean current)
#define pe_rsc_provisional
#define XML_TAG_ATTR_SETS
#define XML_CIB_TAG_RESOURCES
#define XML_RSC_ATTR_PROMOTABLE
const char * role2text(enum rsc_role_e role)
enum rsc_role_e clone_resource_state(const pe_resource_t *rsc, gboolean current)
#define set_bit(word, bit)
#define XML_RSC_ATTR_REQUIRES
#define PCMK_RESOURCE_CLASS_OCF
#define pe_rsc_allow_migrate
pe_resource_t * uber_parent(pe_resource_t *rsc)
#define XML_RSC_ATTR_CONTAINER
gboolean clone_active(pe_resource_t *rsc, gboolean all)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Replace an XML attribute with specified name and (possibly NULL) value.
#define pe_warn_once(pe_wo_bit, fmt...)
char * native_parameter(pe_resource_t *rsc, pe_node_t *node, gboolean create, const char *name, pe_working_set_t *data_set)
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
struct pe_node_shared_s * details
gboolean get_target_role(pe_resource_t *rsc, enum rsc_role_e *role)
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
void pe__unpack_dataset_nvpairs(xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, pe_working_set_t *data_set)
#define XML_AGENT_ATTR_PROVIDER
#define pe_rsc_needs_fencing
void common_free(pe_resource_t *rsc)
#define pe_rsc_promotable
#define XML_TAG_META_SETS
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
#define XML_RSC_ATTR_MANAGED
xmlNode * create_xml_node(xmlNode *parent, const char *name)
#define pe_flag_stonith_enabled
enum rsc_role_e native_resource_state(const pe_resource_t *rsc, gboolean current)
void clone_print(pe_resource_t *rsc, const char *pre_text, long options, void *print_data)
void native_print(pe_resource_t *rsc, const char *pre_text, long options, void *print_data)
#define XML_TAG_RSC_VER_ATTRS
void free_xml(xmlNode *child)
enum pe_obj_types variant
gboolean xml_has_children(const xmlNode *root)
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
void common_update_score(pe_resource_t *rsc, const char *id, int score)
#define XML_REMOTE_ATTR_RECONNECT_INTERVAL
#define XML_RSC_ATTR_NOTIFY
#define XML_RSC_ATTR_FAIL_STICKINESS
resource_object_functions_t resource_class_functions[]
gboolean native_active(pe_resource_t *rsc, gboolean all)
void populate_hash(xmlNode *nvpair_list, GHashTable *hash, const char **attrs, int attrs_length)
#define pe_rsc_fence_device
#define XML_RSC_ATTR_UNIQUE
#define PCMK_RESOURCE_CLASS_STONITH
void get_rsc_attributes(GHashTable *meta_hash, pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
pe_resource_t * native_find_rsc(pe_resource_t *rsc, const char *id, const pe_node_t *node, int flags)
#define XML_CIB_TAG_INCARNATION
#define XML_RSC_ATTR_MAINTENANCE
#define XML_RSC_ATTR_FAIL_TIMEOUT
void add_hash_param(GHashTable *hash, const char *name, const char *value)
int pe__add_scores(int score1, int score2)
gboolean clone_unpack(pe_resource_t *rsc, pe_working_set_t *data_set)
#define pe_rsc_needs_unfencing
#define XML_RSC_ATTR_MULTIPLE
#define pe_rsc_maintenance
#define XML_RSC_ATTR_RESTART
#define XML_CIB_TAG_MASTER
pe_working_set_t * cluster
#define RSC_ROLE_UNKNOWN_S
#define pe_rsc_needs_quorum
#define crm_log_xml_trace(xml, text)
gboolean common_unpack(xmlNode *xml_obj, pe_resource_t **rsc, pe_resource_t *parent, pe_working_set_t *data_set)
gboolean crm_is_true(const char *s)
#define pe_flag_have_stonith_resource
#define XML_CIB_TAG_GROUP
#define pe_flag_enable_unfencing
#define pe_rsc_trace(rsc, fmt, args...)
pe_node_t * pe__find_active_requires(const pe_resource_t *rsc, unsigned int *count)
bool pe__resource_is_disabled(pe_resource_t *rsc)
#define safe_str_eq(a, b)
gboolean native_unpack(pe_resource_t *rsc, pe_working_set_t *data_set)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
GHashTable * template_rsc_sets
void pe__count_bundle(pe_resource_t *rsc)
#define pcmk__config_warn(fmt...)
#define XML_OP_ATTR_ALLOW_MIGRATE
gboolean pe__bundle_active(pe_resource_t *rsc, gboolean all)
#define XML_AGENT_ATTR_CLASS
GHashTable * allowed_nodes
gboolean group_unpack(pe_resource_t *rsc, pe_working_set_t *data_set)