pacemaker  1.1.24-3850484742
Scalable High-Availability cluster resource manager
complex.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 #include <crm_internal.h>
9 
10 #include <crm/pengine/rules.h>
11 #include <crm/pengine/internal.h>
12 #include <crm/msg_xml.h>
13 
14 #include <unpack.h>
15 
16 void populate_hash(xmlNode * nvpair_list, GHashTable * hash, const char **attrs, int attrs_length);
17 
19  {
29  },
30  {
38  group_free,
40  },
41  {
49  clone_free,
51  },
52  {
60  clone_free,
62  },
63  {
73  }
74 };
75 
76 enum pe_obj_types
77 get_resource_type(const char *name)
78 {
79  if (safe_str_eq(name, XML_CIB_TAG_RESOURCE)) {
80  return pe_native;
81 
82  } else if (safe_str_eq(name, XML_CIB_TAG_GROUP)) {
83  return pe_group;
84 
85  } else if (safe_str_eq(name, XML_CIB_TAG_INCARNATION)) {
86  return pe_clone;
87 
88  } else if (safe_str_eq(name, XML_CIB_TAG_MASTER)) {
89  return pe_master;
90 
91  } else if (safe_str_eq(name, XML_CIB_TAG_CONTAINER)) {
92  return pe_container;
93  }
94 
95  return pe_unknown;
96 }
97 
98 const char *
100 {
101  switch (type) {
102  case pe_native:
103  return XML_CIB_TAG_RESOURCE;
104  case pe_group:
105  return XML_CIB_TAG_GROUP;
106  case pe_clone:
108  case pe_master:
109  return XML_CIB_TAG_MASTER;
110  case pe_container:
111  return XML_CIB_TAG_CONTAINER;
112  case pe_unknown:
113  return "unknown";
114  }
115  return "<unknown>";
116 }
117 
118 static void
119 dup_attr(gpointer key, gpointer value, gpointer user_data)
120 {
121  add_hash_param(user_data, key, value);
122 }
123 
124 void
125 get_meta_attributes(GHashTable * meta_hash, resource_t * rsc,
126  node_t * node, pe_working_set_t * data_set)
127 {
128  GHashTable *node_hash = NULL;
129  const char *version = crm_element_value(data_set->input, XML_ATTR_CRM_VERSION);
130 
131  if (node) {
132  node_hash = node->details->attrs;
133  }
134 
135  if (rsc->xml) {
136  xmlAttrPtr xIter = NULL;
137 
138  for (xIter = rsc->xml->properties; xIter; xIter = xIter->next) {
139  const char *prop_name = (const char *)xIter->name;
140  const char *prop_value = crm_element_value(rsc->xml, prop_name);
141 
142  add_hash_param(meta_hash, prop_name, prop_value);
143  }
144  }
145 
146  unpack_instance_attributes(data_set->input, rsc->xml, XML_TAG_META_SETS, node_hash,
147  meta_hash, NULL, FALSE, data_set->now);
148 
149  if(version == NULL || compare_version(version, "3.0.9") < 0) {
150  /* populate from the regular attributes until the GUI can create
151  * meta attributes
152  */
153  unpack_instance_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
154  meta_hash, NULL, FALSE, data_set->now);
155  }
156 
157  /* set anything else based on the parent */
158  if (rsc->parent != NULL) {
159  g_hash_table_foreach(rsc->parent->meta, dup_attr, meta_hash);
160  }
161 
162  /* and finally check the defaults */
164  node_hash, meta_hash, NULL, FALSE, data_set->now);
165 }
166 
167 void
168 get_rsc_attributes(GHashTable * meta_hash, resource_t * rsc,
169  node_t * node, pe_working_set_t * data_set)
170 {
171  GHashTable *node_hash = NULL;
172 
173  if (node) {
174  node_hash = node->details->attrs;
175  }
176 
177  unpack_instance_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
178  meta_hash, NULL, FALSE, data_set->now);
179 
180  /* set anything else based on the parent */
181  if (rsc->parent != NULL) {
182  get_rsc_attributes(meta_hash, rsc->parent, node, data_set);
183 
184  } else {
185  /* and finally check the defaults */
187  node_hash, meta_hash, NULL, FALSE, data_set->now);
188  }
189 }
190 
191 #if ENABLE_VERSIONED_ATTRS
192 void
193 pe_get_versioned_attributes(xmlNode * meta_hash, resource_t * rsc,
194  node_t * node, pe_working_set_t * data_set)
195 {
196  GHashTable *node_hash = NULL;
197 
198  if (node) {
199  node_hash = node->details->attrs;
200  }
201 
202  pe_unpack_versioned_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
203  meta_hash, data_set->now);
204 
205  /* set anything else based on the parent */
206  if (rsc->parent != NULL) {
207  pe_get_versioned_attributes(meta_hash, rsc->parent, node, data_set);
208 
209  } else {
210  /* and finally check the defaults */
211  pe_unpack_versioned_attributes(data_set->input, data_set->rsc_defaults, XML_TAG_ATTR_SETS,
212  node_hash, meta_hash, data_set->now);
213  }
214 }
215 #endif
216 
217 static char *
218 template_op_key(xmlNode * op)
219 {
220  const char *name = crm_element_value(op, "name");
221  const char *role = crm_element_value(op, "role");
222  char *key = NULL;
223 
224  if (role == NULL || crm_str_eq(role, RSC_ROLE_STARTED_S, TRUE)
225  || crm_str_eq(role, RSC_ROLE_SLAVE_S, TRUE)) {
226  role = RSC_ROLE_UNKNOWN_S;
227  }
228 
229  key = crm_concat(name, role, '-');
230  return key;
231 }
232 
233 static gboolean
234 unpack_template(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
235 {
236  xmlNode *cib_resources = NULL;
237  xmlNode *template = NULL;
238  xmlNode *new_xml = NULL;
239  xmlNode *child_xml = NULL;
240  xmlNode *rsc_ops = NULL;
241  xmlNode *template_ops = NULL;
242  const char *template_ref = NULL;
243  const char *clone = NULL;
244  const char *id = NULL;
245 
246  if (xml_obj == NULL) {
247  pe_err("No resource object for template unpacking");
248  return FALSE;
249  }
250 
251  template_ref = crm_element_value(xml_obj, XML_CIB_TAG_RSC_TEMPLATE);
252  if (template_ref == NULL) {
253  return TRUE;
254  }
255 
256  id = ID(xml_obj);
257  if (id == NULL) {
258  pe_err("'%s' object must have a id", crm_element_name(xml_obj));
259  return FALSE;
260  }
261 
262  if (crm_str_eq(template_ref, id, TRUE)) {
263  pe_err("The resource object '%s' should not reference itself", id);
264  return FALSE;
265  }
266 
267  cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE);
268  if (cib_resources == NULL) {
269  pe_err("No resources configured");
270  return FALSE;
271  }
272 
273  template = find_entity(cib_resources, XML_CIB_TAG_RSC_TEMPLATE, template_ref);
274  if (template == NULL) {
275  pe_err("No template named '%s'", template_ref);
276  return FALSE;
277  }
278 
279  new_xml = copy_xml(template);
280  xmlNodeSetName(new_xml, xml_obj->name);
281  crm_xml_replace(new_xml, XML_ATTR_ID, id);
282 
284  if(clone) {
285  crm_xml_add(new_xml, XML_RSC_ATTR_INCARNATION, clone);
286  }
287 
288  template_ops = find_xml_node(new_xml, "operations", FALSE);
289 
290  for (child_xml = __xml_first_child_element(xml_obj); child_xml != NULL;
291  child_xml = __xml_next_element(child_xml)) {
292  xmlNode *new_child = NULL;
293 
294  new_child = add_node_copy(new_xml, child_xml);
295 
296  if (crm_str_eq((const char *)new_child->name, "operations", TRUE)) {
297  rsc_ops = new_child;
298  }
299  }
300 
301  if (template_ops && rsc_ops) {
302  xmlNode *op = NULL;
303  GHashTable *rsc_ops_hash =
304  g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, NULL);
305 
306  for (op = __xml_first_child_element(rsc_ops); op != NULL;
307  op = __xml_next_element(op)) {
308 
309  char *key = template_op_key(op);
310 
311  g_hash_table_insert(rsc_ops_hash, key, op);
312  }
313 
314  for (op = __xml_first_child_element(template_ops); op != NULL;
315  op = __xml_next_element(op)) {
316 
317  char *key = template_op_key(op);
318 
319  if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) {
320  add_node_copy(rsc_ops, op);
321  }
322 
323  free(key);
324  }
325 
326  if (rsc_ops_hash) {
327  g_hash_table_destroy(rsc_ops_hash);
328  }
329 
330  free_xml(template_ops);
331  }
332 
333  /*free_xml(*expanded_xml); */
334  *expanded_xml = new_xml;
335 
336  /* Disable multi-level templates for now */
337  /*if(unpack_template(new_xml, expanded_xml, data_set) == FALSE) {
338  free_xml(*expanded_xml);
339  *expanded_xml = NULL;
340 
341  return FALSE;
342  } */
343 
344  return TRUE;
345 }
346 
347 static gboolean
348 add_template_rsc(xmlNode * xml_obj, pe_working_set_t * data_set)
349 {
350  const char *template_ref = NULL;
351  const char *id = NULL;
352 
353  if (xml_obj == NULL) {
354  pe_err("No resource object for processing resource list of template");
355  return FALSE;
356  }
357 
358  template_ref = crm_element_value(xml_obj, XML_CIB_TAG_RSC_TEMPLATE);
359  if (template_ref == NULL) {
360  return TRUE;
361  }
362 
363  id = ID(xml_obj);
364  if (id == NULL) {
365  pe_err("'%s' object must have a id", crm_element_name(xml_obj));
366  return FALSE;
367  }
368 
369  if (crm_str_eq(template_ref, id, TRUE)) {
370  pe_err("The resource object '%s' should not reference itself", id);
371  return FALSE;
372  }
373 
374  if (add_tag_ref(data_set->template_rsc_sets, template_ref, id) == FALSE) {
375  return FALSE;
376  }
377 
378  return TRUE;
379 }
380 
381 static void
382 handle_rsc_isolation(resource_t *rsc)
383 {
384  resource_t *top = uber_parent(rsc);
385  resource_t *iso = rsc;
386  const char *wrapper = NULL;
387  const char *value;
388 
389  /* check for isolation wrapper mapping if the parent doesn't have one set
390  * isolation mapping is enabled by default. For safety, we are allowing isolation
391  * to be disabled by setting the meta attr, isolation=false. */
392  value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ISOLATION);
393  if (top->isolation_wrapper == NULL && (value == NULL || crm_is_true(value))) {
394  if (g_hash_table_lookup(rsc->parameters, "pcmk_docker_image")) {
395  wrapper = "docker-wrapper";
396  }
397  /* add more isolation technologies here as we expand */
398  } else if (top->isolation_wrapper) {
399  goto set_rsc_opts;
400  }
401 
402  if (wrapper == NULL) {
403  return;
404  }
405 
406  /* if this is a cloned primitive/group, go head and set the isolation wrapper at
407  * at the clone level. this is really the only sane thing to do in this situation.
408  * This allows someone to clone an isolated resource without having to shuffle
409  * around the isolation attributes to the clone parent */
410  if (top == rsc->parent && pe_rsc_is_clone(top)) {
411  iso = top;
412  }
413 
414  iso->isolation_wrapper = wrapper;
415  set_bit(top->flags, pe_rsc_unique);
416 
417 set_rsc_opts:
418  pe_warn_once(pe_wo_isolation, "Support for 'isolation' resource meta-attribute"
419  " is deprecated and will be removed in a future release"
420  " (use bundle syntax instead)");
421 
423  set_bit(rsc->flags, pe_rsc_unique);
424  if (pe_rsc_is_clone(top)) {
426  }
427 }
428 
429 static void
430 check_deprecated_stonith(resource_t *rsc)
431 {
432  GHashTableIter iter;
433  char *key;
434 
435  g_hash_table_iter_init(&iter, rsc->parameters);
436  while (g_hash_table_iter_next(&iter, (gpointer *) &key, NULL)) {
437  if (crm_starts_with(key, "pcmk_")) {
438  char *cmp = key + 5; // the part after "pcmk_"
439 
440  if (!strcmp(cmp, "poweroff_action")) {
442  "Support for the 'pcmk_poweroff_action' stonith resource parameter"
443  " is deprecated and will be removed in a future version"
444  " (use 'pcmk_off_action' instead)");
445 
446  } else if (!strcmp(cmp, "arg_map")) {
448  "Support for the 'pcmk_arg_map' stonith resource parameter"
449  " is deprecated and will be removed in a future version"
450  " (use 'pcmk_host_argument' instead)");
451 
452  } else if (crm_ends_with(cmp, "_cmd")) {
454  "Support for the 'pcmk_*_cmd' stonith resource parameters"
455  " is deprecated and will be removed in a future version"
456  " (use 'pcmk_*_action' instead)");
457  }
458  }
459  }
460 }
461 
462 gboolean
463 common_unpack(xmlNode * xml_obj, resource_t ** rsc,
464  resource_t * parent, pe_working_set_t * data_set)
465 {
466  bool isdefault = FALSE;
467  xmlNode *expanded_xml = NULL;
468  xmlNode *ops = NULL;
469  resource_t *top = NULL;
470  const char *value = NULL;
471  const char *rclass = NULL; /* Look for this after any templates have been expanded */
472  const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
473  int container_remote_node = 0;
474  int baremetal_remote_node = 0;
475  bool has_versioned_params = FALSE;
476 
477  crm_log_xml_trace(xml_obj, "Processing resource input...");
478 
479  if (id == NULL) {
480  pe_err("Must specify id tag in <resource>");
481  return FALSE;
482 
483  } else if (rsc == NULL) {
484  pe_err("Nowhere to unpack resource into");
485  return FALSE;
486 
487  }
488 
489  if (unpack_template(xml_obj, &expanded_xml, data_set) == FALSE) {
490  return FALSE;
491  }
492 
493  *rsc = calloc(1, sizeof(resource_t));
494  (*rsc)->cluster = data_set;
495 
496  if (expanded_xml) {
497  crm_log_xml_trace(expanded_xml, "Expanded resource...");
498  (*rsc)->xml = expanded_xml;
499  (*rsc)->orig_xml = xml_obj;
500 
501  } else {
502  (*rsc)->xml = xml_obj;
503  (*rsc)->orig_xml = NULL;
504  }
505 
506  /* Do not use xml_obj from here on, use (*rsc)->xml in case templates are involved */
507  rclass = crm_element_value((*rsc)->xml, XML_AGENT_ATTR_CLASS);
508  (*rsc)->parent = parent;
509 
510  ops = find_xml_node((*rsc)->xml, "operations", FALSE);
511  (*rsc)->ops_xml = expand_idref(ops, data_set->input);
512 
513  (*rsc)->variant = get_resource_type(crm_element_name((*rsc)->xml));
514  if ((*rsc)->variant == pe_unknown) {
515  pe_err("Unknown resource type: %s", crm_element_name((*rsc)->xml));
516  free(*rsc);
517  return FALSE;
518  }
519 
520  (*rsc)->parameters = crm_str_table_new();
521 
522 #if ENABLE_VERSIONED_ATTRS
523  (*rsc)->versioned_parameters = create_xml_node(NULL, XML_TAG_RSC_VER_ATTRS);
524 #endif
525 
526  (*rsc)->meta = crm_str_table_new();
527 
528  (*rsc)->allowed_nodes =
529  g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_str);
530 
531  (*rsc)->known_on = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_str);
532 
533  value = crm_element_value((*rsc)->xml, XML_RSC_ATTR_INCARNATION);
534  if (value) {
535  (*rsc)->id = crm_concat(id, value, ':');
536  add_hash_param((*rsc)->meta, XML_RSC_ATTR_INCARNATION, value);
537 
538  } else {
539  (*rsc)->id = strdup(id);
540  }
541 
542  (*rsc)->fns = &resource_class_functions[(*rsc)->variant];
543  pe_rsc_trace((*rsc), "Unpacking resource...");
544 
545  get_meta_attributes((*rsc)->meta, *rsc, NULL, data_set);
546  get_rsc_attributes((*rsc)->parameters, *rsc, NULL, data_set);
547 #if ENABLE_VERSIONED_ATTRS
548  pe_get_versioned_attributes((*rsc)->versioned_parameters, *rsc, NULL, data_set);
549 #endif
550 
551  (*rsc)->flags = 0;
552  set_bit((*rsc)->flags, pe_rsc_runnable);
553  set_bit((*rsc)->flags, pe_rsc_provisional);
554 
555  if (is_set(data_set->flags, pe_flag_is_managed_default)) {
556  set_bit((*rsc)->flags, pe_rsc_managed);
557  }
558 
559  (*rsc)->rsc_cons = NULL;
560  (*rsc)->rsc_tickets = NULL;
561  (*rsc)->actions = NULL;
562  (*rsc)->role = RSC_ROLE_STOPPED;
563  (*rsc)->next_role = RSC_ROLE_UNKNOWN;
564 
565  (*rsc)->recovery_type = recovery_stop_start;
566  (*rsc)->stickiness = data_set->default_resource_stickiness;
567  (*rsc)->migration_threshold = INFINITY;
568  (*rsc)->failure_timeout = 0;
569 
570  value = g_hash_table_lookup((*rsc)->meta, XML_CIB_ATTR_PRIORITY);
571  (*rsc)->priority = crm_parse_int(value, "0");
572  (*rsc)->effective_priority = (*rsc)->priority;
573 
574  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_NOTIFY);
575  if (crm_is_true(value)) {
576  set_bit((*rsc)->flags, pe_rsc_notify);
577  }
578 
579  if (xml_contains_remote_node((*rsc)->xml)) {
580  (*rsc)->is_remote_node = TRUE;
581  if (g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_CONTAINER)) {
582  container_remote_node = 1;
583  } else {
584  baremetal_remote_node = 1;
585  }
586  }
587 
588  value = g_hash_table_lookup((*rsc)->meta, XML_OP_ATTR_ALLOW_MIGRATE);
589 #if ENABLE_VERSIONED_ATTRS
590  has_versioned_params = xml_has_children((*rsc)->versioned_parameters);
591 #endif
592  if (crm_is_true(value) && has_versioned_params) {
593  pe_rsc_trace((*rsc), "Migration is disabled for resources with versioned parameters");
594  } else if (crm_is_true(value)) {
595  set_bit((*rsc)->flags, pe_rsc_allow_migrate);
596  } else if ((value == NULL) && baremetal_remote_node && !has_versioned_params) {
597  /* by default, we want baremetal remote-nodes to be able
598  * to float around the cluster without having to stop all the
599  * resources within the remote-node before moving. Allowing
600  * migration support enables this feature. If this ever causes
601  * problems, migration support can be explicitly turned off with
602  * allow-migrate=false.
603  * We don't support migration for versioned resources, though. */
604  set_bit((*rsc)->flags, pe_rsc_allow_migrate);
605  }
606 
607  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MANAGED);
608  if (value != NULL && safe_str_neq("default", value)) {
609  gboolean bool_value = TRUE;
610 
611  crm_str_to_boolean(value, &bool_value);
612  if (bool_value == FALSE) {
613  clear_bit((*rsc)->flags, pe_rsc_managed);
614  } else {
615  set_bit((*rsc)->flags, pe_rsc_managed);
616  }
617  }
618 
619  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MAINTENANCE);
620  if (value != NULL && safe_str_neq("default", value)) {
621  gboolean bool_value = FALSE;
622 
623  crm_str_to_boolean(value, &bool_value);
624  if (bool_value == TRUE) {
625  clear_bit((*rsc)->flags, pe_rsc_managed);
626  set_bit((*rsc)->flags, pe_rsc_maintenance);
627  }
628 
629  }
630  if (is_set(data_set->flags, pe_flag_maintenance_mode)) {
631  clear_bit((*rsc)->flags, pe_rsc_managed);
632  set_bit((*rsc)->flags, pe_rsc_maintenance);
633  }
634 
635  pe_rsc_trace((*rsc), "Options for %s", (*rsc)->id);
636 
637  handle_rsc_isolation(*rsc);
638 
639  top = uber_parent(*rsc);
640  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_UNIQUE);
641  if (crm_is_true(value) || pe_rsc_is_clone(top) == FALSE) {
642  set_bit((*rsc)->flags, pe_rsc_unique);
643  }
644 
645  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_RESTART);
646  if (safe_str_eq(value, "restart")) {
647  (*rsc)->restart_type = pe_restart_restart;
648  pe_rsc_trace((*rsc), "\tDependency restart handling: restart");
649 
650  } else {
651  (*rsc)->restart_type = pe_restart_ignore;
652  pe_rsc_trace((*rsc), "\tDependency restart handling: ignore");
653  }
654 
655  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MULTIPLE);
656  if (safe_str_eq(value, "stop_only")) {
657  (*rsc)->recovery_type = recovery_stop_only;
658  pe_rsc_trace((*rsc), "\tMultiple running resource recovery: stop only");
659 
660  } else if (safe_str_eq(value, "block")) {
661  (*rsc)->recovery_type = recovery_block;
662  pe_rsc_trace((*rsc), "\tMultiple running resource recovery: block");
663 
664  } else {
665  (*rsc)->recovery_type = recovery_stop_start;
666  pe_rsc_trace((*rsc), "\tMultiple running resource recovery: stop/start");
667  }
668 
669  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_STICKINESS);
670  if (value != NULL && safe_str_neq("default", value)) {
671  (*rsc)->stickiness = char2score(value);
672  }
673 
674  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_FAIL_STICKINESS);
675  if (value != NULL && safe_str_neq("default", value)) {
676  (*rsc)->migration_threshold = char2score(value);
677 
678  } else if (value == NULL) {
679  /* Make a best-effort guess at a migration threshold for people with 0.6 configs
680  * try with underscores and hyphens, from both the resource and global defaults section
681  */
682  const char *legacy = NULL;
683 
684  legacy = g_hash_table_lookup((*rsc)->meta,
685  "resource-failure-stickiness");
686  if (legacy == NULL) {
687  legacy = g_hash_table_lookup((*rsc)->meta,
688  "resource_failure_stickiness");
689  }
690  if (legacy) {
691  value = legacy;
693  "Support for 'resource-failure-stickiness' resource meta-attribute"
694  " is deprecated and will be removed in a future release"
695  " (use 'migration-threshold' resource meta-attribute instead)");
696  }
697 
698  legacy = g_hash_table_lookup(data_set->config_hash,
699  "default-resource-failure-stickiness");
700  if (legacy == NULL) {
701  legacy = g_hash_table_lookup(data_set->config_hash,
702  "default_resource_failure_stickiness");
703  }
704  if (legacy) {
705  if (value == NULL) {
706  value = legacy;
707  }
709  "Support for 'default-resource-failure-stickiness' cluster option"
710  " is deprecated and will be removed in a future release"
711  " (use 'migration-threshold' in rsc_defaults instead)");
712  }
713 
714  if (value) {
715  int fail_sticky = char2score(value);
716 
717  if (fail_sticky == -INFINITY) {
718  (*rsc)->migration_threshold = 1;
719  pe_rsc_info((*rsc),
720  "Set a migration threshold of %d for %s based on a failure-stickiness of %s",
721  (*rsc)->migration_threshold, (*rsc)->id, value);
722 
723  } else if ((*rsc)->stickiness != 0 && fail_sticky != 0) {
724  (*rsc)->migration_threshold = (*rsc)->stickiness / fail_sticky;
725  if ((*rsc)->migration_threshold < 0) {
726  /* Make sure it's positive */
727  (*rsc)->migration_threshold = 0 - (*rsc)->migration_threshold;
728  }
729  (*rsc)->migration_threshold += 1;
730  pe_rsc_info((*rsc),
731  "Calculated a migration threshold for %s of %d based on a stickiness of %d/%s",
732  (*rsc)->id, (*rsc)->migration_threshold, (*rsc)->stickiness, value);
733  }
734  }
735  }
736 
739  set_bit((*rsc)->flags, pe_rsc_fence_device);
740  check_deprecated_stonith(*rsc);
741  }
742 
743  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_REQUIRES);
744 
745  handle_requires_pref:
746  if (safe_str_eq(value, "nothing")) {
747 
748  } else if (safe_str_eq(value, "quorum")) {
749  set_bit((*rsc)->flags, pe_rsc_needs_quorum);
750 
751  } else if (safe_str_eq(value, "unfencing")) {
752  if (is_set((*rsc)->flags, pe_rsc_fence_device)) {
753  crm_config_warn("%s is a fencing device but requires (un)fencing", (*rsc)->id);
754  value = "quorum";
755  isdefault = TRUE;
756  goto handle_requires_pref;
757 
758  } else if (is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
759  crm_config_warn("%s requires (un)fencing but fencing is disabled", (*rsc)->id);
760  value = "quorum";
761  isdefault = TRUE;
762  goto handle_requires_pref;
763 
764  } else {
765  set_bit((*rsc)->flags, pe_rsc_needs_fencing);
766  set_bit((*rsc)->flags, pe_rsc_needs_unfencing);
767  }
768 
769  } else if (safe_str_eq(value, "fencing")) {
770  set_bit((*rsc)->flags, pe_rsc_needs_fencing);
771  if (is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
772  crm_config_warn("%s requires fencing but fencing is disabled", (*rsc)->id);
773  }
774 
775  } else {
776  if (value) {
777  crm_config_err("Invalid value for %s->requires: %s%s",
778  (*rsc)->id, value,
779  is_set(data_set->flags, pe_flag_stonith_enabled) ? "" : " (stonith-enabled=false)");
780  }
781 
782  isdefault = TRUE;
783  if(is_set((*rsc)->flags, pe_rsc_fence_device)) {
784  value = "quorum";
785 
786  } else if (((*rsc)->variant == pe_native)
789  && safe_str_eq(crm_element_value((*rsc)->xml, XML_AGENT_ATTR_PROVIDER), "pacemaker")
790  && safe_str_eq(crm_element_value((*rsc)->xml, XML_ATTR_TYPE), "remote")
791  ) {
792  value = "quorum";
793 
794  } else if (is_set(data_set->flags, pe_flag_enable_unfencing)) {
795  value = "unfencing";
796 
797  } else if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
798  value = "fencing";
799 
800  } else if (data_set->no_quorum_policy == no_quorum_ignore) {
801  value = "nothing";
802 
803  } else {
804  value = "quorum";
805  }
806  goto handle_requires_pref;
807  }
808 
809  pe_rsc_trace((*rsc), "\tRequired to start: %s%s", value, isdefault?" (default)":"");
810  value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_FAIL_TIMEOUT);
811  if (value != NULL) {
812  /* call crm_get_msec() and convert back to seconds */
813  (*rsc)->failure_timeout = (crm_get_msec(value) / 1000);
814  }
815 
816  if (baremetal_remote_node) {
817  value = g_hash_table_lookup((*rsc)->parameters, XML_REMOTE_ATTR_RECONNECT_INTERVAL);
818  if (value) {
819  /* reconnect delay works by setting failure_timeout and preventing the
820  * connection from starting until the failure is cleared. */
821  (*rsc)->remote_reconnect_interval = (crm_get_msec(value) / 1000);
822  /* we want to override any default failure_timeout in use when remote
823  * reconnect_interval is in use. */
824  (*rsc)->failure_timeout = (*rsc)->remote_reconnect_interval;
825  }
826  }
827 
828  get_target_role(*rsc, &((*rsc)->next_role));
829  pe_rsc_trace((*rsc), "\tDesired next state: %s",
830  (*rsc)->next_role != RSC_ROLE_UNKNOWN ? role2text((*rsc)->next_role) : "default");
831 
832  if ((*rsc)->fns->unpack(*rsc, data_set) == FALSE) {
833  return FALSE;
834  }
835 
836  if (is_set(data_set->flags, pe_flag_symmetric_cluster)) {
837  // This tag must stay exactly the same because it is tested elsewhere
838  resource_location(*rsc, NULL, 0, "symmetric_default", data_set);
839  } else if (container_remote_node) {
840  /* remote resources tied to a container resource must always be allowed
841  * to opt-in to the cluster. Whether the connection resource is actually
842  * allowed to be placed on a node is dependent on the container resource */
843  resource_location(*rsc, NULL, 0, "remote_connection_default", data_set);
844  }
845 
846  pe_rsc_trace((*rsc), "\tAction notification: %s",
847  is_set((*rsc)->flags, pe_rsc_notify) ? "required" : "not required");
848 
849  (*rsc)->utilization = crm_str_table_new();
850 
851  unpack_instance_attributes(data_set->input, (*rsc)->xml, XML_TAG_UTILIZATION, NULL,
852  (*rsc)->utilization, NULL, FALSE, data_set->now);
853 
854 /* data_set->resources = g_list_append(data_set->resources, (*rsc)); */
855 
856  if (expanded_xml) {
857  if (add_template_rsc(xml_obj, data_set) == FALSE) {
858  return FALSE;
859  }
860  }
861  return TRUE;
862 }
863 
864 void
865 common_update_score(resource_t * rsc, const char *id, int score)
866 {
867  node_t *node = NULL;
868 
869  node = pe_hash_table_lookup(rsc->allowed_nodes, id);
870  if (node != NULL) {
871  pe_rsc_trace(rsc, "Updating score for %s on %s: %d + %d", rsc->id, id, node->weight, score);
872  node->weight = merge_weights(node->weight, score);
873  }
874 
875  if (rsc->children) {
876  GListPtr gIter = rsc->children;
877 
878  for (; gIter != NULL; gIter = gIter->next) {
879  resource_t *child_rsc = (resource_t *) gIter->data;
880 
881  common_update_score(child_rsc, id, score);
882  }
883  }
884 }
885 
886 gboolean
888 {
889  resource_t *parent = child;
890 
891  if (parent == NULL || rsc == NULL) {
892  return FALSE;
893  }
894  while (parent->parent != NULL) {
895  if (parent->parent == rsc) {
896  return TRUE;
897  }
898  parent = parent->parent;
899  }
900  return FALSE;
901 }
902 
903 resource_t *
905 {
906  resource_t *parent = rsc;
907 
908  if (parent == NULL) {
909  return NULL;
910  }
911  while (parent->parent != NULL && parent->parent->variant != pe_container) {
912  parent = parent->parent;
913  }
914  return parent;
915 }
916 
917 void
919 {
920  if (rsc == NULL) {
921  return;
922  }
923 
924  pe_rsc_trace(rsc, "Freeing %s %d", rsc->id, rsc->variant);
925 
926  g_list_free(rsc->rsc_cons);
927  g_list_free(rsc->rsc_cons_lhs);
928  g_list_free(rsc->rsc_tickets);
929  g_list_free(rsc->dangling_migrations);
930 
931  if (rsc->parameters != NULL) {
932  g_hash_table_destroy(rsc->parameters);
933  }
934 #if ENABLE_VERSIONED_ATTRS
935  if (rsc->versioned_parameters != NULL) {
936  free_xml(rsc->versioned_parameters);
937  }
938 #endif
939  if (rsc->meta != NULL) {
940  g_hash_table_destroy(rsc->meta);
941  }
942  if (rsc->utilization != NULL) {
943  g_hash_table_destroy(rsc->utilization);
944  }
945 
946  if (rsc->parent == NULL && is_set(rsc->flags, pe_rsc_orphan)) {
947  free_xml(rsc->xml);
948  rsc->xml = NULL;
949  free_xml(rsc->orig_xml);
950  rsc->orig_xml = NULL;
951 
952  /* if rsc->orig_xml, then rsc->xml is an expanded xml from a template */
953  } else if (rsc->orig_xml) {
954  free_xml(rsc->xml);
955  rsc->xml = NULL;
956  }
957  if (rsc->running_on) {
958  g_list_free(rsc->running_on);
959  rsc->running_on = NULL;
960  }
961  if (rsc->known_on) {
962  g_hash_table_destroy(rsc->known_on);
963  rsc->known_on = NULL;
964  }
965  if (rsc->actions) {
966  g_list_free(rsc->actions);
967  rsc->actions = NULL;
968  }
969  if (rsc->allowed_nodes) {
970  g_hash_table_destroy(rsc->allowed_nodes);
971  rsc->allowed_nodes = NULL;
972  }
973  g_list_free(rsc->fillers);
974  g_list_free(rsc->rsc_location);
975  pe_rsc_trace(rsc, "Resource freed");
976  free(rsc->id);
977  free(rsc->clone_name);
978  free(rsc->allocated_to);
979  free(rsc->variant_opaque);
980  free(rsc->pending_task);
981  free(rsc);
982 }
983 
999 pe_node_t *
1000 pe__find_active_on(const resource_t *rsc, unsigned int *count_all,
1001  unsigned int *count_clean)
1002 {
1003  pe_node_t *active = NULL;
1004  pe_node_t *node = NULL;
1005  bool keep_looking = FALSE;
1006  bool is_happy = FALSE;
1007 
1008  if (count_all) {
1009  *count_all = 0;
1010  }
1011  if (count_clean) {
1012  *count_clean = 0;
1013  }
1014  if (rsc == NULL) {
1015  return NULL;
1016  }
1017 
1018  for (GList *node_iter = rsc->running_on; node_iter != NULL;
1019  node_iter = node_iter->next) {
1020 
1021  node = node_iter->data;
1022  keep_looking = FALSE;
1023 
1024  is_happy = node->details->online && !node->details->unclean;
1025 
1026  if (count_all) {
1027  ++*count_all;
1028  }
1029  if (count_clean && is_happy) {
1030  ++*count_clean;
1031  }
1032  if (count_all || count_clean) {
1033  // If we're counting, we need to go through entire list
1034  keep_looking = TRUE;
1035  }
1036 
1037  if (rsc->partial_migration_source != NULL) {
1038  if (node->details == rsc->partial_migration_source->details) {
1039  // This is the migration source
1040  active = node;
1041  } else {
1042  keep_looking = TRUE;
1043  }
1044  } else if (is_not_set(rsc->flags, pe_rsc_needs_fencing)) {
1045  if (is_happy && (!active || !active->details->online
1046  || active->details->unclean)) {
1047  // This is the first clean node
1048  active = node;
1049  } else {
1050  keep_looking = TRUE;
1051  }
1052  }
1053  if (active == NULL) {
1054  // This is first node in list
1055  active = node;
1056  }
1057 
1058  if (keep_looking == FALSE) {
1059  // Don't waste time iterating if we don't have to
1060  break;
1061  }
1062  }
1063  return active;
1064 }
1065 
1079 pe_node_t *
1080 pe__find_active_requires(const resource_t *rsc, unsigned int *count)
1081 {
1082  if (rsc && is_not_set(rsc->flags, pe_rsc_needs_fencing)) {
1083  return pe__find_active_on(rsc, NULL, count);
1084  }
1085  return pe__find_active_on(rsc, count, NULL);
1086 }
1087 
1088 void
1090 {
1091  if (rsc->children != NULL) {
1092  for (GList *item = rsc->children; item != NULL; item = item->next) {
1093  ((pe_resource_t *) item->data)->fns->count(item->data);
1094  }
1095 
1096  } else if (is_not_set(rsc->flags, pe_rsc_orphan)
1097  || (rsc->role > RSC_ROLE_STOPPED)) {
1098  rsc->cluster->ninstances++;
1099  if (pe__resource_is_disabled(rsc)) {
1100  rsc->cluster->disabled_resources++;
1101  }
1102  if (is_set(rsc->flags, pe_rsc_block)) {
1103  rsc->cluster->blocked_resources++;
1104  }
1105  }
1106 }
#define LOG_TRACE
Definition: logging.h:29
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:1765
void container_free(resource_t *rsc)
Definition: container.c:1393
void clone_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
Definition: clone.c:361
void pe__count_common(pe_resource_t *rsc)
Definition: complex.c:1089
xmlNode * xml
Definition: status.h:294
void group_free(resource_t *rsc)
Definition: group.c:187
#define pe_flag_have_stonith_resource
Definition: status.h:75
gboolean safe_str_neq(const char *a, const char *b)
Definition: strings.c:182
#define INFINITY
Definition: crm.h:73
#define pe_rsc_needs_unfencing
Definition: status.h:254
GHashTable * utilization
Definition: status.h:335
gboolean get_target_role(resource_t *rsc, enum rsc_role_e *role)
Definition: utils.c:1802
#define XML_CIB_TAG_CONTAINER
Definition: msg_xml.h:200
#define pe_flag_enable_unfencing
Definition: status.h:76
int default_resource_stickiness
Definition: status.h:116
#define pe_rsc_maintenance
Definition: status.h:249
int weight
Definition: status.h:210
#define XML_ATTR_TYPE
Definition: msg_xml.h:105
#define XML_TAG_UTILIZATION
Definition: msg_xml.h:193
enum pe_obj_types get_resource_type(const char *name)
Definition: complex.c:77
#define RSC_ROLE_STARTED_S
Definition: common.h:93
#define crm_config_err(fmt...)
Definition: crm_internal.h:225
#define pe_rsc_needs_quorum
Definition: status.h:252
#define XML_RSC_ATTR_INCARNATION
Definition: msg_xml.h:212
void common_free(resource_t *rsc)
Definition: complex.c:918
#define pe_rsc_orphan
Definition: status.h:219
GListPtr rsc_location
Definition: status.h:321
char * native_parameter(resource_t *rsc, node_t *node, gboolean create, const char *name, pe_working_set_t *data_set)
Definition: native.c:315
int char2score(const char *score)
Definition: utils.c:221
pe_node_t * native_location(const pe_resource_t *rsc, GList **list, int current)
Definition: native.c:849
long long crm_get_msec(const char *input)
Definition: utils.c:589
#define pe_rsc_provisional
Definition: status.h:228
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1830
enum pe_obj_types variant
Definition: status.h:300
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:216
node_t * partial_migration_source
Definition: status.h:341
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
Definition: strings.c:157
#define XML_CIB_TAG_RSC_TEMPLATE
Definition: msg_xml.h:202
no_quorum_policy_t no_quorum_policy
Definition: status.h:117
#define XML_RSC_ATTR_STICKINESS
Definition: msg_xml.h:223
char * clone_name
Definition: status.h:293
xmlNode * orig_xml
Definition: status.h:295
#define clear_bit(word, bit)
Definition: crm_internal.h:211
enum rsc_role_e role
Definition: status.h:330
#define pe_rsc_allow_migrate
Definition: status.h:245
void native_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
Definition: native.c:799
GListPtr children
Definition: status.h:337
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:224
bool crm_starts_with(const char *str, const char *prefix)
Check whether a string starts with a certain sequence.
Definition: strings.c:284
void clone_free(resource_t *rsc)
Definition: clone.c:569
enum rsc_role_e group_resource_state(const resource_t *rsc, gboolean current)
Definition: group.c:208
char version[256]
Definition: plugin.c:84
char * id
Definition: status.h:292
GHashTable * parameters
Definition: status.h:334
#define XML_CIB_ATTR_PRIORITY
Definition: msg_xml.h:268
const char * isolation_wrapper
Definition: status.h:348
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2114
#define pe_rsc_block
Definition: status.h:221
#define XML_TAG_ATTR_SETS
Definition: msg_xml.h:185
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:160
gboolean container_unpack(resource_t *rsc, pe_working_set_t *data_set)
Definition: container.c:827
const char * role2text(enum rsc_role_e role)
Definition: common.c:365
struct node_shared_s * details
Definition: status.h:213
pe_working_set_t * cluster
Definition: status.h:352
#define set_bit(word, bit)
Definition: crm_internal.h:210
#define XML_RSC_ATTR_REQUIRES
Definition: msg_xml.h:228
#define PCMK_RESOURCE_CLASS_OCF
Definition: services.h:57
GListPtr rsc_cons_lhs
Definition: status.h:319
gboolean unclean
Definition: status.h:180
resource_object_functions_t resource_class_functions[]
Definition: complex.c:18
resource_t * uber_parent(resource_t *rsc)
Definition: complex.c:904
#define XML_RSC_ATTR_CONTAINER
Definition: msg_xml.h:230
#define XML_ATTR_ID
Definition: msg_xml.h:102
char * pending_task
Definition: status.h:346
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:393
#define XML_CIB_TAG_RESOURCE
Definition: msg_xml.h:196
#define XML_BOOLEAN_TRUE
Definition: msg_xml.h:117
#define XML_RSC_ATTR_ISOLATION
Definition: msg_xml.h:208
xmlNode * rsc_defaults
Definition: status.h:135
pe_obj_types
Definition: complex.h:20
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Replace an XML attribute with specified name and (possibly NULL) value.
Definition: nvpair.c:273
GHashTable * allowed_nodes
Definition: status.h:328
void * variant_opaque
Definition: status.h:299
GListPtr rsc_cons
Definition: status.h:320
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:1955
int blocked_resources
Definition: status.h:150
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:4314
#define XML_AGENT_ATTR_PROVIDER
Definition: msg_xml.h:258
#define pe_rsc_runnable
Definition: status.h:239
#define XML_TAG_META_SETS
Definition: msg_xml.h:186
GHashTable * config_hash
Definition: status.h:119
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
Definition: utils.c:2552
#define XML_RSC_ATTR_MANAGED
Definition: msg_xml.h:219
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1977
unsigned long long flags
Definition: status.h:316
enum rsc_role_e native_resource_state(const resource_t *rsc, gboolean current)
Definition: native.c:827
#define pe_flag_maintenance_mode
Definition: status.h:72
void group_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
Definition: group.c:138
resource_t * parent
Definition: status.h:298
gboolean native_active(resource_t *rsc, gboolean all)
Definition: native.c:360
GListPtr dangling_migrations
Definition: status.h:338
#define XML_TAG_RSC_VER_ATTRS
Definition: msg_xml.h:188
void free_xml(xmlNode *child)
Definition: xml.c:2108
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:3230
xmlNode * input
Definition: status.h:104
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:245
pe_node_t * pe__find_active_on(const resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
Definition: complex.c:1000
GListPtr fillers
Definition: status.h:344
GListPtr rsc_tickets
Definition: status.h:323
#define XML_REMOTE_ATTR_RECONNECT_INTERVAL
Definition: msg_xml.h:240
#define XML_RSC_ATTR_NOTIFY
Definition: msg_xml.h:222
void get_rsc_attributes(GHashTable *meta_hash, resource_t *rsc, node_t *node, pe_working_set_t *data_set)
Definition: complex.c:168
#define XML_RSC_ATTR_FAIL_STICKINESS
Definition: msg_xml.h:224
gboolean crm_ends_with(const char *s, const char *match)
Definition: strings.c:334
enum rsc_role_e clone_resource_state(const resource_t *rsc, gboolean current)
Definition: clone.c:603
void populate_hash(xmlNode *nvpair_list, GHashTable *hash, const char **attrs, int attrs_length)
gboolean is_parent(resource_t *child, resource_t *rsc)
Definition: complex.c:887
#define XML_RSC_ATTR_UNIQUE
Definition: msg_xml.h:221
#define crm_config_warn(fmt...)
Definition: crm_internal.h:226
GListPtr actions
Definition: status.h:322
#define PCMK_RESOURCE_CLASS_STONITH
Definition: services.h:64
void get_meta_attributes(GHashTable *meta_hash, resource_t *rsc, node_t *node, pe_working_set_t *data_set)
Definition: complex.c:125
int crm_str_to_boolean(const char *s, int *ret)
Definition: strings.c:208
#define pe_rsc_unique
Definition: status.h:225
gboolean clone_active(resource_t *rsc, gboolean all)
Definition: clone.c:228
GHashTable * meta
Definition: status.h:333
gboolean xml_contains_remote_node(xmlNode *xml)
Definition: remote.c:81
#define XML_CIB_TAG_INCARNATION
Definition: msg_xml.h:198
#define XML_RSC_ATTR_MAINTENANCE
Definition: msg_xml.h:232
#define XML_RSC_ATTR_FAIL_TIMEOUT
Definition: msg_xml.h:225
void add_hash_param(GHashTable *hash, const char *name, const char *value)
Definition: common.c:442
void resource_location(resource_t *rsc, node_t *node, int score, const char *tag, pe_working_set_t *data_set)
Definition: utils.c:1628
int disabled_resources
Definition: status.h:151
gboolean group_active(resource_t *rsc, gboolean all)
Definition: group.c:93
pe_node_t * pe__find_active_requires(const resource_t *rsc, unsigned int *count)
Definition: complex.c:1080
const char * get_resource_typename(enum pe_obj_types type)
Definition: complex.c:99
enum rsc_role_e container_resource_state(const resource_t *rsc, gboolean current)
Definition: container.c:1426
GHashTable * attrs
Definition: status.h:192
gboolean online
Definition: status.h:176
#define RSC_ROLE_SLAVE_S
Definition: common.h:94
int compare_version(const char *version1, const char *version2)
Definition: utils.c:477
int merge_weights(int w1, int w2)
Definition: common.c:405
#define pe_rsc_managed
Definition: status.h:220
#define crm_str_hash
Definition: util.h:75
#define XML_RSC_ATTR_MULTIPLE
Definition: msg_xml.h:226
#define XML_ATTR_CRM_VERSION
Definition: msg_xml.h:84
void container_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
Definition: container.c:1293
node_t * allocated_to
Definition: status.h:325
void common_update_score(resource_t *rsc, const char *id, int score)
Definition: complex.c:865
gboolean container_active(resource_t *rsc, gboolean all)
Definition: container.c:1127
GHashTable * known_on
Definition: status.h:327
#define XML_RSC_ATTR_RESTART
Definition: msg_xml.h:209
#define XML_CIB_TAG_MASTER
Definition: msg_xml.h:199
void native_free(resource_t *rsc)
Definition: native.c:820
gboolean native_unpack(resource_t *rsc, pe_working_set_t *data_set)
Definition: native.c:190
#define RSC_ROLE_UNKNOWN_S
Definition: common.h:91
void unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, crm_time_t *now)
Definition: rules.c:922
#define pe_flag_is_managed_default
Definition: status.h:71
#define crm_log_xml_trace(xml, text)
Definition: logging.h:288
Definition: status.h:209
gboolean crm_is_true(const char *s)
Definition: strings.c:197
#define XML_CIB_TAG_GROUP
Definition: msg_xml.h:197
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:16
#define pe_flag_symmetric_cluster
Definition: status.h:70
char * crm_concat(const char *prefix, const char *suffix, char join)
Definition: strings.c:33
bool pe__resource_is_disabled(pe_resource_t *rsc)
Definition: utils.c:2690
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
Definition: complex.c:463
unsigned long long flags
Definition: status.h:113
#define ID(x)
Definition: msg_xml.h:452
#define pe_err(fmt...)
Definition: internal.h:18
#define pe_rsc_needs_fencing
Definition: status.h:253
#define safe_str_eq(a, b)
Definition: util.h:74
gboolean group_unpack(resource_t *rsc, pe_working_set_t *data_set)
Definition: group.c:22
#define pe_rsc_fence_device
Definition: status.h:226
GList * GListPtr
Definition: crm.h:210
#define pe_rsc_notify
Definition: status.h:224
crm_time_t * now
Definition: status.h:105
void g_hash_destroy_str(gpointer data)
Definition: strings.c:75
GHashTable * template_rsc_sets
Definition: status.h:146
void pe__count_bundle(pe_resource_t *rsc)
Definition: container.c:1453
resource_t * native_find_rsc(resource_t *rsc, const char *id, node_t *node, int flags)
Definition: native.c:261
#define XML_OP_ATTR_ALLOW_MIGRATE
Definition: msg_xml.h:244
#define pe_flag_stonith_enabled
Definition: status.h:74
enum crm_ais_msg_types type
Definition: internal.h:79
#define pe_warn_once(pe_wo_bit, fmt...)
Definition: unpack.h:116
#define pe_rsc_info(rsc, fmt, args...)
Definition: internal.h:14
gboolean clone_unpack(resource_t *rsc, pe_working_set_t *data_set)
Definition: clone.c:128
#define XML_AGENT_ATTR_CLASS
Definition: msg_xml.h:257
gboolean master_unpack(resource_t *rsc, pe_working_set_t *data_set)
Definition: clone.c:110
GListPtr running_on
Definition: status.h:326