This source file includes following definitions.
- get_resource_type
- get_resource_typename
- dup_attr
- get_meta_attributes
- get_rsc_attributes
- pe_get_versioned_attributes
- template_op_key
- unpack_template
- add_template_rsc
- handle_rsc_isolation
- check_deprecated_stonith
- common_unpack
- common_update_score
- is_parent
- uber_parent
- common_free
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20
21 #include <crm/pengine/rules.h>
22 #include <crm/pengine/internal.h>
23 #include <crm/msg_xml.h>
24
25 #include <unpack.h>
26
27 void populate_hash(xmlNode * nvpair_list, GHashTable * hash, const char **attrs, int attrs_length);
28
29 resource_object_functions_t resource_class_functions[] = {
30 {
31 native_unpack,
32 native_find_rsc,
33 native_parameter,
34 native_print,
35 native_active,
36 native_resource_state,
37 native_location,
38 native_free
39 },
40 {
41 group_unpack,
42 native_find_rsc,
43 native_parameter,
44 group_print,
45 group_active,
46 group_resource_state,
47 native_location,
48 group_free
49 },
50 {
51 clone_unpack,
52 native_find_rsc,
53 native_parameter,
54 clone_print,
55 clone_active,
56 clone_resource_state,
57 native_location,
58 clone_free
59 },
60 {
61 master_unpack,
62 native_find_rsc,
63 native_parameter,
64 clone_print,
65 clone_active,
66 clone_resource_state,
67 native_location,
68 clone_free
69 },
70 {
71 container_unpack,
72 native_find_rsc,
73 native_parameter,
74 container_print,
75 container_active,
76 container_resource_state,
77 native_location,
78 container_free
79 }
80 };
81
82 enum pe_obj_types
83 get_resource_type(const char *name)
84 {
85 if (safe_str_eq(name, XML_CIB_TAG_RESOURCE)) {
86 return pe_native;
87
88 } else if (safe_str_eq(name, XML_CIB_TAG_GROUP)) {
89 return pe_group;
90
91 } else if (safe_str_eq(name, XML_CIB_TAG_INCARNATION)) {
92 return pe_clone;
93
94 } else if (safe_str_eq(name, XML_CIB_TAG_MASTER)) {
95 return pe_master;
96
97 } else if (safe_str_eq(name, XML_CIB_TAG_CONTAINER)) {
98 return pe_container;
99 }
100
101 return pe_unknown;
102 }
103
104 const char *
105 get_resource_typename(enum pe_obj_types type)
106 {
107 switch (type) {
108 case pe_native:
109 return XML_CIB_TAG_RESOURCE;
110 case pe_group:
111 return XML_CIB_TAG_GROUP;
112 case pe_clone:
113 return XML_CIB_TAG_INCARNATION;
114 case pe_master:
115 return XML_CIB_TAG_MASTER;
116 case pe_container:
117 return XML_CIB_TAG_CONTAINER;
118 case pe_unknown:
119 return "unknown";
120 }
121 return "<unknown>";
122 }
123
124 static void
125 dup_attr(gpointer key, gpointer value, gpointer user_data)
126 {
127 add_hash_param(user_data, key, value);
128 }
129
130 void
131 get_meta_attributes(GHashTable * meta_hash, resource_t * rsc,
132 node_t * node, pe_working_set_t * data_set)
133 {
134 GHashTable *node_hash = NULL;
135 const char *version = crm_element_value(data_set->input, XML_ATTR_CRM_VERSION);
136
137 if (node) {
138 node_hash = node->details->attrs;
139 }
140
141 if (rsc->xml) {
142 xmlAttrPtr xIter = NULL;
143
144 for (xIter = rsc->xml->properties; xIter; xIter = xIter->next) {
145 const char *prop_name = (const char *)xIter->name;
146 const char *prop_value = crm_element_value(rsc->xml, prop_name);
147
148 add_hash_param(meta_hash, prop_name, prop_value);
149 }
150 }
151
152 unpack_instance_attributes(data_set->input, rsc->xml, XML_TAG_META_SETS, node_hash,
153 meta_hash, NULL, FALSE, data_set->now);
154
155 if(version == NULL || compare_version(version, "3.0.9") < 0) {
156
157
158
159 unpack_instance_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
160 meta_hash, NULL, FALSE, data_set->now);
161 }
162
163
164 if (rsc->parent != NULL) {
165 g_hash_table_foreach(rsc->parent->meta, dup_attr, meta_hash);
166 }
167
168
169 unpack_instance_attributes(data_set->input, data_set->rsc_defaults, XML_TAG_META_SETS,
170 node_hash, meta_hash, NULL, FALSE, data_set->now);
171 }
172
173 void
174 get_rsc_attributes(GHashTable * meta_hash, resource_t * rsc,
175 node_t * node, pe_working_set_t * data_set)
176 {
177 GHashTable *node_hash = NULL;
178
179 if (node) {
180 node_hash = node->details->attrs;
181 }
182
183 unpack_instance_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
184 meta_hash, NULL, FALSE, data_set->now);
185
186
187 if (rsc->parent != NULL) {
188 get_rsc_attributes(meta_hash, rsc->parent, node, data_set);
189
190 } else {
191
192 unpack_instance_attributes(data_set->input, data_set->rsc_defaults, XML_TAG_ATTR_SETS,
193 node_hash, meta_hash, NULL, FALSE, data_set->now);
194 }
195 }
196
197 #if ENABLE_VERSIONED_ATTRS
198 void
199 pe_get_versioned_attributes(xmlNode * meta_hash, resource_t * rsc,
200 node_t * node, pe_working_set_t * data_set)
201 {
202 GHashTable *node_hash = NULL;
203
204 if (node) {
205 node_hash = node->details->attrs;
206 }
207
208 pe_unpack_versioned_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
209 meta_hash, data_set->now);
210
211
212 if (rsc->parent != NULL) {
213 pe_get_versioned_attributes(meta_hash, rsc->parent, node, data_set);
214
215 } else {
216
217 pe_unpack_versioned_attributes(data_set->input, data_set->rsc_defaults, XML_TAG_ATTR_SETS,
218 node_hash, meta_hash, data_set->now);
219 }
220 }
221 #endif
222
223 static char *
224 template_op_key(xmlNode * op)
225 {
226 const char *name = crm_element_value(op, "name");
227 const char *role = crm_element_value(op, "role");
228 char *key = NULL;
229
230 if (role == NULL || crm_str_eq(role, RSC_ROLE_STARTED_S, TRUE)
231 || crm_str_eq(role, RSC_ROLE_SLAVE_S, TRUE)) {
232 role = RSC_ROLE_UNKNOWN_S;
233 }
234
235 key = crm_concat(name, role, '-');
236 return key;
237 }
238
239 static gboolean
240 unpack_template(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
241 {
242 xmlNode *cib_resources = NULL;
243 xmlNode *template = NULL;
244 xmlNode *new_xml = NULL;
245 xmlNode *child_xml = NULL;
246 xmlNode *rsc_ops = NULL;
247 xmlNode *template_ops = NULL;
248 const char *template_ref = NULL;
249 const char *clone = NULL;
250 const char *id = NULL;
251
252 if (xml_obj == NULL) {
253 pe_err("No resource object for template unpacking");
254 return FALSE;
255 }
256
257 template_ref = crm_element_value(xml_obj, XML_CIB_TAG_RSC_TEMPLATE);
258 if (template_ref == NULL) {
259 return TRUE;
260 }
261
262 id = ID(xml_obj);
263 if (id == NULL) {
264 pe_err("'%s' object must have a id", crm_element_name(xml_obj));
265 return FALSE;
266 }
267
268 if (crm_str_eq(template_ref, id, TRUE)) {
269 pe_err("The resource object '%s' should not reference itself", id);
270 return FALSE;
271 }
272
273 cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE);
274 if (cib_resources == NULL) {
275 pe_err("No resources configured");
276 return FALSE;
277 }
278
279 template = find_entity(cib_resources, XML_CIB_TAG_RSC_TEMPLATE, template_ref);
280 if (template == NULL) {
281 pe_err("No template named '%s'", template_ref);
282 return FALSE;
283 }
284
285 new_xml = copy_xml(template);
286 xmlNodeSetName(new_xml, xml_obj->name);
287 crm_xml_replace(new_xml, XML_ATTR_ID, id);
288
289 clone = crm_element_value(xml_obj, XML_RSC_ATTR_INCARNATION);
290 if(clone) {
291 crm_xml_add(new_xml, XML_RSC_ATTR_INCARNATION, clone);
292 }
293
294 template_ops = find_xml_node(new_xml, "operations", FALSE);
295
296 for (child_xml = __xml_first_child(xml_obj); child_xml != NULL;
297 child_xml = __xml_next_element(child_xml)) {
298 xmlNode *new_child = NULL;
299
300 new_child = add_node_copy(new_xml, child_xml);
301
302 if (crm_str_eq((const char *)new_child->name, "operations", TRUE)) {
303 rsc_ops = new_child;
304 }
305 }
306
307 if (template_ops && rsc_ops) {
308 xmlNode *op = NULL;
309 GHashTable *rsc_ops_hash =
310 g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, NULL);
311
312 for (op = __xml_first_child(rsc_ops); op != NULL; op = __xml_next_element(op)) {
313 char *key = template_op_key(op);
314
315 g_hash_table_insert(rsc_ops_hash, key, op);
316 }
317
318 for (op = __xml_first_child(template_ops); op != NULL; op = __xml_next_element(op)) {
319 char *key = template_op_key(op);
320
321 if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) {
322 add_node_copy(rsc_ops, op);
323 }
324
325 free(key);
326 }
327
328 if (rsc_ops_hash) {
329 g_hash_table_destroy(rsc_ops_hash);
330 }
331
332 free_xml(template_ops);
333 }
334
335
336 *expanded_xml = new_xml;
337
338
339
340
341
342
343
344
345
346 return TRUE;
347 }
348
349 static gboolean
350 add_template_rsc(xmlNode * xml_obj, pe_working_set_t * data_set)
351 {
352 const char *template_ref = NULL;
353 const char *id = NULL;
354
355 if (xml_obj == NULL) {
356 pe_err("No resource object for processing resource list of template");
357 return FALSE;
358 }
359
360 template_ref = crm_element_value(xml_obj, XML_CIB_TAG_RSC_TEMPLATE);
361 if (template_ref == NULL) {
362 return TRUE;
363 }
364
365 id = ID(xml_obj);
366 if (id == NULL) {
367 pe_err("'%s' object must have a id", crm_element_name(xml_obj));
368 return FALSE;
369 }
370
371 if (crm_str_eq(template_ref, id, TRUE)) {
372 pe_err("The resource object '%s' should not reference itself", id);
373 return FALSE;
374 }
375
376 if (add_tag_ref(data_set->template_rsc_sets, template_ref, id) == FALSE) {
377 return FALSE;
378 }
379
380 return TRUE;
381 }
382
383 static void
384 handle_rsc_isolation(resource_t *rsc)
385 {
386 resource_t *top = uber_parent(rsc);
387 resource_t *iso = rsc;
388 const char *wrapper = NULL;
389 const char *value;
390
391
392
393
394 value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ISOLATION);
395 if (top->isolation_wrapper == NULL && (value == NULL || crm_is_true(value))) {
396 if (g_hash_table_lookup(rsc->parameters, "pcmk_docker_image")) {
397 wrapper = "docker-wrapper";
398 }
399
400 } else if (top->isolation_wrapper) {
401 goto set_rsc_opts;
402 }
403
404 if (wrapper == NULL) {
405 return;
406 }
407
408
409
410
411
412 if (top == rsc->parent && pe_rsc_is_clone(top)) {
413 iso = top;
414 }
415
416 iso->isolation_wrapper = wrapper;
417 set_bit(top->flags, pe_rsc_unique);
418
419 set_rsc_opts:
420 pe_warn_once(pe_wo_isolation, "Support for 'isolation' resource meta-attribute"
421 " is deprecated and will be removed in a future release"
422 " (use bundle syntax instead)");
423
424 clear_bit(rsc->flags, pe_rsc_allow_migrate);
425 set_bit(rsc->flags, pe_rsc_unique);
426 if (pe_rsc_is_clone(top)) {
427 add_hash_param(rsc->meta, XML_RSC_ATTR_UNIQUE, XML_BOOLEAN_TRUE);
428 }
429 }
430
431 static void
432 check_deprecated_stonith(resource_t *rsc)
433 {
434 GHashTableIter iter;
435 char *key;
436
437 g_hash_table_iter_init(&iter, rsc->parameters);
438 while (g_hash_table_iter_next(&iter, (gpointer *) &key, NULL)) {
439 if (crm_starts_with(key, "pcmk_")) {
440 char *cmp = key + 5;
441
442 if (!strcmp(cmp, "poweroff_action")) {
443 pe_warn_once(pe_wo_poweroff,
444 "Support for the 'pcmk_poweroff_action' stonith resource parameter"
445 " is deprecated and will be removed in a future version"
446 " (use 'pcmk_off_action' instead)");
447
448 } else if (!strcmp(cmp, "arg_map")) {
449 pe_warn_once(pe_wo_arg_map,
450 "Support for the 'pcmk_arg_map' stonith resource parameter"
451 " is deprecated and will be removed in a future version"
452 " (use 'pcmk_host_argument' instead)");
453
454 } else if (crm_ends_with(cmp, "_cmd")) {
455 pe_warn_once(pe_wo_stonith_cmd,
456 "Support for the 'pcmk_*_cmd' stonith resource parameters"
457 " is deprecated and will be removed in a future version"
458 " (use 'pcmk_*_action' instead)");
459 }
460 }
461 }
462 }
463
464 gboolean
465 common_unpack(xmlNode * xml_obj, resource_t ** rsc,
466 resource_t * parent, pe_working_set_t * data_set)
467 {
468 bool isdefault = FALSE;
469 xmlNode *expanded_xml = NULL;
470 xmlNode *ops = NULL;
471 resource_t *top = NULL;
472 const char *value = NULL;
473 const char *rclass = NULL;
474 const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
475 int container_remote_node = 0;
476 int baremetal_remote_node = 0;
477 bool has_versioned_params = FALSE;
478
479 crm_log_xml_trace(xml_obj, "Processing resource input...");
480
481 if (id == NULL) {
482 pe_err("Must specify id tag in <resource>");
483 return FALSE;
484
485 } else if (rsc == NULL) {
486 pe_err("Nowhere to unpack resource into");
487 return FALSE;
488
489 }
490
491 if (unpack_template(xml_obj, &expanded_xml, data_set) == FALSE) {
492 return FALSE;
493 }
494
495 *rsc = calloc(1, sizeof(resource_t));
496 (*rsc)->cluster = data_set;
497
498 if (expanded_xml) {
499 crm_log_xml_trace(expanded_xml, "Expanded resource...");
500 (*rsc)->xml = expanded_xml;
501 (*rsc)->orig_xml = xml_obj;
502
503 } else {
504 (*rsc)->xml = xml_obj;
505 (*rsc)->orig_xml = NULL;
506 }
507
508
509 rclass = crm_element_value((*rsc)->xml, XML_AGENT_ATTR_CLASS);
510 (*rsc)->parent = parent;
511
512 ops = find_xml_node((*rsc)->xml, "operations", FALSE);
513 (*rsc)->ops_xml = expand_idref(ops, data_set->input);
514
515 (*rsc)->variant = get_resource_type(crm_element_name((*rsc)->xml));
516 if ((*rsc)->variant == pe_unknown) {
517 pe_err("Unknown resource type: %s", crm_element_name((*rsc)->xml));
518 free(*rsc);
519 return FALSE;
520 }
521
522 (*rsc)->parameters = crm_str_table_new();
523
524 #if ENABLE_VERSIONED_ATTRS
525 (*rsc)->versioned_parameters = create_xml_node(NULL, XML_TAG_RSC_VER_ATTRS);
526 #endif
527
528 (*rsc)->meta = crm_str_table_new();
529
530 (*rsc)->allowed_nodes =
531 g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_str);
532
533 (*rsc)->known_on = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_str);
534
535 value = crm_element_value((*rsc)->xml, XML_RSC_ATTR_INCARNATION);
536 if (value) {
537 (*rsc)->id = crm_concat(id, value, ':');
538 add_hash_param((*rsc)->meta, XML_RSC_ATTR_INCARNATION, value);
539
540 } else {
541 (*rsc)->id = strdup(id);
542 }
543
544 (*rsc)->fns = &resource_class_functions[(*rsc)->variant];
545 pe_rsc_trace((*rsc), "Unpacking resource...");
546
547 get_meta_attributes((*rsc)->meta, *rsc, NULL, data_set);
548 get_rsc_attributes((*rsc)->parameters, *rsc, NULL, data_set);
549 #if ENABLE_VERSIONED_ATTRS
550 pe_get_versioned_attributes((*rsc)->versioned_parameters, *rsc, NULL, data_set);
551 #endif
552
553 (*rsc)->flags = 0;
554 set_bit((*rsc)->flags, pe_rsc_runnable);
555 set_bit((*rsc)->flags, pe_rsc_provisional);
556
557 if (is_set(data_set->flags, pe_flag_is_managed_default)) {
558 set_bit((*rsc)->flags, pe_rsc_managed);
559 }
560
561 (*rsc)->rsc_cons = NULL;
562 (*rsc)->rsc_tickets = NULL;
563 (*rsc)->actions = NULL;
564 (*rsc)->role = RSC_ROLE_STOPPED;
565 (*rsc)->next_role = RSC_ROLE_UNKNOWN;
566
567 (*rsc)->recovery_type = recovery_stop_start;
568 (*rsc)->stickiness = data_set->default_resource_stickiness;
569 (*rsc)->migration_threshold = INFINITY;
570 (*rsc)->failure_timeout = 0;
571
572 value = g_hash_table_lookup((*rsc)->meta, XML_CIB_ATTR_PRIORITY);
573 (*rsc)->priority = crm_parse_int(value, "0");
574 (*rsc)->effective_priority = (*rsc)->priority;
575
576 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_NOTIFY);
577 if (crm_is_true(value)) {
578 set_bit((*rsc)->flags, pe_rsc_notify);
579 }
580
581 if (xml_contains_remote_node((*rsc)->xml)) {
582 (*rsc)->is_remote_node = TRUE;
583 if (g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_CONTAINER)) {
584 container_remote_node = 1;
585 } else {
586 baremetal_remote_node = 1;
587 }
588 }
589
590 value = g_hash_table_lookup((*rsc)->meta, XML_OP_ATTR_ALLOW_MIGRATE);
591 #if ENABLE_VERSIONED_ATTRS
592 has_versioned_params = xml_has_children((*rsc)->versioned_parameters);
593 #endif
594 if (crm_is_true(value) && has_versioned_params) {
595 pe_rsc_trace((*rsc), "Migration is disabled for resources with versioned parameters");
596 } else if (crm_is_true(value)) {
597 set_bit((*rsc)->flags, pe_rsc_allow_migrate);
598 } else if ((value == NULL) && baremetal_remote_node && !has_versioned_params) {
599
600
601
602
603
604
605
606 set_bit((*rsc)->flags, pe_rsc_allow_migrate);
607 }
608
609 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MANAGED);
610 if (value != NULL && safe_str_neq("default", value)) {
611 gboolean bool_value = TRUE;
612
613 crm_str_to_boolean(value, &bool_value);
614 if (bool_value == FALSE) {
615 clear_bit((*rsc)->flags, pe_rsc_managed);
616 } else {
617 set_bit((*rsc)->flags, pe_rsc_managed);
618 }
619 }
620
621 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MAINTENANCE);
622 if (value != NULL && safe_str_neq("default", value)) {
623 gboolean bool_value = FALSE;
624
625 crm_str_to_boolean(value, &bool_value);
626 if (bool_value == TRUE) {
627 clear_bit((*rsc)->flags, pe_rsc_managed);
628 set_bit((*rsc)->flags, pe_rsc_maintenance);
629 }
630
631 } else if (is_set(data_set->flags, pe_flag_maintenance_mode)) {
632 clear_bit((*rsc)->flags, pe_rsc_managed);
633 set_bit((*rsc)->flags, pe_rsc_maintenance);
634 }
635
636 pe_rsc_trace((*rsc), "Options for %s", (*rsc)->id);
637
638 handle_rsc_isolation(*rsc);
639
640 top = uber_parent(*rsc);
641 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_UNIQUE);
642 if (crm_is_true(value) || pe_rsc_is_clone(top) == FALSE) {
643 set_bit((*rsc)->flags, pe_rsc_unique);
644 }
645
646 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_RESTART);
647 if (safe_str_eq(value, "restart")) {
648 (*rsc)->restart_type = pe_restart_restart;
649 pe_rsc_trace((*rsc), "\tDependency restart handling: restart");
650
651 } else {
652 (*rsc)->restart_type = pe_restart_ignore;
653 pe_rsc_trace((*rsc), "\tDependency restart handling: ignore");
654 }
655
656 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MULTIPLE);
657 if (safe_str_eq(value, "stop_only")) {
658 (*rsc)->recovery_type = recovery_stop_only;
659 pe_rsc_trace((*rsc), "\tMultiple running resource recovery: stop only");
660
661 } else if (safe_str_eq(value, "block")) {
662 (*rsc)->recovery_type = recovery_block;
663 pe_rsc_trace((*rsc), "\tMultiple running resource recovery: block");
664
665 } else {
666 (*rsc)->recovery_type = recovery_stop_start;
667 pe_rsc_trace((*rsc), "\tMultiple running resource recovery: stop/start");
668 }
669
670 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_STICKINESS);
671 if (value != NULL && safe_str_neq("default", value)) {
672 (*rsc)->stickiness = char2score(value);
673 }
674
675 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_FAIL_STICKINESS);
676 if (value != NULL && safe_str_neq("default", value)) {
677 (*rsc)->migration_threshold = char2score(value);
678
679 } else if (value == NULL) {
680
681
682
683 const char *legacy = NULL;
684
685 legacy = g_hash_table_lookup((*rsc)->meta,
686 "resource-failure-stickiness");
687 if (legacy == NULL) {
688 legacy = g_hash_table_lookup((*rsc)->meta,
689 "resource_failure_stickiness");
690 }
691 if (legacy) {
692 value = legacy;
693 pe_warn_once(pe_wo_rsc_failstick,
694 "Support for 'resource-failure-stickiness' resource meta-attribute"
695 " is deprecated and will be removed in a future release"
696 " (use 'migration-threshold' resource meta-attribute instead)");
697 }
698
699 legacy = g_hash_table_lookup(data_set->config_hash,
700 "default-resource-failure-stickiness");
701 if (legacy == NULL) {
702 legacy = g_hash_table_lookup(data_set->config_hash,
703 "default_resource_failure_stickiness");
704 }
705 if (legacy) {
706 if (value == NULL) {
707 value = legacy;
708 }
709 pe_warn_once(pe_wo_default_rscfs,
710 "Support for 'default-resource-failure-stickiness' cluster option"
711 " is deprecated and will be removed in a future release"
712 " (use 'migration-threshold' in rsc_defaults instead)");
713 }
714
715 if (value) {
716 int fail_sticky = char2score(value);
717
718 if (fail_sticky == -INFINITY) {
719 (*rsc)->migration_threshold = 1;
720 pe_rsc_info((*rsc),
721 "Set a migration threshold of %d for %s based on a failure-stickiness of %s",
722 (*rsc)->migration_threshold, (*rsc)->id, value);
723
724 } else if ((*rsc)->stickiness != 0 && fail_sticky != 0) {
725 (*rsc)->migration_threshold = (*rsc)->stickiness / fail_sticky;
726 if ((*rsc)->migration_threshold < 0) {
727
728 (*rsc)->migration_threshold = 0 - (*rsc)->migration_threshold;
729 }
730 (*rsc)->migration_threshold += 1;
731 pe_rsc_info((*rsc),
732 "Calculated a migration threshold for %s of %d based on a stickiness of %d/%s",
733 (*rsc)->id, (*rsc)->migration_threshold, (*rsc)->stickiness, value);
734 }
735 }
736 }
737
738 if (safe_str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH)) {
739 set_bit(data_set->flags, pe_flag_have_stonith_resource);
740 set_bit((*rsc)->flags, pe_rsc_fence_device);
741 check_deprecated_stonith(*rsc);
742 }
743
744 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_REQUIRES);
745
746 handle_requires_pref:
747 if (safe_str_eq(value, "nothing")) {
748
749 } else if (safe_str_eq(value, "quorum")) {
750 set_bit((*rsc)->flags, pe_rsc_needs_quorum);
751
752 } else if (safe_str_eq(value, "unfencing")) {
753 if (is_set((*rsc)->flags, pe_rsc_fence_device)) {
754 crm_config_warn("%s is a fencing device but requires (un)fencing", (*rsc)->id);
755 value = "quorum";
756 isdefault = TRUE;
757 goto handle_requires_pref;
758
759 } else if (is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
760 crm_config_warn("%s requires (un)fencing but fencing is disabled", (*rsc)->id);
761 value = "quorum";
762 isdefault = TRUE;
763 goto handle_requires_pref;
764
765 } else {
766 set_bit((*rsc)->flags, pe_rsc_needs_fencing);
767 set_bit((*rsc)->flags, pe_rsc_needs_unfencing);
768 }
769
770 } else if (safe_str_eq(value, "fencing")) {
771 set_bit((*rsc)->flags, pe_rsc_needs_fencing);
772 if (is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
773 crm_config_warn("%s requires fencing but fencing is disabled", (*rsc)->id);
774 }
775
776 } else {
777 if (value) {
778 crm_config_err("Invalid value for %s->requires: %s%s",
779 (*rsc)->id, value,
780 is_set(data_set->flags, pe_flag_stonith_enabled) ? "" : " (stonith-enabled=false)");
781 }
782
783 isdefault = TRUE;
784 if(is_set((*rsc)->flags, pe_rsc_fence_device)) {
785 value = "quorum";
786
787 } else if (is_set(data_set->flags, pe_flag_enable_unfencing)) {
788 value = "unfencing";
789
790 } else if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
791 value = "fencing";
792
793 } else if (data_set->no_quorum_policy == no_quorum_ignore) {
794 value = "nothing";
795
796 } else {
797 value = "quorum";
798 }
799 goto handle_requires_pref;
800 }
801
802 pe_rsc_trace((*rsc), "\tRequired to start: %s%s", value, isdefault?" (default)":"");
803 value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_FAIL_TIMEOUT);
804 if (value != NULL) {
805
806 (*rsc)->failure_timeout = (crm_get_msec(value) / 1000);
807 }
808
809 if (baremetal_remote_node) {
810 value = g_hash_table_lookup((*rsc)->parameters, XML_REMOTE_ATTR_RECONNECT_INTERVAL);
811 if (value) {
812
813
814 (*rsc)->remote_reconnect_interval = (crm_get_msec(value) / 1000);
815
816
817 (*rsc)->failure_timeout = (*rsc)->remote_reconnect_interval;
818 }
819 }
820
821 get_target_role(*rsc, &((*rsc)->next_role));
822 pe_rsc_trace((*rsc), "\tDesired next state: %s",
823 (*rsc)->next_role != RSC_ROLE_UNKNOWN ? role2text((*rsc)->next_role) : "default");
824
825 if ((*rsc)->fns->unpack(*rsc, data_set) == FALSE) {
826 return FALSE;
827 }
828
829 if (is_set(data_set->flags, pe_flag_symmetric_cluster)) {
830
831 resource_location(*rsc, NULL, 0, "symmetric_default", data_set);
832 } else if (container_remote_node) {
833
834
835
836 resource_location(*rsc, NULL, 0, "remote_connection_default", data_set);
837 }
838
839 pe_rsc_trace((*rsc), "\tAction notification: %s",
840 is_set((*rsc)->flags, pe_rsc_notify) ? "required" : "not required");
841
842 (*rsc)->utilization = crm_str_table_new();
843
844 unpack_instance_attributes(data_set->input, (*rsc)->xml, XML_TAG_UTILIZATION, NULL,
845 (*rsc)->utilization, NULL, FALSE, data_set->now);
846
847
848
849 if (expanded_xml) {
850 if (add_template_rsc(xml_obj, data_set) == FALSE) {
851 return FALSE;
852 }
853 }
854 return TRUE;
855 }
856
857 void
858 common_update_score(resource_t * rsc, const char *id, int score)
859 {
860 node_t *node = NULL;
861
862 node = pe_hash_table_lookup(rsc->allowed_nodes, id);
863 if (node != NULL) {
864 pe_rsc_trace(rsc, "Updating score for %s on %s: %d + %d", rsc->id, id, node->weight, score);
865 node->weight = merge_weights(node->weight, score);
866 }
867
868 if (rsc->children) {
869 GListPtr gIter = rsc->children;
870
871 for (; gIter != NULL; gIter = gIter->next) {
872 resource_t *child_rsc = (resource_t *) gIter->data;
873
874 common_update_score(child_rsc, id, score);
875 }
876 }
877 }
878
879 gboolean
880 is_parent(resource_t *child, resource_t *rsc)
881 {
882 resource_t *parent = child;
883
884 if (parent == NULL || rsc == NULL) {
885 return FALSE;
886 }
887 while (parent->parent != NULL) {
888 if (parent->parent == rsc) {
889 return TRUE;
890 }
891 parent = parent->parent;
892 }
893 return FALSE;
894 }
895
896 resource_t *
897 uber_parent(resource_t * rsc)
898 {
899 resource_t *parent = rsc;
900
901 if (parent == NULL) {
902 return NULL;
903 }
904 while (parent->parent != NULL && parent->parent->variant != pe_container) {
905 parent = parent->parent;
906 }
907 return parent;
908 }
909
910 void
911 common_free(resource_t * rsc)
912 {
913 if (rsc == NULL) {
914 return;
915 }
916
917 pe_rsc_trace(rsc, "Freeing %s %d", rsc->id, rsc->variant);
918
919 g_list_free(rsc->rsc_cons);
920 g_list_free(rsc->rsc_cons_lhs);
921 g_list_free(rsc->rsc_tickets);
922 g_list_free(rsc->dangling_migrations);
923
924 if (rsc->parameters != NULL) {
925 g_hash_table_destroy(rsc->parameters);
926 }
927 #if ENABLE_VERSIONED_ATTRS
928 if (rsc->versioned_parameters != NULL) {
929 free_xml(rsc->versioned_parameters);
930 }
931 #endif
932 if (rsc->meta != NULL) {
933 g_hash_table_destroy(rsc->meta);
934 }
935 if (rsc->utilization != NULL) {
936 g_hash_table_destroy(rsc->utilization);
937 }
938
939 if (rsc->parent == NULL && is_set(rsc->flags, pe_rsc_orphan)) {
940 free_xml(rsc->xml);
941 rsc->xml = NULL;
942 free_xml(rsc->orig_xml);
943 rsc->orig_xml = NULL;
944
945
946 } else if (rsc->orig_xml) {
947 free_xml(rsc->xml);
948 rsc->xml = NULL;
949 }
950 if (rsc->running_on) {
951 g_list_free(rsc->running_on);
952 rsc->running_on = NULL;
953 }
954 if (rsc->known_on) {
955 g_hash_table_destroy(rsc->known_on);
956 rsc->known_on = NULL;
957 }
958 if (rsc->actions) {
959 g_list_free(rsc->actions);
960 rsc->actions = NULL;
961 }
962 if (rsc->allowed_nodes) {
963 g_hash_table_destroy(rsc->allowed_nodes);
964 rsc->allowed_nodes = NULL;
965 }
966 g_list_free(rsc->fillers);
967 g_list_free(rsc->rsc_location);
968 pe_rsc_trace(rsc, "Resource freed");
969 free(rsc->id);
970 free(rsc->clone_name);
971 free(rsc->allocated_to);
972 free(rsc->variant_opaque);
973 free(rsc->pending_task);
974 free(rsc);
975 }