This source file includes following definitions.
- add_expected_result
- pcmk__probe_resource_list
- probe_then_start
- guest_resource_will_stop
- probe_action
- pcmk__probe_rsc_on_node
- probe_needed_before_action
- add_probe_orderings_for_stops
- add_restart_orderings_for_probe
- clear_actions_tracking_flag
- add_restart_orderings_for_rsc
- order_then_probes
- pcmk__order_probes
- pcmk__schedule_probes
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13
14 #include <crm/crm.h>
15 #include <crm/pengine/status.h>
16 #include <pacemaker-internal.h>
17 #include "libpacemaker_private.h"
18
19
20
21
22
23
24
25
26
27 static void
28 add_expected_result(pe_action_t *probe, pe_resource_t *rsc, pe_node_t *node)
29 {
30
31 pe_node_t *running = pe_find_node_id(rsc->running_on, node->details->id);
32
33
34 if (running == NULL) {
35 pe__add_action_expected_result(probe, CRM_EX_NOT_RUNNING);
36
37 } else if (rsc->role == RSC_ROLE_PROMOTED) {
38 pe__add_action_expected_result(probe, CRM_EX_PROMOTED);
39 }
40 }
41
42
43
44
45
46
47
48
49
50
51 bool
52 pcmk__probe_resource_list(GList *rscs, pe_node_t *node)
53 {
54 bool any_created = false;
55
56 for (GList *iter = rscs; iter != NULL; iter = iter->next) {
57 pe_resource_t *rsc = (pe_resource_t *) iter->data;
58
59 if (rsc->cmds->create_probe(rsc, node)) {
60 any_created = true;
61 }
62 }
63 return any_created;
64 }
65
66
67
68
69
70
71
72
73 static void
74 probe_then_start(pe_resource_t *rsc1, pe_resource_t *rsc2)
75 {
76 if ((rsc1->allocated_to != NULL)
77 && (g_hash_table_lookup(rsc1->known_on,
78 rsc1->allocated_to->details->id) == NULL)) {
79
80 pcmk__new_ordering(rsc1, pcmk__op_key(rsc1->id, RSC_STATUS, 0), NULL,
81 rsc2, pcmk__op_key(rsc2->id, RSC_START, 0), NULL,
82 pe_order_optional, rsc1->cluster);
83 }
84 }
85
86
87
88
89
90
91
92
93
94 static bool
95 guest_resource_will_stop(pe_node_t *node)
96 {
97 pe_resource_t *guest_rsc = node->details->remote_rsc->container;
98
99
100
101
102 return node->details->remote_requires_reset
103 || node->details->unclean
104 || pcmk_is_set(guest_rsc->flags, pe_rsc_failed)
105 || (guest_rsc->next_role == RSC_ROLE_STOPPED)
106
107
108 || ((guest_rsc->role > RSC_ROLE_STOPPED)
109 && (guest_rsc->allocated_to != NULL)
110 && (pe_find_node(guest_rsc->running_on,
111 guest_rsc->allocated_to->details->uname) == NULL));
112 }
113
114
115
116
117
118
119
120
121
122
123 static pe_action_t *
124 probe_action(pe_resource_t *rsc, pe_node_t *node)
125 {
126 pe_action_t *probe = NULL;
127 char *key = pcmk__op_key(rsc->id, RSC_STATUS, 0);
128
129 crm_debug("Scheduling probe of %s %s on %s",
130 role2text(rsc->role), rsc->id, pe__node_name(node));
131
132 probe = custom_action(rsc, key, RSC_STATUS, node, FALSE, TRUE,
133 rsc->cluster);
134 pe__clear_action_flags(probe, pe_action_optional);
135
136 pcmk__order_vs_unfence(rsc, node, probe, pe_order_optional);
137 add_expected_result(probe, rsc, node);
138 return probe;
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152 bool
153 pcmk__probe_rsc_on_node(pe_resource_t *rsc, pe_node_t *node)
154 {
155 uint32_t flags = pe_order_optional;
156 pe_action_t *probe = NULL;
157 pe_node_t *allowed = NULL;
158 pe_resource_t *top = uber_parent(rsc);
159 const char *reason = NULL;
160
161 CRM_CHECK((rsc != NULL) && (node != NULL), return false);
162
163 if (!pcmk_is_set(rsc->cluster->flags, pe_flag_startup_probes)) {
164 reason = "start-up probes are disabled";
165 goto no_probe;
166 }
167
168 if (pe__is_guest_or_remote_node(node)) {
169 const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
170
171 if (pcmk__str_eq(class, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_none)) {
172 reason = "Pacemaker Remote nodes cannot run stonith agents";
173 goto no_probe;
174
175 } else if (pe__is_guest_node(node)
176 && pe__resource_contains_guest_node(rsc->cluster, rsc)) {
177 reason = "guest nodes cannot run resources containing guest nodes";
178 goto no_probe;
179
180 } else if (rsc->is_remote_node) {
181 reason = "Pacemaker Remote nodes cannot host remote connections";
182 goto no_probe;
183 }
184 }
185
186
187 if (rsc->children != NULL) {
188 return pcmk__probe_resource_list(rsc->children, node);
189 }
190
191 if ((rsc->container != NULL) && !rsc->is_remote_node) {
192 reason = "resource is inside a container";
193 goto no_probe;
194
195 } else if (pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
196 reason = "resource is orphaned";
197 goto no_probe;
198
199 } else if (g_hash_table_lookup(rsc->known_on, node->details->id) != NULL) {
200 reason = "resource state is already known";
201 goto no_probe;
202 }
203
204 allowed = g_hash_table_lookup(rsc->allowed_nodes, node->details->id);
205
206 if (rsc->exclusive_discover || top->exclusive_discover) {
207
208
209 if (allowed == NULL) {
210
211 reason = "resource has exclusive discovery but is not allowed "
212 "on node";
213 goto no_probe;
214
215 } else if (allowed->rsc_discover_mode != pe_discover_exclusive) {
216
217 reason = "resource has exclusive discovery but is not enabled "
218 "on node";
219 goto no_probe;
220 }
221 }
222
223 if (allowed == NULL) {
224 allowed = node;
225 }
226 if (allowed->rsc_discover_mode == pe_discover_never) {
227 reason = "node has discovery disabled";
228 goto no_probe;
229 }
230
231 if (pe__is_guest_node(node)) {
232 pe_resource_t *guest = node->details->remote_rsc->container;
233
234 if (guest->role == RSC_ROLE_STOPPED) {
235
236 reason = "node's guest is stopped";
237 probe_then_start(guest, top);
238 goto no_probe;
239
240 } else if (guest_resource_will_stop(node)) {
241 reason = "node's guest will stop";
242
243
244 pcmk__new_ordering(guest, pcmk__op_key(guest->id, RSC_STOP, 0),
245 NULL, top, pcmk__op_key(top->id, RSC_START, 0),
246 NULL, pe_order_optional, rsc->cluster);
247 goto no_probe;
248 }
249 }
250
251
252 probe = probe_action(rsc, node);
253
254
255
256
257 if ((pcmk_is_set(rsc->flags, pe_rsc_fence_device)
258 && pcmk_is_set(rsc->cluster->flags, pe_flag_enable_unfencing))
259 || !pe_rsc_is_clone(top)) {
260 top = rsc;
261 }
262
263 if (!pcmk_is_set(probe->flags, pe_action_runnable)
264 && (rsc->running_on == NULL)) {
265
266
267
268 pe__set_order_flags(flags, pe_order_runnable_left);
269 }
270
271
272 pcmk__new_ordering(rsc, NULL, probe,
273 top, pcmk__op_key(top->id, RSC_START, 0), NULL,
274 flags, rsc->cluster);
275 pcmk__new_ordering(rsc, NULL, probe, top, reload_key(rsc), NULL,
276 pe_order_optional, rsc->cluster);
277
278 return true;
279
280 no_probe:
281 pe_rsc_trace(rsc,
282 "Skipping probe for %s on %s because %s",
283 rsc->id, node->details->id, reason);
284 return false;
285 }
286
287
288
289
290
291
292
293
294
295
296 static bool
297 probe_needed_before_action(pe_action_t *probe, pe_action_t *then)
298 {
299
300 if (pcmk__str_eq(then->task, CRM_OP_FENCE, pcmk__str_casei)
301 && (probe->node != NULL) && (then->node != NULL)
302 && (probe->node->details == then->node->details)) {
303 const char *op = g_hash_table_lookup(then->meta, "stonith_action");
304
305 if (pcmk__str_eq(op, "on", pcmk__str_casei)) {
306 return false;
307 }
308 }
309
310
311 if (pcmk__str_eq(then->task, CRM_OP_SHUTDOWN, pcmk__str_none)
312 && (probe->node != NULL) && (then->node != NULL)
313 && (probe->node->details != then->node->details)) {
314 return false;
315 }
316
317
318 return true;
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334 static void
335 add_probe_orderings_for_stops(pe_working_set_t *data_set)
336 {
337 for (GList *iter = data_set->ordering_constraints; iter != NULL;
338 iter = iter->next) {
339
340 pe__ordering_t *order = iter->data;
341 uint32_t order_flags = pe_order_optional;
342 GList *probes = NULL;
343 GList *then_actions = NULL;
344
345
346 if (order->flags == pe_order_none) {
347 continue;
348 }
349
350
351 if ((order->lh_rsc == NULL) || (order->lh_rsc == order->rh_rsc)) {
352 continue;
353 }
354
355
356 if (((order->lh_action == NULL) && (order->lh_action_task == NULL)) ||
357 ((order->rh_action == NULL) && (order->rh_action_task == NULL))) {
358 continue;
359 }
360
361
362 if ((order->lh_action != NULL)
363 && !pcmk__str_eq(order->lh_action->task, RSC_STOP, pcmk__str_none)) {
364 continue;
365 } else if ((order->lh_action == NULL)
366 && !pcmk__ends_with(order->lh_action_task, "_" RSC_STOP "_0")) {
367 continue;
368 }
369
370
371
372
373
374 if ((order->rh_rsc != NULL)
375 && (order->lh_rsc->container == order->rh_rsc)) {
376
377 if ((order->rh_action != NULL)
378 && pcmk__str_eq(order->rh_action->task, RSC_STOP,
379 pcmk__str_none)) {
380 continue;
381 } else if ((order->rh_action == NULL)
382 && pcmk__ends_with(order->rh_action_task,
383 "_" RSC_STOP "_0")) {
384 continue;
385 }
386 }
387
388
389 if (pcmk_is_set(order->flags, pe_order_apply_first_non_migratable)) {
390 pe__set_order_flags(order_flags,
391 pe_order_apply_first_non_migratable);
392 }
393 if (pcmk_is_set(order->flags, pe_order_same_node)) {
394 pe__set_order_flags(order_flags, pe_order_same_node);
395 }
396
397
398 if ((order->flags == pe_order_anti_colocation)
399 || (order->flags == pe_order_load)) {
400 order_flags = order->flags;
401 }
402
403
404 probes = pe__resource_actions(order->lh_rsc, NULL, RSC_STATUS, FALSE);
405 if (probes == NULL) {
406 continue;
407 }
408
409
410 if (order->rh_action != NULL) {
411 then_actions = g_list_prepend(NULL, order->rh_action);
412
413 } else if (order->rh_rsc != NULL) {
414 then_actions = find_actions(order->rh_rsc->actions,
415 order->rh_action_task, NULL);
416 if (then_actions == NULL) {
417 g_list_free(probes);
418 continue;
419 }
420 }
421
422 crm_trace("Implying 'probe then' orderings for '%s then %s' "
423 "(id=%d, type=%.6x)",
424 order->lh_action? order->lh_action->uuid : order->lh_action_task,
425 order->rh_action? order->rh_action->uuid : order->rh_action_task,
426 order->id, order->flags);
427
428 for (GList *probe_iter = probes; probe_iter != NULL;
429 probe_iter = probe_iter->next) {
430
431 pe_action_t *probe = (pe_action_t *) probe_iter->data;
432
433 for (GList *then_iter = then_actions; then_iter != NULL;
434 then_iter = then_iter->next) {
435
436 pe_action_t *then = (pe_action_t *) then_iter->data;
437
438 if (probe_needed_before_action(probe, then)) {
439 order_actions(probe, then, order_flags);
440 }
441 }
442 }
443
444 g_list_free(then_actions);
445 g_list_free(probes);
446 }
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462 static void
463 add_restart_orderings_for_probe(pe_action_t *probe, pe_action_t *after,
464 pe_working_set_t *data_set)
465 {
466 GList *iter = NULL;
467 bool interleave = false;
468 pe_resource_t *compatible_rsc = NULL;
469
470
471 if ((after == NULL) || (probe == NULL) || (probe->rsc == NULL)
472 || (probe->rsc->variant != pe_native)
473 || !pcmk__str_eq(probe->task, RSC_STATUS, pcmk__str_casei)) {
474 return;
475 }
476
477
478 if (pcmk_is_set(after->flags, pe_action_tracking)) {
479 return;
480 }
481 pe__set_action_flags(after, pe_action_tracking);
482
483 crm_trace("Adding probe restart orderings for '%s@%s then %s@%s'",
484 probe->uuid, pe__node_name(probe->node),
485 after->uuid, pe__node_name(after->node));
486
487
488
489
490 if ((after->rsc != NULL) && (after->rsc->variant == pe_native)
491 && (probe->rsc != after->rsc)) {
492
493 GList *then_actions = NULL;
494
495 if (pcmk__str_eq(after->task, RSC_START, pcmk__str_casei)) {
496 then_actions = pe__resource_actions(after->rsc, NULL, RSC_STOP,
497 FALSE);
498
499 } else if (pcmk__str_eq(after->task, RSC_PROMOTE, pcmk__str_casei)) {
500 then_actions = pe__resource_actions(after->rsc, NULL,
501 RSC_DEMOTE, FALSE);
502 }
503
504 for (iter = then_actions; iter != NULL; iter = iter->next) {
505 pe_action_t *then = (pe_action_t *) iter->data;
506
507
508 if (!pcmk_is_set(then->flags, pe_action_pseudo)) {
509 order_actions(probe, then, pe_order_optional);
510 }
511 }
512 g_list_free(then_actions);
513 }
514
515
516
517
518 if ((after->rsc != NULL)
519 && (after->rsc->variant > pe_group)) {
520 const char *interleave_s = g_hash_table_lookup(after->rsc->meta,
521 XML_RSC_ATTR_INTERLEAVE);
522
523 interleave = crm_is_true(interleave_s);
524 if (interleave) {
525 compatible_rsc = find_compatible_child(probe->rsc,
526 after->rsc,
527 RSC_ROLE_UNKNOWN,
528 FALSE);
529 }
530 }
531
532
533
534
535
536 for (iter = after->actions_after; iter != NULL; iter = iter->next) {
537 pe_action_wrapper_t *after_wrapper = (pe_action_wrapper_t *) iter->data;
538
539
540
541
542
543
544
545
546
547 if (!pcmk_is_set(after_wrapper->type, pe_order_implies_then)) {
548
549
550
551
552
553
554
555 if ((after->rsc == NULL)
556 || (after->rsc->variant < pe_group)
557 || (probe->rsc->parent == after->rsc)
558 || (after_wrapper->action->rsc == NULL)
559 || (after_wrapper->action->rsc->variant > pe_group)
560 || (after->rsc != after_wrapper->action->rsc->parent)) {
561 continue;
562 }
563
564
565
566
567 if ((after->rsc->variant > pe_group) && interleave
568 && ((compatible_rsc == NULL)
569 || (compatible_rsc != after_wrapper->action->rsc))) {
570 continue;
571 }
572 }
573
574 crm_trace("Recursively adding probe restart orderings for "
575 "'%s@%s then %s@%s' (type=%#.6x)",
576 after->uuid, pe__node_name(after->node),
577 after_wrapper->action->uuid,
578 pe__node_name(after_wrapper->action->node),
579 after_wrapper->type);
580
581 add_restart_orderings_for_probe(probe, after_wrapper->action, data_set);
582 }
583 }
584
585
586
587
588
589
590
591 static void
592 clear_actions_tracking_flag(pe_working_set_t *data_set)
593 {
594 GList *gIter = NULL;
595
596 for (gIter = data_set->actions; gIter != NULL; gIter = gIter->next) {
597 pe_action_t *action = (pe_action_t *) gIter->data;
598
599 pe__clear_action_flags(action, pe_action_tracking);
600 }
601 }
602
603
604
605
606
607
608
609
610 static void
611 add_restart_orderings_for_rsc(pe_resource_t *rsc, pe_working_set_t *data_set)
612 {
613 GList *probes = NULL;
614
615
616 if (rsc->variant != pe_native) {
617 g_list_foreach(rsc->children, (GFunc) add_restart_orderings_for_rsc,
618 data_set);
619 return;
620 }
621
622
623 probes = pe__resource_actions(rsc, NULL, RSC_STATUS, FALSE);
624
625
626 for (GList *iter = probes; iter != NULL; iter = iter->next) {
627 pe_action_t *probe = (pe_action_t *) iter->data;
628
629 for (GList *then_iter = probe->actions_after; then_iter != NULL;
630 then_iter = then_iter->next) {
631
632 pe_action_wrapper_t *then = (pe_action_wrapper_t *) then_iter->data;
633
634 add_restart_orderings_for_probe(probe, then->action, data_set);
635 clear_actions_tracking_flag(data_set);
636 }
637 }
638
639 g_list_free(probes);
640 }
641
642
643
644
645
646
647
648
649
650 static void
651 order_then_probes(pe_working_set_t *data_set)
652 {
653 #if 0
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683 for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
684 pe_resource_t *rsc = (pe_resource_t *) iter->data;
685
686 pe_action_t *start = NULL;
687 GList *actions = NULL;
688 GList *probes = NULL;
689
690 actions = pe__resource_actions(rsc, NULL, RSC_START, FALSE);
691
692 if (actions) {
693 start = actions->data;
694 g_list_free(actions);
695 }
696
697 if (start == NULL) {
698 crm_err("No start action for %s", rsc->id);
699 continue;
700 }
701
702 probes = pe__resource_actions(rsc, NULL, RSC_STATUS, FALSE);
703
704 for (actions = start->actions_before; actions != NULL;
705 actions = actions->next) {
706
707 pe_action_wrapper_t *before = (pe_action_wrapper_t *) actions->data;
708
709 pe_action_t *first = before->action;
710 pe_resource_t *first_rsc = first->rsc;
711
712 if (first->required_runnable_before) {
713 for (GList *clone_actions = first->actions_before;
714 clone_actions != NULL;
715 clone_actions = clone_actions->next) {
716
717 before = (pe_action_wrapper_t *) clone_actions->data;
718
719 crm_trace("Testing '%s then %s' for %s",
720 first->uuid, before->action->uuid, start->uuid);
721
722 CRM_ASSERT(before->action->rsc != NULL);
723 first_rsc = before->action->rsc;
724 break;
725 }
726
727 } else if (!pcmk__str_eq(first->task, RSC_START, pcmk__str_none)) {
728 crm_trace("Not a start op %s for %s", first->uuid, start->uuid);
729 }
730
731 if (first_rsc == NULL) {
732 continue;
733
734 } else if (uber_parent(first_rsc) == uber_parent(start->rsc)) {
735 crm_trace("Same parent %s for %s", first_rsc->id, start->uuid);
736 continue;
737
738 } else if (!pe_rsc_is_clone(uber_parent(first_rsc))) {
739 crm_trace("Not a clone %s for %s", first_rsc->id, start->uuid);
740 continue;
741 }
742
743 crm_err("Applying %s before %s %d", first->uuid, start->uuid,
744 uber_parent(first_rsc)->variant);
745
746 for (GList *probe_iter = probes; probe_iter != NULL;
747 probe_iter = probe_iter->next) {
748
749 pe_action_t *probe = (pe_action_t *) probe_iter->data;
750
751 crm_err("Ordering %s before %s", first->uuid, probe->uuid);
752 order_actions(first, probe, pe_order_optional);
753 }
754 }
755 }
756 #endif
757 }
758
759 void
760 pcmk__order_probes(pe_working_set_t *data_set)
761 {
762
763 g_list_foreach(data_set->resources, (GFunc) add_restart_orderings_for_rsc,
764 data_set);
765 add_probe_orderings_for_stops(data_set);
766
767 order_then_probes(data_set);
768 }
769
770
771
772
773
774
775
776
777
778 void
779 pcmk__schedule_probes(pe_working_set_t *data_set)
780 {
781
782 for (GList *iter = data_set->nodes; iter != NULL; iter = iter->next) {
783 pe_node_t *node = (pe_node_t *) iter->data;
784 const char *probed = NULL;
785
786 if (!node->details->online) {
787 if (pcmk__is_failed_remote_node(node)) {
788 pe_fence_node(data_set, node,
789 "the connection is unrecoverable", FALSE);
790 }
791 continue;
792
793 } else if (node->details->unclean) {
794 continue;
795
796 } else if (!node->details->rsc_discovery_enabled) {
797
798 continue;
799 }
800
801
802
803
804
805
806 probed = pe_node_attribute_raw(node, CRM_OP_PROBED);
807 if (probed != NULL && crm_is_true(probed) == FALSE) {
808 pe_action_t *probe_op = NULL;
809
810 probe_op = custom_action(NULL,
811 crm_strdup_printf("%s-%s", CRM_OP_REPROBE,
812 node->details->uname),
813 CRM_OP_REPROBE, node, FALSE, TRUE,
814 data_set);
815 add_hash_param(probe_op->meta, XML_ATTR_TE_NOWAIT,
816 XML_BOOLEAN_TRUE);
817 continue;
818 }
819
820
821 pcmk__probe_resource_list(data_set->resources, node);
822 }
823 }