pacemaker 2.1.5-a3f44794f94
Scalable High-Availability cluster resource manager
pcmk_sched_probes.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2022 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU General Public License version 2
7 * or later (GPLv2+) WITHOUT ANY WARRANTY.
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>
18
27static void
28add_expected_result(pe_action_t *probe, pe_resource_t *rsc, pe_node_t *node)
29{
30 // Check whether resource is currently active on node
31 pe_node_t *running = pe_find_node_id(rsc->running_on, node->details->id);
32
33 // The expected result is what we think the resource's current state is
34 if (running == NULL) {
36
37 } else if (rsc->role == RSC_ROLE_PROMOTED) {
39 }
40}
41
51bool
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
73static void
74probe_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
81 rsc2, pcmk__op_key(rsc2->id, RSC_START, 0), NULL,
83 }
84}
85
94static bool
95guest_resource_will_stop(pe_node_t *node)
96{
97 pe_resource_t *guest_rsc = node->details->remote_rsc->container;
98
99 /* Ideally, we'd check whether the guest has a required stop, but that
100 * information doesn't exist yet, so approximate it ...
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 // Guest is moving
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
123static pe_action_t *
124probe_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);
135
136 pcmk__order_vs_unfence(rsc, node, probe, pe_order_optional);
137 add_expected_result(probe, rsc, node);
138 return probe;
139}
140
152bool
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
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 // If this is a collective resource, probes are created for its children
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 // Exclusive discovery is enabled ...
208
209 if (allowed == NULL) {
210 // ... but this node is not allowed to run the resource
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 // ... but no constraint marks this node for discovery of resource
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 // The guest is stopped, so we know no resource is active there
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 // Order resource start after guest stop (in case it's restarting)
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 // We've eliminated all cases where a probe is not needed, so now it is
252 probe = probe_action(rsc, node);
253
254 /* Order the probe relative to the parent -- or the resource itself if
255 * cloned or a fence device when unfencing is used.
256 */
259 || !pe_rsc_is_clone(top)) {
260 top = rsc;
261 }
262
264 && (rsc->running_on == NULL)) {
265 /* Prevent the parent from starting if the resource can't, but don't
266 * cause the parent to stop if already active.
267 */
269 }
270
271 // Start or reload the parent after probing the resource
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,
277
278 return true;
279
280no_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
296static bool
297probe_needed_before_action(pe_action_t *probe, pe_action_t *then)
298{
299 // Probes on a node are performed after unfencing it, not before
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 // Probes should be done on a node before shutting it down
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 // Otherwise probes should always be done before any other action
318 return true;
319}
320
334static void
335add_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 // Skip disabled orderings
346 if (order->flags == pe_order_none) {
347 continue;
348 }
349
350 // Skip non-resource orderings, and orderings for the same resource
351 if ((order->lh_rsc == NULL) || (order->lh_rsc == order->rh_rsc)) {
352 continue;
353 }
354
355 // Skip invalid orderings (shouldn't be possible)
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 // Skip orderings for first actions other than stop
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 /* Do not imply a probe ordering for a resource inside of a stopping
371 * container. Otherwise, it might introduce a transition loop, since a
372 * probe could be scheduled after the container starts again.
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,
380 continue;
381 } else if ((order->rh_action == NULL)
383 "_" RSC_STOP "_0")) {
384 continue;
385 }
386 }
387
388 // Preserve certain order options for future filtering
390 pe__set_order_flags(order_flags,
392 }
393 if (pcmk_is_set(order->flags, pe_order_same_node)) {
395 }
396
397 // Preserve certain order types for future filtering
398 if ((order->flags == pe_order_anti_colocation)
399 || (order->flags == pe_order_load)) {
400 order_flags = order->flags;
401 }
402
403 // List all scheduled probes for the first resource
404 probes = pe__resource_actions(order->lh_rsc, NULL, RSC_STATUS, FALSE);
405 if (probes == NULL) { // There aren't any
406 continue;
407 }
408
409 // List all relevant "then" actions
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) { // There aren't any
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
462static void
463add_restart_orderings_for_probe(pe_action_t *probe, pe_action_t *after,
465{
466 GList *iter = NULL;
467 bool interleave = false;
468 pe_resource_t *compatible_rsc = NULL;
469
470 // Validate that this is a resource probe followed by some action
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 // Avoid running into any possible loop
478 if (pcmk_is_set(after->flags, pe_action_tracking)) {
479 return;
480 }
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 /* Add restart orderings if "then" is for a different primitive.
488 * Orderings for collective resources will be added later.
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 // Skip pseudo-actions (for example, those implied by fencing)
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 /* Detect whether "then" is an interleaved clone action. For these, we want
516 * to add orderings only for the relevant instance.
517 */
518 if ((after->rsc != NULL)
519 && (after->rsc->variant > pe_group)) {
520 const char *interleave_s = g_hash_table_lookup(after->rsc->meta,
522
523 interleave = crm_is_true(interleave_s);
524 if (interleave) {
525 compatible_rsc = find_compatible_child(probe->rsc,
526 after->rsc,
528 FALSE);
529 }
530 }
531
532 /* Now recursively do the same for all actions ordered after "then". This
533 * also handles collective resources since the collective action will be
534 * ordered before its individual instances' actions.
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 /* pe_order_implies_then is the reason why a required A.start
540 * implies/enforces B.start to be required too, which is the cause of
541 * B.restart/re-promote.
542 *
543 * Not sure about pe_order_implies_then_on_node though. It's now only
544 * used for unfencing case, which tends to introduce transition
545 * loops...
546 */
547 if (!pcmk_is_set(after_wrapper->type, pe_order_implies_then)) {
548 /* The order type between a group/clone and its child such as
549 * B.start-> B_child.start is:
550 * pe_order_implies_first_printed | pe_order_runnable_left
551 *
552 * Proceed through the ordering chain and build dependencies with
553 * its children.
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 /* Proceed to the children of a group or a non-interleaved clone.
565 * For an interleaved clone, proceed only to the relevant child.
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
591static void
592clear_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
600 }
601}
602
610static void
611add_restart_orderings_for_rsc(pe_resource_t *rsc, pe_working_set_t *data_set)
612{
613 GList *probes = NULL;
614
615 // For collective resources, order each instance recursively
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 // Find all probes for given resource
623 probes = pe__resource_actions(rsc, NULL, RSC_STATUS, FALSE);
624
625 // Add probe restart orderings for each probe found
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
650static void
651order_then_probes(pe_working_set_t *data_set)
652{
653#if 0
654 /* Given an ordering "A then B", we would prefer to wait for A to be started
655 * before probing B.
656 *
657 * For example, if A is a filesystem which B can't even run without, it
658 * would be helpful if the author of B's agent could assume that A is
659 * running before B.monitor will be called.
660 *
661 * However, we can't _only_ probe after A is running, otherwise we wouldn't
662 * detect the state of B if A could not be started. We can't even do an
663 * opportunistic version of this, because B may be moving:
664 *
665 * A.stop -> A.start -> B.probe -> B.stop -> B.start
666 *
667 * and if we add B.stop -> A.stop here, we get a loop:
668 *
669 * A.stop -> A.start -> B.probe -> B.stop -> A.stop
670 *
671 * We could kill the "B.probe -> B.stop" dependency, but that could mean
672 * stopping B "too" soon, because B.start must wait for the probe, and
673 * we don't want to stop B if we can't start it.
674 *
675 * We could add the ordering only if A is an anonymous clone with
676 * clone-max == node-max (since we'll never be moving it). However, we could
677 * still be stopping one instance at the same time as starting another.
678 *
679 * The complexity of checking for allowed conditions combined with the ever
680 * narrowing use case suggests that this code should remain disabled until
681 * someone gets smarter.
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
759void
761{
762 // Add orderings for "probe then X"
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
778void
780{
781 // Schedule probes on each node in the cluster as needed
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) { // Don't probe offline nodes
787 if (pcmk__is_failed_remote_node(node)) {
789 "the connection is unrecoverable", FALSE);
790 }
791 continue;
792
793 } else if (node->details->unclean) { // ... or nodes that need fencing
794 continue;
795
796 } else if (!node->details->rsc_discovery_enabled) {
797 // The user requested that probes not be done on this node
798 continue;
799 }
800
801 /* This is no longer needed for live clusters, since the probe_complete
802 * node attribute will never be in the CIB. However this is still useful
803 * for processing old saved CIBs (< 1.1.14), including the
804 * reprobe-target_rc regression test.
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,
812 node->details->uname),
813 CRM_OP_REPROBE, node, FALSE, TRUE,
814 data_set);
817 continue;
818 }
819
820 // Probe each resource in the cluster on this node, as needed
822 }
823}
#define PCMK_RESOURCE_CLASS_STONITH
Definition: agents.h:33
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
Definition: operations.c:45
uint64_t flags
Definition: remote.c:3
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
gboolean crm_is_true(const char *s)
Definition: strings.c:416
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:121
const char * role2text(enum rsc_role_e role)
Definition: common.c:454
@ RSC_ROLE_STOPPED
Definition: common.h:94
@ RSC_ROLE_PROMOTED
Definition: common.h:97
@ RSC_ROLE_UNKNOWN
Definition: common.h:93
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:912
A dumping ground.
#define RSC_PROMOTE
Definition: crm.h:205
#define RSC_DEMOTE
Definition: crm.h:207
#define CRM_OP_SHUTDOWN
Definition: crm.h:143
#define CRM_OP_REPROBE
Definition: crm.h:152
#define RSC_START
Definition: crm.h:199
#define RSC_STOP
Definition: crm.h:202
#define RSC_STATUS
Definition: crm.h:213
#define CRM_OP_PROBED
Definition: crm.h:151
#define CRM_OP_FENCE
Definition: crm.h:144
G_GNUC_INTERNAL void pcmk__order_vs_unfence(pe_resource_t *rsc, pe_node_t *node, pe_action_t *action, enum pe_ordering order)
G_GNUC_INTERNAL bool pcmk__is_failed_remote_node(pe_node_t *node)
G_GNUC_INTERNAL void pcmk__new_ordering(pe_resource_t *first_rsc, char *first_task, pe_action_t *first_action, pe_resource_t *then_rsc, char *then_task, pe_action_t *then_action, uint32_t flags, pe_working_set_t *data_set)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:227
#define crm_debug(fmt, args...)
Definition: logging.h:364
#define crm_err(fmt, args...)
Definition: logging.h:359
#define crm_trace(fmt, args...)
Definition: logging.h:365
#define XML_BOOLEAN_TRUE
Definition: msg_xml.h:146
#define XML_ATTR_TE_NOWAIT
Definition: msg_xml.h:415
#define XML_AGENT_ATTR_CLASS
Definition: msg_xml.h:269
#define XML_RSC_ATTR_INTERLEAVE
Definition: msg_xml.h:227
pe_working_set_t * data_set
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:517
const char * action
Definition: pcmk_fence.c:30
bool pcmk__probe_resource_list(GList *rscs, pe_node_t *node)
void pcmk__order_probes(pe_working_set_t *data_set)
void pcmk__schedule_probes(pe_working_set_t *data_set)
bool pcmk__probe_rsc_on_node(pe_resource_t *rsc, pe_node_t *node)
pe_resource_t * find_compatible_child(const pe_resource_t *local_child, const pe_resource_t *rsc, enum rsc_role_e filter, gboolean current)
pe_resource_t rsc2
pe_resource_t rsc1
#define pe_rsc_fence_device
Definition: pe_types.h:263
@ pe_order_anti_colocation
Definition: pe_types.h:514
@ pe_order_implies_then
Definition: pe_types.h:485
@ pe_order_same_node
Definition: pe_types.h:506
@ pe_order_none
Definition: pe_types.h:480
@ pe_order_optional
Definition: pe_types.h:481
@ pe_order_runnable_left
Definition: pe_types.h:491
@ pe_order_load
Definition: pe_types.h:512
@ pe_order_apply_first_non_migratable
Definition: pe_types.h:482
#define pe_flag_enable_unfencing
Definition: pe_types.h:101
#define pe_rsc_orphan
Definition: pe_types.h:256
#define pe_flag_startup_probes
Definition: pe_types.h:116
@ pe_discover_exclusive
Definition: pe_types.h:475
@ pe_discover_never
Definition: pe_types.h:474
@ pe_action_optional
Definition: pe_types.h:301
@ pe_action_tracking
Definition: pe_types.h:321
@ pe_action_runnable
Definition: pe_types.h:300
@ pe_action_pseudo
Definition: pe_types.h:299
@ pe_group
Definition: pe_types.h:39
@ pe_native
Definition: pe_types.h:38
#define pe_rsc_failed
Definition: pe_types.h:276
GList * pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
Definition: pe_actions.c:1398
GList * find_actions(GList *input, const char *key, const pe_node_t *on_node)
Definition: pe_actions.c:1325
void pe_fence_node(pe_working_set_t *data_set, pe_node_t *node, const char *reason, bool priority_delay)
Schedule a fence action for a node.
Definition: unpack.c:95
const char * pe_node_attribute_raw(const pe_node_t *node, const char *name)
Definition: common.c:562
#define reload_key(rsc)
Definition: internal.h:419
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
Definition: pe_actions.c:940
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
Definition: utils.c:474
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:47
void pe__add_action_expected_result(pe_action_t *action, int expected_result)
Definition: pe_actions.c:1673
#define pe__clear_action_flags(action, flags_to_clear)
Definition: internal.h:95
#define pe__set_order_flags(order_flags, flags_to_set)
Definition: internal.h:138
#define pe__set_action_flags(action, flags_to_set)
Definition: internal.h:86
void add_hash_param(GHashTable *hash, const char *name, const char *value)
Definition: common.c:504
bool pe__is_guest_node(const pe_node_t *node)
Definition: remote.c:33
pe_resource_t * pe__resource_contains_guest_node(const pe_working_set_t *data_set, const pe_resource_t *rsc)
Definition: remote.c:66
bool pe__is_guest_or_remote_node(const pe_node_t *node)
Definition: remote.c:41
#define CRM_ASSERT(expr)
Definition: results.h:42
@ CRM_EX_NOT_RUNNING
Service safely stopped.
Definition: results.h:243
@ CRM_EX_PROMOTED
Service active and promoted.
Definition: results.h:244
Cluster status and scheduling.
pe_node_t * pe_find_node(GList *node_list, const char *uname)
Definition: status.c:443
pe_node_t * pe_find_node_id(GList *node_list, const char *id)
Definition: status.c:427
@ pcmk__str_none
@ pcmk__str_casei
bool pcmk__ends_with(const char *s, const char *match)
Definition: strings.c:536
pe_action_t * rh_action
Definition: internal.h:205
pe_resource_t * rh_rsc
Definition: internal.h:204
pe_resource_t * lh_rsc
Definition: internal.h:199
pe_action_t * lh_action
Definition: internal.h:200
pe_resource_t * rsc
Definition: pe_types.h:406
char * uuid
Definition: pe_types.h:411
char * task
Definition: pe_types.h:410
pe_node_t * node
Definition: pe_types.h:407
GList * actions_after
Definition: pe_types.h:444
GHashTable * meta
Definition: pe_types.h:420
enum pe_action_flags flags
Definition: pe_types.h:415
enum pe_ordering type
Definition: pe_types.h:528
pe_action_t * action
Definition: pe_types.h:530
int rsc_discover_mode
Definition: pe_types.h:253
struct pe_node_shared_s * details
Definition: pe_types.h:252
const char * id
Definition: pe_types.h:215
gboolean online
Definition: pe_types.h:220
const char * uname
Definition: pe_types.h:216
pe_resource_t * remote_rsc
Definition: pe_types.h:237
gboolean unclean
Definition: pe_types.h:224
gboolean remote_requires_reset
Definition: pe_types.h:231
gboolean rsc_discovery_enabled
Definition: pe_types.h:230
GList * running_on
Definition: pe_types.h:373
GList * actions
Definition: pe_types.h:366
enum pe_obj_types variant
Definition: pe_types.h:338
GHashTable * meta
Definition: pe_types.h:380
GList * children
Definition: pe_types.h:384
gboolean exclusive_discover
Definition: pe_types.h:359
GHashTable * known_on
Definition: pe_types.h:374
pe_working_set_t * cluster
Definition: pe_types.h:335
pe_resource_t * container
Definition: pe_types.h:387
gboolean is_remote_node
Definition: pe_types.h:358
char * id
Definition: pe_types.h:329
GHashTable * allowed_nodes
Definition: pe_types.h:375
pe_node_t * allocated_to
Definition: pe_types.h:370
unsigned long long flags
Definition: pe_types.h:355
pe_resource_t * parent
Definition: pe_types.h:336
resource_alloc_functions_t * cmds
Definition: pe_types.h:341
enum rsc_role_e next_role
Definition: pe_types.h:378
enum rsc_role_e role
Definition: pe_types.h:377
GList * actions
Definition: pe_types.h:171
GList * resources
Definition: pe_types.h:165
unsigned long long flags
Definition: pe_types.h:153
GList * nodes
Definition: pe_types.h:164
GList * ordering_constraints
Definition: pe_types.h:167
bool(* create_probe)(pe_resource_t *rsc, pe_node_t *node)