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