From 13f0520789036d7f93cf69a9abcfb398177f3928 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 31 2015 13:17:23 +0000 Subject: import pacemaker-1.1.12-22.el7_1.4 --- diff --git a/SOURCES/bz1117341-remote-imply-stop-on-fence.patch b/SOURCES/bz1117341-remote-imply-stop-on-fence.patch deleted file mode 100644 index 9b3676a..0000000 --- a/SOURCES/bz1117341-remote-imply-stop-on-fence.patch +++ /dev/null @@ -1,1399 +0,0 @@ -diff --git a/pengine/native.c b/pengine/native.c -index 62639d0..3f1807e 100644 ---- a/pengine/native.c -+++ b/pengine/native.c -@@ -2913,6 +2913,39 @@ native_start_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_st - } - } - -+static GListPtr -+find_fence_target_node_actions(GListPtr search_list, const char *key, node_t *fence_target, pe_working_set_t *data_set) -+{ -+ GListPtr gIter = NULL; -+ GListPtr result_list = find_actions(search_list, key, fence_target); -+ -+ /* find stop actions for this rsc on any container nodes running on -+ * the fencing target node */ -+ for (gIter = fence_target->details->running_rsc; gIter != NULL; gIter = gIter->next) { -+ GListPtr iter = NULL; -+ GListPtr tmp_list = NULL; -+ resource_t *tmp_rsc = (resource_t *) gIter->data; -+ node_t *container_node = NULL; -+ -+ /* found a container node that lives on the host node -+ * that is getting fenced. Find stop for our rsc that live on -+ * the container node as well. These stop operations are also -+ * implied by fencing of the host cluster node. */ -+ if (tmp_rsc->is_remote_node && tmp_rsc->container != NULL) { -+ container_node = pe_find_node(data_set->nodes, tmp_rsc->id); -+ } -+ if (container_node) { -+ tmp_list = find_actions(search_list, key, container_node); -+ } -+ for (iter = tmp_list; iter != NULL; iter = iter->next) { -+ result_list = g_list_prepend(result_list, (action_t *) iter->data); -+ } -+ g_list_free(tmp_list); -+ } -+ -+ return result_list; -+} -+ - static void - native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_stonith, - pe_working_set_t * data_set) -@@ -2923,7 +2956,7 @@ native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_sto - resource_t *top = uber_parent(rsc); - - key = stop_key(rsc); -- action_list = find_actions(rsc->actions, key, stonith_op->node); -+ action_list = find_fence_target_node_actions(rsc->actions, key, stonith_op->node, data_set); - free(key); - - /* add the stonith OP as a stop pre-req and the mark the stop -@@ -3032,7 +3065,7 @@ native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_sto - g_list_free(action_list); - - key = demote_key(rsc); -- action_list = find_actions(rsc->actions, key, stonith_op->node); -+ action_list = find_fence_target_node_actions(rsc->actions, key, stonith_op->node, data_set); - free(key); - - for (gIter = action_list; gIter != NULL; gIter = gIter->next) { -diff --git a/pengine/regression.sh b/pengine/regression.sh -index c2bc7fb..9172acb 100755 ---- a/pengine/regression.sh -+++ b/pengine/regression.sh -@@ -768,6 +768,7 @@ do_test whitebox-orphaned "Properly shutdown orphaned whitebox container" - do_test whitebox-orphan-ms "Properly tear down orphan ms resources on remote-nodes" - do_test whitebox-unexpectedly-running "Recover container nodes the cluster did not start." - do_test whitebox-migrate1 "Migrate both container and connection resource" -+do_test whitebox-imply-stop-on-fence "imply stop action on container node rsc when host node is fenced" - - echo "" - do_test remote-startup-probes "Baremetal remote-node startup probes" -diff --git a/pengine/test10/whitebox-imply-stop-on-fence.dot b/pengine/test10/whitebox-imply-stop-on-fence.dot -new file mode 100644 -index 0000000..66700b8 ---- /dev/null -+++ b/pengine/test10/whitebox-imply-stop-on-fence.dot -@@ -0,0 +1,93 @@ -+ digraph "g" { -+"R-lxc-01_kiff-01_monitor_10000 kiff-02" [ style=bold color="green" fontcolor="black"] -+"R-lxc-01_kiff-01_start_0 kiff-02" -> "R-lxc-01_kiff-01_monitor_10000 kiff-02" [ style = bold] -+"R-lxc-01_kiff-01_start_0 kiff-02" -> "lxc-01_kiff-01_start_0 kiff-02" [ style = bold] -+"R-lxc-01_kiff-01_start_0 kiff-02" [ style=bold color="green" fontcolor="black"] -+"R-lxc-01_kiff-01_stop_0 kiff-01" -> "R-lxc-01_kiff-01_start_0 kiff-02" [ style = bold] -+"R-lxc-01_kiff-01_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"R-lxc-01_kiff-01_stop_0 kiff-01" -> "shared0-clone_stop_0" [ style = bold] -+"R-lxc-01_kiff-01_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"R-lxc-02_kiff-01_monitor_10000 kiff-02" [ style=bold color="green" fontcolor="black"] -+"R-lxc-02_kiff-01_start_0 kiff-02" -> "R-lxc-02_kiff-01_monitor_10000 kiff-02" [ style = bold] -+"R-lxc-02_kiff-01_start_0 kiff-02" -> "lxc-02_kiff-01_start_0 kiff-02" [ style = bold] -+"R-lxc-02_kiff-01_start_0 kiff-02" [ style=bold color="green" fontcolor="black"] -+"R-lxc-02_kiff-01_stop_0 kiff-01" -> "R-lxc-02_kiff-01_start_0 kiff-02" [ style = bold] -+"R-lxc-02_kiff-01_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"R-lxc-02_kiff-01_stop_0 kiff-01" -> "shared0-clone_stop_0" [ style = bold] -+"R-lxc-02_kiff-01_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"clvmd-clone_stop_0" -> "clvmd-clone_stopped_0" [ style = bold] -+"clvmd-clone_stop_0" -> "clvmd_stop_0 kiff-01" [ style = bold] -+"clvmd-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"clvmd-clone_stopped_0" -> "dlm-clone_stop_0" [ style = bold] -+"clvmd-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"clvmd_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"clvmd_stop_0 kiff-01" -> "clvmd-clone_stopped_0" [ style = bold] -+"clvmd_stop_0 kiff-01" -> "dlm_stop_0 kiff-01" [ style = bold] -+"clvmd_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"dlm-clone_stop_0" -> "dlm-clone_stopped_0" [ style = bold] -+"dlm-clone_stop_0" -> "dlm_stop_0 kiff-01" [ style = bold] -+"dlm-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"dlm-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"dlm_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"dlm_stop_0 kiff-01" -> "dlm-clone_stopped_0" [ style = bold] -+"dlm_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"fence-kiff-02_monitor_60000 kiff-02" [ style=bold color="green" fontcolor="black"] -+"fence-kiff-02_start_0 kiff-02" -> "fence-kiff-02_monitor_60000 kiff-02" [ style = bold] -+"fence-kiff-02_start_0 kiff-02" [ style=bold color="green" fontcolor="black"] -+"fence-kiff-02_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"fence-kiff-02_stop_0 kiff-01" -> "fence-kiff-02_start_0 kiff-02" [ style = bold] -+"fence-kiff-02_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"lxc-01_kiff-01_monitor_30000 kiff-02" [ style=bold color="green" fontcolor="black"] -+"lxc-01_kiff-01_start_0 kiff-02" -> "lxc-01_kiff-01_monitor_30000 kiff-02" [ style = bold] -+"lxc-01_kiff-01_start_0 kiff-02" -> "vm-fs_monitor_20000 lxc-01_kiff-01" [ style = bold] -+"lxc-01_kiff-01_start_0 kiff-02" -> "vm-fs_start_0 lxc-01_kiff-01" [ style = bold] -+"lxc-01_kiff-01_start_0 kiff-02" [ style=bold color="green" fontcolor="black"] -+"lxc-01_kiff-01_stop_0 kiff-01" -> "R-lxc-01_kiff-01_stop_0 kiff-01" [ style = bold] -+"lxc-01_kiff-01_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"lxc-01_kiff-01_stop_0 kiff-01" -> "lxc-01_kiff-01_start_0 kiff-02" [ style = bold] -+"lxc-01_kiff-01_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"lxc-02_kiff-01_monitor_30000 kiff-02" [ style=bold color="green" fontcolor="black"] -+"lxc-02_kiff-01_start_0 kiff-02" -> "lxc-02_kiff-01_monitor_30000 kiff-02" [ style = bold] -+"lxc-02_kiff-01_start_0 kiff-02" [ style=bold color="green" fontcolor="black"] -+"lxc-02_kiff-01_stop_0 kiff-01" -> "R-lxc-02_kiff-01_stop_0 kiff-01" [ style = bold] -+"lxc-02_kiff-01_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"lxc-02_kiff-01_stop_0 kiff-01" -> "lxc-02_kiff-01_start_0 kiff-02" [ style = bold] -+"lxc-02_kiff-01_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"shared0-clone_stop_0" -> "shared0-clone_stopped_0" [ style = bold] -+"shared0-clone_stop_0" -> "shared0_stop_0 kiff-01" [ style = bold] -+"shared0-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"shared0-clone_stopped_0" -> "clvmd-clone_stop_0" [ style = bold] -+"shared0-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"shared0_stop_0 kiff-01" -> "all_stopped" [ style = bold] -+"shared0_stop_0 kiff-01" -> "clvmd_stop_0 kiff-01" [ style = bold] -+"shared0_stop_0 kiff-01" -> "shared0-clone_stopped_0" [ style = bold] -+"shared0_stop_0 kiff-01" [ style=bold color="green" fontcolor="orange"] -+"stonith 'reboot' kiff-01" -> "R-lxc-01_kiff-01_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "R-lxc-02_kiff-01_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "clvmd-clone_stop_0" [ style = bold] -+"stonith 'reboot' kiff-01" -> "clvmd_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "dlm-clone_stop_0" [ style = bold] -+"stonith 'reboot' kiff-01" -> "dlm_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "fence-kiff-02_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "lxc-01_kiff-01_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "lxc-02_kiff-01_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "shared0-clone_stop_0" [ style = bold] -+"stonith 'reboot' kiff-01" -> "shared0_stop_0 kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" -> "stonith_complete" [ style = bold] -+"stonith 'reboot' kiff-01" -> "vm-fs_stop_0 lxc-01_kiff-01" [ style = bold] -+"stonith 'reboot' kiff-01" [ style=bold color="green" fontcolor="black"] -+"stonith_complete" -> "R-lxc-01_kiff-01_start_0 kiff-02" [ style = bold] -+"stonith_complete" -> "R-lxc-02_kiff-01_start_0 kiff-02" [ style = bold] -+"stonith_complete" -> "all_stopped" [ style = bold] -+"stonith_complete" -> "lxc-01_kiff-01_start_0 kiff-02" [ style = bold] -+"stonith_complete" -> "lxc-02_kiff-01_start_0 kiff-02" [ style = bold] -+"stonith_complete" -> "vm-fs_start_0 lxc-01_kiff-01" [ style = bold] -+"stonith_complete" [ style=bold color="green" fontcolor="orange"] -+"vm-fs_monitor_20000 lxc-01_kiff-01" [ style=bold color="green" fontcolor="black"] -+"vm-fs_start_0 lxc-01_kiff-01" -> "vm-fs_monitor_20000 lxc-01_kiff-01" [ style = bold] -+"vm-fs_start_0 lxc-01_kiff-01" [ style=bold color="green" fontcolor="black"] -+"vm-fs_stop_0 lxc-01_kiff-01" -> "all_stopped" [ style = bold] -+"vm-fs_stop_0 lxc-01_kiff-01" -> "vm-fs_start_0 lxc-01_kiff-01" [ style = bold] -+"vm-fs_stop_0 lxc-01_kiff-01" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/whitebox-imply-stop-on-fence.exp b/pengine/test10/whitebox-imply-stop-on-fence.exp -new file mode 100644 -index 0000000..d13c25f ---- /dev/null -+++ b/pengine/test10/whitebox-imply-stop-on-fence.exp -@@ -0,0 +1,466 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/whitebox-imply-stop-on-fence.scores b/pengine/test10/whitebox-imply-stop-on-fence.scores -new file mode 100644 -index 0000000..e50f077 ---- /dev/null -+++ b/pengine/test10/whitebox-imply-stop-on-fence.scores -@@ -0,0 +1,301 @@ -+Allocation scores: -+clone_color: clvmd-clone allocation score on kiff-01: 0 -+clone_color: clvmd-clone allocation score on kiff-02: 0 -+clone_color: clvmd-clone allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd-clone allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd-clone allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd-clone allocation score on lxc-02_kiff-02: 0 -+clone_color: clvmd:0 allocation score on kiff-01: 1 -+clone_color: clvmd:0 allocation score on kiff-02: 0 -+clone_color: clvmd:0 allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd:0 allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd:0 allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd:0 allocation score on lxc-02_kiff-02: 0 -+clone_color: clvmd:1 allocation score on kiff-01: 0 -+clone_color: clvmd:1 allocation score on kiff-02: 1 -+clone_color: clvmd:1 allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd:1 allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd:1 allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd:1 allocation score on lxc-02_kiff-02: 0 -+clone_color: clvmd:2 allocation score on kiff-01: 0 -+clone_color: clvmd:2 allocation score on kiff-02: 0 -+clone_color: clvmd:2 allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd:2 allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd:2 allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd:2 allocation score on lxc-02_kiff-02: 0 -+clone_color: clvmd:3 allocation score on kiff-01: 0 -+clone_color: clvmd:3 allocation score on kiff-02: 0 -+clone_color: clvmd:3 allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd:3 allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd:3 allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd:3 allocation score on lxc-02_kiff-02: 0 -+clone_color: clvmd:4 allocation score on kiff-01: 0 -+clone_color: clvmd:4 allocation score on kiff-02: 0 -+clone_color: clvmd:4 allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd:4 allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd:4 allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd:4 allocation score on lxc-02_kiff-02: 0 -+clone_color: clvmd:5 allocation score on kiff-01: 0 -+clone_color: clvmd:5 allocation score on kiff-02: 0 -+clone_color: clvmd:5 allocation score on lxc-01_kiff-01: 0 -+clone_color: clvmd:5 allocation score on lxc-01_kiff-02: 0 -+clone_color: clvmd:5 allocation score on lxc-02_kiff-01: 0 -+clone_color: clvmd:5 allocation score on lxc-02_kiff-02: 0 -+clone_color: dlm-clone allocation score on kiff-01: 0 -+clone_color: dlm-clone allocation score on kiff-02: 0 -+clone_color: dlm-clone allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm-clone allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm-clone allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm-clone allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: dlm:0 allocation score on kiff-01: 1 -+clone_color: dlm:0 allocation score on kiff-02: 0 -+clone_color: dlm:0 allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm:0 allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm:0 allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm:0 allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: dlm:1 allocation score on kiff-01: 0 -+clone_color: dlm:1 allocation score on kiff-02: 1 -+clone_color: dlm:1 allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm:1 allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm:1 allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm:1 allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: dlm:2 allocation score on kiff-01: 0 -+clone_color: dlm:2 allocation score on kiff-02: 0 -+clone_color: dlm:2 allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm:2 allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm:2 allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm:2 allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: dlm:3 allocation score on kiff-01: 0 -+clone_color: dlm:3 allocation score on kiff-02: 0 -+clone_color: dlm:3 allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm:3 allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm:3 allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm:3 allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: dlm:4 allocation score on kiff-01: 0 -+clone_color: dlm:4 allocation score on kiff-02: 0 -+clone_color: dlm:4 allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm:4 allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm:4 allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm:4 allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: dlm:5 allocation score on kiff-01: 0 -+clone_color: dlm:5 allocation score on kiff-02: 0 -+clone_color: dlm:5 allocation score on lxc-01_kiff-01: -INFINITY -+clone_color: dlm:5 allocation score on lxc-01_kiff-02: -INFINITY -+clone_color: dlm:5 allocation score on lxc-02_kiff-01: -INFINITY -+clone_color: dlm:5 allocation score on lxc-02_kiff-02: -INFINITY -+clone_color: shared0-clone allocation score on kiff-01: 0 -+clone_color: shared0-clone allocation score on kiff-02: 0 -+clone_color: shared0-clone allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0-clone allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0-clone allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0-clone allocation score on lxc-02_kiff-02: 0 -+clone_color: shared0:0 allocation score on kiff-01: 1 -+clone_color: shared0:0 allocation score on kiff-02: 0 -+clone_color: shared0:0 allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0:0 allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0:0 allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0:0 allocation score on lxc-02_kiff-02: 0 -+clone_color: shared0:1 allocation score on kiff-01: 0 -+clone_color: shared0:1 allocation score on kiff-02: 1 -+clone_color: shared0:1 allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0:1 allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0:1 allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0:1 allocation score on lxc-02_kiff-02: 0 -+clone_color: shared0:2 allocation score on kiff-01: 0 -+clone_color: shared0:2 allocation score on kiff-02: 0 -+clone_color: shared0:2 allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0:2 allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0:2 allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0:2 allocation score on lxc-02_kiff-02: 0 -+clone_color: shared0:3 allocation score on kiff-01: 0 -+clone_color: shared0:3 allocation score on kiff-02: 0 -+clone_color: shared0:3 allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0:3 allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0:3 allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0:3 allocation score on lxc-02_kiff-02: 0 -+clone_color: shared0:4 allocation score on kiff-01: 0 -+clone_color: shared0:4 allocation score on kiff-02: 0 -+clone_color: shared0:4 allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0:4 allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0:4 allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0:4 allocation score on lxc-02_kiff-02: 0 -+clone_color: shared0:5 allocation score on kiff-01: 0 -+clone_color: shared0:5 allocation score on kiff-02: 0 -+clone_color: shared0:5 allocation score on lxc-01_kiff-01: 0 -+clone_color: shared0:5 allocation score on lxc-01_kiff-02: 0 -+clone_color: shared0:5 allocation score on lxc-02_kiff-01: 0 -+clone_color: shared0:5 allocation score on lxc-02_kiff-02: 0 -+native_color: R-lxc-01_kiff-01 allocation score on kiff-01: -INFINITY -+native_color: R-lxc-01_kiff-01 allocation score on kiff-02: 0 -+native_color: R-lxc-01_kiff-01 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: R-lxc-01_kiff-01 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: R-lxc-01_kiff-01 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: R-lxc-01_kiff-01 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: R-lxc-01_kiff-02 allocation score on kiff-01: -INFINITY -+native_color: R-lxc-01_kiff-02 allocation score on kiff-02: 100 -+native_color: R-lxc-01_kiff-02 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: R-lxc-01_kiff-02 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: R-lxc-01_kiff-02 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: R-lxc-01_kiff-02 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: R-lxc-02_kiff-01 allocation score on kiff-01: -INFINITY -+native_color: R-lxc-02_kiff-01 allocation score on kiff-02: 0 -+native_color: R-lxc-02_kiff-01 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: R-lxc-02_kiff-01 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: R-lxc-02_kiff-01 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: R-lxc-02_kiff-01 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: R-lxc-02_kiff-02 allocation score on kiff-01: -INFINITY -+native_color: R-lxc-02_kiff-02 allocation score on kiff-02: 100 -+native_color: R-lxc-02_kiff-02 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: R-lxc-02_kiff-02 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: R-lxc-02_kiff-02 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: R-lxc-02_kiff-02 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: clvmd:0 allocation score on kiff-01: -INFINITY -+native_color: clvmd:0 allocation score on kiff-02: -INFINITY -+native_color: clvmd:0 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: clvmd:0 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: clvmd:0 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: clvmd:0 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: clvmd:1 allocation score on kiff-01: -INFINITY -+native_color: clvmd:1 allocation score on kiff-02: 1 -+native_color: clvmd:1 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: clvmd:1 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: clvmd:1 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: clvmd:1 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: clvmd:2 allocation score on kiff-01: -INFINITY -+native_color: clvmd:2 allocation score on kiff-02: -INFINITY -+native_color: clvmd:2 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: clvmd:2 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: clvmd:2 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: clvmd:2 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: clvmd:3 allocation score on kiff-01: -INFINITY -+native_color: clvmd:3 allocation score on kiff-02: -INFINITY -+native_color: clvmd:3 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: clvmd:3 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: clvmd:3 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: clvmd:3 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: clvmd:4 allocation score on kiff-01: -INFINITY -+native_color: clvmd:4 allocation score on kiff-02: -INFINITY -+native_color: clvmd:4 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: clvmd:4 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: clvmd:4 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: clvmd:4 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: clvmd:5 allocation score on kiff-01: -INFINITY -+native_color: clvmd:5 allocation score on kiff-02: -INFINITY -+native_color: clvmd:5 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: clvmd:5 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: clvmd:5 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: clvmd:5 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: dlm:0 allocation score on kiff-01: -INFINITY -+native_color: dlm:0 allocation score on kiff-02: -INFINITY -+native_color: dlm:0 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: dlm:0 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: dlm:0 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: dlm:0 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: dlm:1 allocation score on kiff-01: -INFINITY -+native_color: dlm:1 allocation score on kiff-02: 1 -+native_color: dlm:1 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: dlm:1 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: dlm:1 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: dlm:1 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: dlm:2 allocation score on kiff-01: -INFINITY -+native_color: dlm:2 allocation score on kiff-02: -INFINITY -+native_color: dlm:2 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: dlm:2 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: dlm:2 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: dlm:2 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: dlm:3 allocation score on kiff-01: -INFINITY -+native_color: dlm:3 allocation score on kiff-02: -INFINITY -+native_color: dlm:3 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: dlm:3 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: dlm:3 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: dlm:3 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: dlm:4 allocation score on kiff-01: -INFINITY -+native_color: dlm:4 allocation score on kiff-02: -INFINITY -+native_color: dlm:4 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: dlm:4 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: dlm:4 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: dlm:4 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: dlm:5 allocation score on kiff-01: -INFINITY -+native_color: dlm:5 allocation score on kiff-02: -INFINITY -+native_color: dlm:5 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: dlm:5 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: dlm:5 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: dlm:5 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: fence-kiff-01 allocation score on kiff-01: 0 -+native_color: fence-kiff-01 allocation score on kiff-02: 0 -+native_color: fence-kiff-01 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: fence-kiff-01 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: fence-kiff-01 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: fence-kiff-01 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: fence-kiff-02 allocation score on kiff-01: 0 -+native_color: fence-kiff-02 allocation score on kiff-02: 0 -+native_color: fence-kiff-02 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: fence-kiff-02 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: fence-kiff-02 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: fence-kiff-02 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: lxc-01_kiff-01 allocation score on kiff-01: -INFINITY -+native_color: lxc-01_kiff-01 allocation score on kiff-02: 0 -+native_color: lxc-01_kiff-01 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: lxc-01_kiff-01 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: lxc-01_kiff-01 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: lxc-01_kiff-01 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: lxc-01_kiff-02 allocation score on kiff-01: -INFINITY -+native_color: lxc-01_kiff-02 allocation score on kiff-02: 0 -+native_color: lxc-01_kiff-02 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: lxc-01_kiff-02 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: lxc-01_kiff-02 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: lxc-01_kiff-02 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: lxc-02_kiff-01 allocation score on kiff-01: -INFINITY -+native_color: lxc-02_kiff-01 allocation score on kiff-02: 0 -+native_color: lxc-02_kiff-01 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: lxc-02_kiff-01 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: lxc-02_kiff-01 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: lxc-02_kiff-01 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: lxc-02_kiff-02 allocation score on kiff-01: -INFINITY -+native_color: lxc-02_kiff-02 allocation score on kiff-02: 0 -+native_color: lxc-02_kiff-02 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: lxc-02_kiff-02 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: lxc-02_kiff-02 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: lxc-02_kiff-02 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: shared0:0 allocation score on kiff-01: -INFINITY -+native_color: shared0:0 allocation score on kiff-02: -INFINITY -+native_color: shared0:0 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: shared0:0 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: shared0:0 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: shared0:0 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: shared0:1 allocation score on kiff-01: -INFINITY -+native_color: shared0:1 allocation score on kiff-02: 1 -+native_color: shared0:1 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: shared0:1 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: shared0:1 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: shared0:1 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: shared0:2 allocation score on kiff-01: -INFINITY -+native_color: shared0:2 allocation score on kiff-02: -INFINITY -+native_color: shared0:2 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: shared0:2 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: shared0:2 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: shared0:2 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: shared0:3 allocation score on kiff-01: -INFINITY -+native_color: shared0:3 allocation score on kiff-02: -INFINITY -+native_color: shared0:3 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: shared0:3 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: shared0:3 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: shared0:3 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: shared0:4 allocation score on kiff-01: -INFINITY -+native_color: shared0:4 allocation score on kiff-02: -INFINITY -+native_color: shared0:4 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: shared0:4 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: shared0:4 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: shared0:4 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: shared0:5 allocation score on kiff-01: -INFINITY -+native_color: shared0:5 allocation score on kiff-02: -INFINITY -+native_color: shared0:5 allocation score on lxc-01_kiff-01: -INFINITY -+native_color: shared0:5 allocation score on lxc-01_kiff-02: -INFINITY -+native_color: shared0:5 allocation score on lxc-02_kiff-01: -INFINITY -+native_color: shared0:5 allocation score on lxc-02_kiff-02: -INFINITY -+native_color: vm-fs allocation score on kiff-01: 0 -+native_color: vm-fs allocation score on kiff-02: 0 -+native_color: vm-fs allocation score on lxc-01_kiff-01: 0 -+native_color: vm-fs allocation score on lxc-01_kiff-02: 0 -+native_color: vm-fs allocation score on lxc-02_kiff-01: 0 -+native_color: vm-fs allocation score on lxc-02_kiff-02: 0 -diff --git a/pengine/test10/whitebox-imply-stop-on-fence.summary b/pengine/test10/whitebox-imply-stop-on-fence.summary -new file mode 100644 -index 0000000..79e77de ---- /dev/null -+++ b/pengine/test10/whitebox-imply-stop-on-fence.summary -@@ -0,0 +1,88 @@ -+ -+Current cluster status: -+Node kiff-01 (1): UNCLEAN (offline) -+Online: [ kiff-02 ] -+Containers: [ lxc-01_kiff-01:R-lxc-01_kiff-01 lxc-01_kiff-02:R-lxc-01_kiff-02 lxc-02_kiff-01:R-lxc-02_kiff-01 lxc-02_kiff-02:R-lxc-02_kiff-02 ] -+ -+ fence-kiff-01 (stonith:fence_ipmilan): Started kiff-02 -+ fence-kiff-02 (stonith:fence_ipmilan): Started kiff-01 -+ Clone Set: dlm-clone [dlm] -+ Started: [ kiff-01 kiff-02 ] -+ Stopped: [ lxc-01_kiff-01 lxc-01_kiff-02 lxc-02_kiff-01 lxc-02_kiff-02 ] -+ Clone Set: clvmd-clone [clvmd] -+ Started: [ kiff-01 kiff-02 ] -+ Stopped: [ lxc-01_kiff-01 lxc-01_kiff-02 lxc-02_kiff-01 lxc-02_kiff-02 ] -+ Clone Set: shared0-clone [shared0] -+ Started: [ kiff-01 kiff-02 ] -+ Stopped: [ lxc-01_kiff-01 lxc-01_kiff-02 lxc-02_kiff-01 lxc-02_kiff-02 ] -+ R-lxc-01_kiff-01 (ocf::heartbeat:VirtualDomain): Started kiff-01 -+ R-lxc-02_kiff-01 (ocf::heartbeat:VirtualDomain): Started kiff-01 -+ R-lxc-01_kiff-02 (ocf::heartbeat:VirtualDomain): Started kiff-02 -+ R-lxc-02_kiff-02 (ocf::heartbeat:VirtualDomain): Started kiff-02 -+ vm-fs (ocf::heartbeat:Filesystem): Started lxc-01_kiff-01 -+ -+Transition Summary: -+ * Move fence-kiff-02 (Started kiff-01 -> kiff-02) -+ * Stop dlm:0 (kiff-01) -+ * Stop clvmd:0 (kiff-01) -+ * Stop shared0:0 (kiff-01) -+ * Move R-lxc-01_kiff-01 (Started kiff-01 -> kiff-02) -+ * Move R-lxc-02_kiff-01 (Started kiff-01 -> kiff-02) -+ * Restart vm-fs (Started lxc-01_kiff-01) -+ * Move lxc-01_kiff-01 (Started kiff-01 -> kiff-02) -+ * Move lxc-02_kiff-01 (Started kiff-01 -> kiff-02) -+ -+Executing cluster transition: -+ * Fencing kiff-01 (reboot) -+ * Pseudo action: stonith_complete -+ * Pseudo action: fence-kiff-02_stop_0 -+ * Pseudo action: vm-fs_stop_0 -+ * Pseudo action: lxc-01_kiff-01_stop_0 -+ * Pseudo action: lxc-02_kiff-01_stop_0 -+ * Resource action: fence-kiff-02 start on kiff-02 -+ * Pseudo action: R-lxc-01_kiff-01_stop_0 -+ * Pseudo action: R-lxc-02_kiff-01_stop_0 -+ * Resource action: fence-kiff-02 monitor=60000 on kiff-02 -+ * Pseudo action: shared0-clone_stop_0 -+ * Resource action: R-lxc-01_kiff-01 start on kiff-02 -+ * Resource action: R-lxc-02_kiff-01 start on kiff-02 -+ * Resource action: lxc-01_kiff-01 start on kiff-02 -+ * Resource action: lxc-02_kiff-01 start on kiff-02 -+ * Pseudo action: shared0_stop_0 -+ * Pseudo action: shared0-clone_stopped_0 -+ * Resource action: R-lxc-01_kiff-01 monitor=10000 on kiff-02 -+ * Resource action: R-lxc-02_kiff-01 monitor=10000 on kiff-02 -+ * Resource action: vm-fs start on lxc-01_kiff-01 -+ * Resource action: vm-fs monitor=20000 on lxc-01_kiff-01 -+ * Resource action: lxc-01_kiff-01 monitor=30000 on kiff-02 -+ * Resource action: lxc-02_kiff-01 monitor=30000 on kiff-02 -+ * Pseudo action: clvmd-clone_stop_0 -+ * Pseudo action: clvmd_stop_0 -+ * Pseudo action: clvmd-clone_stopped_0 -+ * Pseudo action: dlm-clone_stop_0 -+ * Pseudo action: dlm_stop_0 -+ * Pseudo action: dlm-clone_stopped_0 -+ * Pseudo action: all_stopped -+ -+Revised cluster status: -+Online: [ kiff-02 ] -+OFFLINE: [ kiff-01 ] -+Containers: [ lxc-01_kiff-01:R-lxc-01_kiff-01 lxc-01_kiff-02:R-lxc-01_kiff-02 lxc-02_kiff-01:R-lxc-02_kiff-01 lxc-02_kiff-02:R-lxc-02_kiff-02 ] -+ -+ fence-kiff-01 (stonith:fence_ipmilan): Started kiff-02 -+ fence-kiff-02 (stonith:fence_ipmilan): Started kiff-02 -+ Clone Set: dlm-clone [dlm] -+ Started: [ kiff-02 ] -+ Stopped: [ kiff-01 lxc-01_kiff-01 lxc-01_kiff-02 lxc-02_kiff-01 lxc-02_kiff-02 ] -+ Clone Set: clvmd-clone [clvmd] -+ Started: [ kiff-02 ] -+ Stopped: [ kiff-01 lxc-01_kiff-01 lxc-01_kiff-02 lxc-02_kiff-01 lxc-02_kiff-02 ] -+ Clone Set: shared0-clone [shared0] -+ Started: [ kiff-02 ] -+ Stopped: [ kiff-01 lxc-01_kiff-01 lxc-01_kiff-02 lxc-02_kiff-01 lxc-02_kiff-02 ] -+ R-lxc-01_kiff-01 (ocf::heartbeat:VirtualDomain): Started kiff-02 -+ R-lxc-02_kiff-01 (ocf::heartbeat:VirtualDomain): Started kiff-02 -+ R-lxc-01_kiff-02 (ocf::heartbeat:VirtualDomain): Started kiff-02 -+ R-lxc-02_kiff-02 (ocf::heartbeat:VirtualDomain): Started kiff-02 -+ vm-fs (ocf::heartbeat:Filesystem): Started lxc-01_kiff-01 -+ -diff --git a/pengine/test10/whitebox-imply-stop-on-fence.xml b/pengine/test10/whitebox-imply-stop-on-fence.xml -new file mode 100644 -index 0000000..609b281 ---- /dev/null -+++ b/pengine/test10/whitebox-imply-stop-on-fence.xml -@@ -0,0 +1,347 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ diff --git a/SOURCES/bz1162727-pcmk-membership-cleanup.patch b/SOURCES/bz1162727-pcmk-membership-cleanup.patch deleted file mode 100644 index 910b2d7..0000000 --- a/SOURCES/bz1162727-pcmk-membership-cleanup.patch +++ /dev/null @@ -1,897 +0,0 @@ -diff --git a/attrd/commands.c b/attrd/commands.c -index 12771ee..c5badc5 100644 ---- a/attrd/commands.c -+++ b/attrd/commands.c -@@ -377,7 +377,17 @@ attrd_peer_message(crm_node_t *peer, xmlNode *xml) - attrd_peer_sync(peer, xml); - - } else if(safe_str_eq(op, "peer-remove")) { -- attrd_peer_remove(0, host, TRUE, peer->uname); -+ int host_id = 0; -+ char *endptr = NULL; -+ -+ host_id = strtol(host, &endptr, 10); -+ if (errno != 0 || endptr == host || *endptr != '\0') { -+ host_id = 0; -+ } else { -+ host = NULL; -+ } -+ attrd_peer_remove(host_id, host, TRUE, peer->uname); -+ - - } else if(safe_str_eq(op, "sync-response") - && safe_str_neq(peer->uname, attrd_cluster->uname)) { -diff --git a/attrd/legacy.c b/attrd/legacy.c -index d4733ec..d7ed53e 100644 ---- a/attrd/legacy.c -+++ b/attrd/legacy.c -@@ -768,6 +768,9 @@ attrd_local_callback(xmlNode * msg) - crm_notice("Sending full refresh (origin=%s)", from); - g_hash_table_foreach(attr_hash, update_for_hash_entry, NULL); - return; -+ } else if(safe_str_eq(op, "peer-remove")) { -+ /* The legacy code didn't understand this command - swallow silently */ -+ return; - } - - if (host != NULL && safe_str_neq(host, attrd_uname)) { -diff --git a/cib/main.c b/cib/main.c -index 00fca9b..69a957c 100644 ---- a/cib/main.c -+++ b/cib/main.c -@@ -439,6 +439,11 @@ cib_peer_update_callback(enum crm_status_type type, crm_node_t * node, const voi - crm_info("No more peers"); - terminate_cib(__FUNCTION__, FALSE); - } -+ -+ if(type == crm_status_nstate && node->id && safe_str_eq(node->state, CRM_NODE_LOST)) { -+ /* Avoid conflicts, keep the membership list to active members */ -+ reap_crm_member(node->id, NULL); -+ } - } - - #if SUPPORT_HEARTBEAT -diff --git a/crmd/messages.c b/crmd/messages.c -index d38f2a3..eea4f7b 100644 ---- a/crmd/messages.c -+++ b/crmd/messages.c -@@ -39,6 +39,7 @@ - GListPtr fsa_message_queue = NULL; - extern void crm_shutdown(int nsig); - -+extern crm_ipc_t *attrd_ipc; - void handle_response(xmlNode * stored_msg); - enum crmd_fsa_input handle_request(xmlNode * stored_msg, enum crmd_fsa_cause cause); - enum crmd_fsa_input handle_shutdown_request(xmlNode * stored_msg); -diff --git a/doc/Clusters_from_Scratch/en-US/Ap-Configuration.txt b/doc/Clusters_from_Scratch/en-US/Ap-Configuration.txt -index 0cbfeec..5852e7e 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ap-Configuration.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ap-Configuration.txt -@@ -19,7 +19,7 @@ ifdef::pcs[] - Started: [ pcmk-1 pcmk-2 ] - Clone Set: WebSite-clone [WebSite] - Started: [ pcmk-1 pcmk-2 ] --# pcs resource defaults -+# pcs resource rsc defaults - resource-stickiness: 100 - # pcs resource op defaults - timeout: 240s -@@ -303,7 +303,7 @@ ifdef::pcs[] - * resource-stickiness - Specify the aversion to moving resources to other machines - [source,C] - ---- --# pcs resource defaults -+# pcs resource rsc defaults - resource-stickiness: 100 - ---- - endif::[] -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Active-Active.txt b/doc/Clusters_from_Scratch/en-US/Ch-Active-Active.txt -index 5943c19..714a0d3 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Active-Active.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Active-Active.txt -@@ -222,7 +222,7 @@ ifdef::pcs[] - WebFS (ocf::heartbeat:Filesystem) Stopped - Clone Set: dlm-clone [dlm] - Stopped: [ dlm:0 dlm:1 ] --# pcs cluster cib-push dlm_cfg -+# pcs cluster push cib dlm_cfg - CIB updated - # pcs status - -@@ -695,7 +695,7 @@ shell and watching the cluster's response - ifdef::pcs[] - [source,C] - ----- --# pcs cluster cib-push active_cfg -+# pcs cluster push cib active_cfg - # pcs resource enable WebFS - ----- - -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Active-Passive.txt b/doc/Clusters_from_Scratch/en-US/Ch-Active-Passive.txt -index c91647b..7da8fca 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Active-Passive.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Active-Passive.txt -@@ -656,8 +656,8 @@ resource, but it is often sufficient to change the default. - ifdef::pcs[] - [source,C] - ---- --# pcs resource defaults resource-stickiness=100 --# pcs resource defaults -+# pcs resource rsc defaults resource-stickiness=100 -+# pcs resource rsc defaults - resource-stickiness: 100 - ---- - endif::[] -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Apache.txt b/doc/Clusters_from_Scratch/en-US/Ch-Apache.txt -index 71777db..236bb77 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Apache.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Apache.txt -@@ -125,7 +125,7 @@ it fails, the resource agent used by Pacemaker assumes the server-status - URL is available. Look for the following in '/etc/httpd/conf/httpd.conf' - and make sure it is not disabled or commented out: - --[source,Apache Configuration] -+[source,C] - ----- - - SetHandler server-status -@@ -601,7 +601,7 @@ WebSite will be forced to move to pcmk-1. - [source,C] - ----- - # pcs constraint location WebSite prefers pcmk-1=INFINITY --# pcs constraint --full -+# pcs constraint all - Location Constraints: - Resource: WebSite - Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY) -@@ -708,7 +708,7 @@ Ordering Constraints: - start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory) - Colocation Constraints: - WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY) --# pcs constraint remove location-WebSite-pcmk-1-INFINITY -+# pcs constraint rm location-WebSite-pcmk-1-INFINITY - # pcs constraint - Location Constraints: - Ordering Constraints: -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Installation.txt b/doc/Clusters_from_Scratch/en-US/Ch-Installation.txt -index cf47602..aa0b4b9 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Installation.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Installation.txt -@@ -210,11 +210,23 @@ outside world. - ---- - # setenforce 0 - # sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config -+# systemctl disable firewalld.service -+# systemctl stop firewalld.service -+---- -+ -+or (on older Fedora) -+ -+[source,C] -+---- -+# setenforce 0 -+# sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config - # systemctl disable iptables.service - # rm '/etc/systemd/system/basic.target.wants/iptables.service' - # systemctl stop iptables.service - ---- - -+ -+ - === Short Node Names === - - During installation, we filled in the machine's fully qualified domain -@@ -538,7 +550,7 @@ Password: - pcmk-1: Authorized - pcmk-2: Authorized - --# pcs cluster setup --name mycluster pcmk-1 pcmk-2 -+# pcs cluster setup mycluster pcmk-1 pcmk-2 - pcmk-1: Succeeded - pcmk-2: Succeeded - ---- -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Shared-Storage.txt b/doc/Clusters_from_Scratch/en-US/Ch-Shared-Storage.txt -index cc2cec6..f6b50d9 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Shared-Storage.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Shared-Storage.txt -@@ -334,7 +334,7 @@ cib. - - [source,C] - ---- --# pcs cluster cib-push drbd_cfg -+# pcs cluster push cib drbd_cfg - CIB updated - - # pcs status -@@ -594,7 +594,7 @@ cluster put it into effect. - ifdef::pcs[] - [source,C] - ---- --# pcs cluster cib-push fs_cfg -+# pcs cluster push cib fs_cfg - CIB updated - # pcs status - Last updated: Fri Aug 10 12:47:01 2012 -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Stonith.txt b/doc/Clusters_from_Scratch/en-US/Ch-Stonith.txt -index 9518fc2..123bd4b 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Stonith.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Stonith.txt -@@ -81,7 +81,7 @@ ifdef::crmsh[] - endif::[] - - ifdef::pcs[] --. Commit the new configuration. +pcs cluster cib-push stonith_cfg+ -+. Commit the new configuration. +pcs cluster push cib stonith_cfg+ - endif::[] - - . Once the stonith resource is running, you can test it by executing: -@@ -261,7 +261,7 @@ Now push the configuration into the cluster. - ifdef::pcs[] - [source,C] - ---- --# pcs cluster cib-push stonith_cfg -+# pcs cluster push cib stonith_cfg - ---- - endif::[] - -diff --git a/doc/Clusters_from_Scratch/en-US/Ch-Verification.txt b/doc/Clusters_from_Scratch/en-US/Ch-Verification.txt -index 530e37b..c62cae4 100644 ---- a/doc/Clusters_from_Scratch/en-US/Ch-Verification.txt -+++ b/doc/Clusters_from_Scratch/en-US/Ch-Verification.txt -@@ -217,6 +217,13 @@ Next, check for any ERRORs during startup - there shouldn't be any. - # grep -i error /var/log/messages - ---- - -+or (on Fedora 20) -+ -+[source,C] -+---- -+# journalctl | grep -i error -+---- -+ - Repeat these checks on the other node. The results should be the same. - - endif::[] -diff --git a/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Passive.po b/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Passive.po -index f9cc723..daefc41 100644 ---- a/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Passive.po -+++ b/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Passive.po -@@ -379,7 +379,7 @@ msgstr "当有半数以上的节点在线时,这个集群就认为自己拥有 - #. Tag: literallayout - #, no-c-format - msgid "total_nodes < 2 * active_nodes" --msgstr "总节点数 < 2 * 活跃节点数" -+msgstr "" - - #. Tag: para - #, no-c-format -diff --git a/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt b/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt -index 8498ce0..b4eaf49 100644 ---- a/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt -+++ b/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt -@@ -36,28 +36,33 @@ nothing able to run anywhere and selectively enable allowed nodes. - === Options === - - .Options for Simple Location Constraints --[width="95%",cols="2m,5<",options="header",align="center"] -+[width="95%",cols="2m,1,5<",options="header",align="center"] - |========================================================= - - |Field -+|Default - |Description - - |id -+| - |A unique name for the constraint - indexterm:[id,Location Constraints] - indexterm:[Constraints,Location,id] - - |rsc -+| - |A resource name - indexterm:[rsc,Location Constraints] - indexterm:[Constraints,Location,rsc] - - |node -+| - |A node's name - indexterm:[node,Location Constraints] - indexterm:[Constraints,Location,node] - - |score -+| - |Positive values indicate the resource should run on this - node. Negative values indicate the resource should not run on this - node. -@@ -67,6 +72,30 @@ indexterm:[Constraints,Location,node] - indexterm:[score,Location Constraints] - indexterm:[Constraints,Location,score] - -+|resource-discovery -+|+always+ -+|Indicates whether or not Pacemaker should perform resource discovery -+on this node for the specified resource. Limiting resource discovery to -+a subset of nodes the resource is physically capable of running on -+can significantly boost performance when a large set of nodes are preset. -+When pacemaker_remote is in use to expand the node count into the 100s of -+nodes range, this option should be considered. -+ -+* 'always' - Always perform resource discovery for the specified resource on this node. -+ -+* 'never' - Never perform resource discovery for the specified resource on this node. -+ This option should generally be used with a -INFINITY score. Although that is not strictly -+ required. -+ -+* 'exclusive' - Only perform resource discovery for the specified resource on this node. Multiple -+ location constraints using 'exclusive' discovery for the same resource across different nodes -+ creates a subset of nodes resource-discovery is exclusive to. If a resource is marked -+ for 'exclusive' discovery on one or more nodes, that resource is only allowed to be placed -+ within that subset of nodes. -+ -+indexterm:[Resource Discovery,Location Constraints] -+indexterm:[Constraints,Location,Resource Discovery] -+ - |========================================================= - - === Asymmetrical "Opt-In" Clusters === -diff --git a/fencing/commands.c b/fencing/commands.c -index 577ea95..c193a9d 100644 ---- a/fencing/commands.c -+++ b/fencing/commands.c -@@ -2109,6 +2109,14 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req - free_async_command(cmd); - free_xml(reply); - -+ } else if(safe_str_eq(op, CRM_OP_RM_NODE_CACHE)) { -+ int id = 0; -+ const char *name = NULL; -+ -+ crm_element_value_int(request, XML_ATTR_ID, &id); -+ name = crm_element_value(request, XML_ATTR_UNAME); -+ reap_crm_member(id, name); -+ - } else { - crm_err("Unknown %s from %s", op, client ? client->name : remote_peer); - crm_log_xml_warn(request, "UnknownOp"); -diff --git a/fencing/main.c b/fencing/main.c -index 2694452..70b5bde 100644 ---- a/fencing/main.c -+++ b/fencing/main.c -@@ -97,6 +97,7 @@ st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) - int call_options = 0; - xmlNode *request = NULL; - crm_client_t *c = crm_client_get(qbc); -+ const char *op = NULL; - - if (c == NULL) { - crm_info("Invalid client: %p", qbc); -@@ -109,6 +110,20 @@ st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) - return 0; - } - -+ -+ op = crm_element_value(request, F_CRM_TASK); -+ if(safe_str_eq(op, CRM_OP_RM_NODE_CACHE)) { -+ crm_xml_add(request, F_TYPE, T_STONITH_NG); -+ crm_xml_add(request, F_STONITH_OPERATION, op); -+ crm_xml_add(request, F_STONITH_CLIENTID, c->id); -+ crm_xml_add(request, F_STONITH_CLIENTNAME, crm_client_name(c)); -+ crm_xml_add(request, F_STONITH_CLIENTNODE, stonith_our_uname); -+ -+ send_cluster_message(NULL, crm_msg_stonith_ng, request, FALSE); -+ free_xml(request); -+ return 0; -+ } -+ - if (c->name == NULL) { - const char *value = crm_element_value(request, F_STONITH_CLIENTNAME); - -@@ -1099,6 +1114,7 @@ stonith_cleanup(void) - static struct crm_option long_options[] = { - {"stand-alone", 0, 0, 's'}, - {"stand-alone-w-cpg", 0, 0, 'c'}, -+ {"logfile", 1, 0, 'l'}, - {"verbose", 0, 0, 'V'}, - {"version", 0, 0, '$'}, - {"help", 0, 0, '?'}, -@@ -1200,6 +1216,9 @@ main(int argc, char **argv) - case 'V': - crm_bump_log_level(argc, argv); - break; -+ case 'l': -+ crm_add_logfile(optarg); -+ break; - case 's': - stand_alone = TRUE; - break; -diff --git a/fencing/regression.py.in b/fencing/regression.py.in -index c4cb2d8..fe6d418 100644 ---- a/fencing/regression.py.in -+++ b/fencing/regression.py.in -@@ -82,24 +82,34 @@ class Test: - test.wait() - - if self.verbose: -+ self.stonith_options = self.stonith_options + " -V" - print "Starting stonithd with %s" % self.stonith_options - -+ if os.path.exists("/tmp/stonith-regression.log"): -+ os.remove('/tmp/stonith-regression.log') -+ - self.stonith_process = subprocess.Popen( -- shlex.split("@CRM_DAEMON_DIR@/stonithd %s -V" % self.stonith_options), -- stdout=subprocess.PIPE, -- stderr=subprocess.PIPE) -+ shlex.split("@CRM_DAEMON_DIR@/stonithd %s -l /tmp/stonith-regression.log" % self.stonith_options)) - - time.sleep(1) - - def clean_environment(self): - if self.stonith_process: - self.stonith_process.terminate() -+ self.stonith_process.wait() - -- self.stonith_output = self.stonith_process.communicate()[1] -+ self.stonith_output = "" - self.stonith_process = None - -+ f = open('/tmp/stonith-regression.log', 'r') -+ for line in f.readlines(): -+ self.stonith_output = self.stonith_output + line -+ - if self.verbose: -+ print "Daemon Output Start" - print self.stonith_output -+ print "Daemon Output End" -+ os.remove('/tmp/stonith-regression.log') - - def add_stonith_log_pattern(self, pattern): - self.stonith_patterns.append(pattern) -@@ -953,7 +963,7 @@ if __name__ == "__main__": - self.stop_corosync() - - if self.verbose and os.path.exists('/var/log/corosync.log'): -- print "Daemon output" -+ print "Corosync output" - f = open('/var/log/corosync.log', 'r') - for line in f.readlines(): - print line.strip() -diff --git a/lib/cib/cib_remote.c b/lib/cib/cib_remote.c -index d9dde9b..9b98892 100644 ---- a/lib/cib/cib_remote.c -+++ b/lib/cib/cib_remote.c -@@ -226,6 +226,8 @@ cib_tls_signon(cib_t * cib, crm_remote_t * connection, gboolean event_channel) - return -ENOTCONN; - } - -+ connection->tcp_socket = sock; -+ - if (private->encrypted) { - /* initialize GnuTls lib */ - #ifdef HAVE_GNUTLS_GNUTLS_H -@@ -250,8 +252,6 @@ cib_tls_signon(cib_t * cib, crm_remote_t * connection, gboolean event_channel) - #else - return -EPROTONOSUPPORT; - #endif -- } else { -- connection->tcp_socket = sock; - } - - /* login to server */ -diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c -index 24700e5..70a0321 100644 ---- a/lib/cluster/membership.c -+++ b/lib/cluster/membership.c -@@ -389,9 +389,15 @@ crm_find_peer(unsigned int id, const char *uname) - } - - } else if(uname && by_id->uname) { -- crm_dump_peer_hash(LOG_INFO, __FUNCTION__); -- crm_warn("Node '%s' and '%s' share the same cluster nodeid: %u %s", by_id->uname, by_name->uname, id, uname); -- crm_abort(__FILE__, __FUNCTION__, __LINE__, "member weirdness", TRUE, TRUE); -+ if(safe_str_eq(uname, by_id->uname)) { -+ crm_notice("Node '%s' has changed its ID from %u to %u", by_id->uname, by_name->id, by_id->id); -+ g_hash_table_foreach_remove(crm_peer_cache, crm_hash_find_by_data, by_name); -+ -+ } else { -+ crm_warn("Node '%s' and '%s' share the same cluster nodeid: %u %s", by_id->uname, by_name->uname, id, uname); -+ crm_dump_peer_hash(LOG_INFO, __FUNCTION__); -+ crm_abort(__FILE__, __FUNCTION__, __LINE__, "member weirdness", TRUE, TRUE); -+ } - - } else if(id && by_name->id) { - crm_warn("Node %u and %u share the same name: '%s'", by_id->id, by_name->id, uname); -diff --git a/lib/common/remote.c b/lib/common/remote.c -index e2492b9..f11ebcd 100644 ---- a/lib/common/remote.c -+++ b/lib/common/remote.c -@@ -308,13 +308,16 @@ crm_remote_sendv(crm_remote_t * remote, struct iovec * iov, int iovs) - int rc = -ESOCKTNOSUPPORT; - - for(; lpc < iovs; lpc++) { -- if (remote->tcp_socket) { -- rc = crm_send_plaintext(remote->tcp_socket, iov[lpc].iov_base, iov[lpc].iov_len); --#ifdef HAVE_GNUTLS_GNUTLS_H - -- } else if (remote->tls_session) { -+#ifdef HAVE_GNUTLS_GNUTLS_H -+ if (remote->tls_session) { - rc = crm_send_tls(remote->tls_session, iov[lpc].iov_base, iov[lpc].iov_len); -+ } else if (remote->tcp_socket) { -+#else -+ if (remote->tcp_socket) { - #endif -+ rc = crm_send_plaintext(remote->tcp_socket, iov[lpc].iov_base, iov[lpc].iov_len); -+ - } else { - crm_err("Unsupported connection type"); - } -@@ -448,14 +451,16 @@ crm_remote_ready(crm_remote_t * remote, int timeout /* ms */ ) - int rc = 0; - time_t start; - -- if (remote->tcp_socket) { -- sock = remote->tcp_socket; - #ifdef HAVE_GNUTLS_GNUTLS_H -- } else if (remote->tls_session) { -+ if (remote->tls_session) { - void *sock_ptr = gnutls_transport_get_ptr(*remote->tls_session); - - sock = GPOINTER_TO_INT(sock_ptr); -+ } else if (remote->tcp_socket) { -+#else -+ if (remote->tcp_socket) { - #endif -+ sock = remote->tcp_socket; - } else { - crm_err("Unsupported connection type"); - } -@@ -519,17 +524,8 @@ crm_remote_recv_once(crm_remote_t * remote) - CRM_ASSERT(remote->buffer != NULL); - } - -- if (remote->tcp_socket) { -- errno = 0; -- rc = read(remote->tcp_socket, -- remote->buffer + remote->buffer_offset, -- remote->buffer_size - remote->buffer_offset); -- if(rc < 0) { -- rc = -errno; -- } -- - #ifdef HAVE_GNUTLS_GNUTLS_H -- } else if (remote->tls_session) { -+ if (remote->tls_session) { - rc = gnutls_record_recv(*(remote->tls_session), - remote->buffer + remote->buffer_offset, - remote->buffer_size - remote->buffer_offset); -@@ -541,7 +537,18 @@ crm_remote_recv_once(crm_remote_t * remote) - crm_debug("TLS receive failed: %s (%d)", gnutls_strerror(rc), rc); - rc = -pcmk_err_generic; - } -+ } else if (remote->tcp_socket) { -+#else -+ if (remote->tcp_socket) { - #endif -+ errno = 0; -+ rc = read(remote->tcp_socket, -+ remote->buffer + remote->buffer_offset, -+ remote->buffer_size - remote->buffer_offset); -+ if(rc < 0) { -+ rc = -errno; -+ } -+ - } else { - crm_err("Unsupported connection type"); - return -ESOCKTNOSUPPORT; -diff --git a/lib/common/xml.c b/lib/common/xml.c -index 58d0a00..e63a582 100644 ---- a/lib/common/xml.c -+++ b/lib/common/xml.c -@@ -1281,7 +1281,10 @@ __xml_build_changes(xmlNode * xml, xmlNode *patchset) - for (pIter = crm_first_attr(xml); pIter != NULL; pIter = pIter->next) { - const char *value = crm_element_value(xml, (const char *)pIter->name); - -- crm_xml_add(result, (const char *)pIter->name, value); -+ p = pIter->_private; -+ if (is_not_set(p->flags, xpf_deleted)) { -+ crm_xml_add(result, (const char *)pIter->name, value); -+ } - } - } - -@@ -5715,7 +5718,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g - } - - } else { -- crm_notice("Upgrading %s-style configuration to %s with %s", -+ crm_debug("Upgrading %s-style configuration to %s with %s", - known_schemas[lpc].name, known_schemas[next].name, - known_schemas[lpc].transform ? known_schemas[lpc].transform : "no-op"); - -@@ -5746,7 +5749,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g - } - - if (*best > match) { -- crm_notice("%s the configuration from %s to %s", -+ crm_info("%s the configuration from %s to %s", - transform?"Transformed":"Upgraded", - value ? value : "", known_schemas[*best].name); - crm_xml_add(xml, XML_ATTR_VALIDATION, known_schemas[*best].name); -diff --git a/lib/services/services.c b/lib/services/services.c -index 582fbe1..c7b6c89 100644 ---- a/lib/services/services.c -+++ b/lib/services/services.c -@@ -305,6 +305,7 @@ services_action_create_generic(const char *exec, const char *args[]) - void - services_action_cleanup(svc_action_t * op) - { -+#if SUPPORT_DBUS - if(op->opaque->timerid != 0) { - crm_trace("Removing timer for call %s to %s", op->action, op->rsc); - g_source_remove(op->opaque->timerid); -@@ -330,6 +331,7 @@ services_action_cleanup(svc_action_t * op) - mainloop_del_fd(op->opaque->stdout_gsource); - op->opaque->stdout_gsource = NULL; - } -+#endif - } - - void -diff --git a/lrmd/regression.py.in b/lrmd/regression.py.in -index 649c984..50e975e 100755 ---- a/lrmd/regression.py.in -+++ b/lrmd/regression.py.in -@@ -435,14 +435,13 @@ if __name__ == "__main__": - os.system("cp %s/extra/resources/%s @OCF_RA_DIR@/pacemaker/%s" % (build_dir, ra, ra)) - os.system("chmod a+x @OCF_RA_DIR@/pacemaker/%s" % (ra)) - -- else: -- # Assume it's installed -- print "Using @datadir@/@PACKAGE@/tests/cts/LSBDummy" -- os.system("cp @datadir@/@PACKAGE@/tests/cts/LSBDummy /etc/init.d/LSBDummy") -- -- os.system("chmod a+x /etc/init.d/LSBDummy") -- os.system("ls -al /etc/init.d/LSBDummy") -+ else: -+ # Assume it's installed -+ print "Using @datadir@/@PACKAGE@/tests/cts/LSBDummy" -+ os.system("cp @datadir@/@PACKAGE@/tests/cts/LSBDummy /etc/init.d/LSBDummy") - -+ os.system("chmod a+x /etc/init.d/LSBDummy") -+ os.system("ls -al /etc/init.d/LSBDummy") - os.system("mkdir -p @CRM_CORE_DIR@/root") - - if os.path.exists("/bin/systemctl"): -diff --git a/pengine/constraints.c b/pengine/constraints.c -index 88e382b..a2ce9c4 100644 ---- a/pengine/constraints.c -+++ b/pengine/constraints.c -@@ -52,6 +52,8 @@ enum pe_order_kind { - enum pe_ordering get_flags(const char *id, enum pe_order_kind kind, - const char *action_first, const char *action_then, gboolean invert); - enum pe_ordering get_asymmetrical_flags(enum pe_order_kind kind); -+static rsc_to_node_t *generate_location_rule(resource_t * rsc, xmlNode * rule_xml, -+ const char *discovery, pe_working_set_t * data_set); - - gboolean - unpack_constraints(xmlNode * xml_constraints, pe_working_set_t * data_set) -@@ -687,7 +689,7 @@ unpack_rsc_location(xmlNode * xml_obj, resource_t * rsc_lh, const char * role, - if (crm_str_eq((const char *)rule_xml->name, XML_TAG_RULE, TRUE)) { - empty = FALSE; - crm_trace("Unpacking %s/%s", id, ID(rule_xml)); -- generate_location_rule(rsc_lh, rule_xml, data_set); -+ generate_location_rule(rsc_lh, rule_xml, discovery, data_set); - } - } - -@@ -917,8 +919,8 @@ get_node_score(const char *rule, const char *score, gboolean raw, node_t * node) - return score_f; - } - --rsc_to_node_t * --generate_location_rule(resource_t * rsc, xmlNode * rule_xml, pe_working_set_t * data_set) -+static rsc_to_node_t * -+generate_location_rule(resource_t * rsc, xmlNode * rule_xml, const char *discovery, pe_working_set_t * data_set) - { - const char *rule_id = NULL; - const char *score = NULL; -@@ -960,7 +962,7 @@ generate_location_rule(resource_t * rsc, xmlNode * rule_xml, pe_working_set_t * - do_and = FALSE; - } - -- location_rule = rsc2node_new(rule_id, rsc, 0, NULL, NULL, data_set); -+ location_rule = rsc2node_new(rule_id, rsc, 0, discovery, NULL, data_set); - - if (location_rule == NULL) { - return NULL; -diff --git a/pengine/test10/resource-discovery.xml b/pengine/test10/resource-discovery.xml -index 8b517df..1692cdb 100644 ---- a/pengine/test10/resource-discovery.xml -+++ b/pengine/test10/resource-discovery.xml -@@ -97,7 +97,13 @@ - - - -- -+ -+ -+ -+ -+ -+ -+ - - - -diff --git a/pengine/utils.h b/pengine/utils.h -index 5142e68..270d32a 100644 ---- a/pengine/utils.h -+++ b/pengine/utils.h -@@ -39,9 +39,6 @@ extern gboolean rsc_ticket_new(const char *id, resource_t * rsc_lh, ticket_t * t - const char *state_lh, const char *loss_policy, - pe_working_set_t * data_set); - --extern rsc_to_node_t *generate_location_rule(resource_t * rsc, xmlNode * location_rule, -- pe_working_set_t * data_set); -- - extern gint sort_node_weight(gconstpointer a, gconstpointer b, gpointer data_set); - - extern gboolean can_run_resources(const node_t * node); -diff --git a/tools/crm_node.c b/tools/crm_node.c -index 98847f3..5932f98 100644 ---- a/tools/crm_node.c -+++ b/tools/crm_node.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - int command = 0; - int ccm_fd = 0; -@@ -92,7 +93,7 @@ cib_remove_node(uint32_t id, const char *name) - crm_trace("Removing %s from the CIB", name); - - /* TODO: Use 'id' instead */ -- if(name == NULL) { -+ if(name == NULL && id == 0) { - return -ENOTUNIQ; - } - -@@ -101,17 +102,24 @@ cib_remove_node(uint32_t id, const char *name) - - crm_xml_add(node, XML_ATTR_UNAME, name); - crm_xml_add(node_state, XML_ATTR_UNAME, name); -+ if(id) { -+ char buffer[64]; -+ if(snprintf(buffer, 63, "%u", id) > 0) { -+ crm_xml_add(node, XML_ATTR_ID, buffer); -+ crm_xml_add(node_state, XML_ATTR_ID, buffer); -+ } -+ } - - cib = cib_new(); - cib->cmds->signon(cib, crm_system_name, cib_command); - - rc = cib->cmds->delete(cib, XML_CIB_TAG_NODES, node, cib_sync_call); - if (rc != pcmk_ok) { -- printf("Could not remove %s from " XML_CIB_TAG_NODES ": %s", name, pcmk_strerror(rc)); -+ printf("Could not remove %s/%u from " XML_CIB_TAG_NODES ": %s", name, id, pcmk_strerror(rc)); - } - rc = cib->cmds->delete(cib, XML_CIB_TAG_STATUS, node_state, cib_sync_call); - if (rc != pcmk_ok) { -- printf("Could not remove %s from " XML_CIB_TAG_STATUS ": %s", name, pcmk_strerror(rc)); -+ printf("Could not remove %s/%u from " XML_CIB_TAG_STATUS ": %s", name, id, pcmk_strerror(rc)); - } - - cib->cmds->signoff(cib); -@@ -156,6 +164,7 @@ int tools_remove_node_cache(const char *node, const char *target) - } - } - -+ - errno = 0; - n = strtol(node, &endptr, 10); - if (errno != 0 || endptr == node || *endptr != '\0') { -@@ -166,21 +175,39 @@ int tools_remove_node_cache(const char *node, const char *target) - name = get_node_name(n); - } - -- crm_trace("Removing %s aka. %s from the membership cache", name, node); -+ crm_trace("Removing %s aka. %s (%u) from the membership cache", name, node, n); - -- cmd = create_request(CRM_OP_RM_NODE_CACHE, -- NULL, NULL, target, "crm_node", admin_uuid); -+ if(safe_str_eq(target, T_ATTRD)) { -+ cmd = create_xml_node(NULL, __FUNCTION__); - -- if (n) { -- char buffer[64]; -+ crm_xml_add(cmd, F_TYPE, T_ATTRD); -+ crm_xml_add(cmd, F_ORIG, crm_system_name); - -- if(snprintf(buffer, 63, "%u", n) > 0) { -- crm_xml_add(cmd, XML_ATTR_ID, buffer); -+ crm_xml_add(cmd, F_ATTRD_TASK, "peer-remove"); -+ crm_xml_add(cmd, F_ATTRD_HOST, name); -+ -+ if (n) { -+ char buffer[64]; -+ if(snprintf(buffer, 63, "%u", n) > 0) { -+ crm_xml_add(cmd, F_ATTRD_HOST_ID, buffer); -+ } -+ } -+ -+ } else { -+ cmd = create_request(CRM_OP_RM_NODE_CACHE, -+ NULL, NULL, target, crm_system_name, admin_uuid); -+ if (n) { -+ char buffer[64]; -+ if(snprintf(buffer, 63, "%u", n) > 0) { -+ crm_xml_add(cmd, XML_ATTR_ID, buffer); -+ } - } -+ crm_xml_add(cmd, XML_ATTR_UNAME, name); - } -- crm_xml_add(cmd, XML_ATTR_UNAME, name); - - rc = crm_ipc_send(conn, cmd, 0, 0, NULL); -+ crm_debug("%s peer cache cleanup for %s (%u): %d", target, name, n, rc); -+ - if (rc > 0) { - rc = cib_remove_node(n, name); - } -@@ -189,8 +216,8 @@ int tools_remove_node_cache(const char *node, const char *target) - crm_ipc_close(conn); - crm_ipc_destroy(conn); - } -- free_xml(cmd); - free(admin_uuid); -+ free_xml(cmd); - free(name); - return rc > 0 ? 0 : rc; - } -@@ -649,6 +676,12 @@ try_corosync(int command, enum cluster_type_e stack) - - mainloop_io_t *ipc = NULL; - GMainLoop *amainloop = NULL; -+ const char *daemons[] = { -+ CRM_SYSTEM_CRMD, -+ "stonith-ng", -+ T_ATTRD, -+ CRM_SYSTEM_MCP, -+ }; - - struct ipc_client_callbacks node_callbacks = { - .dispatch = node_mcp_dispatch, -@@ -657,13 +690,11 @@ try_corosync(int command, enum cluster_type_e stack) - - switch (command) { - case 'R': -- if (tools_remove_node_cache(target_uname, CRM_SYSTEM_CRMD)) { -- crm_err("Failed to connect to "CRM_SYSTEM_CRMD" to remove node '%s'", target_uname); -- crm_exit(pcmk_err_generic); -- } -- if (tools_remove_node_cache(target_uname, CRM_SYSTEM_MCP)) { -- crm_err("Failed to connect to "CRM_SYSTEM_MCP" to remove node '%s'", target_uname); -- crm_exit(pcmk_err_generic); -+ for(rc = 0; rc < DIMOF(daemons); rc++) { -+ if (tools_remove_node_cache(target_uname, daemons[rc])) { -+ crm_err("Failed to connect to %s to remove node '%s'", daemons[rc], target_uname); -+ crm_exit(pcmk_err_generic); -+ } - } - crm_exit(pcmk_ok); - break; -@@ -834,8 +865,8 @@ main(int argc, char **argv) - force_flag = TRUE; - break; - case 'R': -- dangerous_cmd = TRUE; - command = flag; -+ dangerous_cmd = TRUE; - target_uname = optarg; - break; - case 'N': diff --git a/SOURCES/bz1165423-pcmk-coverity.patch b/SOURCES/bz1165423-pcmk-coverity.patch deleted file mode 100644 index 7207679..0000000 --- a/SOURCES/bz1165423-pcmk-coverity.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/lib/common/xml.c b/lib/common/xml.c -index 0effd47..f7779f5 100644 ---- a/lib/common/xml.c -+++ b/lib/common/xml.c -@@ -2759,7 +2759,7 @@ create_xml_node(xmlNode * parent, const char *name) - xmlNode *node = NULL; - - if (name == NULL || name[0] == 0) { -- CRM_CHECK(name != NULL || name[0] == 0, return NULL); -+ CRM_CHECK(name != NULL && name[0] == 0, return NULL); - return NULL; - } - -diff --git a/tools/crm_resource.c b/tools/crm_resource.c -index 236d43c..968683a 100644 ---- a/tools/crm_resource.c -+++ b/tools/crm_resource.c -@@ -1430,7 +1430,6 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate) - goto cleanup; - } - -- free(pid); - rc = write_xml_file(cib_xml_copy, shadow_file, FALSE); - - if (rc < 0) { diff --git a/SOURCES/bz1165423-pcmk-long-systemd-stop.patch b/SOURCES/bz1165423-pcmk-long-systemd-stop.patch deleted file mode 100644 index 0a22ae9..0000000 --- a/SOURCES/bz1165423-pcmk-long-systemd-stop.patch +++ /dev/null @@ -1,709 +0,0 @@ -diff --git a/GNUmakefile b/GNUmakefile -index f28dea8..7a4c929 100644 ---- a/GNUmakefile -+++ b/GNUmakefile -@@ -325,7 +325,7 @@ clang: - test -e $(CLANG_analyzer) - scan-build $(CLANG_checkers:%=-enable-checker %) make - --# V3 = scandir unsetenv alphasort -+# V3 = scandir unsetenv alphasort xalloc - # V2 = setenv strerror strchrnul strndup - # http://www.gnu.org/software/gnulib/manual/html_node/Initial-import.html#Initial-import - GNU_MODS = crypto/md5 -diff --git a/crmd/lrm.c b/crmd/lrm.c -index b68f657..8315f6f 100644 ---- a/crmd/lrm.c -+++ b/crmd/lrm.c -@@ -630,7 +630,7 @@ append_restart_list(lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, xmlNode * upd - crm_xml_add(restart, param, value); - } - len += strlen(param) + 2; -- list = realloc(list, len + 1); -+ list = realloc_safe(list, len + 1); - sprintf(list + start, " %s ", param); - } - -diff --git a/cts/CIB.py b/cts/CIB.py -index d26efdb..7922d8b 100644 ---- a/cts/CIB.py -+++ b/cts/CIB.py -@@ -298,7 +298,28 @@ class CIB11(ConfigBase): - # Group Resource - g = Group(self.Factory, "group-1") - g.add_child(self.NewIP()) -- g.add_child(self.NewIP()) -+ -+ if self.CM.Env["have_systemd"]: -+ dummy_service_file = """ -+[Unit] -+Description=Dummy resource that takes a while to start -+ -+[Service] -+Type=notify -+ExecStart=/usr/bin/python -c 'import time; import systemd.daemon;time.sleep(10); systemd.daemon.notify("READY=1"); time.sleep(3600)' -+ExecStop=sleep 10 -+ExecStop=/bin/kill -KILL $MAINPID -+""" -+ -+ os.system("cat <<-END >/tmp/DummySD.service\n%s\nEND" % (dummy_service_file)) -+ -+ self.CM.install_helper("DummySD.service", destdir="/usr/lib/systemd/system/", sourcedir="/tmp") -+ sysd = Resource(self.Factory, "petulant", "DummySD", "service") -+ sysd.add_op("monitor", "P10S") -+ g.add_child(sysd) -+ else: -+ g.add_child(self.NewIP()) -+ - g.add_child(self.NewIP()) - - # Group with the master -diff --git a/cts/environment.py b/cts/environment.py -index d741452..2b2a343 100644 ---- a/cts/environment.py -+++ b/cts/environment.py -@@ -283,9 +283,9 @@ class Environment: - break; - self["cts-master"] = master - -- if self.has_key("have_systemd"): -- self["have_systemd"] = not rsh(discover, "systemctl list-units") -- -+ if not self.has_key("have_systemd"): -+ self["have_systemd"] = not self.rsh(self.target, "systemctl list-units") -+ - self.detect_syslog() - self.detect_at_boot() - self.detect_ip_offset() -diff --git a/fencing/standalone_config.c b/fencing/standalone_config.c -index 01c22b6..4319c4a 100644 ---- a/fencing/standalone_config.c -+++ b/fencing/standalone_config.c -@@ -170,7 +170,7 @@ standalone_cfg_add_node(const char *node, const char *device, const char *ports) - - if (tmp) { - offset = strlen(tmp); -- tmp = realloc(tmp, len + offset + 1); -+ tmp = realloc_safe(tmp, len + offset + 1); - } else { - tmp = malloc(len); - } -diff --git a/include/crm_internal.h b/include/crm_internal.h -index 3eb88de..169d6d3 100644 ---- a/include/crm_internal.h -+++ b/include/crm_internal.h -@@ -341,4 +341,16 @@ void cib_ipc_servers_destroy(qb_ipcs_service_t *ipcs_ro, - qb_ipcs_service_t *ipcs_rw, - qb_ipcs_service_t *ipcs_shm); - -+static inline void *realloc_safe(void *ptr, size_t size) -+{ -+ void *ret = realloc(ptr, size); -+ -+ if(ret == NULL) { -+ abort(); -+ } -+ -+ return ret; -+} -+ -+ - #endif /* CRM_INTERNAL__H */ -diff --git a/lib/ais/plugin.c b/lib/ais/plugin.c -index 3d4f369..ab534fa 100644 ---- a/lib/ais/plugin.c -+++ b/lib/ais/plugin.c -@@ -1214,7 +1214,7 @@ pcmk_generate_membership_data(void) - - g_hash_table_foreach(membership_list, member_loop_fn, &data); - size = strlen(data.string); -- data.string = realloc(data.string, size + 9); /* 9 = + nul */ -+ data.string = realloc_safe(data.string, size + 9); /* 9 = + nul */ - sprintf(data.string + size, ""); - return data.string; - } -diff --git a/lib/ais/utils.c b/lib/ais/utils.c -index e56fb6d..94a2505 100644 ---- a/lib/ais/utils.c -+++ b/lib/ais/utils.c -@@ -409,7 +409,7 @@ append_member(char *data, crm_node_t * node) - if (node->version) { - size += (9 + strlen(node->version)); - } -- data = realloc(data, size); -+ data = realloc_safe(data, size); - - offset += snprintf(data + offset, size - offset, "id); - if (node->uname) { -diff --git a/lib/cluster/cpg.c b/lib/cluster/cpg.c -index 6c86e83..cda6326 100644 ---- a/lib/cluster/cpg.c -+++ b/lib/cluster/cpg.c -@@ -584,7 +584,7 @@ send_cluster_text(int class, const char *data, - msg->header.size = sizeof(AIS_Message) + msg->size; - - if (msg->size < CRM_BZ2_THRESHOLD) { -- msg = realloc(msg, msg->header.size); -+ msg = realloc_safe(msg, msg->header.size); - memcpy(msg->data, data, msg->size); - - } else { -@@ -595,14 +595,14 @@ send_cluster_text(int class, const char *data, - if (crm_compress_string(uncompressed, msg->size, 0, &compressed, &new_size)) { - - msg->header.size = sizeof(AIS_Message) + new_size; -- msg = realloc(msg, msg->header.size); -+ msg = realloc_safe(msg, msg->header.size); - memcpy(msg->data, compressed, new_size); - - msg->is_compressed = TRUE; - msg->compressed_size = new_size; - - } else { -- msg = realloc(msg, msg->header.size); -+ msg = realloc_safe(msg, msg->header.size); - memcpy(msg->data, data, msg->size); - } - -diff --git a/lib/cluster/heartbeat.c b/lib/cluster/heartbeat.c -index a801c8e..6f6a388 100644 ---- a/lib/cluster/heartbeat.c -+++ b/lib/cluster/heartbeat.c -@@ -106,7 +106,7 @@ convert_ha_field(xmlNode * parent, void *msg_v, int lpc) - - crm_trace("Trying to decompress %d bytes", (int)orig_len); - retry: -- uncompressed = realloc(uncompressed, size); -+ uncompressed = realloc_safe(uncompressed, size); - memset(uncompressed, 0, size); - used = size - 1; /* always leave room for a trailing '\0' - * BZ2_bzBuffToBuffDecompress wont say anything if -diff --git a/lib/common/logging.c b/lib/common/logging.c -index d64b77a..f211d80 100644 ---- a/lib/common/logging.c -+++ b/lib/common/logging.c -@@ -956,7 +956,7 @@ crm_log_args(int argc, char **argv) - } - - len = 2 + strlen(argv[lpc]); /* +1 space, +1 EOS */ -- arg_string = realloc(arg_string, len + existing_len); -+ arg_string = realloc_safe(arg_string, len + existing_len); - existing_len += sprintf(arg_string + existing_len, "%s ", argv[lpc]); - } - -diff --git a/lib/common/remote.c b/lib/common/remote.c -index f11ebcd..2a5b449 100644 ---- a/lib/common/remote.c -+++ b/lib/common/remote.c -@@ -520,7 +520,7 @@ crm_remote_recv_once(crm_remote_t * remote) - remote->buffer_size = 2 * read_len; - crm_trace("Expanding buffer to %u bytes", remote->buffer_size); - -- remote->buffer = realloc(remote->buffer, remote->buffer_size + 1); -+ remote->buffer = realloc_safe(remote->buffer, remote->buffer_size + 1); - CRM_ASSERT(remote->buffer != NULL); - } - -diff --git a/lib/common/utils.c b/lib/common/utils.c -index eacd8e9..d70778d 100644 ---- a/lib/common/utils.c -+++ b/lib/common/utils.c -@@ -1712,7 +1712,7 @@ crm_create_long_opts(struct crm_option *long_options) - * This dummy entry allows us to differentiate between the two in crm_get_option() - * and exit with the correct error code - */ -- long_opts = realloc(long_opts, (index + 1) * sizeof(struct option)); -+ long_opts = realloc_safe(long_opts, (index + 1) * sizeof(struct option)); - long_opts[index].name = "__dummmy__"; - long_opts[index].has_arg = 0; - long_opts[index].flag = 0; -@@ -1724,7 +1724,7 @@ crm_create_long_opts(struct crm_option *long_options) - continue; - } - -- long_opts = realloc(long_opts, (index + 1) * sizeof(struct option)); -+ long_opts = realloc_safe(long_opts, (index + 1) * sizeof(struct option)); - /*fprintf(stderr, "Creating %d %s = %c\n", index, - * long_options[lpc].name, long_options[lpc].val); */ - long_opts[index].name = long_options[lpc].name; -@@ -1735,7 +1735,7 @@ crm_create_long_opts(struct crm_option *long_options) - } - - /* Now create the list terminator */ -- long_opts = realloc(long_opts, (index + 1) * sizeof(struct option)); -+ long_opts = realloc_safe(long_opts, (index + 1) * sizeof(struct option)); - long_opts[index].name = NULL; - long_opts[index].has_arg = 0; - long_opts[index].flag = 0; -@@ -1759,7 +1759,7 @@ crm_set_options(const char *short_options, const char *app_usage, struct crm_opt - - for (lpc = 0; long_options[lpc].name != NULL; lpc++) { - if (long_options[lpc].val && long_options[lpc].val != '-' && long_options[lpc].val < UCHAR_MAX) { -- local_short_options = realloc(local_short_options, opt_string_len + 4); -+ local_short_options = realloc_safe(local_short_options, opt_string_len + 4); - local_short_options[opt_string_len++] = long_options[lpc].val; - /* getopt(3) says: Two colons mean an option takes an optional arg; */ - if (long_options[lpc].has_arg == optional_argument) { -@@ -2517,7 +2517,7 @@ add_list_element(char *list, const char *value) - } - len = last + 2; /* +1 space, +1 EOS */ - len += strlen(value); -- list = realloc(list, len); -+ list = realloc_safe(list, len); - sprintf(list + last, " %s", value); - return list; - } -diff --git a/lib/common/xml.c b/lib/common/xml.c -index e63a582..0effd47 100644 ---- a/lib/common/xml.c -+++ b/lib/common/xml.c -@@ -206,7 +206,7 @@ static inline bool TRACKING_CHANGES(xmlNode *xml) - } else if(rc >= ((max) - (offset))) { \ - char *tmp = NULL; \ - (max) = QB_MAX(CHUNK_SIZE, (max) * 2); \ -- tmp = realloc((buffer), (max) + 1); \ -+ tmp = realloc_safe((buffer), (max) + 1); \ - CRM_ASSERT(tmp); \ - (buffer) = tmp; \ - } else { \ -@@ -223,7 +223,7 @@ insert_prefix(int options, char **buffer, int *offset, int *max, int depth) - - if ((*buffer) == NULL || spaces >= ((*max) - (*offset))) { - (*max) = QB_MAX(CHUNK_SIZE, (*max) * 2); -- (*buffer) = realloc((*buffer), (*max) + 1); -+ (*buffer) = realloc_safe((*buffer), (*max) + 1); - } - memset((*buffer) + (*offset), ' ', spaces); - (*offset) += spaces; -@@ -305,7 +305,7 @@ static void __xml_schema_add( - int last = xml_schema_max; - - xml_schema_max++; -- known_schemas = realloc(known_schemas, xml_schema_max*sizeof(struct schema_s)); -+ known_schemas = realloc_safe(known_schemas, xml_schema_max*sizeof(struct schema_s)); - CRM_ASSERT(known_schemas != NULL); - memset(known_schemas+last, 0, sizeof(struct schema_s)); - known_schemas[last].type = type; -@@ -2759,6 +2759,7 @@ create_xml_node(xmlNode * parent, const char *name) - xmlNode *node = NULL; - - if (name == NULL || name[0] == 0) { -+ CRM_CHECK(name != NULL || name[0] == 0, return NULL); - return NULL; - } - -@@ -2905,7 +2906,7 @@ crm_xml_err(void *ctx, const char *msg, ...) - buf = NULL; - - } else { -- buffer = realloc(buffer, 1 + buffer_len + len); -+ buffer = realloc_safe(buffer, 1 + buffer_len + len); - memcpy(buffer + buffer_len, buf, len); - buffer_len += len; - buffer[buffer_len] = 0; -@@ -2997,7 +2998,7 @@ stdin2xml(void) - break; - } - -- xml_buffer = realloc(xml_buffer, next); -+ xml_buffer = realloc_safe(xml_buffer, next); - read_chars = fread(xml_buffer + data_length, 1, XML_BUFFER_SIZE, stdin); - data_length += read_chars; - } while (read_chars > 0); -@@ -3043,7 +3044,7 @@ decompress_file(const char *filename) - - rc = BZ_OK; - while (rc == BZ_OK) { -- buffer = realloc(buffer, XML_BUFFER_SIZE + length + 1); -+ buffer = realloc_safe(buffer, XML_BUFFER_SIZE + length + 1); - read_len = BZ2_bzRead(&rc, bz_file, buffer + length, XML_BUFFER_SIZE); - - crm_trace("Read %ld bytes from file: %d", (long)read_len, rc); -@@ -3301,7 +3302,7 @@ crm_xml_escape_shuffle(char *text, int start, int *length, const char *replace) - int offset = strlen(replace) - 1; /* We have space for 1 char already */ - - *length += offset; -- text = realloc(text, *length); -+ text = realloc_safe(text, *length); - - for (lpc = (*length) - 1; lpc > (start + offset); lpc--) { - text[lpc] = text[lpc - offset]; -@@ -5369,7 +5370,7 @@ crm_xml_init(void) - if(init) { - init = FALSE; - /* The default allocator XML_BUFFER_ALLOC_EXACT does far too many -- * realloc()s and it can take upwards of 18 seconds (yes, seconds) -+ * realloc_safe()s and it can take upwards of 18 seconds (yes, seconds) - * to dump a 28kb tree which XML_BUFFER_ALLOC_DOUBLEIT can do in - * less than 1 second. - */ -@@ -5987,7 +5988,7 @@ get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level) - len += strlen(xpath); - - xpath_full = strdup(xpath_prefix); -- xpath_full = realloc(xpath_full, len + 1); -+ xpath_full = realloc_safe(xpath_full, len + 1); - strncat(xpath_full, xpath, len); - - result = get_xpath_object(xpath_full, xml_obj, error_level); -diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c -index 06b9492..e51d673 100644 ---- a/lib/fencing/st_client.c -+++ b/lib/fencing/st_client.c -@@ -308,7 +308,7 @@ append_arg(gpointer key, gpointer value, gpointer user_data) - last = strlen(*args); - } - -- *args = realloc(*args, last + len); -+ *args = realloc_safe(*args, last + len); - crm_trace("Appending: %s=%s", (char *)key, (char *)value); - sprintf((*args) + last, "%s=%s\n", (char *)key, (char *)value); - } -@@ -627,7 +627,7 @@ read_output(int fd) - * 'more' is always less than our buffer size - */ - crm_trace("Got %d more bytes: %.200s...", more, buffer); -- output = realloc(output, len + more + 1); -+ output = realloc_safe(output, len + more + 1); - snprintf(output + len, more + 1, "%s", buffer); - len += more; - } -diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c -index 8d6f450..de29706 100644 ---- a/lib/services/services_linux.c -+++ b/lib/services/services_linux.c -@@ -94,7 +94,7 @@ svc_read_output(int fd, svc_action_t * op, bool is_stderr) - if (rc > 0) { - crm_trace("Got %d characters starting with %.20s", rc, buf); - buf[rc] = 0; -- data = realloc(data, len + rc + 1); -+ data = realloc_safe(data, len + rc + 1); - len += sprintf(data + len, "%s", buf); - - } else if (errno != EINTR) { -diff --git a/lib/services/systemd.c b/lib/services/systemd.c -index a8bf1b4..c0a1721 100644 ---- a/lib/services/systemd.c -+++ b/lib/services/systemd.c -@@ -462,10 +462,11 @@ systemd_async_dispatch(DBusPendingCall *pending, void *user_data) - if(op) { - crm_trace("Got result: %p for %p for %s, %s", reply, pending, op->rsc, op->action); - op->opaque->pending = NULL; -+ systemd_exec_result(reply, op); -+ - } else { - crm_trace("Got result: %p for %p", reply, pending); - } -- systemd_exec_result(reply, op); - - if(pending) { - dbus_pending_call_unref(pending); -@@ -491,6 +492,8 @@ systemd_unit_check(const char *name, const char *state, void *userdata) - op->rc = PCMK_OCF_OK; - } else if (g_strcmp0(state, "activating") == 0) { - op->rc = PCMK_OCF_PENDING; -+ } else if (g_strcmp0(state, "deactivating") == 0) { -+ op->rc = PCMK_OCF_PENDING; - } else { - op->rc = PCMK_OCF_NOT_RUNNING; - } -diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c -index d3ede18..0f5f529 100644 ---- a/lrmd/lrmd.c -+++ b/lrmd/lrmd.c -@@ -790,10 +790,30 @@ action_complete(svc_action_t * action) - cmd->real_action = cmd->action; - cmd->action = strdup("monitor"); - -+ } else if(cmd->exec_rc == PCMK_OCF_OK && safe_str_eq(cmd->action, "stop")) { -+ goagain = true; -+ cmd->real_action = cmd->action; -+ cmd->action = strdup("monitor"); -+ - } else if(cmd->real_action) { - /* Ok, so this is the follow up monitor action to check if start actually completed */ - if(cmd->lrmd_op_status == PCMK_LRM_OP_DONE && cmd->exec_rc == PCMK_OCF_PENDING) { - goagain = true; -+ -+ } else { -+ int time_sum = 0; -+ int timeout_left = 0; -+ struct timeb now = { 0, }; -+ -+ ftime(&now); -+ time_sum = time_diff_ms(&now, &cmd->t_first_run); -+ timeout_left = cmd->timeout_orig - time_sum; -+ crm_debug("%s %s is now complete (elapsed=%dms, remaining=%dms): %s (%d)", -+ cmd->rsc_id, cmd->real_action, time_sum, timeout_left, services_ocf_exitcode_str(cmd->exec_rc), cmd->exec_rc); -+ -+ if(cmd->lrmd_op_status == PCMK_LRM_OP_DONE && cmd->exec_rc == PCMK_OCF_NOT_RUNNING && safe_str_eq(cmd->real_action, "stop")) { -+ cmd->exec_rc = PCMK_OCF_OK; -+ } - } - } - } -@@ -827,13 +847,22 @@ action_complete(svc_action_t * action) - delay = timeout_left/2; - } - -+ delay = QB_MIN(2000, delay); - if (delay < timeout_left) { - cmd->start_delay = delay; - cmd->timeout = timeout_left; - -- if(cmd->exec_rc != PCMK_OCF_OK) { -- crm_info("%s %s failed (rc=%d): re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)", -- cmd->rsc_id, cmd->action, cmd->exec_rc, time_sum, timeout_left, delay); -+ if(cmd->exec_rc == PCMK_OCF_OK) { -+ crm_debug("%s %s may still be in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)", -+ cmd->rsc_id, cmd->real_action, time_sum, timeout_left, delay); -+ -+ } else if(cmd->exec_rc == PCMK_OCF_PENDING) { -+ crm_info("%s %s is still in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)", -+ cmd->rsc_id, cmd->action, time_sum, timeout_left, delay); -+ -+ } else { -+ crm_notice("%s %s failed '%s' (%d): re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)", -+ cmd->rsc_id, cmd->action, services_ocf_exitcode_str(cmd->exec_rc), cmd->exec_rc, time_sum, timeout_left, delay); - } - - cmd_reset(cmd); -diff --git a/pengine/allocate.c b/pengine/allocate.c -index 45e2212..748ca54 100644 ---- a/pengine/allocate.c -+++ b/pengine/allocate.c -@@ -1913,7 +1913,7 @@ expand_list(GListPtr list, char **rsc_list, char **node_list) - } - - crm_trace("Adding %s (%dc) at offset %d", rsc_id, len - 2, existing_len); -- *rsc_list = realloc(*rsc_list, len + existing_len); -+ *rsc_list = realloc_safe(*rsc_list, len + existing_len); - sprintf(*rsc_list + existing_len, "%s ", rsc_id); - } - -@@ -1930,7 +1930,7 @@ expand_list(GListPtr list, char **rsc_list, char **node_list) - } - - crm_trace("Adding %s (%dc) at offset %d", uname, len - 2, existing_len); -- *node_list = realloc(*node_list, len + existing_len); -+ *node_list = realloc_safe(*node_list, len + existing_len); - sprintf(*node_list + existing_len, "%s ", uname); - } - } -diff --git a/replace/scandir.c b/replace/scandir.c -index 7a8efea..0011630 100644 ---- a/replace/scandir.c -+++ b/replace/scandir.c -@@ -202,7 +202,7 @@ scandir(const char *directory_name, - if (counter + 1 == allocated) { - allocated <<= 1; - array = (struct dirent **) -- realloc((char *)array, allocated * sizeof(struct dirent *)); -+ realloc_safe((char *)array, allocated * sizeof(struct dirent *)); - if (array == NULL) { - closedir(directory); - free(array); -diff --git a/tools/crm_resource.c b/tools/crm_resource.c -index 6e510e1..236d43c 100644 ---- a/tools/crm_resource.c -+++ b/tools/crm_resource.c -@@ -1399,16 +1399,20 @@ static void display_list(GList *items, const char *tag) - static int - update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate) - { -+ char *pid = NULL; -+ char *shadow_file = NULL; -+ cib_t *shadow_cib = NULL; - xmlNode *cib_xml_copy = NULL; - int rc = cib->cmds->query(cib, NULL, &cib_xml_copy, cib_scope_local | cib_sync_call); - - if(rc != pcmk_ok) { - fprintf(stdout, "Could not obtain the current CIB: %s (%d)\n", pcmk_strerror(rc), rc); -- return crm_exit(rc); -+ goto cleanup; - - } else if (cli_config_update(&cib_xml_copy, NULL, FALSE) == FALSE) { - fprintf(stderr, "Could not upgrade the current CIB\n"); -- return -ENOKEY; -+ rc = -ENOKEY; -+ goto cleanup; - } - - set_working_set_defaults(data_set); -@@ -1416,70 +1420,103 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate) - data_set->now = crm_time_new(NULL); - - if(simulate) { -- char *pid = crm_itoa(getpid()); -- cib_t *shadow_cib = cib_shadow_new(pid); -- char *shadow_file = get_shadow_file(pid); -+ pid = crm_itoa(getpid()); -+ shadow_cib = cib_shadow_new(pid); -+ shadow_file = get_shadow_file(pid); - - if (shadow_cib == NULL) { - fprintf(stderr, "Could not create shadow cib: '%s'\n", pid); -- crm_exit(-ENXIO); -+ rc = -ENXIO; -+ goto cleanup; - } - -+ free(pid); - rc = write_xml_file(cib_xml_copy, shadow_file, FALSE); - - if (rc < 0) { - fprintf(stderr, "Could not populate shadow cib: %s (%d)\n", pcmk_strerror(rc), rc); -- free_xml(cib_xml_copy); -- return rc; -+ goto cleanup; - } - - rc = shadow_cib->cmds->signon(shadow_cib, crm_system_name, cib_command); - if(rc != pcmk_ok) { - fprintf(stderr, "Could not connect to shadow cib: %s (%d)\n", pcmk_strerror(rc), rc); -- free_xml(cib_xml_copy); -- return rc; -+ goto cleanup; - } - - do_calculations(data_set, cib_xml_copy, NULL); - run_simulation(data_set, shadow_cib, NULL, TRUE); - rc = update_dataset(shadow_cib, data_set, FALSE); - -- cib_delete(shadow_cib); -- /* unlink(shadow_file); */ -- free(shadow_file); -- - } else { - cluster_status(data_set); - } - -+ cleanup: -+ cib_delete(shadow_cib); -+ free_xml(cib_xml_copy); -+ free(pid); -+ -+ if(shadow_file) { -+ unlink(shadow_file); -+ free(shadow_file); -+ } -+ - return rc; - } - - static int --max_delay_in(pe_working_set_t * data_set, GList *resources) -+max_delay_for_resource(pe_working_set_t * data_set, resource_t *rsc) - { -+ int delay = 0; - int max_delay = 0; -- GList *item = NULL; - -- for (item = resources; item != NULL; item = item->next) { -- resource_t *rsc = pe_find_resource(data_set->resources, (const char *)item->data); -+ if(rsc && rsc->children) { -+ GList *iter = NULL; - -- if(rsc) { -- char *key = g_strdup_printf("%s_%s_0", rsc->id, RSC_STOP); -- action_t *stop = custom_action(rsc, key, RSC_STOP, NULL, TRUE, FALSE, data_set); -- const char *value = g_hash_table_lookup(stop->meta, XML_ATTR_TIMEOUT); -- int delay = crm_int_helper(value, NULL); -+ for(iter = rsc->children; iter; iter = iter->next) { -+ resource_t *child = (resource_t *)iter->data; - -+ delay = max_delay_for_resource(data_set, child); - if(delay > max_delay) { -- crm_trace("Calculated new delay of %s ms due to %s", value, rsc->id); -+ double seconds = delay / 1000; -+ crm_trace("Calculated new delay of %.1fs due to %s", seconds, child->id); - max_delay = delay; - } -- -- pe_free_action(stop); - } -+ -+ } else if(rsc) { -+ char *key = g_strdup_printf("%s_%s_0", rsc->id, RSC_STOP); -+ action_t *stop = custom_action(rsc, key, RSC_STOP, NULL, TRUE, FALSE, data_set); -+ const char *value = g_hash_table_lookup(stop->meta, XML_ATTR_TIMEOUT); -+ -+ max_delay = crm_int_helper(value, NULL); -+ pe_free_action(stop); - } - - -+ return max_delay; -+} -+ -+static int -+max_delay_in(pe_working_set_t * data_set, GList *resources) -+{ -+ int max_delay = 0; -+ GList *item = NULL; -+ -+ for (item = resources; item != NULL; item = item->next) { -+ int delay = 0; -+ resource_t *rsc = pe_find_resource(data_set->resources, (const char *)item->data); -+ -+ delay = max_delay_for_resource(data_set, rsc); -+ -+ if(delay > max_delay) { -+ double seconds = delay / 1000; -+ crm_trace("Calculated new delay of %.1fs due to %s", seconds, rsc->id); -+ max_delay = delay; -+ } -+ } -+ - return 5 + (max_delay / 1000); - } - -@@ -1507,7 +1544,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib - return -ENXIO; - } - -- -+ attr_set_type = XML_TAG_META_SETS; - rsc_id = strdup(rsc->id); - if(rsc->variant > pe_group) { - is_clone = TRUE; -@@ -1536,6 +1573,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib - rc = update_dataset(cib, &data_set, FALSE); - if(rc != pcmk_ok) { - fprintf(stdout, "Could not get new resource list: %s (%d)\n", pcmk_strerror(rc), rc); -+ free(rsc_id); - return rc; - } - -@@ -1553,6 +1591,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib - } - if(rc != pcmk_ok) { - fprintf(stderr, "Could not set target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc); -+ free(rsc_id); - return crm_exit(rc); - } - -@@ -1615,6 +1654,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib - - if(rc != pcmk_ok) { - fprintf(stderr, "Could not unset target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc); -+ free(rsc_id); - return crm_exit(rc); - } - -@@ -1659,6 +1699,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib - - } while(g_list_length(list_delta) > 0); - -+ free(rsc_id); - return pcmk_ok; - - failure: -@@ -1668,6 +1709,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib - } else { - delete_resource_attr(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set); - } -+ free(rsc_id); - return rc; - } - diff --git a/SOURCES/bz1176210-handle-orphaned-remote-nodes.patch b/SOURCES/bz1176210-handle-orphaned-remote-nodes.patch deleted file mode 100644 index 9331bab..0000000 --- a/SOURCES/bz1176210-handle-orphaned-remote-nodes.patch +++ /dev/null @@ -1,816 +0,0 @@ -diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c -index bdd6450..39756b1 100644 ---- a/lib/pengine/unpack.c -+++ b/lib/pengine/unpack.c -@@ -1828,7 +1828,7 @@ process_rsc_state(resource_t * rsc, node_t * node, - - should_fence = TRUE; - } else if (is_set(data_set->flags, pe_flag_stonith_enabled)) { -- if (is_baremetal_remote_node(node) && is_not_set(node->details->remote_rsc->flags, pe_rsc_failed)) { -+ if (is_baremetal_remote_node(node) && node->details->remote_rsc && is_not_set(node->details->remote_rsc->flags, pe_rsc_failed)) { - /* setting unseen = true means that fencing of the remote node will - * only occur if the connection resource is not going to start somewhere. - * This allows connection resources on a failed cluster-node to move to -diff --git a/pengine/allocate.c b/pengine/allocate.c -index 3241273..7dd70f1 100644 ---- a/pengine/allocate.c -+++ b/pengine/allocate.c -@@ -1636,6 +1636,7 @@ apply_remote_node_ordering(pe_working_set_t *data_set) - - if (action->node == NULL || - is_remote_node(action->node) == FALSE || -+ action->node->details->remote_rsc == NULL || - action->rsc == NULL || - is_set(action->flags, pe_action_pseudo)) { - continue; -diff --git a/pengine/regression.sh b/pengine/regression.sh -index 9172acb..93d4de1 100755 ---- a/pengine/regression.sh -+++ b/pengine/regression.sh -@@ -778,6 +778,7 @@ do_test remote-fence-unclean2 "Fence baremetal remote-node after cluster node f - do_test remote-move "Move remote-node connection resource" - do_test remote-disable "Disable a baremetal remote-node" - do_test remote-orphaned "Properly shutdown orphaned connection resource" -+do_test remote-orphaned2 "verify we can handle orphaned remote connections with active resources on the remote" - do_test remote-recover "Recover connection resource after cluster-node fails." - do_test remote-stale-node-entry "Make sure we properly handle leftover remote-node entries in the node section" - do_test remote-partial-migrate "Make sure partial migrations are handled before ops on the remote node." -diff --git a/pengine/test10/remote-orphaned2.dot b/pengine/test10/remote-orphaned2.dot -new file mode 100644 -index 0000000..d8f1c9f ---- /dev/null -+++ b/pengine/test10/remote-orphaned2.dot -@@ -0,0 +1,2 @@ -+ digraph "g" { -+} -diff --git a/pengine/test10/remote-orphaned2.exp b/pengine/test10/remote-orphaned2.exp -new file mode 100644 -index 0000000..56e315f ---- /dev/null -+++ b/pengine/test10/remote-orphaned2.exp -@@ -0,0 +1 @@ -+ -diff --git a/pengine/test10/remote-orphaned2.scores b/pengine/test10/remote-orphaned2.scores -new file mode 100644 -index 0000000..98853b1 ---- /dev/null -+++ b/pengine/test10/remote-orphaned2.scores -@@ -0,0 +1 @@ -+Allocation scores: -diff --git a/pengine/test10/remote-orphaned2.summary b/pengine/test10/remote-orphaned2.summary -new file mode 100644 -index 0000000..f4e5e17 ---- /dev/null -+++ b/pengine/test10/remote-orphaned2.summary -@@ -0,0 +1,27 @@ -+ -+Current cluster status: -+RemoteNode mrg-02: UNCLEAN (offline) -+RemoteNode mrg-03: UNCLEAN (offline) -+RemoteNode mrg-04: UNCLEAN (offline) -+Online: [ host-026 host-027 host-028 ] -+ -+ neutron-openvswitch-agent-compute (ocf::heartbeat:Dummy): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ libvirtd-compute (systemd:libvirtd): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ ceilometer-compute (systemd:openstack-ceilometer-compute): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ nova-compute (systemd:openstack-nova-compute): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ -+Transition Summary: -+ -+Executing cluster transition: -+ -+Revised cluster status: -+RemoteNode mrg-02: UNCLEAN (offline) -+RemoteNode mrg-03: UNCLEAN (offline) -+RemoteNode mrg-04: UNCLEAN (offline) -+Online: [ host-026 host-027 host-028 ] -+ -+ neutron-openvswitch-agent-compute (ocf::heartbeat:Dummy): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ libvirtd-compute (systemd:libvirtd): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ ceilometer-compute (systemd:openstack-ceilometer-compute): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ nova-compute (systemd:openstack-nova-compute): ORPHANED Started [ mrg-03 mrg-02 mrg-04 ] -+ -diff --git a/pengine/test10/remote-orphaned2.xml b/pengine/test10/remote-orphaned2.xml -new file mode 100644 -index 0000000..0bf6d33 ---- /dev/null -+++ b/pengine/test10/remote-orphaned2.xml -@@ -0,0 +1,718 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ diff --git a/SOURCES/bz1176210-require-all.patch b/SOURCES/bz1176210-require-all.patch deleted file mode 100644 index 21fbac5..0000000 --- a/SOURCES/bz1176210-require-all.patch +++ /dev/null @@ -1,5799 +0,0 @@ -diff --git a/include/crm/crm.h b/include/crm/crm.h -index 41279b0..37bc5ce 100644 ---- a/include/crm/crm.h -+++ b/include/crm/crm.h -@@ -133,6 +133,7 @@ extern char *crm_system_name; - # define CRM_OP_REPROBE "probe_again" - # define CRM_OP_CLEAR_FAILCOUNT "clear_failcount" - # define CRM_OP_RELAXED_SET "one-or-more" -+# define CRM_OP_RELAXED_CLONE "clone-one-or-more" - # define CRM_OP_RM_NODE_CACHE "rm_node_cache" - - # define CRMD_JOINSTATE_DOWN "down" -diff --git a/pengine/constraints.c b/pengine/constraints.c -index a2ce9c4..7054a8e 100644 ---- a/pengine/constraints.c -+++ b/pengine/constraints.c -@@ -255,6 +255,7 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) - resource_t *rsc_then = NULL; - resource_t *rsc_first = NULL; - gboolean invert_bool = TRUE; -+ gboolean require_all = TRUE; - enum pe_order_kind kind = pe_order_kind_mandatory; - enum pe_ordering cons_weight = pe_order_optional; - -@@ -264,6 +265,7 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) - const char *action_first = NULL; - const char *instance_then = NULL; - const char *instance_first = NULL; -+ const char *require_all_s = NULL; - - const char *id = crm_element_value(xml_obj, XML_ATTR_ID); - const char *invert = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL); -@@ -343,6 +345,14 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) - } - } - -+ require_all_s = crm_element_value(xml_obj, "require-all"); -+ if (require_all_s -+ && crm_is_true(require_all_s) == FALSE -+ && rsc_first->variant >= pe_clone) { -+ -+ require_all = FALSE; -+ } -+ - cons_weight = pe_order_optional; - kind = get_ordering_type(xml_obj); - -@@ -356,7 +366,29 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) - } else { - cons_weight |= get_flags(id, kind, action_first, action_then, FALSE); - } -- order_id = new_rsc_order(rsc_first, action_first, rsc_then, action_then, cons_weight, data_set); -+ -+ if (require_all == FALSE) { -+ GListPtr rIter = NULL; -+ char *task = crm_concat(CRM_OP_RELAXED_CLONE, id, ':'); -+ action_t *unordered_action = get_pseudo_op(task, data_set); -+ free(task); -+ -+ update_action_flags(unordered_action, pe_action_requires_any); -+ -+ for (rIter = rsc_first->children; id && rIter; rIter = rIter->next) { -+ resource_t *child = rIter->data; -+ -+ custom_action_order(child, generate_op_key(child->id, action_first, 0), NULL, -+ NULL, NULL, unordered_action, -+ pe_order_one_or_more | pe_order_implies_then_printed, data_set); -+ } -+ -+ order_id = custom_action_order(NULL, NULL, unordered_action, -+ rsc_then, generate_op_key(rsc_then->id, action_then, 0), NULL, -+ cons_weight | pe_order_runnable_left, data_set); -+ } else { -+ order_id = new_rsc_order(rsc_first, action_first, rsc_then, action_then, cons_weight, data_set); -+ } - - pe_rsc_trace(rsc_first, "order-%d (%s): %s_%s before %s_%s flags=0x%.6x", - order_id, id, rsc_first->id, action_first, rsc_then->id, action_then, cons_weight); -@@ -387,6 +419,7 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) - } - - cons_weight |= get_flags(id, kind, action_first, action_then, TRUE); -+ - order_id = new_rsc_order(rsc_then, action_then, rsc_first, action_first, cons_weight, data_set); - - pe_rsc_trace(rsc_then, "order-%d (%s): %s_%s before %s_%s flags=0x%.6x", -diff --git a/pengine/regression.sh b/pengine/regression.sh -index 3a244d7..c2bc7fb 100755 ---- a/pengine/regression.sh -+++ b/pengine/regression.sh -@@ -126,6 +126,16 @@ do_test one-or-more-5 "Start A and F even though C and D are stopped" - do_test one-or-more-6 "Leave A running even though B is stopped" - do_test one-or-more-7 "Leave A running even though C is stopped" - do_test bug-5140-require-all-false "Allow basegrp:0 to stop" -+do_test clone-require-all-1 "clone B starts node 3 and 4" -+do_test clone-require-all-2 "clone B remains stopped everywhere" -+do_test clone-require-all-3 "clone B stops everywhere because A stops everywhere" -+do_test clone-require-all-4 "clone B remains on node 3 and 4 with only one instance of A remaining." -+do_test clone-require-all-5 "clone B starts on node 1 3 and 4" -+do_test clone-require-all-6 "clone B remains active after shutting down instances of A" -+do_test clone-require-all-7 "clone A and B both start at the same time. all instances of A start before B." -+do_test clone-require-all-no-interleave-1 "C starts everywhere after A and B" -+do_test clone-require-all-no-interleave-2 "C starts on nodes 1, 2, and 4 with only one active instance of B" -+do_test clone-require-all-no-interleave-3 "C remains active when instance of B is stopped on one node and started on another." - - echo "" - do_test order1 "Order start 1 " -diff --git a/pengine/test10/clone-require-all-1.dot b/pengine/test10/clone-require-all-1.dot -new file mode 100644 -index 0000000..9856969 ---- /dev/null -+++ b/pengine/test10/clone-require-all-1.dot -@@ -0,0 +1,15 @@ -+ digraph "g" { -+"B-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = bold] -+"B-clone_start_0" -> "B:1_start_0 rhel7-auto4" [ style = bold] -+"B-clone_start_0" -> "B_start_0 rhel7-auto3" [ style = bold] -+"B-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"B:1_monitor_10000 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B:1_start_0 rhel7-auto4" -> "B-clone_running_0" [ style = bold] -+"B:1_start_0 rhel7-auto4" -> "B:1_monitor_10000 rhel7-auto4" [ style = bold] -+"B:1_start_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = bold] -+"B_start_0 rhel7-auto3" -> "B_monitor_10000 rhel7-auto3" [ style = bold] -+"B_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/clone-require-all-1.exp b/pengine/test10/clone-require-all-1.exp -new file mode 100644 -index 0000000..c2d1abd ---- /dev/null -+++ b/pengine/test10/clone-require-all-1.exp -@@ -0,0 +1,80 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-1.scores b/pengine/test10/clone-require-all-1.scores -new file mode 100644 -index 0000000..fe3ce21 ---- /dev/null -+++ b/pengine/test10/clone-require-all-1.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: 0 -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: 1 -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: 0 -+clone_color: A:1 allocation score on rhel7-auto2: 1 -+clone_color: A:1 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: 0 -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: 0 -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: 1 -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: 0 -+native_color: A:1 allocation score on rhel7-auto2: 1 -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 0 -+native_color: B:0 allocation score on rhel7-auto4: 0 -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: -INFINITY -+native_color: B:1 allocation score on rhel7-auto4: 0 -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-1.summary b/pengine/test10/clone-require-all-1.summary -new file mode 100644 -index 0000000..2cbb97d ---- /dev/null -+++ b/pengine/test10/clone-require-all-1.summary -@@ -0,0 +1,34 @@ -+ -+Current cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+Transition Summary: -+ * Start B:0 (rhel7-auto3) -+ * Start B:1 (rhel7-auto4) -+ -+Executing cluster transition: -+ * Pseudo action: B-clone_start_0 -+ * Resource action: B start on rhel7-auto3 -+ * Resource action: B start on rhel7-auto4 -+ * Pseudo action: B-clone_running_0 -+ * Resource action: B monitor=10000 on rhel7-auto3 -+ * Resource action: B monitor=10000 on rhel7-auto4 -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 ] -+ -diff --git a/pengine/test10/clone-require-all-1.xml b/pengine/test10/clone-require-all-1.xml -new file mode 100644 -index 0000000..724fac1 ---- /dev/null -+++ b/pengine/test10/clone-require-all-1.xml -@@ -0,0 +1,152 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-2.dot b/pengine/test10/clone-require-all-2.dot -new file mode 100644 -index 0000000..4f830ce ---- /dev/null -+++ b/pengine/test10/clone-require-all-2.dot -@@ -0,0 +1,42 @@ -+ digraph "g" { -+"A-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = dashed] -+"A-clone_start_0" -> "A_start_0 " [ style = dashed] -+"A-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"A-clone_stop_0" -> "A-clone_stopped_0" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto1" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto2" [ style = bold] -+"A-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stopped_0" -> "A-clone_start_0" [ style = dashed] -+"A-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"A_start_0 " -> "A-clone_running_0" [ style = dashed] -+"A_start_0 " [ style=dashed color="red" fontcolor="black"] -+"A_stop_0 rhel7-auto1" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto1" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"A_stop_0 rhel7-auto2" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto2" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto2" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = dashed] -+"B-clone_start_0" -> "B:1_start_0 rhel7-auto3" [ style = dashed] -+"B-clone_start_0" -> "B_start_0 rhel7-auto4" [ style = dashed] -+"B-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"B:1_monitor_10000 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"B:1_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = dashed] -+"B:1_start_0 rhel7-auto3" -> "B:1_monitor_10000 rhel7-auto3" [ style = dashed] -+"B:1_start_0 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"B_monitor_10000 rhel7-auto4" [ style=dashed color="red" fontcolor="black"] -+"B_start_0 rhel7-auto4" -> "B-clone_running_0" [ style = dashed] -+"B_start_0 rhel7-auto4" -> "B_monitor_10000 rhel7-auto4" [ style = dashed] -+"B_start_0 rhel7-auto4" [ style=dashed color="red" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"shooter_monitor_60000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"shooter_start_0 rhel7-auto3" -> "shooter_monitor_60000 rhel7-auto3" [ style = bold] -+"shooter_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"shooter_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"shooter_stop_0 rhel7-auto1" -> "shooter_start_0 rhel7-auto3" [ style = bold] -+"shooter_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/clone-require-all-2.exp b/pengine/test10/clone-require-all-2.exp -new file mode 100644 -index 0000000..a5ad63f ---- /dev/null -+++ b/pengine/test10/clone-require-all-2.exp -@@ -0,0 +1,107 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-2.scores b/pengine/test10/clone-require-all-2.scores -new file mode 100644 -index 0000000..cdbf611 ---- /dev/null -+++ b/pengine/test10/clone-require-all-2.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: 0 -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: 1 -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: 0 -+clone_color: A:1 allocation score on rhel7-auto2: 1 -+clone_color: A:1 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: 0 -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: 0 -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: -INFINITY -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 0 -+native_color: B:0 allocation score on rhel7-auto4: 0 -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: 0 -+native_color: B:1 allocation score on rhel7-auto4: -INFINITY -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-2.summary b/pengine/test10/clone-require-all-2.summary -new file mode 100644 -index 0000000..d4b2519 ---- /dev/null -+++ b/pengine/test10/clone-require-all-2.summary -@@ -0,0 +1,41 @@ -+ -+Current cluster status: -+Node rhel7-auto1 (1): standby -+Node rhel7-auto2 (2): standby -+Online: [ rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+Transition Summary: -+ * Move shooter (Started rhel7-auto1 -> rhel7-auto3) -+ * Stop A:0 (rhel7-auto1) -+ * Stop A:1 (rhel7-auto2) -+ * Start B:0 (rhel7-auto4 - blocked) -+ * Start B:1 (rhel7-auto3 - blocked) -+ -+Executing cluster transition: -+ * Resource action: shooter stop on rhel7-auto1 -+ * Pseudo action: A-clone_stop_0 -+ * Resource action: shooter start on rhel7-auto3 -+ * Resource action: A stop on rhel7-auto1 -+ * Resource action: A stop on rhel7-auto2 -+ * Pseudo action: A-clone_stopped_0 -+ * Pseudo action: all_stopped -+ * Resource action: shooter monitor=60000 on rhel7-auto3 -+ -+Revised cluster status: -+Node rhel7-auto1 (1): standby -+Node rhel7-auto2 (2): standby -+Online: [ rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto3 -+ Clone Set: A-clone [A] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -diff --git a/pengine/test10/clone-require-all-2.xml b/pengine/test10/clone-require-all-2.xml -new file mode 100644 -index 0000000..1fd9576 ---- /dev/null -+++ b/pengine/test10/clone-require-all-2.xml -@@ -0,0 +1,160 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-3.dot b/pengine/test10/clone-require-all-3.dot -new file mode 100644 -index 0000000..d93693d ---- /dev/null -+++ b/pengine/test10/clone-require-all-3.dot -@@ -0,0 +1,57 @@ -+ digraph "g" { -+"A-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = dashed] -+"A-clone_start_0" -> "A_start_0 " [ style = dashed] -+"A-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"A-clone_stop_0" -> "A-clone_stopped_0" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto1" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto2" [ style = bold] -+"A-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stopped_0" -> "A-clone_start_0" [ style = dashed] -+"A-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"A_start_0 " -> "A-clone_running_0" [ style = dashed] -+"A_start_0 " [ style=dashed color="red" fontcolor="black"] -+"A_stop_0 rhel7-auto1" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto1" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"A_stop_0 rhel7-auto2" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto2" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto2" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = dashed] -+"B-clone_start_0" -> "B_start_0 rhel7-auto3" [ style = dashed] -+"B-clone_start_0" -> "B_start_0 rhel7-auto4" [ style = dashed] -+"B-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"B-clone_stop_0" -> "B-clone_stopped_0" [ style = bold] -+"B-clone_stop_0" -> "B_stop_0 rhel7-auto3" [ style = bold] -+"B-clone_stop_0" -> "B_stop_0 rhel7-auto4" [ style = bold] -+"B-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_stopped_0" -> "A-clone_stop_0" [ style = bold] -+"B-clone_stopped_0" -> "B-clone_start_0" [ style = dashed] -+"B-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"B_monitor_10000 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"B_monitor_10000 rhel7-auto4" [ style=dashed color="red" fontcolor="black"] -+"B_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = dashed] -+"B_start_0 rhel7-auto3" -> "B_monitor_10000 rhel7-auto3" [ style = dashed] -+"B_start_0 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"B_start_0 rhel7-auto4" -> "B-clone_running_0" [ style = dashed] -+"B_start_0 rhel7-auto4" -> "B_monitor_10000 rhel7-auto4" [ style = dashed] -+"B_start_0 rhel7-auto4" [ style=dashed color="red" fontcolor="black"] -+"B_stop_0 rhel7-auto3" -> "B-clone_stopped_0" [ style = bold] -+"B_stop_0 rhel7-auto3" -> "B_start_0 rhel7-auto3" [ style = dashed] -+"B_stop_0 rhel7-auto3" -> "all_stopped" [ style = bold] -+"B_stop_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B_stop_0 rhel7-auto4" -> "B-clone_stopped_0" [ style = bold] -+"B_stop_0 rhel7-auto4" -> "B_start_0 rhel7-auto4" [ style = dashed] -+"B_stop_0 rhel7-auto4" -> "all_stopped" [ style = bold] -+"B_stop_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"shooter_monitor_60000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"shooter_start_0 rhel7-auto3" -> "shooter_monitor_60000 rhel7-auto3" [ style = bold] -+"shooter_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"shooter_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"shooter_stop_0 rhel7-auto1" -> "shooter_start_0 rhel7-auto3" [ style = bold] -+"shooter_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/clone-require-all-3.exp b/pengine/test10/clone-require-all-3.exp -new file mode 100644 -index 0000000..02eea7a ---- /dev/null -+++ b/pengine/test10/clone-require-all-3.exp -@@ -0,0 +1,169 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-3.scores b/pengine/test10/clone-require-all-3.scores -new file mode 100644 -index 0000000..814a972 ---- /dev/null -+++ b/pengine/test10/clone-require-all-3.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: 0 -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: 1 -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: 0 -+clone_color: A:1 allocation score on rhel7-auto2: 1 -+clone_color: A:1 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: 0 -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: 0 -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 1 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 1 -+clone_color: B:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: -INFINITY -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 1 -+native_color: B:0 allocation score on rhel7-auto4: -INFINITY -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: 0 -+native_color: B:1 allocation score on rhel7-auto4: 1 -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-3.summary b/pengine/test10/clone-require-all-3.summary -new file mode 100644 -index 0000000..68191b1 ---- /dev/null -+++ b/pengine/test10/clone-require-all-3.summary -@@ -0,0 +1,46 @@ -+ -+Current cluster status: -+Node rhel7-auto1 (1): standby -+Node rhel7-auto2 (2): standby -+Online: [ rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 ] -+ -+Transition Summary: -+ * Move shooter (Started rhel7-auto1 -> rhel7-auto3) -+ * Stop A:0 (rhel7-auto1) -+ * Stop A:1 (rhel7-auto2) -+ * Stop B:0 (Started rhel7-auto3) -+ * Stop B:1 (Started rhel7-auto4) -+ -+Executing cluster transition: -+ * Resource action: shooter stop on rhel7-auto1 -+ * Pseudo action: B-clone_stop_0 -+ * Resource action: shooter start on rhel7-auto3 -+ * Resource action: B stop on rhel7-auto3 -+ * Resource action: B stop on rhel7-auto4 -+ * Pseudo action: B-clone_stopped_0 -+ * Resource action: shooter monitor=60000 on rhel7-auto3 -+ * Pseudo action: A-clone_stop_0 -+ * Resource action: A stop on rhel7-auto1 -+ * Resource action: A stop on rhel7-auto2 -+ * Pseudo action: A-clone_stopped_0 -+ * Pseudo action: all_stopped -+ -+Revised cluster status: -+Node rhel7-auto1 (1): standby -+Node rhel7-auto2 (2): standby -+Online: [ rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto3 -+ Clone Set: A-clone [A] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -diff --git a/pengine/test10/clone-require-all-3.xml b/pengine/test10/clone-require-all-3.xml -new file mode 100644 -index 0000000..b04f0e2 ---- /dev/null -+++ b/pengine/test10/clone-require-all-3.xml -@@ -0,0 +1,160 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-4.dot b/pengine/test10/clone-require-all-4.dot -new file mode 100644 -index 0000000..4b9521f ---- /dev/null -+++ b/pengine/test10/clone-require-all-4.dot -@@ -0,0 +1,24 @@ -+ digraph "g" { -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A_start_0 " [ style = dashed] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stop_0" -> "A-clone_stopped_0" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto1" [ style = bold] -+"A-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stopped_0" -> "A-clone_start_0" [ style = bold] -+"A-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"A_start_0 " -> "A-clone_running_0" [ style = dashed] -+"A_start_0 " [ style=dashed color="red" fontcolor="black"] -+"A_stop_0 rhel7-auto1" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto1" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"shooter_monitor_60000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"shooter_start_0 rhel7-auto2" -> "shooter_monitor_60000 rhel7-auto2" [ style = bold] -+"shooter_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"shooter_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"shooter_stop_0 rhel7-auto1" -> "shooter_start_0 rhel7-auto2" [ style = bold] -+"shooter_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/clone-require-all-4.exp b/pengine/test10/clone-require-all-4.exp -new file mode 100644 -index 0000000..53c1529 ---- /dev/null -+++ b/pengine/test10/clone-require-all-4.exp -@@ -0,0 +1,112 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-4.scores b/pengine/test10/clone-require-all-4.scores -new file mode 100644 -index 0000000..c602a1d ---- /dev/null -+++ b/pengine/test10/clone-require-all-4.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: 0 -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: 1 -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: 0 -+clone_color: A:1 allocation score on rhel7-auto2: 1 -+clone_color: A:1 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: 0 -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: 0 -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 1 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 1 -+clone_color: B:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: 1 -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 1 -+native_color: B:0 allocation score on rhel7-auto4: 0 -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: -INFINITY -+native_color: B:1 allocation score on rhel7-auto4: 1 -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-4.summary b/pengine/test10/clone-require-all-4.summary -new file mode 100644 -index 0000000..49ae3bd ---- /dev/null -+++ b/pengine/test10/clone-require-all-4.summary -@@ -0,0 +1,40 @@ -+ -+Current cluster status: -+Node rhel7-auto1 (1): standby -+Online: [ rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 ] -+ -+Transition Summary: -+ * Move shooter (Started rhel7-auto1 -> rhel7-auto2) -+ * Stop A:0 (rhel7-auto1) -+ -+Executing cluster transition: -+ * Resource action: shooter stop on rhel7-auto1 -+ * Pseudo action: A-clone_stop_0 -+ * Resource action: shooter start on rhel7-auto2 -+ * Resource action: A stop on rhel7-auto1 -+ * Pseudo action: A-clone_stopped_0 -+ * Pseudo action: A-clone_start_0 -+ * Pseudo action: all_stopped -+ * Resource action: shooter monitor=60000 on rhel7-auto2 -+ * Pseudo action: A-clone_running_0 -+ -+Revised cluster status: -+Node rhel7-auto1 (1): standby -+Online: [ rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto2 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto2 ] -+ Stopped: [ rhel7-auto1 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 ] -+ -diff --git a/pengine/test10/clone-require-all-4.xml b/pengine/test10/clone-require-all-4.xml -new file mode 100644 -index 0000000..8bfd27f ---- /dev/null -+++ b/pengine/test10/clone-require-all-4.xml -@@ -0,0 +1,156 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-5.dot b/pengine/test10/clone-require-all-5.dot -new file mode 100644 -index 0000000..ce5a593 ---- /dev/null -+++ b/pengine/test10/clone-require-all-5.dot -@@ -0,0 +1,31 @@ -+ digraph "g" { -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A_start_0 rhel7-auto3" [ style = bold] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"A_start_0 rhel7-auto3" -> "A-clone_running_0" [ style = bold] -+"A_start_0 rhel7-auto3" -> "A_monitor_10000 rhel7-auto3" [ style = bold] -+"A_start_0 rhel7-auto3" -> "clone-one-or-more:order-A-clone-B-clone-mandatory" [ style = bold] -+"A_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = bold] -+"B-clone_start_0" -> "B:1_start_0 rhel7-auto3" [ style = bold] -+"B-clone_start_0" -> "B:2_start_0 rhel7-auto1" [ style = bold] -+"B-clone_start_0" -> "B_start_0 rhel7-auto4" [ style = bold] -+"B-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"B:1_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B:1_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = bold] -+"B:1_start_0 rhel7-auto3" -> "B:1_monitor_10000 rhel7-auto3" [ style = bold] -+"B:1_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B:2_monitor_10000 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"B:2_start_0 rhel7-auto1" -> "B-clone_running_0" [ style = bold] -+"B:2_start_0 rhel7-auto1" -> "B:2_monitor_10000 rhel7-auto1" [ style = bold] -+"B:2_start_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"B_monitor_10000 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B_start_0 rhel7-auto4" -> "B-clone_running_0" [ style = bold] -+"B_start_0 rhel7-auto4" -> "B_monitor_10000 rhel7-auto4" [ style = bold] -+"B_start_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"clone-one-or-more:order-A-clone-B-clone-mandatory" -> "B-clone_start_0" [ style = bold] -+"clone-one-or-more:order-A-clone-B-clone-mandatory" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/clone-require-all-5.exp b/pengine/test10/clone-require-all-5.exp -new file mode 100644 -index 0000000..abb4d25 ---- /dev/null -+++ b/pengine/test10/clone-require-all-5.exp -@@ -0,0 +1,174 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-5.scores b/pengine/test10/clone-require-all-5.scores -new file mode 100644 -index 0000000..cca6739 ---- /dev/null -+++ b/pengine/test10/clone-require-all-5.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: 0 -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: 0 -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: 1 -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: 0 -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: 0 -+clone_color: A:1 allocation score on rhel7-auto2: 1 -+clone_color: A:1 allocation score on rhel7-auto3: 0 -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: 0 -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: 0 -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: 0 -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: 0 -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: 0 -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: 0 -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: 0 -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: 0 -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: 0 -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: 1 -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: 0 -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: 0 -+native_color: A:1 allocation score on rhel7-auto2: 1 -+native_color: A:1 allocation score on rhel7-auto3: 0 -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: 0 -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: 0 -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 0 -+native_color: B:0 allocation score on rhel7-auto4: 0 -+native_color: B:1 allocation score on rhel7-auto1: 0 -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: 0 -+native_color: B:1 allocation score on rhel7-auto4: -INFINITY -+native_color: B:2 allocation score on rhel7-auto1: 0 -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-5.summary b/pengine/test10/clone-require-all-5.summary -new file mode 100644 -index 0000000..2820093 ---- /dev/null -+++ b/pengine/test10/clone-require-all-5.summary -@@ -0,0 +1,43 @@ -+ -+Current cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+Transition Summary: -+ * Start A:2 (rhel7-auto3) -+ * Start B:0 (rhel7-auto4) -+ * Start B:1 (rhel7-auto3) -+ * Start B:2 (rhel7-auto1) -+ -+Executing cluster transition: -+ * Pseudo action: A-clone_start_0 -+ * Resource action: A start on rhel7-auto3 -+ * Pseudo action: A-clone_running_0 -+ * Pseudo action: clone-one-or-more:order-A-clone-B-clone-mandatory -+ * Resource action: A monitor=10000 on rhel7-auto3 -+ * Pseudo action: B-clone_start_0 -+ * Resource action: B start on rhel7-auto4 -+ * Resource action: B start on rhel7-auto3 -+ * Resource action: B start on rhel7-auto1 -+ * Pseudo action: B-clone_running_0 -+ * Resource action: B monitor=10000 on rhel7-auto4 -+ * Resource action: B monitor=10000 on rhel7-auto3 -+ * Resource action: B monitor=10000 on rhel7-auto1 -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Stopped: [ rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto1 rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto2 ] -+ -diff --git a/pengine/test10/clone-require-all-5.xml b/pengine/test10/clone-require-all-5.xml -new file mode 100644 -index 0000000..1079dae ---- /dev/null -+++ b/pengine/test10/clone-require-all-5.xml -@@ -0,0 +1,150 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-6.dot b/pengine/test10/clone-require-all-6.dot -new file mode 100644 -index 0000000..3ee5c89 ---- /dev/null -+++ b/pengine/test10/clone-require-all-6.dot -@@ -0,0 +1,23 @@ -+ digraph "g" { -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A_start_0 " [ style = dashed] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stop_0" -> "A-clone_stopped_0" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto1" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto3" [ style = bold] -+"A-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stopped_0" -> "A-clone_start_0" [ style = bold] -+"A-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"A_start_0 " -> "A-clone_running_0" [ style = dashed] -+"A_start_0 " [ style=dashed color="red" fontcolor="black"] -+"A_stop_0 rhel7-auto1" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto1" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"A_stop_0 rhel7-auto3" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto3" -> "A_start_0 " [ style = dashed] -+"A_stop_0 rhel7-auto3" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/clone-require-all-6.exp b/pengine/test10/clone-require-all-6.exp -new file mode 100644 -index 0000000..8cc4c57 ---- /dev/null -+++ b/pengine/test10/clone-require-all-6.exp -@@ -0,0 +1,93 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-6.scores b/pengine/test10/clone-require-all-6.scores -new file mode 100644 -index 0000000..4e8ee5a ---- /dev/null -+++ b/pengine/test10/clone-require-all-6.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto2: 1 -+clone_color: A:1 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: 0 -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: 1 -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: 0 -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 1 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: 0 -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 1 -+clone_color: B:3 allocation score on rhel7-auto1: 0 -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: 1 -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: 1 -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: -INFINITY -+native_color: B:0 allocation score on rhel7-auto4: -INFINITY -+native_color: B:1 allocation score on rhel7-auto1: 0 -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: 1 -+native_color: B:1 allocation score on rhel7-auto4: 0 -+native_color: B:2 allocation score on rhel7-auto1: 0 -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: 1 -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-6.summary b/pengine/test10/clone-require-all-6.summary -new file mode 100644 -index 0000000..6561ea3 ---- /dev/null -+++ b/pengine/test10/clone-require-all-6.summary -@@ -0,0 +1,36 @@ -+ -+Current cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Stopped: [ rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto1 rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto2 ] -+ -+Transition Summary: -+ * Stop A:0 (rhel7-auto1) -+ * Stop A:2 (rhel7-auto3) -+ -+Executing cluster transition: -+ * Pseudo action: A-clone_stop_0 -+ * Resource action: A stop on rhel7-auto1 -+ * Resource action: A stop on rhel7-auto3 -+ * Pseudo action: A-clone_stopped_0 -+ * Pseudo action: A-clone_start_0 -+ * Pseudo action: all_stopped -+ * Pseudo action: A-clone_running_0 -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto2 ] -+ Stopped: [ rhel7-auto1 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto1 rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto2 ] -+ -diff --git a/pengine/test10/clone-require-all-6.xml b/pengine/test10/clone-require-all-6.xml -new file mode 100644 -index 0000000..5222b33 ---- /dev/null -+++ b/pengine/test10/clone-require-all-6.xml -@@ -0,0 +1,153 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-7.dot b/pengine/test10/clone-require-all-7.dot -new file mode 100644 -index 0000000..baa87a2 ---- /dev/null -+++ b/pengine/test10/clone-require-all-7.dot -@@ -0,0 +1,51 @@ -+ digraph "g" { -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A:0_start_0 rhel7-auto2" [ style = bold] -+"A-clone_start_0" -> "A:1_start_0 rhel7-auto1" [ style = bold] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A:0_monitor_0 rhel7-auto2" -> "probe_complete rhel7-auto2" [ style = bold] -+"A:0_monitor_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"A:0_monitor_0 rhel7-auto3" -> "probe_complete rhel7-auto3" [ style = bold] -+"A:0_monitor_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"A:0_monitor_0 rhel7-auto4" -> "probe_complete rhel7-auto4" [ style = bold] -+"A:0_monitor_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"A:0_monitor_10000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"A:0_start_0 rhel7-auto2" -> "A-clone_running_0" [ style = bold] -+"A:0_start_0 rhel7-auto2" -> "A:0_monitor_10000 rhel7-auto2" [ style = bold] -+"A:0_start_0 rhel7-auto2" -> "clone-one-or-more:order-A-clone-B-clone-mandatory" [ style = bold] -+"A:0_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"A:1_monitor_0 rhel7-auto1" -> "probe_complete rhel7-auto1" [ style = bold] -+"A:1_monitor_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"A:1_monitor_10000 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"A:1_start_0 rhel7-auto1" -> "A-clone_running_0" [ style = bold] -+"A:1_start_0 rhel7-auto1" -> "A:1_monitor_10000 rhel7-auto1" [ style = bold] -+"A:1_start_0 rhel7-auto1" -> "clone-one-or-more:order-A-clone-B-clone-mandatory" [ style = bold] -+"A:1_start_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = bold] -+"B-clone_start_0" -> "B:1_start_0 rhel7-auto4" [ style = bold] -+"B-clone_start_0" -> "B_start_0 rhel7-auto3" [ style = bold] -+"B-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"B:1_monitor_10000 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B:1_start_0 rhel7-auto4" -> "B-clone_running_0" [ style = bold] -+"B:1_start_0 rhel7-auto4" -> "B:1_monitor_10000 rhel7-auto4" [ style = bold] -+"B:1_start_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = bold] -+"B_start_0 rhel7-auto3" -> "B_monitor_10000 rhel7-auto3" [ style = bold] -+"B_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"clone-one-or-more:order-A-clone-B-clone-mandatory" -> "B-clone_start_0" [ style = bold] -+"clone-one-or-more:order-A-clone-B-clone-mandatory" [ style=bold color="green" fontcolor="orange"] -+"probe_complete rhel7-auto1" -> "probe_complete" [ style = bold] -+"probe_complete rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"probe_complete rhel7-auto2" -> "probe_complete" [ style = bold] -+"probe_complete rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"probe_complete rhel7-auto3" -> "probe_complete" [ style = bold] -+"probe_complete rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"probe_complete rhel7-auto4" -> "probe_complete" [ style = bold] -+"probe_complete rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"probe_complete" -> "A:0_start_0 rhel7-auto2" [ style = bold] -+"probe_complete" -> "A:1_start_0 rhel7-auto1" [ style = bold] -+"probe_complete" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/clone-require-all-7.exp b/pengine/test10/clone-require-all-7.exp -new file mode 100644 -index 0000000..d37a82f ---- /dev/null -+++ b/pengine/test10/clone-require-all-7.exp -@@ -0,0 +1,288 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-7.scores b/pengine/test10/clone-require-all-7.scores -new file mode 100644 -index 0000000..8c61fd1 ---- /dev/null -+++ b/pengine/test10/clone-require-all-7.scores -@@ -0,0 +1,77 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: 0 -+clone_color: A-clone allocation score on rhel7-auto2: 0 -+clone_color: A-clone allocation score on rhel7-auto3: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto4: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto1: 0 -+clone_color: A:0 allocation score on rhel7-auto2: 0 -+clone_color: A:0 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto1: 0 -+clone_color: A:1 allocation score on rhel7-auto2: 0 -+clone_color: A:1 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto1: 0 -+clone_color: A:2 allocation score on rhel7-auto2: 0 -+clone_color: A:2 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto4: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto1: 0 -+clone_color: A:3 allocation score on rhel7-auto2: 0 -+clone_color: A:3 allocation score on rhel7-auto3: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto4: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: 0 -+native_color: A:0 allocation score on rhel7-auto2: 0 -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: 0 -+native_color: A:1 allocation score on rhel7-auto2: -INFINITY -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 0 -+native_color: B:0 allocation score on rhel7-auto4: 0 -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: -INFINITY -+native_color: B:1 allocation score on rhel7-auto4: 0 -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-7.summary b/pengine/test10/clone-require-all-7.summary -new file mode 100644 -index 0000000..411f738 ---- /dev/null -+++ b/pengine/test10/clone-require-all-7.summary -@@ -0,0 +1,47 @@ -+ -+Current cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+Transition Summary: -+ * Start A:0 (rhel7-auto2) -+ * Start A:1 (rhel7-auto1) -+ * Start B:0 (rhel7-auto3) -+ * Start B:1 (rhel7-auto4) -+ -+Executing cluster transition: -+ * Resource action: A:0 monitor on rhel7-auto4 -+ * Resource action: A:0 monitor on rhel7-auto3 -+ * Resource action: A:0 monitor on rhel7-auto2 -+ * Resource action: A:1 monitor on rhel7-auto1 -+ * Pseudo action: A-clone_start_0 -+ * Pseudo action: probe_complete -+ * Resource action: A:0 start on rhel7-auto2 -+ * Resource action: A:1 start on rhel7-auto1 -+ * Pseudo action: A-clone_running_0 -+ * Pseudo action: clone-one-or-more:order-A-clone-B-clone-mandatory -+ * Resource action: A:0 monitor=10000 on rhel7-auto2 -+ * Resource action: A:1 monitor=10000 on rhel7-auto1 -+ * Pseudo action: B-clone_start_0 -+ * Resource action: B start on rhel7-auto3 -+ * Resource action: B start on rhel7-auto4 -+ * Pseudo action: B-clone_running_0 -+ * Resource action: B monitor=10000 on rhel7-auto3 -+ * Resource action: B monitor=10000 on rhel7-auto4 -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto1 rhel7-auto2 ] -+ Stopped: [ rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 ] -+ -diff --git a/pengine/test10/clone-require-all-7.xml b/pengine/test10/clone-require-all-7.xml -new file mode 100644 -index 0000000..6aea47b ---- /dev/null -+++ b/pengine/test10/clone-require-all-7.xml -@@ -0,0 +1,138 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-1.dot b/pengine/test10/clone-require-all-no-interleave-1.dot -new file mode 100644 -index 0000000..d03703b ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-1.dot -@@ -0,0 +1,40 @@ -+ digraph "g" { -+"A-clone_running_0" -> "B-clone_start_0" [ style = bold] -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A_start_0 rhel7-auto3" [ style = bold] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"A_start_0 rhel7-auto3" -> "A-clone_running_0" [ style = bold] -+"A_start_0 rhel7-auto3" -> "A_monitor_10000 rhel7-auto3" [ style = bold] -+"A_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = bold] -+"B-clone_start_0" -> "B_start_0 rhel7-auto3" [ style = bold] -+"B-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"B_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = bold] -+"B_start_0 rhel7-auto3" -> "B_monitor_10000 rhel7-auto3" [ style = bold] -+"B_start_0 rhel7-auto3" -> "clone-one-or-more:order-B-clone-C-clone-mandatory" [ style = bold] -+"B_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"C-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"C-clone_start_0" -> "C-clone_running_0" [ style = bold] -+"C-clone_start_0" -> "C:1_start_0 rhel7-auto1" [ style = bold] -+"C-clone_start_0" -> "C:2_start_0 rhel7-auto3" [ style = bold] -+"C-clone_start_0" -> "C_start_0 rhel7-auto2" [ style = bold] -+"C-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"C:1_monitor_10000 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"C:1_start_0 rhel7-auto1" -> "C-clone_running_0" [ style = bold] -+"C:1_start_0 rhel7-auto1" -> "C:1_monitor_10000 rhel7-auto1" [ style = bold] -+"C:1_start_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"C:2_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"C:2_start_0 rhel7-auto3" -> "C-clone_running_0" [ style = bold] -+"C:2_start_0 rhel7-auto3" -> "C:2_monitor_10000 rhel7-auto3" [ style = bold] -+"C:2_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"C_monitor_10000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"C_start_0 rhel7-auto2" -> "C-clone_running_0" [ style = bold] -+"C_start_0 rhel7-auto2" -> "C_monitor_10000 rhel7-auto2" [ style = bold] -+"C_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"clone-one-or-more:order-B-clone-C-clone-mandatory" -> "C-clone_start_0" [ style = bold] -+"clone-one-or-more:order-B-clone-C-clone-mandatory" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/clone-require-all-no-interleave-1.exp b/pengine/test10/clone-require-all-no-interleave-1.exp -new file mode 100644 -index 0000000..7048f51 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-1.exp -@@ -0,0 +1,227 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-1.scores b/pengine/test10/clone-require-all-no-interleave-1.scores -new file mode 100644 -index 0000000..f6d3232 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-1.scores -@@ -0,0 +1,113 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto3: 0 -+clone_color: A-clone allocation score on rhel7-auto4: 0 -+clone_color: A:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto3: 0 -+clone_color: A:0 allocation score on rhel7-auto4: 0 -+clone_color: A:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto3: 0 -+clone_color: A:1 allocation score on rhel7-auto4: 0 -+clone_color: A:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto3: 0 -+clone_color: A:2 allocation score on rhel7-auto4: 0 -+clone_color: A:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto3: 0 -+clone_color: A:3 allocation score on rhel7-auto4: 0 -+clone_color: B-clone allocation score on rhel7-auto1: 0 -+clone_color: B-clone allocation score on rhel7-auto2: 0 -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: 0 -+clone_color: B:0 allocation score on rhel7-auto2: 0 -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: 0 -+clone_color: B:1 allocation score on rhel7-auto2: 0 -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: 0 -+clone_color: B:2 allocation score on rhel7-auto2: 0 -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: 0 -+clone_color: B:3 allocation score on rhel7-auto2: 0 -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+clone_color: C-clone allocation score on rhel7-auto1: 0 -+clone_color: C-clone allocation score on rhel7-auto2: 0 -+clone_color: C-clone allocation score on rhel7-auto3: 0 -+clone_color: C-clone allocation score on rhel7-auto4: 0 -+clone_color: C:0 allocation score on rhel7-auto1: 0 -+clone_color: C:0 allocation score on rhel7-auto2: 0 -+clone_color: C:0 allocation score on rhel7-auto3: 0 -+clone_color: C:0 allocation score on rhel7-auto4: 0 -+clone_color: C:1 allocation score on rhel7-auto1: 0 -+clone_color: C:1 allocation score on rhel7-auto2: 0 -+clone_color: C:1 allocation score on rhel7-auto3: 0 -+clone_color: C:1 allocation score on rhel7-auto4: 0 -+clone_color: C:2 allocation score on rhel7-auto1: 0 -+clone_color: C:2 allocation score on rhel7-auto2: 0 -+clone_color: C:2 allocation score on rhel7-auto3: 0 -+clone_color: C:2 allocation score on rhel7-auto4: 0 -+clone_color: C:3 allocation score on rhel7-auto1: 0 -+clone_color: C:3 allocation score on rhel7-auto2: 0 -+clone_color: C:3 allocation score on rhel7-auto3: 0 -+clone_color: C:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: 0 -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: -INFINITY -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 0 -+native_color: B:0 allocation score on rhel7-auto4: -INFINITY -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: -INFINITY -+native_color: B:1 allocation score on rhel7-auto4: -INFINITY -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: C:0 allocation score on rhel7-auto1: 0 -+native_color: C:0 allocation score on rhel7-auto2: 0 -+native_color: C:0 allocation score on rhel7-auto3: 0 -+native_color: C:0 allocation score on rhel7-auto4: -INFINITY -+native_color: C:1 allocation score on rhel7-auto1: 0 -+native_color: C:1 allocation score on rhel7-auto2: -INFINITY -+native_color: C:1 allocation score on rhel7-auto3: 0 -+native_color: C:1 allocation score on rhel7-auto4: -INFINITY -+native_color: C:2 allocation score on rhel7-auto1: -INFINITY -+native_color: C:2 allocation score on rhel7-auto2: -INFINITY -+native_color: C:2 allocation score on rhel7-auto3: 0 -+native_color: C:2 allocation score on rhel7-auto4: -INFINITY -+native_color: C:3 allocation score on rhel7-auto1: -INFINITY -+native_color: C:3 allocation score on rhel7-auto2: -INFINITY -+native_color: C:3 allocation score on rhel7-auto3: -INFINITY -+native_color: C:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-no-interleave-1.summary b/pengine/test10/clone-require-all-no-interleave-1.summary -new file mode 100644 -index 0000000..dd4bc99 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-1.summary -@@ -0,0 +1,54 @@ -+ -+Current cluster status: -+Node rhel7-auto4 (4): standby -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: C-clone [C] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+Transition Summary: -+ * Start A:0 (rhel7-auto3) -+ * Start B:0 (rhel7-auto3) -+ * Start C:0 (rhel7-auto2) -+ * Start C:1 (rhel7-auto1) -+ * Start C:2 (rhel7-auto3) -+ -+Executing cluster transition: -+ * Pseudo action: A-clone_start_0 -+ * Resource action: A start on rhel7-auto3 -+ * Pseudo action: A-clone_running_0 -+ * Pseudo action: B-clone_start_0 -+ * Resource action: A monitor=10000 on rhel7-auto3 -+ * Resource action: B start on rhel7-auto3 -+ * Pseudo action: B-clone_running_0 -+ * Pseudo action: clone-one-or-more:order-B-clone-C-clone-mandatory -+ * Resource action: B monitor=10000 on rhel7-auto3 -+ * Pseudo action: C-clone_start_0 -+ * Resource action: C start on rhel7-auto2 -+ * Resource action: C start on rhel7-auto1 -+ * Resource action: C start on rhel7-auto3 -+ * Pseudo action: C-clone_running_0 -+ * Resource action: C monitor=10000 on rhel7-auto2 -+ * Resource action: C monitor=10000 on rhel7-auto1 -+ * Resource action: C monitor=10000 on rhel7-auto3 -+ -+Revised cluster status: -+Node rhel7-auto4 (4): standby -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto3 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ Clone Set: C-clone [C] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Stopped: [ rhel7-auto4 ] -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-1.xml b/pengine/test10/clone-require-all-no-interleave-1.xml -new file mode 100644 -index 0000000..4630f96 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-1.xml -@@ -0,0 +1,177 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-2.dot b/pengine/test10/clone-require-all-no-interleave-2.dot -new file mode 100644 -index 0000000..1d7f8be ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-2.dot -@@ -0,0 +1,40 @@ -+ digraph "g" { -+"A-clone_running_0" -> "B-clone_start_0" [ style = bold] -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A_start_0 rhel7-auto4" [ style = bold] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A_monitor_10000 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"A_start_0 rhel7-auto4" -> "A-clone_running_0" [ style = bold] -+"A_start_0 rhel7-auto4" -> "A_monitor_10000 rhel7-auto4" [ style = bold] -+"A_start_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = bold] -+"B-clone_start_0" -> "B_start_0 rhel7-auto4" [ style = bold] -+"B-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"B_monitor_10000 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B_start_0 rhel7-auto4" -> "B-clone_running_0" [ style = bold] -+"B_start_0 rhel7-auto4" -> "B_monitor_10000 rhel7-auto4" [ style = bold] -+"B_start_0 rhel7-auto4" -> "clone-one-or-more:order-B-clone-C-clone-mandatory" [ style = bold] -+"B_start_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"C-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"C-clone_start_0" -> "C-clone_running_0" [ style = bold] -+"C-clone_start_0" -> "C:1_start_0 rhel7-auto1" [ style = bold] -+"C-clone_start_0" -> "C:2_start_0 rhel7-auto4" [ style = bold] -+"C-clone_start_0" -> "C_start_0 rhel7-auto2" [ style = bold] -+"C-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"C:1_monitor_10000 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"C:1_start_0 rhel7-auto1" -> "C-clone_running_0" [ style = bold] -+"C:1_start_0 rhel7-auto1" -> "C:1_monitor_10000 rhel7-auto1" [ style = bold] -+"C:1_start_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"C:2_monitor_10000 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"C:2_start_0 rhel7-auto4" -> "C-clone_running_0" [ style = bold] -+"C:2_start_0 rhel7-auto4" -> "C:2_monitor_10000 rhel7-auto4" [ style = bold] -+"C:2_start_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"C_monitor_10000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"C_start_0 rhel7-auto2" -> "C-clone_running_0" [ style = bold] -+"C_start_0 rhel7-auto2" -> "C_monitor_10000 rhel7-auto2" [ style = bold] -+"C_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"clone-one-or-more:order-B-clone-C-clone-mandatory" -> "C-clone_start_0" [ style = bold] -+"clone-one-or-more:order-B-clone-C-clone-mandatory" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/clone-require-all-no-interleave-2.exp b/pengine/test10/clone-require-all-no-interleave-2.exp -new file mode 100644 -index 0000000..35a2df6 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-2.exp -@@ -0,0 +1,227 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-2.scores b/pengine/test10/clone-require-all-no-interleave-2.scores -new file mode 100644 -index 0000000..50e054e ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-2.scores -@@ -0,0 +1,113 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto3: 0 -+clone_color: A-clone allocation score on rhel7-auto4: 0 -+clone_color: A:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto3: 0 -+clone_color: A:0 allocation score on rhel7-auto4: 0 -+clone_color: A:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto3: 0 -+clone_color: A:1 allocation score on rhel7-auto4: 0 -+clone_color: A:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto3: 0 -+clone_color: A:2 allocation score on rhel7-auto4: 0 -+clone_color: A:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto3: 0 -+clone_color: A:3 allocation score on rhel7-auto4: 0 -+clone_color: B-clone allocation score on rhel7-auto1: 0 -+clone_color: B-clone allocation score on rhel7-auto2: 0 -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: 0 -+clone_color: B:0 allocation score on rhel7-auto2: 0 -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 0 -+clone_color: B:1 allocation score on rhel7-auto1: 0 -+clone_color: B:1 allocation score on rhel7-auto2: 0 -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: 0 -+clone_color: B:2 allocation score on rhel7-auto2: 0 -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: 0 -+clone_color: B:3 allocation score on rhel7-auto2: 0 -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+clone_color: C-clone allocation score on rhel7-auto1: 0 -+clone_color: C-clone allocation score on rhel7-auto2: 0 -+clone_color: C-clone allocation score on rhel7-auto3: 0 -+clone_color: C-clone allocation score on rhel7-auto4: 0 -+clone_color: C:0 allocation score on rhel7-auto1: 0 -+clone_color: C:0 allocation score on rhel7-auto2: 0 -+clone_color: C:0 allocation score on rhel7-auto3: 0 -+clone_color: C:0 allocation score on rhel7-auto4: 0 -+clone_color: C:1 allocation score on rhel7-auto1: 0 -+clone_color: C:1 allocation score on rhel7-auto2: 0 -+clone_color: C:1 allocation score on rhel7-auto3: 0 -+clone_color: C:1 allocation score on rhel7-auto4: 0 -+clone_color: C:2 allocation score on rhel7-auto1: 0 -+clone_color: C:2 allocation score on rhel7-auto2: 0 -+clone_color: C:2 allocation score on rhel7-auto3: 0 -+clone_color: C:2 allocation score on rhel7-auto4: 0 -+clone_color: C:3 allocation score on rhel7-auto1: 0 -+clone_color: C:3 allocation score on rhel7-auto2: 0 -+clone_color: C:3 allocation score on rhel7-auto3: 0 -+clone_color: C:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: -INFINITY -+native_color: A:0 allocation score on rhel7-auto4: 0 -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: -INFINITY -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: -INFINITY -+native_color: B:0 allocation score on rhel7-auto4: 0 -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: -INFINITY -+native_color: B:1 allocation score on rhel7-auto4: -INFINITY -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: C:0 allocation score on rhel7-auto1: 0 -+native_color: C:0 allocation score on rhel7-auto2: 0 -+native_color: C:0 allocation score on rhel7-auto3: -INFINITY -+native_color: C:0 allocation score on rhel7-auto4: 0 -+native_color: C:1 allocation score on rhel7-auto1: 0 -+native_color: C:1 allocation score on rhel7-auto2: -INFINITY -+native_color: C:1 allocation score on rhel7-auto3: -INFINITY -+native_color: C:1 allocation score on rhel7-auto4: 0 -+native_color: C:2 allocation score on rhel7-auto1: -INFINITY -+native_color: C:2 allocation score on rhel7-auto2: -INFINITY -+native_color: C:2 allocation score on rhel7-auto3: -INFINITY -+native_color: C:2 allocation score on rhel7-auto4: 0 -+native_color: C:3 allocation score on rhel7-auto1: -INFINITY -+native_color: C:3 allocation score on rhel7-auto2: -INFINITY -+native_color: C:3 allocation score on rhel7-auto3: -INFINITY -+native_color: C:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-no-interleave-2.summary b/pengine/test10/clone-require-all-no-interleave-2.summary -new file mode 100644 -index 0000000..f16be9b ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-2.summary -@@ -0,0 +1,54 @@ -+ -+Current cluster status: -+Node rhel7-auto3 (3): standby -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ Clone Set: C-clone [C] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 rhel7-auto4 ] -+ -+Transition Summary: -+ * Start A:0 (rhel7-auto4) -+ * Start B:0 (rhel7-auto4) -+ * Start C:0 (rhel7-auto2) -+ * Start C:1 (rhel7-auto1) -+ * Start C:2 (rhel7-auto4) -+ -+Executing cluster transition: -+ * Pseudo action: A-clone_start_0 -+ * Resource action: A start on rhel7-auto4 -+ * Pseudo action: A-clone_running_0 -+ * Pseudo action: B-clone_start_0 -+ * Resource action: A monitor=10000 on rhel7-auto4 -+ * Resource action: B start on rhel7-auto4 -+ * Pseudo action: B-clone_running_0 -+ * Pseudo action: clone-one-or-more:order-B-clone-C-clone-mandatory -+ * Resource action: B monitor=10000 on rhel7-auto4 -+ * Pseudo action: C-clone_start_0 -+ * Resource action: C start on rhel7-auto2 -+ * Resource action: C start on rhel7-auto1 -+ * Resource action: C start on rhel7-auto4 -+ * Pseudo action: C-clone_running_0 -+ * Resource action: C monitor=10000 on rhel7-auto2 -+ * Resource action: C monitor=10000 on rhel7-auto1 -+ * Resource action: C monitor=10000 on rhel7-auto4 -+ -+Revised cluster status: -+Node rhel7-auto3 (3): standby -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Clone Set: C-clone [C] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ Stopped: [ rhel7-auto3 ] -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-2.xml b/pengine/test10/clone-require-all-no-interleave-2.xml -new file mode 100644 -index 0000000..214a7c7 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-2.xml -@@ -0,0 +1,179 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-3.dot b/pengine/test10/clone-require-all-no-interleave-3.dot -new file mode 100644 -index 0000000..58f97a5 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-3.dot -@@ -0,0 +1,60 @@ -+ digraph "g" { -+"A-clone_running_0" -> "B-clone_start_0" [ style = bold] -+"A-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_start_0" -> "A-clone_running_0" [ style = bold] -+"A-clone_start_0" -> "A_start_0 rhel7-auto3" [ style = bold] -+"A-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stop_0" -> "A-clone_stopped_0" [ style = bold] -+"A-clone_stop_0" -> "A_stop_0 rhel7-auto4" [ style = bold] -+"A-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"A-clone_stopped_0" -> "A-clone_start_0" [ style = bold] -+"A-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"A_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"A_start_0 rhel7-auto3" -> "A-clone_running_0" [ style = bold] -+"A_start_0 rhel7-auto3" -> "A_monitor_10000 rhel7-auto3" [ style = bold] -+"A_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"A_stop_0 rhel7-auto4" -> "A-clone_stopped_0" [ style = bold] -+"A_stop_0 rhel7-auto4" -> "A_start_0 rhel7-auto3" [ style = bold] -+"A_stop_0 rhel7-auto4" -> "all_stopped" [ style = bold] -+"A_stop_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"B-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_start_0" -> "B-clone_running_0" [ style = bold] -+"B-clone_start_0" -> "B_start_0 rhel7-auto3" [ style = bold] -+"B-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_stop_0" -> "B-clone_stopped_0" [ style = bold] -+"B-clone_stop_0" -> "B_stop_0 rhel7-auto4" [ style = bold] -+"B-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"B-clone_stopped_0" -> "A-clone_stop_0" [ style = bold] -+"B-clone_stopped_0" -> "B-clone_start_0" [ style = bold] -+"B-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"B_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B_start_0 rhel7-auto3" -> "B-clone_running_0" [ style = bold] -+"B_start_0 rhel7-auto3" -> "B_monitor_10000 rhel7-auto3" [ style = bold] -+"B_start_0 rhel7-auto3" -> "clone-one-or-more:order-B-clone-C-clone-mandatory" [ style = bold] -+"B_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"B_stop_0 rhel7-auto4" -> "B-clone_stopped_0" [ style = bold] -+"B_stop_0 rhel7-auto4" -> "B_start_0 rhel7-auto3" [ style = bold] -+"B_stop_0 rhel7-auto4" -> "all_stopped" [ style = bold] -+"B_stop_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"C-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"C-clone_start_0" -> "C-clone_running_0" [ style = bold] -+"C-clone_start_0" -> "C_start_0 rhel7-auto3" [ style = bold] -+"C-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"C-clone_stop_0" -> "C-clone_stopped_0" [ style = bold] -+"C-clone_stop_0" -> "C_stop_0 rhel7-auto4" [ style = bold] -+"C-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"C-clone_stopped_0" -> "B-clone_stop_0" [ style = bold] -+"C-clone_stopped_0" -> "C-clone_start_0" [ style = bold] -+"C-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"C_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"C_start_0 rhel7-auto3" -> "C-clone_running_0" [ style = bold] -+"C_start_0 rhel7-auto3" -> "C_monitor_10000 rhel7-auto3" [ style = bold] -+"C_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"C_stop_0 rhel7-auto4" -> "C-clone_stopped_0" [ style = bold] -+"C_stop_0 rhel7-auto4" -> "C_start_0 rhel7-auto3" [ style = bold] -+"C_stop_0 rhel7-auto4" -> "all_stopped" [ style = bold] -+"C_stop_0 rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"clone-one-or-more:order-B-clone-C-clone-mandatory" -> "C-clone_start_0" [ style = bold] -+"clone-one-or-more:order-B-clone-C-clone-mandatory" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/clone-require-all-no-interleave-3.exp b/pengine/test10/clone-require-all-no-interleave-3.exp -new file mode 100644 -index 0000000..8aba35e ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-3.exp -@@ -0,0 +1,322 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-3.scores b/pengine/test10/clone-require-all-no-interleave-3.scores -new file mode 100644 -index 0000000..70dd2d1 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-3.scores -@@ -0,0 +1,113 @@ -+Allocation scores: -+clone_color: A-clone allocation score on rhel7-auto1: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto2: -INFINITY -+clone_color: A-clone allocation score on rhel7-auto3: 0 -+clone_color: A-clone allocation score on rhel7-auto4: 0 -+clone_color: A:0 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:0 allocation score on rhel7-auto3: 0 -+clone_color: A:0 allocation score on rhel7-auto4: 1 -+clone_color: A:1 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:1 allocation score on rhel7-auto3: 0 -+clone_color: A:1 allocation score on rhel7-auto4: 0 -+clone_color: A:2 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:2 allocation score on rhel7-auto3: 0 -+clone_color: A:2 allocation score on rhel7-auto4: 0 -+clone_color: A:3 allocation score on rhel7-auto1: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto2: -INFINITY -+clone_color: A:3 allocation score on rhel7-auto3: 0 -+clone_color: A:3 allocation score on rhel7-auto4: 0 -+clone_color: B-clone allocation score on rhel7-auto1: 0 -+clone_color: B-clone allocation score on rhel7-auto2: 0 -+clone_color: B-clone allocation score on rhel7-auto3: 0 -+clone_color: B-clone allocation score on rhel7-auto4: 0 -+clone_color: B:0 allocation score on rhel7-auto1: 0 -+clone_color: B:0 allocation score on rhel7-auto2: 0 -+clone_color: B:0 allocation score on rhel7-auto3: 0 -+clone_color: B:0 allocation score on rhel7-auto4: 1 -+clone_color: B:1 allocation score on rhel7-auto1: 0 -+clone_color: B:1 allocation score on rhel7-auto2: 0 -+clone_color: B:1 allocation score on rhel7-auto3: 0 -+clone_color: B:1 allocation score on rhel7-auto4: 0 -+clone_color: B:2 allocation score on rhel7-auto1: 0 -+clone_color: B:2 allocation score on rhel7-auto2: 0 -+clone_color: B:2 allocation score on rhel7-auto3: 0 -+clone_color: B:2 allocation score on rhel7-auto4: 0 -+clone_color: B:3 allocation score on rhel7-auto1: 0 -+clone_color: B:3 allocation score on rhel7-auto2: 0 -+clone_color: B:3 allocation score on rhel7-auto3: 0 -+clone_color: B:3 allocation score on rhel7-auto4: 0 -+clone_color: C-clone allocation score on rhel7-auto1: 0 -+clone_color: C-clone allocation score on rhel7-auto2: 0 -+clone_color: C-clone allocation score on rhel7-auto3: 0 -+clone_color: C-clone allocation score on rhel7-auto4: 0 -+clone_color: C:0 allocation score on rhel7-auto1: 0 -+clone_color: C:0 allocation score on rhel7-auto2: 0 -+clone_color: C:0 allocation score on rhel7-auto3: 0 -+clone_color: C:0 allocation score on rhel7-auto4: 1 -+clone_color: C:1 allocation score on rhel7-auto1: 1 -+clone_color: C:1 allocation score on rhel7-auto2: 0 -+clone_color: C:1 allocation score on rhel7-auto3: 0 -+clone_color: C:1 allocation score on rhel7-auto4: 0 -+clone_color: C:2 allocation score on rhel7-auto1: 0 -+clone_color: C:2 allocation score on rhel7-auto2: 1 -+clone_color: C:2 allocation score on rhel7-auto3: 0 -+clone_color: C:2 allocation score on rhel7-auto4: 0 -+clone_color: C:3 allocation score on rhel7-auto1: 0 -+clone_color: C:3 allocation score on rhel7-auto2: 0 -+clone_color: C:3 allocation score on rhel7-auto3: 0 -+clone_color: C:3 allocation score on rhel7-auto4: 0 -+native_color: A:0 allocation score on rhel7-auto1: -INFINITY -+native_color: A:0 allocation score on rhel7-auto2: -INFINITY -+native_color: A:0 allocation score on rhel7-auto3: 0 -+native_color: A:0 allocation score on rhel7-auto4: -INFINITY -+native_color: A:1 allocation score on rhel7-auto1: -INFINITY -+native_color: A:1 allocation score on rhel7-auto2: -INFINITY -+native_color: A:1 allocation score on rhel7-auto3: -INFINITY -+native_color: A:1 allocation score on rhel7-auto4: -INFINITY -+native_color: A:2 allocation score on rhel7-auto1: -INFINITY -+native_color: A:2 allocation score on rhel7-auto2: -INFINITY -+native_color: A:2 allocation score on rhel7-auto3: -INFINITY -+native_color: A:2 allocation score on rhel7-auto4: -INFINITY -+native_color: A:3 allocation score on rhel7-auto1: -INFINITY -+native_color: A:3 allocation score on rhel7-auto2: -INFINITY -+native_color: A:3 allocation score on rhel7-auto3: -INFINITY -+native_color: A:3 allocation score on rhel7-auto4: -INFINITY -+native_color: B:0 allocation score on rhel7-auto1: -INFINITY -+native_color: B:0 allocation score on rhel7-auto2: -INFINITY -+native_color: B:0 allocation score on rhel7-auto3: 0 -+native_color: B:0 allocation score on rhel7-auto4: -INFINITY -+native_color: B:1 allocation score on rhel7-auto1: -INFINITY -+native_color: B:1 allocation score on rhel7-auto2: -INFINITY -+native_color: B:1 allocation score on rhel7-auto3: -INFINITY -+native_color: B:1 allocation score on rhel7-auto4: -INFINITY -+native_color: B:2 allocation score on rhel7-auto1: -INFINITY -+native_color: B:2 allocation score on rhel7-auto2: -INFINITY -+native_color: B:2 allocation score on rhel7-auto3: -INFINITY -+native_color: B:2 allocation score on rhel7-auto4: -INFINITY -+native_color: B:3 allocation score on rhel7-auto1: -INFINITY -+native_color: B:3 allocation score on rhel7-auto2: -INFINITY -+native_color: B:3 allocation score on rhel7-auto3: -INFINITY -+native_color: B:3 allocation score on rhel7-auto4: -INFINITY -+native_color: C:0 allocation score on rhel7-auto1: -INFINITY -+native_color: C:0 allocation score on rhel7-auto2: -INFINITY -+native_color: C:0 allocation score on rhel7-auto3: 0 -+native_color: C:0 allocation score on rhel7-auto4: -INFINITY -+native_color: C:1 allocation score on rhel7-auto1: 1 -+native_color: C:1 allocation score on rhel7-auto2: -INFINITY -+native_color: C:1 allocation score on rhel7-auto3: 0 -+native_color: C:1 allocation score on rhel7-auto4: -INFINITY -+native_color: C:2 allocation score on rhel7-auto1: 0 -+native_color: C:2 allocation score on rhel7-auto2: 1 -+native_color: C:2 allocation score on rhel7-auto3: 0 -+native_color: C:2 allocation score on rhel7-auto4: -INFINITY -+native_color: C:3 allocation score on rhel7-auto1: -INFINITY -+native_color: C:3 allocation score on rhel7-auto2: -INFINITY -+native_color: C:3 allocation score on rhel7-auto3: -INFINITY -+native_color: C:3 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: 0 -diff --git a/pengine/test10/clone-require-all-no-interleave-3.summary b/pengine/test10/clone-require-all-no-interleave-3.summary -new file mode 100644 -index 0000000..4379644 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-3.summary -@@ -0,0 +1,61 @@ -+ -+Current cluster status: -+Node rhel7-auto4 (4): standby -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto4 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Clone Set: C-clone [C] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ Stopped: [ rhel7-auto3 ] -+ -+Transition Summary: -+ * Move A:0 (Started rhel7-auto4 -> rhel7-auto3) -+ * Move B:0 (Started rhel7-auto4 -> rhel7-auto3) -+ * Move C:0 (Started rhel7-auto4 -> rhel7-auto3) -+ -+Executing cluster transition: -+ * Pseudo action: C-clone_stop_0 -+ * Resource action: C stop on rhel7-auto4 -+ * Pseudo action: C-clone_stopped_0 -+ * Pseudo action: B-clone_stop_0 -+ * Resource action: B stop on rhel7-auto4 -+ * Pseudo action: B-clone_stopped_0 -+ * Pseudo action: A-clone_stop_0 -+ * Resource action: A stop on rhel7-auto4 -+ * Pseudo action: A-clone_stopped_0 -+ * Pseudo action: A-clone_start_0 -+ * Pseudo action: all_stopped -+ * Resource action: A start on rhel7-auto3 -+ * Pseudo action: A-clone_running_0 -+ * Pseudo action: B-clone_start_0 -+ * Resource action: A monitor=10000 on rhel7-auto3 -+ * Resource action: B start on rhel7-auto3 -+ * Pseudo action: B-clone_running_0 -+ * Pseudo action: clone-one-or-more:order-B-clone-C-clone-mandatory -+ * Resource action: B monitor=10000 on rhel7-auto3 -+ * Pseudo action: C-clone_start_0 -+ * Resource action: C start on rhel7-auto3 -+ * Pseudo action: C-clone_running_0 -+ * Resource action: C monitor=10000 on rhel7-auto3 -+ -+Revised cluster status: -+Node rhel7-auto4 (4): standby -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ Clone Set: A-clone [A] -+ Started: [ rhel7-auto3 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ Clone Set: B-clone [B] -+ Started: [ rhel7-auto3 ] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto4 ] -+ Clone Set: C-clone [C] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ Stopped: [ rhel7-auto4 ] -+ -diff --git a/pengine/test10/clone-require-all-no-interleave-3.xml b/pengine/test10/clone-require-all-no-interleave-3.xml -new file mode 100644 -index 0000000..8a9bea8 ---- /dev/null -+++ b/pengine/test10/clone-require-all-no-interleave-3.xml -@@ -0,0 +1,179 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/xml/constraints-2.3.rng b/xml/constraints-2.3.rng -new file mode 100644 -index 0000000..d9a4701 ---- /dev/null -+++ b/xml/constraints-2.3.rng -@@ -0,0 +1,252 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ group -+ listed -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ stop -+ demote -+ fence -+ freeze -+ -+ -+ -+ -+ -+ -+ -+ -+ always -+ never -+ exclusive -+ -+ -+ -+ -+ -+ start -+ promote -+ demote -+ stop -+ -+ -+ -+ -+ -+ Stopped -+ Started -+ Master -+ Slave -+ -+ -+ -+ -+ -+ Optional -+ Mandatory -+ Serialize -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/xml/constraints-next.rng b/xml/constraints-next.rng -index 0defe8f..9d11003 100644 ---- a/xml/constraints-next.rng -+++ b/xml/constraints-next.rng -@@ -154,6 +154,9 @@ - - - -+ -+ -+ - - - diff --git a/SOURCES/bz1198886-0315c57-ask-dbus-not-to-kill-on-shutdown-2.patch b/SOURCES/bz1198886-0315c57-ask-dbus-not-to-kill-on-shutdown-2.patch deleted file mode 100644 index c315029..0000000 --- a/SOURCES/bz1198886-0315c57-ask-dbus-not-to-kill-on-shutdown-2.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0315c578905378726787c695d7d07188ba97f892 Mon Sep 17 00:00:00 2001 -From: Andrew Beekhof -Date: Tue, 24 Mar 2015 07:48:51 +1100 -Subject: [PATCH] Fix: systemd: Kindly ask dbus NOT to kill the process if the - dbus connection fails - ---- - lib/services/dbus.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/lib/services/dbus.c b/lib/services/dbus.c -index f44b590..0623168 100644 ---- a/lib/services/dbus.c -+++ b/lib/services/dbus.c -@@ -533,6 +533,7 @@ pcmk_dbus_timeout_toggle(DBusTimeout *timeout, void *data){ - /* Inspired by http://www.kolej.mff.cuni.cz/~vesej3am/devel/dbus-select.c */ - - void pcmk_dbus_connection_setup_with_select(DBusConnection *c){ -+ dbus_connection_set_exit_on_disconnect (c, FALSE); - dbus_connection_set_timeout_functions( - c, pcmk_dbus_timeout_add, pcmk_dbus_timeout_remove, pcmk_dbus_timeout_toggle, NULL, NULL); - dbus_connection_set_watch_functions(c, pcmk_dbus_watch_add, pcmk_dbus_watch_remove, pcmk_dbus_watch_toggle, NULL, NULL); --- -1.8.4.2 - diff --git a/SOURCES/bz1198886-2ab97ec-systemd-stop-1.patch b/SOURCES/bz1198886-2ab97ec-systemd-stop-1.patch deleted file mode 100644 index 2159a43..0000000 --- a/SOURCES/bz1198886-2ab97ec-systemd-stop-1.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/lib/services/systemd.c b/lib/services/systemd.c -index 10c605a..c797c47 100644 ---- a/lib/services/systemd.c -+++ b/lib/services/systemd.c -@@ -545,15 +545,27 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - - } else if (g_strcmp0(method, "start") == 0) { - FILE *file_strm = NULL; -- char *override_dir = g_strdup_printf("%s/%s", SYSTEMD_OVERRIDE_ROOT, unit); -- char *override_file = g_strdup_printf("%s/%s/50-pacemaker.conf", SYSTEMD_OVERRIDE_ROOT, unit); -+ char *override_dir = g_strdup_printf("%s/%s.service.d", SYSTEMD_OVERRIDE_ROOT, op->agent); -+ char *override_file = g_strdup_printf("%s/%s.service.d/50-pacemaker.conf", SYSTEMD_OVERRIDE_ROOT, op->agent); - - method = "StartUnit"; - crm_build_path(override_dir, 0755); - - file_strm = fopen(override_file, "w"); - if (file_strm != NULL) { -- int rc = fprintf(file_strm, "[Service]\nRestart=no"); -+ /* TODO: Insert the start timeout in too */ -+ char *override = g_strdup_printf( -+ "[Unit]\n" -+ "Description=Cluster Controlled %s\n" -+ "Before=pacemaker.service\n" -+ "\n" -+ "[Service]\n" -+ "Restart=no\n", -+ op->agent); -+ -+ int rc = fprintf(file_strm, "%s\n", override); -+ -+ free(override); - if (rc < 0) { - crm_perror(LOG_ERR, "Cannot write to systemd override file %s", override_file); - } -@@ -571,7 +583,7 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - free(override_dir); - - } else if (g_strcmp0(method, "stop") == 0) { -- char *override_file = g_strdup_printf("%s/%s/50-pacemaker.conf", SYSTEMD_OVERRIDE_ROOT, unit); -+ char *override_file = g_strdup_printf("%s/%s.service.d/50-pacemaker.conf", SYSTEMD_OVERRIDE_ROOT, op->agent); - - method = "StopUnit"; - unlink(override_file); diff --git a/SOURCES/bz1198886-382efe0-hint-lrmd-sd-notify-not-required-4.patch b/SOURCES/bz1198886-382efe0-hint-lrmd-sd-notify-not-required-4.patch deleted file mode 100644 index 2e073c1..0000000 --- a/SOURCES/bz1198886-382efe0-hint-lrmd-sd-notify-not-required-4.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 382efe0f55e9accb30193cbbb80d7c9d423bea25 Mon Sep 17 00:00:00 2001 -From: Andrew Beekhof -Date: Tue, 21 Apr 2015 08:04:10 +1000 -Subject: [PATCH] Fix: lrmd: Hint to child processes that using sd_notify is - not required - ---- - lrmd/main.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/lrmd/main.c b/lrmd/main.c -index 4c588be..636cf44 100644 ---- a/lrmd/main.c -+++ b/lrmd/main.c -@@ -312,6 +312,12 @@ main(int argc, char **argv) - } - } - -+ /* The presence of this variable allegedly controls whether child -+ * processes like httpd will try and use Systemd's sd_notify -+ * API -+ */ -+ unsetenv("NOTIFY_SOCKET"); -+ - /* Used by RAs - Leave owned by root */ - crm_build_path(CRM_RSCTMP_DIR, 0755); - --- -1.8.4.2 - diff --git a/SOURCES/bz1198886-90d725d-dbus-after-pcmk-shutdown-3.patch b/SOURCES/bz1198886-90d725d-dbus-after-pcmk-shutdown-3.patch deleted file mode 100644 index 052431a..0000000 --- a/SOURCES/bz1198886-90d725d-dbus-after-pcmk-shutdown-3.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 90d725d8d8f535a55dde405877a028782b727cec Mon Sep 17 00:00:00 2001 -From: Andrew Beekhof -Date: Mon, 23 Mar 2015 14:43:27 +1100 -Subject: [PATCH] Fix: systemd: Tell systemd not to take DBus down from - underneath us - ---- - mcp/pacemaker.service.in | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/mcp/pacemaker.service.in b/mcp/pacemaker.service.in -index 7871167..3562608 100644 ---- a/mcp/pacemaker.service.in -+++ b/mcp/pacemaker.service.in -@@ -1,10 +1,13 @@ - [Unit] - Description=Pacemaker High Availability Cluster Manager - -+After=dbus.service - After=basic.target -+After=syslog.service - After=network.target - After=corosync.service - -+Requires=dbus.service - Requires=basic.target - Requires=network.target - Requires=corosync.service --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-094c0ea-to-d9a51c6.patch b/SOURCES/pacemaker-094c0ea-to-d9a51c6.patch deleted file mode 100644 index d166559..0000000 --- a/SOURCES/pacemaker-094c0ea-to-d9a51c6.patch +++ /dev/null @@ -1,8513 +0,0 @@ -diff --git a/crmd/crmd_lrm.h b/crmd/crmd_lrm.h -index 46cddc2..3a08392 100644 ---- a/crmd/crmd_lrm.h -+++ b/crmd/crmd_lrm.h -@@ -71,6 +71,12 @@ struct pending_deletion_op_s { - xmlNode *do_lrm_query_internal(lrm_state_t * lrm_state, gboolean is_replace); - - /*! -+ * \brief Is this the local ipc connection to the lrmd -+ */ -+gboolean -+lrm_state_is_local(lrm_state_t *lrm_state); -+ -+/*! - * \brief Clear all state information from a single state entry. - * \note This does not close the lrmd connection - */ -diff --git a/crmd/lrm.c b/crmd/lrm.c -index b68f657..5bff4d5 100644 ---- a/crmd/lrm.c -+++ b/crmd/lrm.c -@@ -1163,7 +1163,12 @@ get_lrm_resource(lrm_state_t * lrm_state, xmlNode * resource, xmlNode * op_msg, - fsa_data_t *msg_data = NULL; - - crm_err("Could not add resource %s to LRM %s", id, lrm_state->node_name); -- register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); -+ /* only register this as a internal error if this involves the local -+ * lrmd. Otherwise we're likely dealing with an unresponsive remote-node -+ * which is not a FSA failure. */ -+ if (lrm_state_is_local(lrm_state) == TRUE) { -+ register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); -+ } - } - } - -@@ -1211,6 +1216,28 @@ delete_resource(lrm_state_t * lrm_state, - delete_rsc_entry(lrm_state, request, id, gIter, rc, user); - } - -+static int -+get_fake_call_id(lrm_state_t *lrm_state, const char *rsc_id) -+{ -+ int call_id = 0; -+ rsc_history_t *entry = NULL; -+ -+ entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id); -+ -+ /* Make sure the call id is greater than the last successful operation, -+ * otherwise the failure will not result in a possible recovery of the resource -+ * as it could appear the failure occurred before the successful start */ -+ if (entry) { -+ call_id = entry->last_callid + 1; -+ } -+ -+ if (call_id < 0) { -+ call_id = 1; -+ } -+ return call_id; -+} -+ -+ - /* A_LRM_INVOKE */ - void - do_lrm_invoke(long long action, -@@ -1272,7 +1299,6 @@ do_lrm_invoke(long long action, - operation = CRM_OP_LRM_REFRESH; - - } else if (safe_str_eq(crm_op, CRM_OP_LRM_FAIL)) { -- rsc_history_t *entry = NULL; - lrmd_event_data_t *op = NULL; - lrmd_rsc_info_t *rsc = NULL; - xmlNode *xml_rsc = find_xml_node(input->xml, XML_CIB_TAG_RESOURCE, TRUE); -@@ -1293,16 +1319,7 @@ do_lrm_invoke(long long action, - - free((char *)op->user_data); - op->user_data = NULL; -- entry = g_hash_table_lookup(lrm_state->resource_history, op->rsc_id); -- /* Make sure the call id is greater than the last successful operation, -- * otherwise the failure will not result in a possible recovery of the resource -- * as it could appear the failure occurred before the successful start */ -- if (entry) { -- op->call_id = entry->last_callid + 1; -- if (op->call_id < 0) { -- op->call_id = 1; -- } -- } -+ op->call_id = get_fake_call_id(lrm_state, op->rsc_id); - op->interval = 0; - op->op_status = PCMK_LRM_OP_DONE; - op->rc = PCMK_OCF_UNKNOWN_ERROR; -@@ -1430,6 +1447,21 @@ do_lrm_invoke(long long action, - rsc = get_lrm_resource(lrm_state, xml_rsc, input->xml, create_rsc); - - if (rsc == NULL && create_rsc) { -+ lrmd_event_data_t *op = NULL; -+ -+ /* if the operation couldn't complete because we can't register -+ * the resource, return a generic error */ -+ op = construct_op(lrm_state, input->xml, ID(xml_rsc), operation); -+ CRM_ASSERT(op != NULL); -+ -+ op->op_status = PCMK_LRM_OP_DONE; -+ op->rc = PCMK_OCF_UNKNOWN_ERROR; -+ op->t_run = time(NULL); -+ op->t_rcchange = op->t_run; -+ -+ send_direct_ack(from_host, from_sys, NULL, op, ID(xml_rsc)); -+ lrmd_free_event(op); -+ - crm_err("Invalid resource definition"); - crm_log_xml_warn(input->msg, "bad input"); - -@@ -1767,6 +1799,7 @@ do_lrm_rsc_op(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *operat - lrmd_key_value_t *params = NULL; - fsa_data_t *msg_data = NULL; - const char *transition = NULL; -+ gboolean stop_recurring = FALSE; - - CRM_CHECK(rsc != NULL, return); - CRM_CHECK(operation != NULL, return); -@@ -1781,10 +1814,25 @@ do_lrm_rsc_op(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *operat - op = construct_op(lrm_state, msg, rsc->id, operation); - CRM_CHECK(op != NULL, return); - -- /* stop any previous monitor operations before changing the resource state */ -- if (op->interval == 0 -+ if (is_remote_lrmd_ra(NULL, NULL, rsc->id) -+ && op->interval == 0 -+ && strcmp(operation, CRMD_ACTION_MIGRATE) == 0) { -+ -+ /* pcmk remote connections are a special use case. -+ * We never ever want to stop monitoring a connection resource until -+ * the entire migration has completed. If the connection is ever unexpected -+ * severed, even during a migration, this is an event we must detect.*/ -+ stop_recurring = FALSE; -+ -+ } else if (op->interval == 0 - && strcmp(operation, CRMD_ACTION_STATUS) != 0 - && strcmp(operation, CRMD_ACTION_NOTIFY) != 0) { -+ -+ /* stop any previous monitor operations before changing the resource state */ -+ stop_recurring = TRUE; -+ } -+ -+ if (stop_recurring == TRUE) { - guint removed = 0; - struct stop_recurring_action_s data; - -@@ -1837,10 +1885,20 @@ do_lrm_rsc_op(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *operat - op->op_type, - op->user_data, op->interval, op->timeout, op->start_delay, params); - -- if (call_id <= 0) { -+ if (call_id <= 0 && lrm_state_is_local(lrm_state)) { - crm_err("Operation %s on %s failed: %d", operation, rsc->id, call_id); - register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); - -+ } else if (call_id <= 0) { -+ -+ crm_err("Operation %s on resource %s failed to execute on remote node %s: %d", operation, rsc->id, lrm_state->node_name, call_id); -+ op->call_id = get_fake_call_id(lrm_state, rsc->id); -+ op->op_status = PCMK_LRM_OP_DONE; -+ op->rc = PCMK_OCF_UNKNOWN_ERROR; -+ op->t_run = time(NULL); -+ op->t_rcchange = op->t_run; -+ process_lrm_event(lrm_state, op); -+ - } else { - /* record all operations so we can wait - * for them to complete during shutdown -diff --git a/crmd/lrm_state.c b/crmd/lrm_state.c -index 72f66c7..efd061c 100644 ---- a/crmd/lrm_state.c -+++ b/crmd/lrm_state.c -@@ -90,6 +90,21 @@ free_recurring_op(gpointer value) - free(op); - } - -+gboolean -+lrm_state_is_local(lrm_state_t *lrm_state) -+{ -+ if (lrm_state == NULL || fsa_our_uname == NULL) { -+ return FALSE; -+ } -+ -+ if (strcmp(lrm_state->node_name, fsa_our_uname) != 0) { -+ return FALSE; -+ } -+ -+ return TRUE; -+ -+} -+ - lrm_state_t * - lrm_state_create(const char *node_name) - { -diff --git a/crmd/remote_lrmd_ra.c b/crmd/remote_lrmd_ra.c -index 2f658ee..ae59070 100644 ---- a/crmd/remote_lrmd_ra.c -+++ b/crmd/remote_lrmd_ra.c -@@ -231,7 +231,7 @@ retry_start_cmd_cb(gpointer data) - return FALSE; - } - cmd = ra_data->cur_cmd; -- if (safe_str_neq(cmd->action, "start")) { -+ if (safe_str_neq(cmd->action, "start") && safe_str_neq(cmd->action, "migrate_from")) { - return FALSE; - } - update_remaining_timeout(cmd); -@@ -264,7 +264,7 @@ connection_takeover_timeout_cb(gpointer data) - lrm_state_t *lrm_state = NULL; - remote_ra_cmd_t *cmd = data; - -- crm_debug("takeover event timed out for node %s", cmd->rsc_id); -+ crm_info("takeover event timed out for node %s", cmd->rsc_id); - cmd->takeover_timeout_id = 0; - - lrm_state = lrm_state_find(cmd->rsc_id); -@@ -281,7 +281,7 @@ monitor_timeout_cb(gpointer data) - lrm_state_t *lrm_state = NULL; - remote_ra_cmd_t *cmd = data; - -- crm_debug("Poke async response timed out for node %s", cmd->rsc_id); -+ crm_info("Poke async response timed out for node %s", cmd->rsc_id); - cmd->monitor_timeout_id = 0; - cmd->op_status = PCMK_LRM_OP_TIMEOUT; - cmd->rc = PCMK_OCF_UNKNOWN_ERROR; -diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h -index 33acc6e..0d853c0 100644 ---- a/include/crm/pengine/common.h -+++ b/include/crm/pengine/common.h -@@ -34,7 +34,18 @@ enum action_fail_response { - action_fail_stop, - action_fail_standby, - action_fail_fence, -- action_fail_restart_container -+ action_fail_restart_container, -+ /* This is reserved for internal use for baremetal remote node connection -+ * resources. This fail action means -+ * 1. If stonith is enabled, fence the baremetal remote node -+ * 2. stonith not enabled, attempt to recover the connection resources -+ * -+ * This response value gives us control of saying types of -+ * connection resource failures result in fencing the remote node. -+ * Example: recurring monitors failure should result in fencing. -+ */ -+ action_fail_reset_remote, -+ - }; - - /* the "done" action must be the "pre" action +1 */ -diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h -index f08a910..da20f64 100644 ---- a/include/crm/pengine/status.h -+++ b/include/crm/pengine/status.h -@@ -138,6 +138,8 @@ struct node_shared_s { - gboolean is_dc; - gboolean rsc_discovery_enabled; - -+ gboolean remote_requires_reset; -+ - int num_resources; - GListPtr running_rsc; /* resource_t* */ - GListPtr allocated_rsc; /* resource_t* */ -diff --git a/lib/common/ipc.c b/lib/common/ipc.c -index f26225f..1b8558d 100644 ---- a/lib/common/ipc.c -+++ b/lib/common/ipc.c -@@ -1144,7 +1144,7 @@ crm_ipc_send(crm_ipc_t * client, xmlNode * message, enum crm_ipc_flags flags, in - - id++; - CRM_LOG_ASSERT(id != 0); /* Crude wrap-around detection */ -- rc = crm_ipc_prepare(id, message, &iov, ipc_buffer_max); -+ rc = crm_ipc_prepare(id, message, &iov, client->max_buf_size); - if(rc < 0) { - return rc; - } -@@ -1158,10 +1158,10 @@ crm_ipc_send(crm_ipc_t * client, xmlNode * message, enum crm_ipc_flags flags, in - } - - if(header->size_compressed) { -- if(factor < 10 && (ipc_buffer_max / 10) < (rc / factor)) { -+ if(factor < 10 && (client->max_buf_size / 10) < (rc / factor)) { - crm_notice("Compressed message exceeds %d0%% of the configured ipc limit (%d bytes), " - "consider setting PCMK_ipc_buffer to %d or higher", -- factor, ipc_buffer_max, 2*ipc_buffer_max); -+ factor, client->max_buf_size, 2*client->max_buf_size); - factor++; - } - } -diff --git a/lib/lrmd/lrmd_client.c b/lib/lrmd/lrmd_client.c -index b8c5d23..74bd692 100644 ---- a/lib/lrmd/lrmd_client.c -+++ b/lib/lrmd/lrmd_client.c -@@ -604,12 +604,18 @@ lrmd_tls_recv_reply(lrmd_t * lrmd, int total_timeout, int expected_reply_id, int - remaining_timeout = total_timeout; - } - if (remaining_timeout <= 0) { -+ crm_err("Never received the expected reply during the timeout period, disconnecting."); -+ *disconnected = TRUE; - return NULL; - } - - crm_remote_recv(native->remote, remaining_timeout, disconnected); - xml = crm_remote_parse_buffer(native->remote); -- if (!xml || *disconnected) { -+ if (!xml) { -+ crm_err("Unable to receive expected reply, disconnecting."); -+ *disconnected = TRUE; -+ return NULL; -+ } else if (*disconnected) { - return NULL; - } - } -diff --git a/lib/pengine/common.c b/lib/pengine/common.c -index e5e4ea7..42eda33 100644 ---- a/lib/pengine/common.c -+++ b/lib/pengine/common.c -@@ -214,6 +214,9 @@ fail2text(enum action_fail_response fail) - case action_fail_restart_container: - result = "restart-container"; - break; -+ case action_fail_reset_remote: -+ result = "reset-remote"; -+ break; - } - return result; - } -diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c -index a19bdff..bdd6450 100644 ---- a/lib/pengine/unpack.c -+++ b/lib/pengine/unpack.c -@@ -80,6 +80,15 @@ pe_fence_node(pe_working_set_t * data_set, node_t * node, const char *reason) - node->details->uname, reason); - set_bit(node->details->remote_rsc->flags, pe_rsc_failed); - -+ } else if (is_baremetal_remote_node(node)) { -+ if(pe_can_fence(data_set, node)) { -+ crm_warn("Node %s will be fenced %s", node->details->uname, reason); -+ } else { -+ crm_warn("Node %s is unclean %s", node->details->uname, reason); -+ } -+ node->details->unclean = TRUE; -+ node->details->remote_requires_reset = TRUE; -+ - } else if (node->details->unclean == FALSE) { - if(pe_can_fence(data_set, node)) { - crm_warn("Node %s will be fenced %s", node->details->uname, reason); -@@ -1143,8 +1152,10 @@ unpack_remote_status(xmlNode * status, pe_working_set_t * data_set) - } - crm_trace("Processing remote node id=%s, uname=%s", id, uname); - -- this_node->details->unclean = FALSE; -- this_node->details->unseen = FALSE; -+ if (this_node->details->remote_requires_reset == FALSE) { -+ this_node->details->unclean = FALSE; -+ this_node->details->unseen = FALSE; -+ } - attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, FALSE); - add_node_attrs(attrs, this_node, TRUE, data_set); - -@@ -1777,6 +1788,7 @@ process_rsc_state(resource_t * rsc, node_t * node, - enum action_fail_response on_fail, - xmlNode * migrate_op, pe_working_set_t * data_set) - { -+ node_t *tmpnode = NULL; - CRM_ASSERT(rsc); - pe_rsc_trace(rsc, "Resource %s is %s on %s: on_fail=%s", - rsc->id, role2text(rsc->role), node->details->uname, fail2text(on_fail)); -@@ -1817,7 +1829,7 @@ process_rsc_state(resource_t * rsc, node_t * node, - should_fence = TRUE; - } else if (is_set(data_set->flags, pe_flag_stonith_enabled)) { - if (is_baremetal_remote_node(node) && is_not_set(node->details->remote_rsc->flags, pe_rsc_failed)) { -- /* setting unceen = true means that fencing of the remote node will -+ /* setting unseen = true means that fencing of the remote node will - * only occur if the connection resource is not going to start somewhere. - * This allows connection resources on a failed cluster-node to move to - * another node without requiring the baremetal remote nodes to be fenced -@@ -1892,7 +1904,20 @@ process_rsc_state(resource_t * rsc, node_t * node, - - if (rsc->container) { - stop_action(rsc->container, node, FALSE); -- -+ } else if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) { -+ stop_action(rsc, node, FALSE); -+ } -+ break; -+ case action_fail_reset_remote: -+ set_bit(rsc->flags, pe_rsc_failed); -+ tmpnode = NULL; -+ if (rsc->is_remote_node) { -+ tmpnode = pe_find_node(data_set->nodes, rsc->id); -+ } -+ if (tmpnode && is_baremetal_remote_node(tmpnode)) { -+ /* connection resource to baremetal resource failed in a way that -+ * should result in fencing the remote-node. */ -+ pe_fence_node(data_set, tmpnode, "because of connection failure(s)"); - } else if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) { - stop_action(rsc, node, FALSE); - } -@@ -1904,7 +1929,7 @@ process_rsc_state(resource_t * rsc, node_t * node, - * result in a fencing operation regardless if we're going to attempt to - * reconnect to the remote-node in this transition or not. */ - if (is_set(rsc->flags, pe_rsc_failed) && rsc->is_remote_node) { -- node_t *tmpnode = pe_find_node(data_set->nodes, rsc->id); -+ tmpnode = pe_find_node(data_set->nodes, rsc->id); - if (tmpnode && tmpnode->details->unclean) { - tmpnode->details->unseen = FALSE; - } -@@ -2510,10 +2535,9 @@ unpack_rsc_op_failure(resource_t *rsc, node_t *node, int rc, xmlNode *xml_op, en - - action = custom_action(rsc, strdup(key), task, NULL, TRUE, FALSE, data_set); - if ((action->on_fail <= action_fail_fence && *on_fail < action->on_fail) || -- (action->on_fail == action_fail_restart_container -- && *on_fail <= action_fail_recover) || (*on_fail == action_fail_restart_container -- && action->on_fail >= -- action_fail_migrate)) { -+ (action->on_fail == action_fail_reset_remote && *on_fail <= action_fail_recover) || -+ (action->on_fail == action_fail_restart_container && *on_fail <= action_fail_recover) || -+ (*on_fail == action_fail_restart_container && action->on_fail >= action_fail_migrate)) { - pe_rsc_trace(rsc, "on-fail %s -> %s for %s (%s)", fail2text(*on_fail), - fail2text(action->on_fail), action->uuid, key); - *on_fail = action->on_fail; -@@ -2881,13 +2905,11 @@ update_resource_state(resource_t *rsc, node_t * node, xmlNode * xml_op, const ch - case action_fail_block: - case action_fail_ignore: - case action_fail_recover: -- *on_fail = action_fail_ignore; -- rsc->next_role = RSC_ROLE_UNKNOWN; -- break; -- - case action_fail_restart_container: -+ case action_fail_reset_remote: - *on_fail = action_fail_ignore; - rsc->next_role = RSC_ROLE_UNKNOWN; -+ break; - } - } - } -diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c -index baf6cb9..a40de60 100644 ---- a/lib/pengine/utils.c -+++ b/lib/pengine/utils.c -@@ -35,6 +35,7 @@ void unpack_operation(action_t * action, xmlNode * xml_obj, resource_t * contain - pe_working_set_t * data_set); - static xmlNode *find_rsc_op_entry_helper(resource_t * rsc, const char *key, - gboolean include_disabled); -+static gboolean is_rsc_baremetal_remote_node(resource_t *rsc, pe_working_set_t * data_set); - - bool pe_can_fence(pe_working_set_t * data_set, node_t *node) - { -@@ -686,6 +687,19 @@ unpack_operation(action_t * action, xmlNode * xml_obj, resource_t * container, - NULL, action->meta, NULL, FALSE, data_set->now); - g_hash_table_remove(action->meta, "id"); - -+ field = XML_LRM_ATTR_INTERVAL; -+ value = g_hash_table_lookup(action->meta, field); -+ if (value != NULL) { -+ interval = crm_get_interval(value); -+ if (interval > 0) { -+ value_ms = crm_itoa(interval); -+ g_hash_table_replace(action->meta, strdup(field), value_ms); -+ -+ } else { -+ g_hash_table_remove(action->meta, field); -+ } -+ } -+ - /* Begin compatability code */ - value = g_hash_table_lookup(action->meta, "requires"); - -@@ -789,6 +803,22 @@ unpack_operation(action_t * action, xmlNode * xml_obj, resource_t * container, - action->on_fail = action_fail_restart_container; - value = "restart container (and possibly migrate) (default)"; - -+ /* for baremetal remote nodes, ensure that a recurring monitor operation failure -+ * defaults to either fencing the remote-node for recovery, or at least -+ * attempting to recover the the connection when fencing is disabled. */ -+ } else if (value == NULL && -+ is_rsc_baremetal_remote_node(action->rsc, data_set) && -+ safe_str_eq(action->task, CRMD_ACTION_STATUS) && -+ interval > 0) { -+ -+ if (is_set(data_set->flags, pe_flag_stonith_enabled)) { -+ action->on_fail = action_fail_reset_remote; -+ value = "fence baremetal remote node (default)"; -+ } else { -+ action->on_fail = action_fail_recover; -+ value = "recover baremetal remote node connection (default)"; -+ } -+ - } else if (value == NULL && safe_str_eq(action->task, CRMD_ACTION_STOP)) { - if (is_set(data_set->flags, pe_flag_stonith_enabled)) { - action->on_fail = action_fail_fence; -@@ -824,19 +854,6 @@ unpack_operation(action_t * action, xmlNode * xml_obj, resource_t * container, - pe_rsc_trace(action->rsc, "\t%s failure results in: %s", action->task, - role2text(action->fail_role)); - -- field = XML_LRM_ATTR_INTERVAL; -- value = g_hash_table_lookup(action->meta, field); -- if (value != NULL) { -- interval = crm_get_interval(value); -- if (interval > 0) { -- value_ms = crm_itoa(interval); -- g_hash_table_replace(action->meta, strdup(field), value_ms); -- -- } else { -- g_hash_table_remove(action->meta, field); -- } -- } -- - field = XML_OP_ATTR_START_DELAY; - value = g_hash_table_lookup(action->meta, field); - if (value != NULL) { -@@ -1939,6 +1956,25 @@ const char *rsc_printable_id(resource_t *rsc) - } - - gboolean -+is_rsc_baremetal_remote_node(resource_t *rsc, pe_working_set_t * data_set) -+{ -+ node_t *node; -+ -+ if (rsc == NULL) { -+ return FALSE; -+ } else if (rsc->is_remote_node == FALSE) { -+ return FALSE; -+ } -+ -+ node = pe_find_node(data_set->nodes, rsc->id); -+ if (node == NULL) { -+ return FALSE; -+ } -+ -+ return is_baremetal_remote_node(node); -+} -+ -+gboolean - is_baremetal_remote_node(node_t *node) - { - if (is_remote_node(node) && (node->details->remote_rsc == FALSE || node->details->remote_rsc->container == FALSE)) { -diff --git a/pengine/allocate.c b/pengine/allocate.c -index 45e2212..9c3cb60 100644 ---- a/pengine/allocate.c -+++ b/pengine/allocate.c -@@ -1191,7 +1191,10 @@ allocate_resources(pe_working_set_t * data_set) - continue; - } - pe_rsc_trace(rsc, "Allocating: %s", rsc->id); -- rsc->cmds->allocate(rsc, NULL, data_set); -+ /* for remote node connection resources, always prefer the partial migration -+ * target during resource allocation if the rsc is in the middle of a -+ * migration */ -+ rsc->cmds->allocate(rsc, rsc->partial_migration_target, data_set); - } - } - -@@ -1716,9 +1719,18 @@ apply_remote_node_ordering(pe_working_set_t *data_set) - node_t *cluster_node = remote_rsc->running_on ? remote_rsc->running_on->data : NULL; - - /* if the current cluster node a baremetal connection resource -- * is residing on is unclean, we can't process any operations on that -- * remote node until after it starts somewhere else. */ -- if (cluster_node && cluster_node->details->unclean == TRUE) { -+ * is residing on is unclean or went offline we can't process any -+ * operations on that remote node until after it starts somewhere else. */ -+ if (cluster_node == NULL || -+ cluster_node->details->unclean == TRUE || -+ cluster_node->details->online == FALSE) { -+ after_start = TRUE; -+ } else if (g_list_length(remote_rsc->running_on) > 1 && -+ remote_rsc->partial_migration_source && -+ remote_rsc->partial_migration_target) { -+ /* if we're caught in the middle of migrating a connection resource, -+ * then we have to wait until after the resource migrates before performing -+ * any actions. */ - after_start = TRUE; - } - } -diff --git a/pengine/native.c b/pengine/native.c -index 6d62010..62639d0 100644 ---- a/pengine/native.c -+++ b/pengine/native.c -@@ -1137,12 +1137,18 @@ handle_migration_actions(resource_t * rsc, node_t *current, node_t *chosen, pe_w - if (migrate_to) { - add_hash_param(migrate_to->meta, XML_LRM_ATTR_MIGRATE_SOURCE, current->details->uname); - add_hash_param(migrate_to->meta, XML_LRM_ATTR_MIGRATE_TARGET, chosen->details->uname); -- /* migrate_to takes place on the source node, but can -- * have an effect on the target node depending on how -- * the agent is written. Because of this, we have to maintain -- * a record that the migrate_to occurred incase the source node -- * loses membership while the migrate_to action is still in-flight. */ -- add_hash_param(migrate_to->meta, XML_OP_ATTR_PENDING, "true"); -+ -+ /* pcmk remote connections don't require pending to be recorded in cib. -+ * We can optimize cib writes by only setting PENDING for non pcmk remote -+ * connection resources */ -+ if (rsc->is_remote_node == FALSE) { -+ /* migrate_to takes place on the source node, but can -+ * have an effect on the target node depending on how -+ * the agent is written. Because of this, we have to maintain -+ * a record that the migrate_to occurred incase the source node -+ * loses membership while the migrate_to action is still in-flight. */ -+ add_hash_param(migrate_to->meta, XML_OP_ATTR_PENDING, "true"); -+ } - } - - if (migrate_from) { -diff --git a/pengine/regression.sh b/pengine/regression.sh -index aa03b18..3a244d7 100755 ---- a/pengine/regression.sh -+++ b/pengine/regression.sh -@@ -769,6 +769,11 @@ do_test remote-disable "Disable a baremetal remote-node" - do_test remote-orphaned "Properly shutdown orphaned connection resource" - do_test remote-recover "Recover connection resource after cluster-node fails." - do_test remote-stale-node-entry "Make sure we properly handle leftover remote-node entries in the node section" -+do_test remote-partial-migrate "Make sure partial migrations are handled before ops on the remote node." -+do_test remote-partial-migrate2 "Make sure partial migration target is prefered for remote connection." -+do_test remote-recover-fail "Make sure start failure causes fencing if rsc are active on remote." -+do_test remote-start-fail "Make sure a start failure does not result in fencing if no active resources are on remote." -+do_test remote-unclean2 "Make monitor failure always results in fencing, even if no rsc are active on remote." - - echo "" - do_test resource-discovery "Exercises resource-discovery location constraint option." -diff --git a/pengine/test10/remote-fence-unclean.exp b/pengine/test10/remote-fence-unclean.exp -index 9b1e327..b8c90f2 100644 ---- a/pengine/test10/remote-fence-unclean.exp -+++ b/pengine/test10/remote-fence-unclean.exp -@@ -8,7 +8,7 @@ - - - -- -+ - - - -@@ -17,7 +17,7 @@ - - - -- -+ - - - -@@ -176,13 +176,13 @@ - - - -- -+ - - - - - -- -+ - - - -diff --git a/pengine/test10/remote-move.exp b/pengine/test10/remote-move.exp -index 6724679..6287daa 100644 ---- a/pengine/test10/remote-move.exp -+++ b/pengine/test10/remote-move.exp -@@ -51,7 +51,7 @@ - - - -- -+ - - - -diff --git a/pengine/test10/remote-partial-migrate.dot b/pengine/test10/remote-partial-migrate.dot -new file mode 100644 -index 0000000..8d776dc ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate.dot -@@ -0,0 +1,86 @@ -+ digraph "g" { -+"FAKE10_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE10_start_0 pcmk1" -> "FAKE10_monitor_10000 pcmk1" [ style = bold] -+"FAKE10_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE13_monitor_10000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE13_start_0 pcmk2" -> "FAKE13_monitor_10000 pcmk2" [ style = bold] -+"FAKE13_start_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE15_monitor_10000 pcmk3" [ style=bold color="green" fontcolor="black"] -+"FAKE15_start_0 pcmk3" -> "FAKE15_monitor_10000 pcmk3" [ style = bold] -+"FAKE15_start_0 pcmk3" [ style=bold color="green" fontcolor="black"] -+"FAKE16_monitor_10000 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE16_start_0 pcmk_remote3" -> "FAKE16_monitor_10000 pcmk_remote3" [ style = bold] -+"FAKE16_start_0 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE16_stop_0 pcmk1" -> "FAKE16_start_0 pcmk_remote3" [ style = bold] -+"FAKE16_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE16_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE22_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE22_start_0 pcmk1" -> "FAKE22_monitor_10000 pcmk1" [ style = bold] -+"FAKE22_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE23_monitor_10000 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE23_start_0 pcmk_remote1" -> "FAKE23_monitor_10000 pcmk_remote1" [ style = bold] -+"FAKE23_start_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE23_stop_0 pcmk1" -> "FAKE23_start_0 pcmk_remote1" [ style = bold] -+"FAKE23_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE23_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE26_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE26_start_0 pcmk1" -> "FAKE26_monitor_10000 pcmk1" [ style = bold] -+"FAKE26_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE29_monitor_10000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE29_start_0 pcmk2" -> "FAKE29_monitor_10000 pcmk2" [ style = bold] -+"FAKE29_start_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE30_monitor_10000 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE30_start_0 pcmk_remote2" -> "FAKE30_monitor_10000 pcmk_remote2" [ style = bold] -+"FAKE30_start_0 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE30_stop_0 pcmk1" -> "FAKE30_start_0 pcmk_remote2" [ style = bold] -+"FAKE30_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE30_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE36_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE36_start_0 pcmk1" -> "FAKE36_monitor_10000 pcmk1" [ style = bold] -+"FAKE36_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE37_monitor_10000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE37_start_0 pcmk2" -> "FAKE37_monitor_10000 pcmk2" [ style = bold] -+"FAKE37_start_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE37_stop_0 pcmk1" -> "FAKE37_start_0 pcmk2" [ style = bold] -+"FAKE37_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE37_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE43_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE43_start_0 pcmk1" -> "FAKE43_monitor_10000 pcmk1" [ style = bold] -+"FAKE43_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE44_monitor_10000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE44_start_0 pcmk2" -> "FAKE44_monitor_10000 pcmk2" [ style = bold] -+"FAKE44_start_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE44_stop_0 pcmk1" -> "FAKE44_start_0 pcmk2" [ style = bold] -+"FAKE44_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE44_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_10000 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE4_start_0 pcmk_remote3" -> "FAKE4_monitor_10000 pcmk_remote3" [ style = bold] -+"FAKE4_start_0 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE50_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE50_start_0 pcmk1" -> "FAKE50_monitor_10000 pcmk1" [ style = bold] -+"FAKE50_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE9_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE9_start_0 pcmk1" -> "FAKE9_monitor_10000 pcmk1" [ style = bold] -+"FAKE9_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE9_stop_0 pcmk_remote3" -> "FAKE9_start_0 pcmk1" [ style = bold] -+"FAKE9_stop_0 pcmk_remote3" -> "all_stopped" [ style = bold] -+"FAKE9_stop_0 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"pcmk_remote3_migrate_from_0 pcmk2" -> "pcmk_remote3_start_0 pcmk2" [ style = bold] -+"pcmk_remote3_migrate_from_0 pcmk2" -> "pcmk_remote3_stop_0 pcmk1" [ style = bold] -+"pcmk_remote3_migrate_from_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote3_monitor_60000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote3_start_0 pcmk2" -> "FAKE16_monitor_10000 pcmk_remote3" [ style = bold] -+"pcmk_remote3_start_0 pcmk2" -> "FAKE16_start_0 pcmk_remote3" [ style = bold] -+"pcmk_remote3_start_0 pcmk2" -> "FAKE4_monitor_10000 pcmk_remote3" [ style = bold] -+"pcmk_remote3_start_0 pcmk2" -> "FAKE4_start_0 pcmk_remote3" [ style = bold] -+"pcmk_remote3_start_0 pcmk2" -> "FAKE9_stop_0 pcmk_remote3" [ style = bold] -+"pcmk_remote3_start_0 pcmk2" -> "pcmk_remote3_monitor_60000 pcmk2" [ style = bold] -+"pcmk_remote3_start_0 pcmk2" [ style=bold color="green" fontcolor="orange"] -+"pcmk_remote3_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"pcmk_remote3_stop_0 pcmk1" -> "pcmk_remote3_start_0 pcmk2" [ style = bold] -+"pcmk_remote3_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"probe_complete pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"probe_complete pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"probe_complete pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/remote-partial-migrate.exp b/pengine/test10/remote-partial-migrate.exp -new file mode 100644 -index 0000000..0a531df ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate.exp -@@ -0,0 +1,553 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-partial-migrate.scores b/pengine/test10/remote-partial-migrate.scores -new file mode 100644 -index 0000000..a81602d ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate.scores -@@ -0,0 +1,449 @@ -+Allocation scores: -+native_color: FAKE1 allocation score on pcmk1: 0 -+native_color: FAKE1 allocation score on pcmk2: 0 -+native_color: FAKE1 allocation score on pcmk3: 0 -+native_color: FAKE1 allocation score on pcmk_remote1: 0 -+native_color: FAKE1 allocation score on pcmk_remote2: 0 -+native_color: FAKE1 allocation score on pcmk_remote3: 0 -+native_color: FAKE1 allocation score on pcmk_remote4: 0 -+native_color: FAKE1 allocation score on pcmk_remote5: 0 -+native_color: FAKE10 allocation score on pcmk1: 0 -+native_color: FAKE10 allocation score on pcmk2: 0 -+native_color: FAKE10 allocation score on pcmk3: 0 -+native_color: FAKE10 allocation score on pcmk_remote1: 0 -+native_color: FAKE10 allocation score on pcmk_remote2: 0 -+native_color: FAKE10 allocation score on pcmk_remote3: 0 -+native_color: FAKE10 allocation score on pcmk_remote4: 0 -+native_color: FAKE10 allocation score on pcmk_remote5: 0 -+native_color: FAKE11 allocation score on pcmk1: 0 -+native_color: FAKE11 allocation score on pcmk2: 0 -+native_color: FAKE11 allocation score on pcmk3: 0 -+native_color: FAKE11 allocation score on pcmk_remote1: 0 -+native_color: FAKE11 allocation score on pcmk_remote2: 0 -+native_color: FAKE11 allocation score on pcmk_remote3: 0 -+native_color: FAKE11 allocation score on pcmk_remote4: 0 -+native_color: FAKE11 allocation score on pcmk_remote5: 0 -+native_color: FAKE12 allocation score on pcmk1: 0 -+native_color: FAKE12 allocation score on pcmk2: 0 -+native_color: FAKE12 allocation score on pcmk3: 0 -+native_color: FAKE12 allocation score on pcmk_remote1: 0 -+native_color: FAKE12 allocation score on pcmk_remote2: 0 -+native_color: FAKE12 allocation score on pcmk_remote3: 0 -+native_color: FAKE12 allocation score on pcmk_remote4: 0 -+native_color: FAKE12 allocation score on pcmk_remote5: 0 -+native_color: FAKE13 allocation score on pcmk1: 0 -+native_color: FAKE13 allocation score on pcmk2: 0 -+native_color: FAKE13 allocation score on pcmk3: 0 -+native_color: FAKE13 allocation score on pcmk_remote1: 0 -+native_color: FAKE13 allocation score on pcmk_remote2: 0 -+native_color: FAKE13 allocation score on pcmk_remote3: 0 -+native_color: FAKE13 allocation score on pcmk_remote4: 0 -+native_color: FAKE13 allocation score on pcmk_remote5: 0 -+native_color: FAKE14 allocation score on pcmk1: 0 -+native_color: FAKE14 allocation score on pcmk2: 0 -+native_color: FAKE14 allocation score on pcmk3: 0 -+native_color: FAKE14 allocation score on pcmk_remote1: 0 -+native_color: FAKE14 allocation score on pcmk_remote2: 0 -+native_color: FAKE14 allocation score on pcmk_remote3: 0 -+native_color: FAKE14 allocation score on pcmk_remote4: 0 -+native_color: FAKE14 allocation score on pcmk_remote5: 0 -+native_color: FAKE15 allocation score on pcmk1: 0 -+native_color: FAKE15 allocation score on pcmk2: 0 -+native_color: FAKE15 allocation score on pcmk3: 0 -+native_color: FAKE15 allocation score on pcmk_remote1: 0 -+native_color: FAKE15 allocation score on pcmk_remote2: 0 -+native_color: FAKE15 allocation score on pcmk_remote3: 0 -+native_color: FAKE15 allocation score on pcmk_remote4: 0 -+native_color: FAKE15 allocation score on pcmk_remote5: 0 -+native_color: FAKE16 allocation score on pcmk1: 0 -+native_color: FAKE16 allocation score on pcmk2: 0 -+native_color: FAKE16 allocation score on pcmk3: 0 -+native_color: FAKE16 allocation score on pcmk_remote1: 0 -+native_color: FAKE16 allocation score on pcmk_remote2: 0 -+native_color: FAKE16 allocation score on pcmk_remote3: 0 -+native_color: FAKE16 allocation score on pcmk_remote4: 0 -+native_color: FAKE16 allocation score on pcmk_remote5: 0 -+native_color: FAKE17 allocation score on pcmk1: 0 -+native_color: FAKE17 allocation score on pcmk2: 0 -+native_color: FAKE17 allocation score on pcmk3: 0 -+native_color: FAKE17 allocation score on pcmk_remote1: 0 -+native_color: FAKE17 allocation score on pcmk_remote2: 0 -+native_color: FAKE17 allocation score on pcmk_remote3: 0 -+native_color: FAKE17 allocation score on pcmk_remote4: 0 -+native_color: FAKE17 allocation score on pcmk_remote5: 0 -+native_color: FAKE18 allocation score on pcmk1: 0 -+native_color: FAKE18 allocation score on pcmk2: 0 -+native_color: FAKE18 allocation score on pcmk3: 0 -+native_color: FAKE18 allocation score on pcmk_remote1: 0 -+native_color: FAKE18 allocation score on pcmk_remote2: 0 -+native_color: FAKE18 allocation score on pcmk_remote3: 0 -+native_color: FAKE18 allocation score on pcmk_remote4: 0 -+native_color: FAKE18 allocation score on pcmk_remote5: 0 -+native_color: FAKE19 allocation score on pcmk1: 0 -+native_color: FAKE19 allocation score on pcmk2: 0 -+native_color: FAKE19 allocation score on pcmk3: 0 -+native_color: FAKE19 allocation score on pcmk_remote1: 0 -+native_color: FAKE19 allocation score on pcmk_remote2: 0 -+native_color: FAKE19 allocation score on pcmk_remote3: 0 -+native_color: FAKE19 allocation score on pcmk_remote4: 0 -+native_color: FAKE19 allocation score on pcmk_remote5: 0 -+native_color: FAKE2 allocation score on pcmk1: 0 -+native_color: FAKE2 allocation score on pcmk2: 0 -+native_color: FAKE2 allocation score on pcmk3: 0 -+native_color: FAKE2 allocation score on pcmk_remote1: 0 -+native_color: FAKE2 allocation score on pcmk_remote2: 0 -+native_color: FAKE2 allocation score on pcmk_remote3: 0 -+native_color: FAKE2 allocation score on pcmk_remote4: 0 -+native_color: FAKE2 allocation score on pcmk_remote5: 0 -+native_color: FAKE20 allocation score on pcmk1: 0 -+native_color: FAKE20 allocation score on pcmk2: 0 -+native_color: FAKE20 allocation score on pcmk3: 0 -+native_color: FAKE20 allocation score on pcmk_remote1: 0 -+native_color: FAKE20 allocation score on pcmk_remote2: 0 -+native_color: FAKE20 allocation score on pcmk_remote3: 0 -+native_color: FAKE20 allocation score on pcmk_remote4: 0 -+native_color: FAKE20 allocation score on pcmk_remote5: 0 -+native_color: FAKE21 allocation score on pcmk1: 0 -+native_color: FAKE21 allocation score on pcmk2: 0 -+native_color: FAKE21 allocation score on pcmk3: 0 -+native_color: FAKE21 allocation score on pcmk_remote1: 0 -+native_color: FAKE21 allocation score on pcmk_remote2: 0 -+native_color: FAKE21 allocation score on pcmk_remote3: 0 -+native_color: FAKE21 allocation score on pcmk_remote4: 0 -+native_color: FAKE21 allocation score on pcmk_remote5: 0 -+native_color: FAKE22 allocation score on pcmk1: 0 -+native_color: FAKE22 allocation score on pcmk2: 0 -+native_color: FAKE22 allocation score on pcmk3: 0 -+native_color: FAKE22 allocation score on pcmk_remote1: 0 -+native_color: FAKE22 allocation score on pcmk_remote2: 0 -+native_color: FAKE22 allocation score on pcmk_remote3: 0 -+native_color: FAKE22 allocation score on pcmk_remote4: 0 -+native_color: FAKE22 allocation score on pcmk_remote5: 0 -+native_color: FAKE23 allocation score on pcmk1: 0 -+native_color: FAKE23 allocation score on pcmk2: 0 -+native_color: FAKE23 allocation score on pcmk3: 0 -+native_color: FAKE23 allocation score on pcmk_remote1: 0 -+native_color: FAKE23 allocation score on pcmk_remote2: 0 -+native_color: FAKE23 allocation score on pcmk_remote3: 0 -+native_color: FAKE23 allocation score on pcmk_remote4: 0 -+native_color: FAKE23 allocation score on pcmk_remote5: 0 -+native_color: FAKE24 allocation score on pcmk1: 0 -+native_color: FAKE24 allocation score on pcmk2: 0 -+native_color: FAKE24 allocation score on pcmk3: 0 -+native_color: FAKE24 allocation score on pcmk_remote1: 0 -+native_color: FAKE24 allocation score on pcmk_remote2: 0 -+native_color: FAKE24 allocation score on pcmk_remote3: 0 -+native_color: FAKE24 allocation score on pcmk_remote4: 0 -+native_color: FAKE24 allocation score on pcmk_remote5: 0 -+native_color: FAKE25 allocation score on pcmk1: 0 -+native_color: FAKE25 allocation score on pcmk2: 0 -+native_color: FAKE25 allocation score on pcmk3: 0 -+native_color: FAKE25 allocation score on pcmk_remote1: 0 -+native_color: FAKE25 allocation score on pcmk_remote2: 0 -+native_color: FAKE25 allocation score on pcmk_remote3: 0 -+native_color: FAKE25 allocation score on pcmk_remote4: 0 -+native_color: FAKE25 allocation score on pcmk_remote5: 0 -+native_color: FAKE26 allocation score on pcmk1: 0 -+native_color: FAKE26 allocation score on pcmk2: 0 -+native_color: FAKE26 allocation score on pcmk3: 0 -+native_color: FAKE26 allocation score on pcmk_remote1: 0 -+native_color: FAKE26 allocation score on pcmk_remote2: 0 -+native_color: FAKE26 allocation score on pcmk_remote3: 0 -+native_color: FAKE26 allocation score on pcmk_remote4: 0 -+native_color: FAKE26 allocation score on pcmk_remote5: 0 -+native_color: FAKE27 allocation score on pcmk1: 0 -+native_color: FAKE27 allocation score on pcmk2: 0 -+native_color: FAKE27 allocation score on pcmk3: 0 -+native_color: FAKE27 allocation score on pcmk_remote1: 0 -+native_color: FAKE27 allocation score on pcmk_remote2: 0 -+native_color: FAKE27 allocation score on pcmk_remote3: 0 -+native_color: FAKE27 allocation score on pcmk_remote4: 0 -+native_color: FAKE27 allocation score on pcmk_remote5: 0 -+native_color: FAKE28 allocation score on pcmk1: 0 -+native_color: FAKE28 allocation score on pcmk2: 0 -+native_color: FAKE28 allocation score on pcmk3: 0 -+native_color: FAKE28 allocation score on pcmk_remote1: 0 -+native_color: FAKE28 allocation score on pcmk_remote2: 0 -+native_color: FAKE28 allocation score on pcmk_remote3: 0 -+native_color: FAKE28 allocation score on pcmk_remote4: 0 -+native_color: FAKE28 allocation score on pcmk_remote5: 0 -+native_color: FAKE29 allocation score on pcmk1: 0 -+native_color: FAKE29 allocation score on pcmk2: 0 -+native_color: FAKE29 allocation score on pcmk3: 0 -+native_color: FAKE29 allocation score on pcmk_remote1: 0 -+native_color: FAKE29 allocation score on pcmk_remote2: 0 -+native_color: FAKE29 allocation score on pcmk_remote3: 0 -+native_color: FAKE29 allocation score on pcmk_remote4: 0 -+native_color: FAKE29 allocation score on pcmk_remote5: 0 -+native_color: FAKE3 allocation score on pcmk1: 0 -+native_color: FAKE3 allocation score on pcmk2: 0 -+native_color: FAKE3 allocation score on pcmk3: 0 -+native_color: FAKE3 allocation score on pcmk_remote1: 0 -+native_color: FAKE3 allocation score on pcmk_remote2: 0 -+native_color: FAKE3 allocation score on pcmk_remote3: 0 -+native_color: FAKE3 allocation score on pcmk_remote4: 0 -+native_color: FAKE3 allocation score on pcmk_remote5: 0 -+native_color: FAKE30 allocation score on pcmk1: 0 -+native_color: FAKE30 allocation score on pcmk2: 0 -+native_color: FAKE30 allocation score on pcmk3: 0 -+native_color: FAKE30 allocation score on pcmk_remote1: 0 -+native_color: FAKE30 allocation score on pcmk_remote2: 0 -+native_color: FAKE30 allocation score on pcmk_remote3: 0 -+native_color: FAKE30 allocation score on pcmk_remote4: 0 -+native_color: FAKE30 allocation score on pcmk_remote5: 0 -+native_color: FAKE31 allocation score on pcmk1: 0 -+native_color: FAKE31 allocation score on pcmk2: 0 -+native_color: FAKE31 allocation score on pcmk3: 0 -+native_color: FAKE31 allocation score on pcmk_remote1: 0 -+native_color: FAKE31 allocation score on pcmk_remote2: 0 -+native_color: FAKE31 allocation score on pcmk_remote3: 0 -+native_color: FAKE31 allocation score on pcmk_remote4: 0 -+native_color: FAKE31 allocation score on pcmk_remote5: 0 -+native_color: FAKE32 allocation score on pcmk1: 0 -+native_color: FAKE32 allocation score on pcmk2: 0 -+native_color: FAKE32 allocation score on pcmk3: 0 -+native_color: FAKE32 allocation score on pcmk_remote1: 0 -+native_color: FAKE32 allocation score on pcmk_remote2: 0 -+native_color: FAKE32 allocation score on pcmk_remote3: 0 -+native_color: FAKE32 allocation score on pcmk_remote4: 0 -+native_color: FAKE32 allocation score on pcmk_remote5: 0 -+native_color: FAKE33 allocation score on pcmk1: 0 -+native_color: FAKE33 allocation score on pcmk2: 0 -+native_color: FAKE33 allocation score on pcmk3: 0 -+native_color: FAKE33 allocation score on pcmk_remote1: 0 -+native_color: FAKE33 allocation score on pcmk_remote2: 0 -+native_color: FAKE33 allocation score on pcmk_remote3: 0 -+native_color: FAKE33 allocation score on pcmk_remote4: 0 -+native_color: FAKE33 allocation score on pcmk_remote5: 0 -+native_color: FAKE34 allocation score on pcmk1: 0 -+native_color: FAKE34 allocation score on pcmk2: 0 -+native_color: FAKE34 allocation score on pcmk3: 0 -+native_color: FAKE34 allocation score on pcmk_remote1: 0 -+native_color: FAKE34 allocation score on pcmk_remote2: 0 -+native_color: FAKE34 allocation score on pcmk_remote3: 0 -+native_color: FAKE34 allocation score on pcmk_remote4: 0 -+native_color: FAKE34 allocation score on pcmk_remote5: 0 -+native_color: FAKE35 allocation score on pcmk1: 0 -+native_color: FAKE35 allocation score on pcmk2: 0 -+native_color: FAKE35 allocation score on pcmk3: 0 -+native_color: FAKE35 allocation score on pcmk_remote1: 0 -+native_color: FAKE35 allocation score on pcmk_remote2: 0 -+native_color: FAKE35 allocation score on pcmk_remote3: 0 -+native_color: FAKE35 allocation score on pcmk_remote4: 0 -+native_color: FAKE35 allocation score on pcmk_remote5: 0 -+native_color: FAKE36 allocation score on pcmk1: 0 -+native_color: FAKE36 allocation score on pcmk2: 0 -+native_color: FAKE36 allocation score on pcmk3: 0 -+native_color: FAKE36 allocation score on pcmk_remote1: 0 -+native_color: FAKE36 allocation score on pcmk_remote2: 0 -+native_color: FAKE36 allocation score on pcmk_remote3: 0 -+native_color: FAKE36 allocation score on pcmk_remote4: 0 -+native_color: FAKE36 allocation score on pcmk_remote5: 0 -+native_color: FAKE37 allocation score on pcmk1: 0 -+native_color: FAKE37 allocation score on pcmk2: 0 -+native_color: FAKE37 allocation score on pcmk3: 0 -+native_color: FAKE37 allocation score on pcmk_remote1: 0 -+native_color: FAKE37 allocation score on pcmk_remote2: 0 -+native_color: FAKE37 allocation score on pcmk_remote3: 0 -+native_color: FAKE37 allocation score on pcmk_remote4: 0 -+native_color: FAKE37 allocation score on pcmk_remote5: 0 -+native_color: FAKE38 allocation score on pcmk1: 0 -+native_color: FAKE38 allocation score on pcmk2: 0 -+native_color: FAKE38 allocation score on pcmk3: 0 -+native_color: FAKE38 allocation score on pcmk_remote1: 0 -+native_color: FAKE38 allocation score on pcmk_remote2: 0 -+native_color: FAKE38 allocation score on pcmk_remote3: 0 -+native_color: FAKE38 allocation score on pcmk_remote4: 0 -+native_color: FAKE38 allocation score on pcmk_remote5: 0 -+native_color: FAKE39 allocation score on pcmk1: 0 -+native_color: FAKE39 allocation score on pcmk2: 0 -+native_color: FAKE39 allocation score on pcmk3: 0 -+native_color: FAKE39 allocation score on pcmk_remote1: 0 -+native_color: FAKE39 allocation score on pcmk_remote2: 0 -+native_color: FAKE39 allocation score on pcmk_remote3: 0 -+native_color: FAKE39 allocation score on pcmk_remote4: 0 -+native_color: FAKE39 allocation score on pcmk_remote5: 0 -+native_color: FAKE4 allocation score on pcmk1: 0 -+native_color: FAKE4 allocation score on pcmk2: 0 -+native_color: FAKE4 allocation score on pcmk3: 0 -+native_color: FAKE4 allocation score on pcmk_remote1: 0 -+native_color: FAKE4 allocation score on pcmk_remote2: 0 -+native_color: FAKE4 allocation score on pcmk_remote3: 0 -+native_color: FAKE4 allocation score on pcmk_remote4: 0 -+native_color: FAKE4 allocation score on pcmk_remote5: 0 -+native_color: FAKE40 allocation score on pcmk1: 0 -+native_color: FAKE40 allocation score on pcmk2: 0 -+native_color: FAKE40 allocation score on pcmk3: 0 -+native_color: FAKE40 allocation score on pcmk_remote1: 0 -+native_color: FAKE40 allocation score on pcmk_remote2: 0 -+native_color: FAKE40 allocation score on pcmk_remote3: 0 -+native_color: FAKE40 allocation score on pcmk_remote4: 0 -+native_color: FAKE40 allocation score on pcmk_remote5: 0 -+native_color: FAKE41 allocation score on pcmk1: 0 -+native_color: FAKE41 allocation score on pcmk2: 0 -+native_color: FAKE41 allocation score on pcmk3: 0 -+native_color: FAKE41 allocation score on pcmk_remote1: 0 -+native_color: FAKE41 allocation score on pcmk_remote2: 0 -+native_color: FAKE41 allocation score on pcmk_remote3: 0 -+native_color: FAKE41 allocation score on pcmk_remote4: 0 -+native_color: FAKE41 allocation score on pcmk_remote5: 0 -+native_color: FAKE42 allocation score on pcmk1: 0 -+native_color: FAKE42 allocation score on pcmk2: 0 -+native_color: FAKE42 allocation score on pcmk3: 0 -+native_color: FAKE42 allocation score on pcmk_remote1: 0 -+native_color: FAKE42 allocation score on pcmk_remote2: 0 -+native_color: FAKE42 allocation score on pcmk_remote3: 0 -+native_color: FAKE42 allocation score on pcmk_remote4: 0 -+native_color: FAKE42 allocation score on pcmk_remote5: 0 -+native_color: FAKE43 allocation score on pcmk1: 0 -+native_color: FAKE43 allocation score on pcmk2: 0 -+native_color: FAKE43 allocation score on pcmk3: 0 -+native_color: FAKE43 allocation score on pcmk_remote1: 0 -+native_color: FAKE43 allocation score on pcmk_remote2: 0 -+native_color: FAKE43 allocation score on pcmk_remote3: 0 -+native_color: FAKE43 allocation score on pcmk_remote4: 0 -+native_color: FAKE43 allocation score on pcmk_remote5: 0 -+native_color: FAKE44 allocation score on pcmk1: 0 -+native_color: FAKE44 allocation score on pcmk2: 0 -+native_color: FAKE44 allocation score on pcmk3: 0 -+native_color: FAKE44 allocation score on pcmk_remote1: 0 -+native_color: FAKE44 allocation score on pcmk_remote2: 0 -+native_color: FAKE44 allocation score on pcmk_remote3: 0 -+native_color: FAKE44 allocation score on pcmk_remote4: 0 -+native_color: FAKE44 allocation score on pcmk_remote5: 0 -+native_color: FAKE45 allocation score on pcmk1: 0 -+native_color: FAKE45 allocation score on pcmk2: 0 -+native_color: FAKE45 allocation score on pcmk3: 0 -+native_color: FAKE45 allocation score on pcmk_remote1: 0 -+native_color: FAKE45 allocation score on pcmk_remote2: 0 -+native_color: FAKE45 allocation score on pcmk_remote3: 0 -+native_color: FAKE45 allocation score on pcmk_remote4: 0 -+native_color: FAKE45 allocation score on pcmk_remote5: 0 -+native_color: FAKE46 allocation score on pcmk1: 0 -+native_color: FAKE46 allocation score on pcmk2: 0 -+native_color: FAKE46 allocation score on pcmk3: 0 -+native_color: FAKE46 allocation score on pcmk_remote1: 0 -+native_color: FAKE46 allocation score on pcmk_remote2: 0 -+native_color: FAKE46 allocation score on pcmk_remote3: 0 -+native_color: FAKE46 allocation score on pcmk_remote4: 0 -+native_color: FAKE46 allocation score on pcmk_remote5: 0 -+native_color: FAKE47 allocation score on pcmk1: 0 -+native_color: FAKE47 allocation score on pcmk2: 0 -+native_color: FAKE47 allocation score on pcmk3: 0 -+native_color: FAKE47 allocation score on pcmk_remote1: 0 -+native_color: FAKE47 allocation score on pcmk_remote2: 0 -+native_color: FAKE47 allocation score on pcmk_remote3: 0 -+native_color: FAKE47 allocation score on pcmk_remote4: 0 -+native_color: FAKE47 allocation score on pcmk_remote5: 0 -+native_color: FAKE48 allocation score on pcmk1: 0 -+native_color: FAKE48 allocation score on pcmk2: 0 -+native_color: FAKE48 allocation score on pcmk3: 0 -+native_color: FAKE48 allocation score on pcmk_remote1: 0 -+native_color: FAKE48 allocation score on pcmk_remote2: 0 -+native_color: FAKE48 allocation score on pcmk_remote3: 0 -+native_color: FAKE48 allocation score on pcmk_remote4: 0 -+native_color: FAKE48 allocation score on pcmk_remote5: 0 -+native_color: FAKE49 allocation score on pcmk1: 0 -+native_color: FAKE49 allocation score on pcmk2: 0 -+native_color: FAKE49 allocation score on pcmk3: 0 -+native_color: FAKE49 allocation score on pcmk_remote1: 0 -+native_color: FAKE49 allocation score on pcmk_remote2: 0 -+native_color: FAKE49 allocation score on pcmk_remote3: 0 -+native_color: FAKE49 allocation score on pcmk_remote4: 0 -+native_color: FAKE49 allocation score on pcmk_remote5: 0 -+native_color: FAKE5 allocation score on pcmk1: 0 -+native_color: FAKE5 allocation score on pcmk2: 0 -+native_color: FAKE5 allocation score on pcmk3: 0 -+native_color: FAKE5 allocation score on pcmk_remote1: 0 -+native_color: FAKE5 allocation score on pcmk_remote2: 0 -+native_color: FAKE5 allocation score on pcmk_remote3: 0 -+native_color: FAKE5 allocation score on pcmk_remote4: 0 -+native_color: FAKE5 allocation score on pcmk_remote5: 0 -+native_color: FAKE50 allocation score on pcmk1: 0 -+native_color: FAKE50 allocation score on pcmk2: 0 -+native_color: FAKE50 allocation score on pcmk3: 0 -+native_color: FAKE50 allocation score on pcmk_remote1: 0 -+native_color: FAKE50 allocation score on pcmk_remote2: 0 -+native_color: FAKE50 allocation score on pcmk_remote3: 0 -+native_color: FAKE50 allocation score on pcmk_remote4: 0 -+native_color: FAKE50 allocation score on pcmk_remote5: 0 -+native_color: FAKE6 allocation score on pcmk1: 0 -+native_color: FAKE6 allocation score on pcmk2: 0 -+native_color: FAKE6 allocation score on pcmk3: 0 -+native_color: FAKE6 allocation score on pcmk_remote1: 0 -+native_color: FAKE6 allocation score on pcmk_remote2: 0 -+native_color: FAKE6 allocation score on pcmk_remote3: 0 -+native_color: FAKE6 allocation score on pcmk_remote4: 0 -+native_color: FAKE6 allocation score on pcmk_remote5: 0 -+native_color: FAKE7 allocation score on pcmk1: 0 -+native_color: FAKE7 allocation score on pcmk2: 0 -+native_color: FAKE7 allocation score on pcmk3: 0 -+native_color: FAKE7 allocation score on pcmk_remote1: 0 -+native_color: FAKE7 allocation score on pcmk_remote2: 0 -+native_color: FAKE7 allocation score on pcmk_remote3: 0 -+native_color: FAKE7 allocation score on pcmk_remote4: 0 -+native_color: FAKE7 allocation score on pcmk_remote5: 0 -+native_color: FAKE8 allocation score on pcmk1: 0 -+native_color: FAKE8 allocation score on pcmk2: 0 -+native_color: FAKE8 allocation score on pcmk3: 0 -+native_color: FAKE8 allocation score on pcmk_remote1: 0 -+native_color: FAKE8 allocation score on pcmk_remote2: 0 -+native_color: FAKE8 allocation score on pcmk_remote3: 0 -+native_color: FAKE8 allocation score on pcmk_remote4: 0 -+native_color: FAKE8 allocation score on pcmk_remote5: 0 -+native_color: FAKE9 allocation score on pcmk1: 0 -+native_color: FAKE9 allocation score on pcmk2: -INFINITY -+native_color: FAKE9 allocation score on pcmk3: 0 -+native_color: FAKE9 allocation score on pcmk_remote1: 0 -+native_color: FAKE9 allocation score on pcmk_remote2: 0 -+native_color: FAKE9 allocation score on pcmk_remote3: 0 -+native_color: FAKE9 allocation score on pcmk_remote4: 0 -+native_color: FAKE9 allocation score on pcmk_remote5: 0 -+native_color: pcmk_remote1 allocation score on pcmk1: 0 -+native_color: pcmk_remote1 allocation score on pcmk2: 0 -+native_color: pcmk_remote1 allocation score on pcmk3: 0 -+native_color: pcmk_remote1 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk1: 0 -+native_color: pcmk_remote2 allocation score on pcmk2: 0 -+native_color: pcmk_remote2 allocation score on pcmk3: 0 -+native_color: pcmk_remote2 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk1: 0 -+native_color: pcmk_remote3 allocation score on pcmk2: 0 -+native_color: pcmk_remote3 allocation score on pcmk3: 0 -+native_color: pcmk_remote3 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk1: 0 -+native_color: pcmk_remote4 allocation score on pcmk2: 0 -+native_color: pcmk_remote4 allocation score on pcmk3: 0 -+native_color: pcmk_remote4 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk1: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk2: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk3: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote5: -INFINITY -+native_color: shooter allocation score on pcmk1: 0 -+native_color: shooter allocation score on pcmk2: 0 -+native_color: shooter allocation score on pcmk3: 0 -+native_color: shooter allocation score on pcmk_remote1: -INFINITY -+native_color: shooter allocation score on pcmk_remote2: -INFINITY -+native_color: shooter allocation score on pcmk_remote3: -INFINITY -+native_color: shooter allocation score on pcmk_remote4: -INFINITY -+native_color: shooter allocation score on pcmk_remote5: -INFINITY -diff --git a/pengine/test10/remote-partial-migrate.summary b/pengine/test10/remote-partial-migrate.summary -new file mode 100644 -index 0000000..e8abf92 ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate.summary -@@ -0,0 +1,189 @@ -+ -+Current cluster status: -+Online: [ pcmk1 pcmk2 pcmk3 ] -+RemoteOnline: [ pcmk_remote1 pcmk_remote2 pcmk_remote3 pcmk_remote4 ] -+RemoteOFFLINE: [ pcmk_remote5 ] -+ -+ shooter (stonith:fence_docker_cts): Started pcmk2 -+ pcmk_remote1 (ocf::pacemaker:remote): Started pcmk1 -+ pcmk_remote2 (ocf::pacemaker:remote): Started pcmk3 -+ pcmk_remote3 (ocf::pacemaker:remote): Started [ pcmk2 pcmk1 ] -+ pcmk_remote4 (ocf::pacemaker:remote): Started pcmk3 -+ pcmk_remote5 (ocf::pacemaker:remote): Stopped -+ FAKE1 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE2 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE3 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE4 (ocf::heartbeat:Dummy): Stopped -+ FAKE5 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE6 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE7 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE8 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE9 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE10 (ocf::heartbeat:Dummy): Stopped -+ FAKE11 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE12 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE13 (ocf::heartbeat:Dummy): Stopped -+ FAKE14 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE15 (ocf::heartbeat:Dummy): Stopped -+ FAKE16 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE17 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE18 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE19 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE20 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE21 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE22 (ocf::heartbeat:Dummy): Stopped -+ FAKE23 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE24 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE25 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE26 (ocf::heartbeat:Dummy): Stopped -+ FAKE27 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE28 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE29 (ocf::heartbeat:Dummy): Stopped -+ FAKE30 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE31 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE32 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE33 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE34 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE35 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE36 (ocf::heartbeat:Dummy): Stopped -+ FAKE37 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE38 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE39 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE40 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE41 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE42 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE43 (ocf::heartbeat:Dummy): Stopped -+ FAKE44 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE45 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE46 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE47 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE48 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE49 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE50 (ocf::heartbeat:Dummy): Stopped -+ -+Transition Summary: -+ * Migrate pcmk_remote3 (Started pcmk1 -> pcmk2) -+ * Start FAKE4 (pcmk_remote3) -+ * Move FAKE9 (Started pcmk_remote3 -> pcmk1) -+ * Start FAKE10 (pcmk1) -+ * Start FAKE13 (pcmk2) -+ * Start FAKE15 (pcmk3) -+ * Move FAKE16 (Started pcmk1 -> pcmk_remote3) -+ * Start FAKE22 (pcmk1) -+ * Move FAKE23 (Started pcmk1 -> pcmk_remote1) -+ * Start FAKE26 (pcmk1) -+ * Start FAKE29 (pcmk2) -+ * Move FAKE30 (Started pcmk1 -> pcmk_remote2) -+ * Start FAKE36 (pcmk1) -+ * Move FAKE37 (Started pcmk1 -> pcmk2) -+ * Start FAKE43 (pcmk1) -+ * Move FAKE44 (Started pcmk1 -> pcmk2) -+ * Start FAKE50 (pcmk1) -+ -+Executing cluster transition: -+ * Resource action: pcmk_remote3 migrate_from on pcmk2 -+ * Resource action: pcmk_remote3 stop on pcmk1 -+ * Resource action: FAKE10 start on pcmk1 -+ * Resource action: FAKE13 start on pcmk2 -+ * Resource action: FAKE15 start on pcmk3 -+ * Resource action: FAKE16 stop on pcmk1 -+ * Resource action: FAKE22 start on pcmk1 -+ * Resource action: FAKE23 stop on pcmk1 -+ * Resource action: FAKE26 start on pcmk1 -+ * Resource action: FAKE29 start on pcmk2 -+ * Resource action: FAKE30 stop on pcmk1 -+ * Resource action: FAKE36 start on pcmk1 -+ * Resource action: FAKE37 stop on pcmk1 -+ * Resource action: FAKE43 start on pcmk1 -+ * Resource action: FAKE44 stop on pcmk1 -+ * Resource action: FAKE50 start on pcmk1 -+ * Pseudo action: pcmk_remote3_start_0 -+ * Resource action: FAKE4 start on pcmk_remote3 -+ * Resource action: FAKE9 stop on pcmk_remote3 -+ * Resource action: FAKE10 monitor=10000 on pcmk1 -+ * Resource action: FAKE13 monitor=10000 on pcmk2 -+ * Resource action: FAKE15 monitor=10000 on pcmk3 -+ * Resource action: FAKE16 start on pcmk_remote3 -+ * Resource action: FAKE22 monitor=10000 on pcmk1 -+ * Resource action: FAKE23 start on pcmk_remote1 -+ * Resource action: FAKE26 monitor=10000 on pcmk1 -+ * Resource action: FAKE29 monitor=10000 on pcmk2 -+ * Resource action: FAKE30 start on pcmk_remote2 -+ * Resource action: FAKE36 monitor=10000 on pcmk1 -+ * Resource action: FAKE37 start on pcmk2 -+ * Resource action: FAKE43 monitor=10000 on pcmk1 -+ * Resource action: FAKE44 start on pcmk2 -+ * Resource action: FAKE50 monitor=10000 on pcmk1 -+ * Pseudo action: all_stopped -+ * Resource action: pcmk_remote3 monitor=60000 on pcmk2 -+ * Resource action: FAKE4 monitor=10000 on pcmk_remote3 -+ * Resource action: FAKE9 start on pcmk1 -+ * Resource action: FAKE16 monitor=10000 on pcmk_remote3 -+ * Resource action: FAKE23 monitor=10000 on pcmk_remote1 -+ * Resource action: FAKE30 monitor=10000 on pcmk_remote2 -+ * Resource action: FAKE37 monitor=10000 on pcmk2 -+ * Resource action: FAKE44 monitor=10000 on pcmk2 -+ * Resource action: FAKE9 monitor=10000 on pcmk1 -+ -+Revised cluster status: -+Online: [ pcmk1 pcmk2 pcmk3 ] -+RemoteOnline: [ pcmk_remote1 pcmk_remote2 pcmk_remote3 pcmk_remote4 ] -+RemoteOFFLINE: [ pcmk_remote5 ] -+ -+ shooter (stonith:fence_docker_cts): Started pcmk2 -+ pcmk_remote1 (ocf::pacemaker:remote): Started pcmk1 -+ pcmk_remote2 (ocf::pacemaker:remote): Started pcmk3 -+ pcmk_remote3 (ocf::pacemaker:remote): Started pcmk2 -+ pcmk_remote4 (ocf::pacemaker:remote): Started pcmk3 -+ pcmk_remote5 (ocf::pacemaker:remote): Stopped -+ FAKE1 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE2 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE3 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE4 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE5 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE6 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE7 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE8 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE9 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE10 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE11 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE12 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE13 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE14 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE15 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE16 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE17 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE18 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE19 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE20 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE21 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE22 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE23 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE24 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE25 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE26 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE27 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE28 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE29 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE30 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE31 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE32 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE33 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE34 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE35 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE36 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE37 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE38 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE39 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE40 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE41 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE42 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE43 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE44 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE45 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE46 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE47 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE48 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE49 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE50 (ocf::heartbeat:Dummy): Started pcmk1 -+ -diff --git a/pengine/test10/remote-partial-migrate.xml b/pengine/test10/remote-partial-migrate.xml -new file mode 100644 -index 0000000..e71f029 ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate.xml -@@ -0,0 +1,1734 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-partial-migrate2.dot b/pengine/test10/remote-partial-migrate2.dot -new file mode 100644 -index 0000000..a8bf29b ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate2.dot -@@ -0,0 +1,159 @@ -+ digraph "g" { -+"FAKE12_monitor_10000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE12_start_0 pcmk2" -> "FAKE12_monitor_10000 pcmk2" [ style = bold] -+"FAKE12_start_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE12_stop_0 pcmk1" -> "FAKE12_start_0 pcmk2" [ style = bold] -+"FAKE12_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE12_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE14_monitor_10000 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE14_start_0 pcmk_remote1" -> "FAKE14_monitor_10000 pcmk_remote1" [ style = bold] -+"FAKE14_start_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE14_stop_0 pcmk2" -> "FAKE14_start_0 pcmk_remote1" [ style = bold] -+"FAKE14_stop_0 pcmk2" -> "all_stopped" [ style = bold] -+"FAKE14_stop_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE17_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE17_start_0 pcmk_remote4" -> "FAKE17_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE17_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE17_stop_0 pcmk_remote1" -> "FAKE17_start_0 pcmk_remote4" [ style = bold] -+"FAKE17_stop_0 pcmk_remote1" -> "all_stopped" [ style = bold] -+"FAKE17_stop_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE25_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE25_start_0 pcmk_remote4" -> "FAKE25_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE25_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE25_stop_0 pcmk_remote1" -> "FAKE25_start_0 pcmk_remote4" [ style = bold] -+"FAKE25_stop_0 pcmk_remote1" -> "all_stopped" [ style = bold] -+"FAKE25_stop_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE28_monitor_10000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE28_start_0 pcmk1" -> "FAKE28_monitor_10000 pcmk1" [ style = bold] -+"FAKE28_start_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE28_stop_0 pcmk3" -> "FAKE28_start_0 pcmk1" [ style = bold] -+"FAKE28_stop_0 pcmk3" -> "all_stopped" [ style = bold] -+"FAKE28_stop_0 pcmk3" [ style=bold color="green" fontcolor="black"] -+"FAKE30_monitor_10000 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE30_start_0 pcmk_remote1" -> "FAKE30_monitor_10000 pcmk_remote1" [ style = bold] -+"FAKE30_start_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE30_stop_0 pcmk1" -> "FAKE30_start_0 pcmk_remote1" [ style = bold] -+"FAKE30_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE30_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE33_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE33_start_0 pcmk_remote4" -> "FAKE33_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE33_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE33_stop_0 pcmk_remote1" -> "FAKE33_start_0 pcmk_remote4" [ style = bold] -+"FAKE33_stop_0 pcmk_remote1" -> "all_stopped" [ style = bold] -+"FAKE33_stop_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE38_monitor_10000 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE38_start_0 pcmk_remote1" -> "FAKE38_monitor_10000 pcmk_remote1" [ style = bold] -+"FAKE38_start_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE38_stop_0 pcmk2" -> "FAKE38_start_0 pcmk_remote1" [ style = bold] -+"FAKE38_stop_0 pcmk2" -> "all_stopped" [ style = bold] -+"FAKE38_stop_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"FAKE39_monitor_10000 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE39_start_0 pcmk_remote2" -> "FAKE39_monitor_10000 pcmk_remote2" [ style = bold] -+"FAKE39_start_0 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE39_stop_0 pcmk1" -> "FAKE39_start_0 pcmk_remote2" [ style = bold] -+"FAKE39_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE39_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE41_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE41_start_0 pcmk_remote4" -> "FAKE41_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE41_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE41_stop_0 pcmk_remote2" -> "FAKE41_start_0 pcmk_remote4" [ style = bold] -+"FAKE41_stop_0 pcmk_remote2" -> "all_stopped" [ style = bold] -+"FAKE41_stop_0 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE47_monitor_10000 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE47_start_0 pcmk_remote2" -> "FAKE47_monitor_10000 pcmk_remote2" [ style = bold] -+"FAKE47_start_0 pcmk_remote2" [ style=bold color="green" fontcolor="black"] -+"FAKE47_stop_0 pcmk_remote1" -> "FAKE47_start_0 pcmk_remote2" [ style = bold] -+"FAKE47_stop_0 pcmk_remote1" -> "all_stopped" [ style = bold] -+"FAKE47_stop_0 pcmk_remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE48_monitor_10000 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE48_start_0 pcmk_remote3" -> "FAKE48_monitor_10000 pcmk_remote3" [ style = bold] -+"FAKE48_start_0 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE48_stop_0 pcmk1" -> "FAKE48_start_0 pcmk_remote3" [ style = bold] -+"FAKE48_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE48_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE49_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE49_start_0 pcmk_remote4" -> "FAKE49_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE49_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE49_stop_0 pcmk_remote3" -> "FAKE49_start_0 pcmk_remote4" [ style = bold] -+"FAKE49_stop_0 pcmk_remote3" -> "all_stopped" [ style = bold] -+"FAKE49_stop_0 pcmk_remote3" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE5_start_0 pcmk_remote4" -> "FAKE5_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE5_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE5_stop_0 pcmk1" -> "FAKE5_start_0 pcmk_remote4" [ style = bold] -+"FAKE5_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"FAKE5_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"FAKE9_monitor_10000 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE9_start_0 pcmk_remote4" -> "FAKE9_monitor_10000 pcmk_remote4" [ style = bold] -+"FAKE9_start_0 pcmk_remote4" [ style=bold color="green" fontcolor="black"] -+"FAKE9_stop_0 pcmk2" -> "FAKE9_start_0 pcmk_remote4" [ style = bold] -+"FAKE9_stop_0 pcmk2" -> "all_stopped" [ style = bold] -+"FAKE9_stop_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"pcmk_remote2_migrate_from_0 pcmk1" -> "pcmk_remote2_start_0 pcmk1" [ style = bold] -+"pcmk_remote2_migrate_from_0 pcmk1" -> "pcmk_remote2_stop_0 pcmk3" [ style = bold] -+"pcmk_remote2_migrate_from_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote2_monitor_60000 pcmk1" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote2_start_0 pcmk1" -> "FAKE39_monitor_10000 pcmk_remote2" [ style = bold] -+"pcmk_remote2_start_0 pcmk1" -> "FAKE39_start_0 pcmk_remote2" [ style = bold] -+"pcmk_remote2_start_0 pcmk1" -> "FAKE41_stop_0 pcmk_remote2" [ style = bold] -+"pcmk_remote2_start_0 pcmk1" -> "FAKE47_monitor_10000 pcmk_remote2" [ style = bold] -+"pcmk_remote2_start_0 pcmk1" -> "FAKE47_start_0 pcmk_remote2" [ style = bold] -+"pcmk_remote2_start_0 pcmk1" -> "pcmk_remote2_monitor_60000 pcmk1" [ style = bold] -+"pcmk_remote2_start_0 pcmk1" [ style=bold color="green" fontcolor="orange"] -+"pcmk_remote2_stop_0 pcmk3" -> "all_stopped" [ style = bold] -+"pcmk_remote2_stop_0 pcmk3" -> "pcmk_remote2_start_0 pcmk1" [ style = bold] -+"pcmk_remote2_stop_0 pcmk3" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote4_monitor_60000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE17_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE17_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE25_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE25_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE33_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE33_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE41_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE41_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE49_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE49_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE5_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE5_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE9_monitor_10000 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "FAKE9_start_0 pcmk_remote4" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" -> "pcmk_remote4_monitor_60000 pcmk2" [ style = bold] -+"pcmk_remote4_start_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote5_migrate_from_0 pcmk2" -> "pcmk_remote5_start_0 pcmk2" [ style = bold] -+"pcmk_remote5_migrate_from_0 pcmk2" -> "pcmk_remote5_stop_0 pcmk1" [ style = bold] -+"pcmk_remote5_migrate_from_0 pcmk2" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote5_migrate_to_0 pcmk1" -> "pcmk_remote5_migrate_from_0 pcmk2" [ style = bold] -+"pcmk_remote5_migrate_to_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote5_monitor_60000 pcmk2" [ style=bold color="green" fontcolor="black"] -+"pcmk_remote5_start_0 pcmk2" -> "pcmk_remote5_monitor_60000 pcmk2" [ style = bold] -+"pcmk_remote5_start_0 pcmk2" [ style=bold color="green" fontcolor="orange"] -+"pcmk_remote5_stop_0 pcmk1" -> "all_stopped" [ style = bold] -+"pcmk_remote5_stop_0 pcmk1" -> "pcmk_remote5_start_0 pcmk2" [ style = bold] -+"pcmk_remote5_stop_0 pcmk1" [ style=bold color="green" fontcolor="black"] -+"stonith 'reboot' pcmk4" -> "stonith_complete" [ style = bold] -+"stonith 'reboot' pcmk4" [ style=bold color="green" fontcolor="black"] -+"stonith_complete" -> "FAKE12_start_0 pcmk2" [ style = bold] -+"stonith_complete" -> "FAKE14_start_0 pcmk_remote1" [ style = bold] -+"stonith_complete" -> "FAKE17_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "FAKE25_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "FAKE28_start_0 pcmk1" [ style = bold] -+"stonith_complete" -> "FAKE30_start_0 pcmk_remote1" [ style = bold] -+"stonith_complete" -> "FAKE33_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "FAKE38_start_0 pcmk_remote1" [ style = bold] -+"stonith_complete" -> "FAKE39_start_0 pcmk_remote2" [ style = bold] -+"stonith_complete" -> "FAKE41_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "FAKE47_start_0 pcmk_remote2" [ style = bold] -+"stonith_complete" -> "FAKE48_start_0 pcmk_remote3" [ style = bold] -+"stonith_complete" -> "FAKE49_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "FAKE5_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "FAKE9_start_0 pcmk_remote4" [ style = bold] -+"stonith_complete" -> "all_stopped" [ style = bold] -+"stonith_complete" -> "pcmk_remote2_migrate_from_0 pcmk1" [ style = bold] -+"stonith_complete" -> "pcmk_remote2_start_0 pcmk1" [ style = bold] -+"stonith_complete" -> "pcmk_remote4_start_0 pcmk2" [ style = bold] -+"stonith_complete" -> "pcmk_remote5_migrate_to_0 pcmk1" [ style = bold] -+"stonith_complete" -> "pcmk_remote5_start_0 pcmk2" [ style = bold] -+"stonith_complete" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/remote-partial-migrate2.exp b/pengine/test10/remote-partial-migrate2.exp -new file mode 100644 -index 0000000..e3d7495 ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate2.exp -@@ -0,0 +1,866 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-partial-migrate2.scores b/pengine/test10/remote-partial-migrate2.scores -new file mode 100644 -index 0000000..6965507 ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate2.scores -@@ -0,0 +1,505 @@ -+Allocation scores: -+native_color: FAKE1 allocation score on pcmk1: -INFINITY -+native_color: FAKE1 allocation score on pcmk2: 0 -+native_color: FAKE1 allocation score on pcmk3: 0 -+native_color: FAKE1 allocation score on pcmk4: 0 -+native_color: FAKE1 allocation score on pcmk_remote1: 0 -+native_color: FAKE1 allocation score on pcmk_remote2: 0 -+native_color: FAKE1 allocation score on pcmk_remote3: 0 -+native_color: FAKE1 allocation score on pcmk_remote4: 0 -+native_color: FAKE1 allocation score on pcmk_remote5: 0 -+native_color: FAKE10 allocation score on pcmk1: 0 -+native_color: FAKE10 allocation score on pcmk2: 0 -+native_color: FAKE10 allocation score on pcmk3: 0 -+native_color: FAKE10 allocation score on pcmk4: 0 -+native_color: FAKE10 allocation score on pcmk_remote1: 0 -+native_color: FAKE10 allocation score on pcmk_remote2: 0 -+native_color: FAKE10 allocation score on pcmk_remote3: 0 -+native_color: FAKE10 allocation score on pcmk_remote4: 0 -+native_color: FAKE10 allocation score on pcmk_remote5: 0 -+native_color: FAKE11 allocation score on pcmk1: 0 -+native_color: FAKE11 allocation score on pcmk2: 0 -+native_color: FAKE11 allocation score on pcmk3: 0 -+native_color: FAKE11 allocation score on pcmk4: 0 -+native_color: FAKE11 allocation score on pcmk_remote1: 0 -+native_color: FAKE11 allocation score on pcmk_remote2: 0 -+native_color: FAKE11 allocation score on pcmk_remote3: 0 -+native_color: FAKE11 allocation score on pcmk_remote4: 0 -+native_color: FAKE11 allocation score on pcmk_remote5: 0 -+native_color: FAKE12 allocation score on pcmk1: 0 -+native_color: FAKE12 allocation score on pcmk2: 0 -+native_color: FAKE12 allocation score on pcmk3: 0 -+native_color: FAKE12 allocation score on pcmk4: 0 -+native_color: FAKE12 allocation score on pcmk_remote1: 0 -+native_color: FAKE12 allocation score on pcmk_remote2: 0 -+native_color: FAKE12 allocation score on pcmk_remote3: 0 -+native_color: FAKE12 allocation score on pcmk_remote4: 0 -+native_color: FAKE12 allocation score on pcmk_remote5: 0 -+native_color: FAKE13 allocation score on pcmk1: 0 -+native_color: FAKE13 allocation score on pcmk2: 0 -+native_color: FAKE13 allocation score on pcmk3: 0 -+native_color: FAKE13 allocation score on pcmk4: 0 -+native_color: FAKE13 allocation score on pcmk_remote1: 0 -+native_color: FAKE13 allocation score on pcmk_remote2: 0 -+native_color: FAKE13 allocation score on pcmk_remote3: 0 -+native_color: FAKE13 allocation score on pcmk_remote4: 0 -+native_color: FAKE13 allocation score on pcmk_remote5: 0 -+native_color: FAKE14 allocation score on pcmk1: 0 -+native_color: FAKE14 allocation score on pcmk2: 0 -+native_color: FAKE14 allocation score on pcmk3: 0 -+native_color: FAKE14 allocation score on pcmk4: 0 -+native_color: FAKE14 allocation score on pcmk_remote1: 0 -+native_color: FAKE14 allocation score on pcmk_remote2: 0 -+native_color: FAKE14 allocation score on pcmk_remote3: 0 -+native_color: FAKE14 allocation score on pcmk_remote4: 0 -+native_color: FAKE14 allocation score on pcmk_remote5: 0 -+native_color: FAKE15 allocation score on pcmk1: 0 -+native_color: FAKE15 allocation score on pcmk2: 0 -+native_color: FAKE15 allocation score on pcmk3: 0 -+native_color: FAKE15 allocation score on pcmk4: 0 -+native_color: FAKE15 allocation score on pcmk_remote1: 0 -+native_color: FAKE15 allocation score on pcmk_remote2: 0 -+native_color: FAKE15 allocation score on pcmk_remote3: 0 -+native_color: FAKE15 allocation score on pcmk_remote4: 0 -+native_color: FAKE15 allocation score on pcmk_remote5: 0 -+native_color: FAKE16 allocation score on pcmk1: 0 -+native_color: FAKE16 allocation score on pcmk2: 0 -+native_color: FAKE16 allocation score on pcmk3: 0 -+native_color: FAKE16 allocation score on pcmk4: 0 -+native_color: FAKE16 allocation score on pcmk_remote1: 0 -+native_color: FAKE16 allocation score on pcmk_remote2: 0 -+native_color: FAKE16 allocation score on pcmk_remote3: 0 -+native_color: FAKE16 allocation score on pcmk_remote4: 0 -+native_color: FAKE16 allocation score on pcmk_remote5: 0 -+native_color: FAKE17 allocation score on pcmk1: 0 -+native_color: FAKE17 allocation score on pcmk2: 0 -+native_color: FAKE17 allocation score on pcmk3: 0 -+native_color: FAKE17 allocation score on pcmk4: 0 -+native_color: FAKE17 allocation score on pcmk_remote1: 0 -+native_color: FAKE17 allocation score on pcmk_remote2: 0 -+native_color: FAKE17 allocation score on pcmk_remote3: 0 -+native_color: FAKE17 allocation score on pcmk_remote4: 0 -+native_color: FAKE17 allocation score on pcmk_remote5: 0 -+native_color: FAKE18 allocation score on pcmk1: 0 -+native_color: FAKE18 allocation score on pcmk2: 0 -+native_color: FAKE18 allocation score on pcmk3: 0 -+native_color: FAKE18 allocation score on pcmk4: 0 -+native_color: FAKE18 allocation score on pcmk_remote1: 0 -+native_color: FAKE18 allocation score on pcmk_remote2: 0 -+native_color: FAKE18 allocation score on pcmk_remote3: 0 -+native_color: FAKE18 allocation score on pcmk_remote4: 0 -+native_color: FAKE18 allocation score on pcmk_remote5: 0 -+native_color: FAKE19 allocation score on pcmk1: 0 -+native_color: FAKE19 allocation score on pcmk2: 0 -+native_color: FAKE19 allocation score on pcmk3: 0 -+native_color: FAKE19 allocation score on pcmk4: 0 -+native_color: FAKE19 allocation score on pcmk_remote1: 0 -+native_color: FAKE19 allocation score on pcmk_remote2: 0 -+native_color: FAKE19 allocation score on pcmk_remote3: 0 -+native_color: FAKE19 allocation score on pcmk_remote4: 0 -+native_color: FAKE19 allocation score on pcmk_remote5: 0 -+native_color: FAKE2 allocation score on pcmk1: 0 -+native_color: FAKE2 allocation score on pcmk2: 0 -+native_color: FAKE2 allocation score on pcmk3: 0 -+native_color: FAKE2 allocation score on pcmk4: 0 -+native_color: FAKE2 allocation score on pcmk_remote1: 0 -+native_color: FAKE2 allocation score on pcmk_remote2: 0 -+native_color: FAKE2 allocation score on pcmk_remote3: 0 -+native_color: FAKE2 allocation score on pcmk_remote4: 0 -+native_color: FAKE2 allocation score on pcmk_remote5: 0 -+native_color: FAKE20 allocation score on pcmk1: 0 -+native_color: FAKE20 allocation score on pcmk2: 0 -+native_color: FAKE20 allocation score on pcmk3: 0 -+native_color: FAKE20 allocation score on pcmk4: 0 -+native_color: FAKE20 allocation score on pcmk_remote1: 0 -+native_color: FAKE20 allocation score on pcmk_remote2: 0 -+native_color: FAKE20 allocation score on pcmk_remote3: 0 -+native_color: FAKE20 allocation score on pcmk_remote4: 0 -+native_color: FAKE20 allocation score on pcmk_remote5: 0 -+native_color: FAKE21 allocation score on pcmk1: 0 -+native_color: FAKE21 allocation score on pcmk2: 0 -+native_color: FAKE21 allocation score on pcmk3: 0 -+native_color: FAKE21 allocation score on pcmk4: 0 -+native_color: FAKE21 allocation score on pcmk_remote1: 0 -+native_color: FAKE21 allocation score on pcmk_remote2: 0 -+native_color: FAKE21 allocation score on pcmk_remote3: 0 -+native_color: FAKE21 allocation score on pcmk_remote4: 0 -+native_color: FAKE21 allocation score on pcmk_remote5: 0 -+native_color: FAKE22 allocation score on pcmk1: 0 -+native_color: FAKE22 allocation score on pcmk2: 0 -+native_color: FAKE22 allocation score on pcmk3: 0 -+native_color: FAKE22 allocation score on pcmk4: 0 -+native_color: FAKE22 allocation score on pcmk_remote1: 0 -+native_color: FAKE22 allocation score on pcmk_remote2: 0 -+native_color: FAKE22 allocation score on pcmk_remote3: 0 -+native_color: FAKE22 allocation score on pcmk_remote4: 0 -+native_color: FAKE22 allocation score on pcmk_remote5: 0 -+native_color: FAKE23 allocation score on pcmk1: 0 -+native_color: FAKE23 allocation score on pcmk2: 0 -+native_color: FAKE23 allocation score on pcmk3: 0 -+native_color: FAKE23 allocation score on pcmk4: 0 -+native_color: FAKE23 allocation score on pcmk_remote1: 0 -+native_color: FAKE23 allocation score on pcmk_remote2: 0 -+native_color: FAKE23 allocation score on pcmk_remote3: 0 -+native_color: FAKE23 allocation score on pcmk_remote4: 0 -+native_color: FAKE23 allocation score on pcmk_remote5: 0 -+native_color: FAKE24 allocation score on pcmk1: 0 -+native_color: FAKE24 allocation score on pcmk2: 0 -+native_color: FAKE24 allocation score on pcmk3: 0 -+native_color: FAKE24 allocation score on pcmk4: 0 -+native_color: FAKE24 allocation score on pcmk_remote1: 0 -+native_color: FAKE24 allocation score on pcmk_remote2: 0 -+native_color: FAKE24 allocation score on pcmk_remote3: 0 -+native_color: FAKE24 allocation score on pcmk_remote4: 0 -+native_color: FAKE24 allocation score on pcmk_remote5: 0 -+native_color: FAKE25 allocation score on pcmk1: 0 -+native_color: FAKE25 allocation score on pcmk2: 0 -+native_color: FAKE25 allocation score on pcmk3: 0 -+native_color: FAKE25 allocation score on pcmk4: 0 -+native_color: FAKE25 allocation score on pcmk_remote1: 0 -+native_color: FAKE25 allocation score on pcmk_remote2: 0 -+native_color: FAKE25 allocation score on pcmk_remote3: 0 -+native_color: FAKE25 allocation score on pcmk_remote4: 0 -+native_color: FAKE25 allocation score on pcmk_remote5: 0 -+native_color: FAKE26 allocation score on pcmk1: 0 -+native_color: FAKE26 allocation score on pcmk2: 0 -+native_color: FAKE26 allocation score on pcmk3: 0 -+native_color: FAKE26 allocation score on pcmk4: 0 -+native_color: FAKE26 allocation score on pcmk_remote1: 0 -+native_color: FAKE26 allocation score on pcmk_remote2: 0 -+native_color: FAKE26 allocation score on pcmk_remote3: 0 -+native_color: FAKE26 allocation score on pcmk_remote4: 0 -+native_color: FAKE26 allocation score on pcmk_remote5: 0 -+native_color: FAKE27 allocation score on pcmk1: 0 -+native_color: FAKE27 allocation score on pcmk2: 0 -+native_color: FAKE27 allocation score on pcmk3: 0 -+native_color: FAKE27 allocation score on pcmk4: 0 -+native_color: FAKE27 allocation score on pcmk_remote1: 0 -+native_color: FAKE27 allocation score on pcmk_remote2: 0 -+native_color: FAKE27 allocation score on pcmk_remote3: 0 -+native_color: FAKE27 allocation score on pcmk_remote4: 0 -+native_color: FAKE27 allocation score on pcmk_remote5: 0 -+native_color: FAKE28 allocation score on pcmk1: 0 -+native_color: FAKE28 allocation score on pcmk2: 0 -+native_color: FAKE28 allocation score on pcmk3: 0 -+native_color: FAKE28 allocation score on pcmk4: 0 -+native_color: FAKE28 allocation score on pcmk_remote1: 0 -+native_color: FAKE28 allocation score on pcmk_remote2: 0 -+native_color: FAKE28 allocation score on pcmk_remote3: 0 -+native_color: FAKE28 allocation score on pcmk_remote4: 0 -+native_color: FAKE28 allocation score on pcmk_remote5: 0 -+native_color: FAKE29 allocation score on pcmk1: 0 -+native_color: FAKE29 allocation score on pcmk2: 0 -+native_color: FAKE29 allocation score on pcmk3: 0 -+native_color: FAKE29 allocation score on pcmk4: 0 -+native_color: FAKE29 allocation score on pcmk_remote1: 0 -+native_color: FAKE29 allocation score on pcmk_remote2: 0 -+native_color: FAKE29 allocation score on pcmk_remote3: 0 -+native_color: FAKE29 allocation score on pcmk_remote4: 0 -+native_color: FAKE29 allocation score on pcmk_remote5: 0 -+native_color: FAKE3 allocation score on pcmk1: 0 -+native_color: FAKE3 allocation score on pcmk2: 0 -+native_color: FAKE3 allocation score on pcmk3: 0 -+native_color: FAKE3 allocation score on pcmk4: 0 -+native_color: FAKE3 allocation score on pcmk_remote1: 0 -+native_color: FAKE3 allocation score on pcmk_remote2: 0 -+native_color: FAKE3 allocation score on pcmk_remote3: 0 -+native_color: FAKE3 allocation score on pcmk_remote4: 0 -+native_color: FAKE3 allocation score on pcmk_remote5: 0 -+native_color: FAKE30 allocation score on pcmk1: 0 -+native_color: FAKE30 allocation score on pcmk2: 0 -+native_color: FAKE30 allocation score on pcmk3: 0 -+native_color: FAKE30 allocation score on pcmk4: 0 -+native_color: FAKE30 allocation score on pcmk_remote1: 0 -+native_color: FAKE30 allocation score on pcmk_remote2: 0 -+native_color: FAKE30 allocation score on pcmk_remote3: 0 -+native_color: FAKE30 allocation score on pcmk_remote4: 0 -+native_color: FAKE30 allocation score on pcmk_remote5: 0 -+native_color: FAKE31 allocation score on pcmk1: 0 -+native_color: FAKE31 allocation score on pcmk2: 0 -+native_color: FAKE31 allocation score on pcmk3: 0 -+native_color: FAKE31 allocation score on pcmk4: 0 -+native_color: FAKE31 allocation score on pcmk_remote1: 0 -+native_color: FAKE31 allocation score on pcmk_remote2: 0 -+native_color: FAKE31 allocation score on pcmk_remote3: 0 -+native_color: FAKE31 allocation score on pcmk_remote4: 0 -+native_color: FAKE31 allocation score on pcmk_remote5: 0 -+native_color: FAKE32 allocation score on pcmk1: 0 -+native_color: FAKE32 allocation score on pcmk2: 0 -+native_color: FAKE32 allocation score on pcmk3: 0 -+native_color: FAKE32 allocation score on pcmk4: 0 -+native_color: FAKE32 allocation score on pcmk_remote1: 0 -+native_color: FAKE32 allocation score on pcmk_remote2: 0 -+native_color: FAKE32 allocation score on pcmk_remote3: 0 -+native_color: FAKE32 allocation score on pcmk_remote4: 0 -+native_color: FAKE32 allocation score on pcmk_remote5: 0 -+native_color: FAKE33 allocation score on pcmk1: 0 -+native_color: FAKE33 allocation score on pcmk2: 0 -+native_color: FAKE33 allocation score on pcmk3: 0 -+native_color: FAKE33 allocation score on pcmk4: 0 -+native_color: FAKE33 allocation score on pcmk_remote1: 0 -+native_color: FAKE33 allocation score on pcmk_remote2: 0 -+native_color: FAKE33 allocation score on pcmk_remote3: 0 -+native_color: FAKE33 allocation score on pcmk_remote4: 0 -+native_color: FAKE33 allocation score on pcmk_remote5: 0 -+native_color: FAKE34 allocation score on pcmk1: 0 -+native_color: FAKE34 allocation score on pcmk2: 0 -+native_color: FAKE34 allocation score on pcmk3: 0 -+native_color: FAKE34 allocation score on pcmk4: 0 -+native_color: FAKE34 allocation score on pcmk_remote1: 0 -+native_color: FAKE34 allocation score on pcmk_remote2: 0 -+native_color: FAKE34 allocation score on pcmk_remote3: 0 -+native_color: FAKE34 allocation score on pcmk_remote4: 0 -+native_color: FAKE34 allocation score on pcmk_remote5: 0 -+native_color: FAKE35 allocation score on pcmk1: 0 -+native_color: FAKE35 allocation score on pcmk2: 0 -+native_color: FAKE35 allocation score on pcmk3: 0 -+native_color: FAKE35 allocation score on pcmk4: 0 -+native_color: FAKE35 allocation score on pcmk_remote1: 0 -+native_color: FAKE35 allocation score on pcmk_remote2: 0 -+native_color: FAKE35 allocation score on pcmk_remote3: 0 -+native_color: FAKE35 allocation score on pcmk_remote4: 0 -+native_color: FAKE35 allocation score on pcmk_remote5: 0 -+native_color: FAKE36 allocation score on pcmk1: 0 -+native_color: FAKE36 allocation score on pcmk2: 0 -+native_color: FAKE36 allocation score on pcmk3: 0 -+native_color: FAKE36 allocation score on pcmk4: 0 -+native_color: FAKE36 allocation score on pcmk_remote1: 0 -+native_color: FAKE36 allocation score on pcmk_remote2: 0 -+native_color: FAKE36 allocation score on pcmk_remote3: 0 -+native_color: FAKE36 allocation score on pcmk_remote4: 0 -+native_color: FAKE36 allocation score on pcmk_remote5: 0 -+native_color: FAKE37 allocation score on pcmk1: 0 -+native_color: FAKE37 allocation score on pcmk2: 0 -+native_color: FAKE37 allocation score on pcmk3: 0 -+native_color: FAKE37 allocation score on pcmk4: 0 -+native_color: FAKE37 allocation score on pcmk_remote1: 0 -+native_color: FAKE37 allocation score on pcmk_remote2: 0 -+native_color: FAKE37 allocation score on pcmk_remote3: 0 -+native_color: FAKE37 allocation score on pcmk_remote4: 0 -+native_color: FAKE37 allocation score on pcmk_remote5: 0 -+native_color: FAKE38 allocation score on pcmk1: 0 -+native_color: FAKE38 allocation score on pcmk2: 0 -+native_color: FAKE38 allocation score on pcmk3: 0 -+native_color: FAKE38 allocation score on pcmk4: 0 -+native_color: FAKE38 allocation score on pcmk_remote1: 0 -+native_color: FAKE38 allocation score on pcmk_remote2: 0 -+native_color: FAKE38 allocation score on pcmk_remote3: 0 -+native_color: FAKE38 allocation score on pcmk_remote4: 0 -+native_color: FAKE38 allocation score on pcmk_remote5: 0 -+native_color: FAKE39 allocation score on pcmk1: 0 -+native_color: FAKE39 allocation score on pcmk2: 0 -+native_color: FAKE39 allocation score on pcmk3: 0 -+native_color: FAKE39 allocation score on pcmk4: 0 -+native_color: FAKE39 allocation score on pcmk_remote1: 0 -+native_color: FAKE39 allocation score on pcmk_remote2: 0 -+native_color: FAKE39 allocation score on pcmk_remote3: 0 -+native_color: FAKE39 allocation score on pcmk_remote4: 0 -+native_color: FAKE39 allocation score on pcmk_remote5: 0 -+native_color: FAKE4 allocation score on pcmk1: 0 -+native_color: FAKE4 allocation score on pcmk2: 0 -+native_color: FAKE4 allocation score on pcmk3: 0 -+native_color: FAKE4 allocation score on pcmk4: 0 -+native_color: FAKE4 allocation score on pcmk_remote1: 0 -+native_color: FAKE4 allocation score on pcmk_remote2: 0 -+native_color: FAKE4 allocation score on pcmk_remote3: 0 -+native_color: FAKE4 allocation score on pcmk_remote4: 0 -+native_color: FAKE4 allocation score on pcmk_remote5: 0 -+native_color: FAKE40 allocation score on pcmk1: 0 -+native_color: FAKE40 allocation score on pcmk2: 0 -+native_color: FAKE40 allocation score on pcmk3: 0 -+native_color: FAKE40 allocation score on pcmk4: 0 -+native_color: FAKE40 allocation score on pcmk_remote1: 0 -+native_color: FAKE40 allocation score on pcmk_remote2: 0 -+native_color: FAKE40 allocation score on pcmk_remote3: 0 -+native_color: FAKE40 allocation score on pcmk_remote4: 0 -+native_color: FAKE40 allocation score on pcmk_remote5: 0 -+native_color: FAKE41 allocation score on pcmk1: 0 -+native_color: FAKE41 allocation score on pcmk2: 0 -+native_color: FAKE41 allocation score on pcmk3: 0 -+native_color: FAKE41 allocation score on pcmk4: 0 -+native_color: FAKE41 allocation score on pcmk_remote1: 0 -+native_color: FAKE41 allocation score on pcmk_remote2: 0 -+native_color: FAKE41 allocation score on pcmk_remote3: 0 -+native_color: FAKE41 allocation score on pcmk_remote4: 0 -+native_color: FAKE41 allocation score on pcmk_remote5: 0 -+native_color: FAKE42 allocation score on pcmk1: 0 -+native_color: FAKE42 allocation score on pcmk2: 0 -+native_color: FAKE42 allocation score on pcmk3: 0 -+native_color: FAKE42 allocation score on pcmk4: 0 -+native_color: FAKE42 allocation score on pcmk_remote1: 0 -+native_color: FAKE42 allocation score on pcmk_remote2: 0 -+native_color: FAKE42 allocation score on pcmk_remote3: 0 -+native_color: FAKE42 allocation score on pcmk_remote4: 0 -+native_color: FAKE42 allocation score on pcmk_remote5: 0 -+native_color: FAKE43 allocation score on pcmk1: 0 -+native_color: FAKE43 allocation score on pcmk2: 0 -+native_color: FAKE43 allocation score on pcmk3: 0 -+native_color: FAKE43 allocation score on pcmk4: 0 -+native_color: FAKE43 allocation score on pcmk_remote1: 0 -+native_color: FAKE43 allocation score on pcmk_remote2: 0 -+native_color: FAKE43 allocation score on pcmk_remote3: 0 -+native_color: FAKE43 allocation score on pcmk_remote4: 0 -+native_color: FAKE43 allocation score on pcmk_remote5: 0 -+native_color: FAKE44 allocation score on pcmk1: 0 -+native_color: FAKE44 allocation score on pcmk2: 0 -+native_color: FAKE44 allocation score on pcmk3: 0 -+native_color: FAKE44 allocation score on pcmk4: 0 -+native_color: FAKE44 allocation score on pcmk_remote1: 0 -+native_color: FAKE44 allocation score on pcmk_remote2: 0 -+native_color: FAKE44 allocation score on pcmk_remote3: 0 -+native_color: FAKE44 allocation score on pcmk_remote4: 0 -+native_color: FAKE44 allocation score on pcmk_remote5: 0 -+native_color: FAKE45 allocation score on pcmk1: 0 -+native_color: FAKE45 allocation score on pcmk2: 0 -+native_color: FAKE45 allocation score on pcmk3: 0 -+native_color: FAKE45 allocation score on pcmk4: 0 -+native_color: FAKE45 allocation score on pcmk_remote1: 0 -+native_color: FAKE45 allocation score on pcmk_remote2: 0 -+native_color: FAKE45 allocation score on pcmk_remote3: 0 -+native_color: FAKE45 allocation score on pcmk_remote4: 0 -+native_color: FAKE45 allocation score on pcmk_remote5: 0 -+native_color: FAKE46 allocation score on pcmk1: 0 -+native_color: FAKE46 allocation score on pcmk2: 0 -+native_color: FAKE46 allocation score on pcmk3: 0 -+native_color: FAKE46 allocation score on pcmk4: 0 -+native_color: FAKE46 allocation score on pcmk_remote1: 0 -+native_color: FAKE46 allocation score on pcmk_remote2: 0 -+native_color: FAKE46 allocation score on pcmk_remote3: 0 -+native_color: FAKE46 allocation score on pcmk_remote4: 0 -+native_color: FAKE46 allocation score on pcmk_remote5: 0 -+native_color: FAKE47 allocation score on pcmk1: 0 -+native_color: FAKE47 allocation score on pcmk2: 0 -+native_color: FAKE47 allocation score on pcmk3: 0 -+native_color: FAKE47 allocation score on pcmk4: 0 -+native_color: FAKE47 allocation score on pcmk_remote1: 0 -+native_color: FAKE47 allocation score on pcmk_remote2: 0 -+native_color: FAKE47 allocation score on pcmk_remote3: 0 -+native_color: FAKE47 allocation score on pcmk_remote4: 0 -+native_color: FAKE47 allocation score on pcmk_remote5: 0 -+native_color: FAKE48 allocation score on pcmk1: 0 -+native_color: FAKE48 allocation score on pcmk2: 0 -+native_color: FAKE48 allocation score on pcmk3: 0 -+native_color: FAKE48 allocation score on pcmk4: 0 -+native_color: FAKE48 allocation score on pcmk_remote1: 0 -+native_color: FAKE48 allocation score on pcmk_remote2: 0 -+native_color: FAKE48 allocation score on pcmk_remote3: 0 -+native_color: FAKE48 allocation score on pcmk_remote4: 0 -+native_color: FAKE48 allocation score on pcmk_remote5: 0 -+native_color: FAKE49 allocation score on pcmk1: 0 -+native_color: FAKE49 allocation score on pcmk2: 0 -+native_color: FAKE49 allocation score on pcmk3: 0 -+native_color: FAKE49 allocation score on pcmk4: 0 -+native_color: FAKE49 allocation score on pcmk_remote1: 0 -+native_color: FAKE49 allocation score on pcmk_remote2: 0 -+native_color: FAKE49 allocation score on pcmk_remote3: 0 -+native_color: FAKE49 allocation score on pcmk_remote4: 0 -+native_color: FAKE49 allocation score on pcmk_remote5: 0 -+native_color: FAKE5 allocation score on pcmk1: 0 -+native_color: FAKE5 allocation score on pcmk2: 0 -+native_color: FAKE5 allocation score on pcmk3: 0 -+native_color: FAKE5 allocation score on pcmk4: 0 -+native_color: FAKE5 allocation score on pcmk_remote1: 0 -+native_color: FAKE5 allocation score on pcmk_remote2: 0 -+native_color: FAKE5 allocation score on pcmk_remote3: 0 -+native_color: FAKE5 allocation score on pcmk_remote4: 0 -+native_color: FAKE5 allocation score on pcmk_remote5: 0 -+native_color: FAKE50 allocation score on pcmk1: 0 -+native_color: FAKE50 allocation score on pcmk2: 0 -+native_color: FAKE50 allocation score on pcmk3: 0 -+native_color: FAKE50 allocation score on pcmk4: 0 -+native_color: FAKE50 allocation score on pcmk_remote1: 0 -+native_color: FAKE50 allocation score on pcmk_remote2: 0 -+native_color: FAKE50 allocation score on pcmk_remote3: 0 -+native_color: FAKE50 allocation score on pcmk_remote4: 0 -+native_color: FAKE50 allocation score on pcmk_remote5: 0 -+native_color: FAKE6 allocation score on pcmk1: 0 -+native_color: FAKE6 allocation score on pcmk2: 0 -+native_color: FAKE6 allocation score on pcmk3: 0 -+native_color: FAKE6 allocation score on pcmk4: 0 -+native_color: FAKE6 allocation score on pcmk_remote1: 0 -+native_color: FAKE6 allocation score on pcmk_remote2: 0 -+native_color: FAKE6 allocation score on pcmk_remote3: 0 -+native_color: FAKE6 allocation score on pcmk_remote4: 0 -+native_color: FAKE6 allocation score on pcmk_remote5: 0 -+native_color: FAKE7 allocation score on pcmk1: 0 -+native_color: FAKE7 allocation score on pcmk2: 0 -+native_color: FAKE7 allocation score on pcmk3: 0 -+native_color: FAKE7 allocation score on pcmk4: 0 -+native_color: FAKE7 allocation score on pcmk_remote1: 0 -+native_color: FAKE7 allocation score on pcmk_remote2: 0 -+native_color: FAKE7 allocation score on pcmk_remote3: 0 -+native_color: FAKE7 allocation score on pcmk_remote4: 0 -+native_color: FAKE7 allocation score on pcmk_remote5: 0 -+native_color: FAKE8 allocation score on pcmk1: 0 -+native_color: FAKE8 allocation score on pcmk2: 0 -+native_color: FAKE8 allocation score on pcmk3: 0 -+native_color: FAKE8 allocation score on pcmk4: 0 -+native_color: FAKE8 allocation score on pcmk_remote1: 0 -+native_color: FAKE8 allocation score on pcmk_remote2: 0 -+native_color: FAKE8 allocation score on pcmk_remote3: 0 -+native_color: FAKE8 allocation score on pcmk_remote4: 0 -+native_color: FAKE8 allocation score on pcmk_remote5: 0 -+native_color: FAKE9 allocation score on pcmk1: 0 -+native_color: FAKE9 allocation score on pcmk2: 0 -+native_color: FAKE9 allocation score on pcmk3: 0 -+native_color: FAKE9 allocation score on pcmk4: 0 -+native_color: FAKE9 allocation score on pcmk_remote1: 0 -+native_color: FAKE9 allocation score on pcmk_remote2: 0 -+native_color: FAKE9 allocation score on pcmk_remote3: 0 -+native_color: FAKE9 allocation score on pcmk_remote4: 0 -+native_color: FAKE9 allocation score on pcmk_remote5: 0 -+native_color: pcmk_remote1 allocation score on pcmk1: 0 -+native_color: pcmk_remote1 allocation score on pcmk2: 0 -+native_color: pcmk_remote1 allocation score on pcmk3: 0 -+native_color: pcmk_remote1 allocation score on pcmk4: 0 -+native_color: pcmk_remote1 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote1 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk1: 0 -+native_color: pcmk_remote2 allocation score on pcmk2: 0 -+native_color: pcmk_remote2 allocation score on pcmk3: 0 -+native_color: pcmk_remote2 allocation score on pcmk4: 0 -+native_color: pcmk_remote2 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote2 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk1: 0 -+native_color: pcmk_remote3 allocation score on pcmk2: 0 -+native_color: pcmk_remote3 allocation score on pcmk3: 0 -+native_color: pcmk_remote3 allocation score on pcmk4: 0 -+native_color: pcmk_remote3 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote3 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk1: 0 -+native_color: pcmk_remote4 allocation score on pcmk2: 0 -+native_color: pcmk_remote4 allocation score on pcmk3: 0 -+native_color: pcmk_remote4 allocation score on pcmk4: 0 -+native_color: pcmk_remote4 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote4 allocation score on pcmk_remote5: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk1: 0 -+native_color: pcmk_remote5 allocation score on pcmk2: 0 -+native_color: pcmk_remote5 allocation score on pcmk3: 0 -+native_color: pcmk_remote5 allocation score on pcmk4: 0 -+native_color: pcmk_remote5 allocation score on pcmk_remote1: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote2: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote3: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote4: -INFINITY -+native_color: pcmk_remote5 allocation score on pcmk_remote5: -INFINITY -+native_color: shooter allocation score on pcmk1: 0 -+native_color: shooter allocation score on pcmk2: 0 -+native_color: shooter allocation score on pcmk3: 0 -+native_color: shooter allocation score on pcmk4: 0 -+native_color: shooter allocation score on pcmk_remote1: -INFINITY -+native_color: shooter allocation score on pcmk_remote2: -INFINITY -+native_color: shooter allocation score on pcmk_remote3: -INFINITY -+native_color: shooter allocation score on pcmk_remote4: -INFINITY -+native_color: shooter allocation score on pcmk_remote5: -INFINITY -diff --git a/pengine/test10/remote-partial-migrate2.summary b/pengine/test10/remote-partial-migrate2.summary -new file mode 100644 -index 0000000..6a65975 ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate2.summary -@@ -0,0 +1,207 @@ -+ -+Current cluster status: -+Node pcmk4 (4): UNCLEAN (offline) -+Online: [ pcmk1 pcmk2 pcmk3 ] -+RemoteOnline: [ pcmk_remote1 pcmk_remote2 pcmk_remote3 pcmk_remote5 ] -+RemoteOFFLINE: [ pcmk_remote4 ] -+ -+ shooter (stonith:fence_docker_cts): Started pcmk3 -+ pcmk_remote1 (ocf::pacemaker:remote): Started pcmk1 -+ pcmk_remote2 (ocf::pacemaker:remote): Started [ pcmk1 pcmk3 ] -+ pcmk_remote3 (ocf::pacemaker:remote): Started pcmk3 -+ pcmk_remote4 (ocf::pacemaker:remote): Stopped -+ pcmk_remote5 (ocf::pacemaker:remote): Started pcmk1 -+ FAKE1 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE2 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE3 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE4 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE5 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE6 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE7 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE8 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE9 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE10 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE11 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE12 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE13 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE14 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE15 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE16 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE17 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE18 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE19 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE20 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE21 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE22 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE23 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE24 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE25 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE26 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE27 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE28 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE29 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE30 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE31 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE32 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE33 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE34 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE35 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE36 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE37 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE38 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE39 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE40 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE41 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE42 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE43 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE44 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE45 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE46 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE47 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE48 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE49 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE50 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ -+Transition Summary: -+ * Migrate pcmk_remote2 (Started pcmk3 -> pcmk1) -+ * Start pcmk_remote4 (pcmk2) -+ * Migrate pcmk_remote5 (Started pcmk1 -> pcmk2) -+ * Move FAKE5 (Started pcmk1 -> pcmk_remote4) -+ * Move FAKE9 (Started pcmk2 -> pcmk_remote4) -+ * Move FAKE12 (Started pcmk1 -> pcmk2) -+ * Move FAKE14 (Started pcmk2 -> pcmk_remote1) -+ * Move FAKE17 (Started pcmk_remote1 -> pcmk_remote4) -+ * Move FAKE25 (Started pcmk_remote1 -> pcmk_remote4) -+ * Move FAKE28 (Started pcmk3 -> pcmk1) -+ * Move FAKE30 (Started pcmk1 -> pcmk_remote1) -+ * Move FAKE33 (Started pcmk_remote1 -> pcmk_remote4) -+ * Move FAKE38 (Started pcmk2 -> pcmk_remote1) -+ * Move FAKE39 (Started pcmk1 -> pcmk_remote2) -+ * Move FAKE41 (Started pcmk_remote2 -> pcmk_remote4) -+ * Move FAKE47 (Started pcmk_remote1 -> pcmk_remote2) -+ * Move FAKE48 (Started pcmk1 -> pcmk_remote3) -+ * Move FAKE49 (Started pcmk_remote3 -> pcmk_remote4) -+ -+Executing cluster transition: -+ * Resource action: FAKE5 stop on pcmk1 -+ * Resource action: FAKE9 stop on pcmk2 -+ * Resource action: FAKE12 stop on pcmk1 -+ * Resource action: FAKE14 stop on pcmk2 -+ * Resource action: FAKE17 stop on pcmk_remote1 -+ * Resource action: FAKE25 stop on pcmk_remote1 -+ * Resource action: FAKE28 stop on pcmk3 -+ * Resource action: FAKE30 stop on pcmk1 -+ * Resource action: FAKE33 stop on pcmk_remote1 -+ * Resource action: FAKE38 stop on pcmk2 -+ * Resource action: FAKE39 stop on pcmk1 -+ * Resource action: FAKE47 stop on pcmk_remote1 -+ * Resource action: FAKE48 stop on pcmk1 -+ * Resource action: FAKE49 stop on pcmk_remote3 -+ * Fencing pcmk4 (reboot) -+ * Pseudo action: stonith_complete -+ * Resource action: pcmk_remote2 migrate_from on pcmk1 -+ * Resource action: pcmk_remote2 stop on pcmk3 -+ * Resource action: pcmk_remote4 start on pcmk2 -+ * Resource action: pcmk_remote5 migrate_to on pcmk1 -+ * Resource action: FAKE5 start on pcmk_remote4 -+ * Resource action: FAKE9 start on pcmk_remote4 -+ * Resource action: FAKE12 start on pcmk2 -+ * Resource action: FAKE14 start on pcmk_remote1 -+ * Resource action: FAKE17 start on pcmk_remote4 -+ * Resource action: FAKE25 start on pcmk_remote4 -+ * Resource action: FAKE28 start on pcmk1 -+ * Resource action: FAKE30 start on pcmk_remote1 -+ * Resource action: FAKE33 start on pcmk_remote4 -+ * Resource action: FAKE38 start on pcmk_remote1 -+ * Resource action: FAKE48 start on pcmk_remote3 -+ * Resource action: FAKE49 start on pcmk_remote4 -+ * Pseudo action: pcmk_remote2_start_0 -+ * Resource action: pcmk_remote4 monitor=60000 on pcmk2 -+ * Resource action: pcmk_remote5 migrate_from on pcmk2 -+ * Resource action: pcmk_remote5 stop on pcmk1 -+ * Resource action: FAKE5 monitor=10000 on pcmk_remote4 -+ * Resource action: FAKE9 monitor=10000 on pcmk_remote4 -+ * Resource action: FAKE12 monitor=10000 on pcmk2 -+ * Resource action: FAKE14 monitor=10000 on pcmk_remote1 -+ * Resource action: FAKE17 monitor=10000 on pcmk_remote4 -+ * Resource action: FAKE25 monitor=10000 on pcmk_remote4 -+ * Resource action: FAKE28 monitor=10000 on pcmk1 -+ * Resource action: FAKE30 monitor=10000 on pcmk_remote1 -+ * Resource action: FAKE33 monitor=10000 on pcmk_remote4 -+ * Resource action: FAKE38 monitor=10000 on pcmk_remote1 -+ * Resource action: FAKE39 start on pcmk_remote2 -+ * Resource action: FAKE41 stop on pcmk_remote2 -+ * Resource action: FAKE47 start on pcmk_remote2 -+ * Resource action: FAKE48 monitor=10000 on pcmk_remote3 -+ * Resource action: FAKE49 monitor=10000 on pcmk_remote4 -+ * Pseudo action: all_stopped -+ * Resource action: pcmk_remote2 monitor=60000 on pcmk1 -+ * Pseudo action: pcmk_remote5_start_0 -+ * Resource action: FAKE39 monitor=10000 on pcmk_remote2 -+ * Resource action: FAKE41 start on pcmk_remote4 -+ * Resource action: FAKE47 monitor=10000 on pcmk_remote2 -+ * Resource action: pcmk_remote5 monitor=60000 on pcmk2 -+ * Resource action: FAKE41 monitor=10000 on pcmk_remote4 -+ -+Revised cluster status: -+Online: [ pcmk1 pcmk2 pcmk3 ] -+OFFLINE: [ pcmk4 ] -+RemoteOnline: [ pcmk_remote1 pcmk_remote2 pcmk_remote3 pcmk_remote4 pcmk_remote5 ] -+ -+ shooter (stonith:fence_docker_cts): Started pcmk3 -+ pcmk_remote1 (ocf::pacemaker:remote): Started pcmk1 -+ pcmk_remote2 (ocf::pacemaker:remote): Started pcmk1 -+ pcmk_remote3 (ocf::pacemaker:remote): Started pcmk3 -+ pcmk_remote4 (ocf::pacemaker:remote): Started pcmk2 -+ pcmk_remote5 (ocf::pacemaker:remote): Started pcmk2 -+ FAKE1 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE2 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE3 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE4 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE5 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE6 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE7 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE8 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE9 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE10 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE11 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE12 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE13 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE14 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE15 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE16 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE17 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE18 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE19 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE20 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE21 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE22 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE23 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE24 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE25 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE26 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE27 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE28 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE29 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE30 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE31 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE32 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE33 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE34 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE35 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE36 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE37 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE38 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE39 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE40 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE41 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE42 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ FAKE43 (ocf::heartbeat:Dummy): Started pcmk_remote1 -+ FAKE44 (ocf::heartbeat:Dummy): Started pcmk2 -+ FAKE45 (ocf::heartbeat:Dummy): Started pcmk3 -+ FAKE46 (ocf::heartbeat:Dummy): Started pcmk1 -+ FAKE47 (ocf::heartbeat:Dummy): Started pcmk_remote2 -+ FAKE48 (ocf::heartbeat:Dummy): Started pcmk_remote3 -+ FAKE49 (ocf::heartbeat:Dummy): Started pcmk_remote4 -+ FAKE50 (ocf::heartbeat:Dummy): Started pcmk_remote5 -+ -diff --git a/pengine/test10/remote-partial-migrate2.xml b/pengine/test10/remote-partial-migrate2.xml -new file mode 100644 -index 0000000..ed9299b ---- /dev/null -+++ b/pengine/test10/remote-partial-migrate2.xml -@@ -0,0 +1,1947 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-recover-fail.dot b/pengine/test10/remote-recover-fail.dot -new file mode 100644 -index 0000000..a920089 ---- /dev/null -+++ b/pengine/test10/remote-recover-fail.dot -@@ -0,0 +1,36 @@ -+ digraph "g" { -+"FAKE1_monitor_10000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"FAKE1_start_0 rhel7-auto2" -> "FAKE1_monitor_10000 rhel7-auto2" [ style = bold] -+"FAKE1_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_start_0 rhel7-auto3" -> "FAKE2_monitor_10000 rhel7-auto3" [ style = bold] -+"FAKE2_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_stop_0 rhel7-auto4" -> "FAKE2_start_0 rhel7-auto3" [ style = bold] -+"FAKE2_stop_0 rhel7-auto4" -> "all_stopped" [ style = bold] -+"FAKE2_stop_0 rhel7-auto4" [ style=bold color="green" fontcolor="orange"] -+"FAKE3_monitor_10000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_10000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"FAKE6_monitor_10000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"FAKE6_start_0 rhel7-auto2" -> "FAKE6_monitor_10000 rhel7-auto2" [ style = bold] -+"FAKE6_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"FAKE6_stop_0 rhel7-auto4" -> "FAKE6_start_0 rhel7-auto2" [ style = bold] -+"FAKE6_stop_0 rhel7-auto4" -> "all_stopped" [ style = bold] -+"FAKE6_stop_0 rhel7-auto4" [ style=bold color="green" fontcolor="orange"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"rhel7-auto4_monitor_60000 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"rhel7-auto4_start_0 rhel7-auto2" -> "rhel7-auto4_monitor_60000 rhel7-auto2" [ style = bold] -+"rhel7-auto4_start_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"rhel7-auto4_stop_0 rhel7-auto2" -> "all_stopped" [ style = bold] -+"rhel7-auto4_stop_0 rhel7-auto2" -> "rhel7-auto4_start_0 rhel7-auto2" [ style = bold] -+"rhel7-auto4_stop_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"stonith 'reboot' rhel7-auto4" -> "FAKE2_stop_0 rhel7-auto4" [ style = bold] -+"stonith 'reboot' rhel7-auto4" -> "FAKE6_stop_0 rhel7-auto4" [ style = bold] -+"stonith 'reboot' rhel7-auto4" -> "stonith_complete" [ style = bold] -+"stonith 'reboot' rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"stonith_complete" -> "FAKE1_start_0 rhel7-auto2" [ style = bold] -+"stonith_complete" -> "FAKE2_start_0 rhel7-auto3" [ style = bold] -+"stonith_complete" -> "FAKE6_start_0 rhel7-auto2" [ style = bold] -+"stonith_complete" -> "all_stopped" [ style = bold] -+"stonith_complete" -> "rhel7-auto4_start_0 rhel7-auto2" [ style = bold] -+"stonith_complete" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/remote-recover-fail.exp b/pengine/test10/remote-recover-fail.exp -new file mode 100644 -index 0000000..dee4acf ---- /dev/null -+++ b/pengine/test10/remote-recover-fail.exp -@@ -0,0 +1,207 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-recover-fail.scores b/pengine/test10/remote-recover-fail.scores -new file mode 100644 -index 0000000..8fc7805 ---- /dev/null -+++ b/pengine/test10/remote-recover-fail.scores -@@ -0,0 +1,33 @@ -+Allocation scores: -+native_color: FAKE1 allocation score on rhel7-auto1: 0 -+native_color: FAKE1 allocation score on rhel7-auto2: 0 -+native_color: FAKE1 allocation score on rhel7-auto3: 0 -+native_color: FAKE1 allocation score on rhel7-auto4: 0 -+native_color: FAKE2 allocation score on rhel7-auto1: 0 -+native_color: FAKE2 allocation score on rhel7-auto2: 0 -+native_color: FAKE2 allocation score on rhel7-auto3: 0 -+native_color: FAKE2 allocation score on rhel7-auto4: 0 -+native_color: FAKE3 allocation score on rhel7-auto1: 0 -+native_color: FAKE3 allocation score on rhel7-auto2: 0 -+native_color: FAKE3 allocation score on rhel7-auto3: 0 -+native_color: FAKE3 allocation score on rhel7-auto4: 0 -+native_color: FAKE4 allocation score on rhel7-auto1: 0 -+native_color: FAKE4 allocation score on rhel7-auto2: 0 -+native_color: FAKE4 allocation score on rhel7-auto3: 0 -+native_color: FAKE4 allocation score on rhel7-auto4: 0 -+native_color: FAKE5 allocation score on rhel7-auto1: 0 -+native_color: FAKE5 allocation score on rhel7-auto2: 0 -+native_color: FAKE5 allocation score on rhel7-auto3: 0 -+native_color: FAKE5 allocation score on rhel7-auto4: 0 -+native_color: FAKE6 allocation score on rhel7-auto1: 0 -+native_color: FAKE6 allocation score on rhel7-auto2: 0 -+native_color: FAKE6 allocation score on rhel7-auto3: 0 -+native_color: FAKE6 allocation score on rhel7-auto4: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto1: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto2: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto3: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: -INFINITY -diff --git a/pengine/test10/remote-recover-fail.summary b/pengine/test10/remote-recover-fail.summary -new file mode 100644 -index 0000000..2811fdc ---- /dev/null -+++ b/pengine/test10/remote-recover-fail.summary -@@ -0,0 +1,53 @@ -+ -+Current cluster status: -+RemoteNode rhel7-auto4: UNCLEAN (offline) -+Online: [ rhel7-auto2 rhel7-auto3 ] -+OFFLINE: [ rhel7-auto1 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto3 -+ rhel7-auto4 (ocf::pacemaker:remote): FAILED rhel7-auto2 -+ FAKE1 (ocf::heartbeat:Dummy): Stopped -+ FAKE2 (ocf::heartbeat:Dummy): Started rhel7-auto4 -+ FAKE3 (ocf::heartbeat:Dummy): Started rhel7-auto2 -+ FAKE4 (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ FAKE5 (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ FAKE6 (ocf::heartbeat:Dummy): Started rhel7-auto4 -+ -+Transition Summary: -+ * Recover rhel7-auto4 (Started rhel7-auto2) -+ * Start FAKE1 (rhel7-auto2) -+ * Move FAKE2 (Started rhel7-auto4 -> rhel7-auto3) -+ * Move FAKE6 (Started rhel7-auto4 -> rhel7-auto2) -+ -+Executing cluster transition: -+ * Resource action: rhel7-auto4 stop on rhel7-auto2 -+ * Resource action: FAKE3 monitor=10000 on rhel7-auto2 -+ * Resource action: FAKE4 monitor=10000 on rhel7-auto3 -+ * Fencing rhel7-auto4 (reboot) -+ * Pseudo action: stonith_complete -+ * Resource action: rhel7-auto4 start on rhel7-auto2 -+ * Resource action: FAKE1 start on rhel7-auto2 -+ * Pseudo action: FAKE2_stop_0 -+ * Pseudo action: FAKE6_stop_0 -+ * Pseudo action: all_stopped -+ * Resource action: rhel7-auto4 monitor=60000 on rhel7-auto2 -+ * Resource action: FAKE1 monitor=10000 on rhel7-auto2 -+ * Resource action: FAKE2 start on rhel7-auto3 -+ * Resource action: FAKE6 start on rhel7-auto2 -+ * Resource action: FAKE2 monitor=10000 on rhel7-auto3 -+ * Resource action: FAKE6 monitor=10000 on rhel7-auto2 -+ -+Revised cluster status: -+Online: [ rhel7-auto2 rhel7-auto3 ] -+OFFLINE: [ rhel7-auto1 ] -+RemoteOnline: [ rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto3 -+ rhel7-auto4 (ocf::pacemaker:remote): Started rhel7-auto2 -+ FAKE1 (ocf::heartbeat:Dummy): Started rhel7-auto2 -+ FAKE2 (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ FAKE3 (ocf::heartbeat:Dummy): Started rhel7-auto2 -+ FAKE4 (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ FAKE5 (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ FAKE6 (ocf::heartbeat:Dummy): Started rhel7-auto2 -+ -diff --git a/pengine/test10/remote-recover-fail.xml b/pengine/test10/remote-recover-fail.xml -new file mode 100644 -index 0000000..8703e75 ---- /dev/null -+++ b/pengine/test10/remote-recover-fail.xml -@@ -0,0 +1,198 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-recover.dot b/pengine/test10/remote-recover.dot -index 1da6a7b..22e0cc7 100644 ---- a/pengine/test10/remote-recover.dot -+++ b/pengine/test10/remote-recover.dot -@@ -9,6 +9,7 @@ - "rhel7-alt4_monitor_60000 rhel7-alt1" [ style=bold color="green" fontcolor="black"] - "rhel7-alt4_start_0 rhel7-alt1" -> "fake_monitor_10000 rhel7-alt4" [ style = bold] - "rhel7-alt4_start_0 rhel7-alt1" -> "fake_start_0 rhel7-alt4" [ style = bold] -+"rhel7-alt4_start_0 rhel7-alt1" -> "fake_stop_0 rhel7-alt4" [ style = bold] - "rhel7-alt4_start_0 rhel7-alt1" -> "rhel7-alt4_monitor_60000 rhel7-alt1" [ style = bold] - "rhel7-alt4_start_0 rhel7-alt1" [ style=bold color="green" fontcolor="black"] - "shooter_monitor_60000 rhel7-alt1" [ style=bold color="green" fontcolor="black"] -diff --git a/pengine/test10/remote-recover.exp b/pengine/test10/remote-recover.exp -index 37e4f71..6386740 100644 ---- a/pengine/test10/remote-recover.exp -+++ b/pengine/test10/remote-recover.exp -@@ -82,7 +82,11 @@ - - - -- -+ -+ -+ -+ -+ - - - -diff --git a/pengine/test10/remote-start-fail.dot b/pengine/test10/remote-start-fail.dot -new file mode 100644 -index 0000000..26c9f33 ---- /dev/null -+++ b/pengine/test10/remote-start-fail.dot -@@ -0,0 +1,9 @@ -+ digraph "g" { -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"rhel7-auto4_monitor_60000 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"rhel7-auto4_start_0 rhel7-auto3" -> "rhel7-auto4_monitor_60000 rhel7-auto3" [ style = bold] -+"rhel7-auto4_start_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"rhel7-auto4_stop_0 rhel7-auto2" -> "all_stopped" [ style = bold] -+"rhel7-auto4_stop_0 rhel7-auto2" -> "rhel7-auto4_start_0 rhel7-auto3" [ style = bold] -+"rhel7-auto4_stop_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/remote-start-fail.exp b/pengine/test10/remote-start-fail.exp -new file mode 100644 -index 0000000..6e2ce8b ---- /dev/null -+++ b/pengine/test10/remote-start-fail.exp -@@ -0,0 +1,49 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-start-fail.scores b/pengine/test10/remote-start-fail.scores -new file mode 100644 -index 0000000..d36577f ---- /dev/null -+++ b/pengine/test10/remote-start-fail.scores -@@ -0,0 +1,9 @@ -+Allocation scores: -+native_color: rhel7-auto4 allocation score on rhel7-auto1: -INFINITY -+native_color: rhel7-auto4 allocation score on rhel7-auto2: -INFINITY -+native_color: rhel7-auto4 allocation score on rhel7-auto3: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: -INFINITY -diff --git a/pengine/test10/remote-start-fail.summary b/pengine/test10/remote-start-fail.summary -new file mode 100644 -index 0000000..4f64c75 ---- /dev/null -+++ b/pengine/test10/remote-start-fail.summary -@@ -0,0 +1,24 @@ -+ -+Current cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+RemoteOFFLINE: [ rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ rhel7-auto4 (ocf::pacemaker:remote): FAILED rhel7-auto2 -+ -+Transition Summary: -+ * Recover rhel7-auto4 (Started rhel7-auto2 -> rhel7-auto3) -+ -+Executing cluster transition: -+ * Resource action: rhel7-auto4 stop on rhel7-auto2 -+ * Pseudo action: all_stopped -+ * Resource action: rhel7-auto4 start on rhel7-auto3 -+ * Resource action: rhel7-auto4 monitor=60000 on rhel7-auto3 -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+RemoteOnline: [ rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto1 -+ rhel7-auto4 (ocf::pacemaker:remote): Started rhel7-auto3 -+ -diff --git a/pengine/test10/remote-start-fail.xml b/pengine/test10/remote-start-fail.xml -new file mode 100644 -index 0000000..7f92eaf ---- /dev/null -+++ b/pengine/test10/remote-start-fail.xml -@@ -0,0 +1,107 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-unclean2.dot b/pengine/test10/remote-unclean2.dot -new file mode 100644 -index 0000000..3f8981b ---- /dev/null -+++ b/pengine/test10/remote-unclean2.dot -@@ -0,0 +1,14 @@ -+ digraph "g" { -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"rhel7-auto4_monitor_60000 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"rhel7-auto4_start_0 rhel7-auto1" -> "rhel7-auto4_monitor_60000 rhel7-auto1" [ style = bold] -+"rhel7-auto4_start_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"rhel7-auto4_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"rhel7-auto4_stop_0 rhel7-auto1" -> "rhel7-auto4_start_0 rhel7-auto1" [ style = bold] -+"rhel7-auto4_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"stonith 'reboot' rhel7-auto4" -> "stonith_complete" [ style = bold] -+"stonith 'reboot' rhel7-auto4" [ style=bold color="green" fontcolor="black"] -+"stonith_complete" -> "all_stopped" [ style = bold] -+"stonith_complete" -> "rhel7-auto4_start_0 rhel7-auto1" [ style = bold] -+"stonith_complete" [ style=bold color="green" fontcolor="orange"] -+} -diff --git a/pengine/test10/remote-unclean2.exp b/pengine/test10/remote-unclean2.exp -new file mode 100644 -index 0000000..19d5863 ---- /dev/null -+++ b/pengine/test10/remote-unclean2.exp -@@ -0,0 +1,75 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/remote-unclean2.scores b/pengine/test10/remote-unclean2.scores -new file mode 100644 -index 0000000..72a5953 ---- /dev/null -+++ b/pengine/test10/remote-unclean2.scores -@@ -0,0 +1,9 @@ -+Allocation scores: -+native_color: rhel7-auto4 allocation score on rhel7-auto1: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto2: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto3: 0 -+native_color: rhel7-auto4 allocation score on rhel7-auto4: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -+native_color: shooter allocation score on rhel7-auto4: -INFINITY -diff --git a/pengine/test10/remote-unclean2.summary b/pengine/test10/remote-unclean2.summary -new file mode 100644 -index 0000000..0a73cbd ---- /dev/null -+++ b/pengine/test10/remote-unclean2.summary -@@ -0,0 +1,26 @@ -+ -+Current cluster status: -+RemoteNode rhel7-auto4: UNCLEAN (offline) -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto2 -+ rhel7-auto4 (ocf::pacemaker:remote): FAILED rhel7-auto1 -+ -+Transition Summary: -+ * Recover rhel7-auto4 (Started rhel7-auto1) -+ -+Executing cluster transition: -+ * Resource action: rhel7-auto4 stop on rhel7-auto1 -+ * Fencing rhel7-auto4 (reboot) -+ * Pseudo action: stonith_complete -+ * Pseudo action: all_stopped -+ * Resource action: rhel7-auto4 start on rhel7-auto1 -+ * Resource action: rhel7-auto4 monitor=60000 on rhel7-auto1 -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+RemoteOnline: [ rhel7-auto4 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto2 -+ rhel7-auto4 (ocf::pacemaker:remote): Started rhel7-auto1 -+ -diff --git a/pengine/test10/remote-unclean2.xml b/pengine/test10/remote-unclean2.xml -new file mode 100644 -index 0000000..616b482 ---- /dev/null -+++ b/pengine/test10/remote-unclean2.xml -@@ -0,0 +1,103 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/whitebox-migrate1.exp b/pengine/test10/whitebox-migrate1.exp -index 0a2b5ac..ce77eb1 100644 ---- a/pengine/test10/whitebox-migrate1.exp -+++ b/pengine/test10/whitebox-migrate1.exp -@@ -152,7 +152,7 @@ - - - -- -+ - - - diff --git a/SOURCES/pacemaker-31c6cc-enforce-colocation-fix-test.patch b/SOURCES/pacemaker-31c6cc-enforce-colocation-fix-test.patch deleted file mode 100644 index 4bd0169..0000000 --- a/SOURCES/pacemaker-31c6cc-enforce-colocation-fix-test.patch +++ /dev/null @@ -1,7172 +0,0 @@ -From 31c6cc60f3d8140f4a8972ac7b2c975cdecfe2af Mon Sep 17 00:00:00 2001 -From: David Vossel -Date: Tue, 17 Feb 2015 15:44:42 -0500 -Subject: [PATCH] Low: pengine: enforce colocation fix regression test - ---- - pengine/regression.sh | 2 + - pengine/test10/complex_enforce_colo.dot | 1257 +++++++++++++ - pengine/test10/complex_enforce_colo.exp | 2689 +++++++++++++++++++++++++++ - pengine/test10/complex_enforce_colo.scores | 844 +++++++++ - pengine/test10/complex_enforce_colo.summary | 452 +++++ - pengine/test10/complex_enforce_colo.xml | 1461 +++++++++++++++ - pengine/test10/enforce-colo1.dot | 31 + - pengine/test10/enforce-colo1.exp | 116 ++ - pengine/test10/enforce-colo1.scores | 31 + - pengine/test10/enforce-colo1.summary | 36 + - pengine/test10/enforce-colo1.xml | 150 ++ - 11 files changed, 7069 insertions(+) - create mode 100644 pengine/test10/complex_enforce_colo.dot - create mode 100644 pengine/test10/complex_enforce_colo.exp - create mode 100644 pengine/test10/complex_enforce_colo.scores - create mode 100644 pengine/test10/complex_enforce_colo.summary - create mode 100644 pengine/test10/complex_enforce_colo.xml - create mode 100644 pengine/test10/enforce-colo1.dot - create mode 100644 pengine/test10/enforce-colo1.exp - create mode 100644 pengine/test10/enforce-colo1.scores - create mode 100644 pengine/test10/enforce-colo1.summary - create mode 100644 pengine/test10/enforce-colo1.xml - -diff --git a/pengine/regression.sh b/pengine/regression.sh -index 93d4de1..b52e0f2 100755 ---- a/pengine/regression.sh -+++ b/pengine/regression.sh -@@ -176,6 +176,8 @@ do_test coloc_fp_logic "Verify floating point calculations in colocation are wor - do_test colo_master_w_native "cl#5070 - Verify promotion order is affected when colocating master to native rsc." - do_test colo_slave_w_native "cl#5070 - Verify promotion order is affected when colocating slave to native rsc." - do_test anti-colocation-order "cl#5187 - Prevent resources in an anti-colocation from even temporarily running on a same node" -+do_test enforce-colo1 "Always enforce B with A INFINITY." -+do_test complex_enforce_colo "Always enforce B with A INFINITY. (make sure heat-engine stops)" - - echo "" - do_test rsc-sets-seq-true "Resource Sets - sequential=false" -diff --git a/pengine/test10/complex_enforce_colo.dot b/pengine/test10/complex_enforce_colo.dot -new file mode 100644 -index 0000000..a4811b8 ---- /dev/null -+++ b/pengine/test10/complex_enforce_colo.dot -@@ -0,0 +1,1257 @@ -+ digraph "g" { -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-alarm-evaluator-clone_running_0" -> "ceilometer-alarm-notifier-clone_start_0" [ style = dashed] -+"ceilometer-alarm-evaluator-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-alarm-evaluator-clone_start_0" -> "ceilometer-alarm-evaluator-clone_running_0" [ style = dashed] -+"ceilometer-alarm-evaluator-clone_start_0" -> "ceilometer-alarm-evaluator_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-evaluator-clone_start_0" -> "ceilometer-alarm-evaluator_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-evaluator-clone_start_0" -> "ceilometer-alarm-evaluator_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-evaluator-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-alarm-evaluator-clone_stop_0" -> "ceilometer-alarm-evaluator-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-evaluator-clone_stop_0" -> "ceilometer-alarm-evaluator_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-alarm-evaluator-clone_stop_0" -> "ceilometer-alarm-evaluator_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-alarm-evaluator-clone_stop_0" -> "ceilometer-alarm-evaluator_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-alarm-evaluator-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-alarm-evaluator-clone_stopped_0" -> "ceilometer-alarm-evaluator-clone_start_0" [ style = dashed] -+"ceilometer-alarm-evaluator-clone_stopped_0" -> "ceilometer-delay-clone_stop_0" [ style = bold] -+"ceilometer-alarm-evaluator-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-alarm-evaluator_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-evaluator_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-evaluator_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-evaluator_start_0 rhos6-node1" -> "ceilometer-alarm-evaluator-clone_running_0" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node1" -> "ceilometer-alarm-evaluator_monitor_60000 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node1" -> "ceilometer-alarm-notifier_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-evaluator_start_0 rhos6-node2" -> "ceilometer-alarm-evaluator-clone_running_0" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node2" -> "ceilometer-alarm-evaluator_monitor_60000 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node2" -> "ceilometer-alarm-notifier_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-evaluator_start_0 rhos6-node3" -> "ceilometer-alarm-evaluator-clone_running_0" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node3" -> "ceilometer-alarm-evaluator_monitor_60000 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node3" -> "ceilometer-alarm-notifier_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-evaluator_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node1" -> "ceilometer-alarm-evaluator-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node1" -> "ceilometer-alarm-evaluator_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node1" -> "ceilometer-delay_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node2" -> "ceilometer-alarm-evaluator-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node2" -> "ceilometer-alarm-evaluator_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node2" -> "ceilometer-delay_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node3" -> "ceilometer-alarm-evaluator-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node3" -> "ceilometer-alarm-evaluator_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node3" -> "ceilometer-delay_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-alarm-evaluator_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"ceilometer-alarm-notifier-clone_running_0" -> "ceilometer-notification-clone_start_0" [ style = dashed] -+"ceilometer-alarm-notifier-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-alarm-notifier-clone_start_0" -> "ceilometer-alarm-notifier-clone_running_0" [ style = dashed] -+"ceilometer-alarm-notifier-clone_start_0" -> "ceilometer-alarm-notifier_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-notifier-clone_start_0" -> "ceilometer-alarm-notifier_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-notifier-clone_start_0" -> "ceilometer-alarm-notifier_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-notifier-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-alarm-notifier-clone_stop_0" -> "ceilometer-alarm-notifier-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-notifier-clone_stop_0" -> "ceilometer-alarm-notifier_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-alarm-notifier-clone_stop_0" -> "ceilometer-alarm-notifier_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-alarm-notifier-clone_stop_0" -> "ceilometer-alarm-notifier_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-alarm-notifier-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-alarm-notifier-clone_stopped_0" -> "ceilometer-alarm-evaluator-clone_stop_0" [ style = bold] -+"ceilometer-alarm-notifier-clone_stopped_0" -> "ceilometer-alarm-notifier-clone_start_0" [ style = dashed] -+"ceilometer-alarm-notifier-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-alarm-notifier_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-notifier_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-notifier_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-notifier_start_0 rhos6-node1" -> "ceilometer-alarm-notifier-clone_running_0" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node1" -> "ceilometer-alarm-notifier_monitor_60000 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node1" -> "ceilometer-notification_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-notifier_start_0 rhos6-node2" -> "ceilometer-alarm-notifier-clone_running_0" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node2" -> "ceilometer-alarm-notifier_monitor_60000 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node2" -> "ceilometer-notification_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-notifier_start_0 rhos6-node3" -> "ceilometer-alarm-notifier-clone_running_0" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node3" -> "ceilometer-alarm-notifier_monitor_60000 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node3" -> "ceilometer-notification_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-notifier_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-alarm-notifier_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node1" -> "ceilometer-alarm-evaluator_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node1" -> "ceilometer-alarm-notifier-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node1" -> "ceilometer-alarm-notifier_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-alarm-notifier_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"ceilometer-alarm-notifier_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node2" -> "ceilometer-alarm-evaluator_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node2" -> "ceilometer-alarm-notifier-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node2" -> "ceilometer-alarm-notifier_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-alarm-notifier_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"ceilometer-alarm-notifier_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node3" -> "ceilometer-alarm-evaluator_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node3" -> "ceilometer-alarm-notifier-clone_stopped_0" [ style = bold] -+"ceilometer-alarm-notifier_stop_0 rhos6-node3" -> "ceilometer-alarm-notifier_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-alarm-notifier_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"ceilometer-api-clone_running_0" -> "ceilometer-delay-clone_start_0" [ style = dashed] -+"ceilometer-api-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-api-clone_start_0" -> "ceilometer-api-clone_running_0" [ style = dashed] -+"ceilometer-api-clone_start_0" -> "ceilometer-api_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-api-clone_start_0" -> "ceilometer-api_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-api-clone_start_0" -> "ceilometer-api_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-api-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-api-clone_stop_0" -> "ceilometer-api-clone_stopped_0" [ style = bold] -+"ceilometer-api-clone_stop_0" -> "ceilometer-api_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-api-clone_stop_0" -> "ceilometer-api_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-api-clone_stop_0" -> "ceilometer-api_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-api-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-api-clone_stopped_0" -> "ceilometer-api-clone_start_0" [ style = dashed] -+"ceilometer-api-clone_stopped_0" -> "ceilometer-collector-clone_stop_0" [ style = bold] -+"ceilometer-api-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-api_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-api_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-api_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-api_start_0 rhos6-node1" -> "ceilometer-api-clone_running_0" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node1" -> "ceilometer-api_monitor_60000 rhos6-node1" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node1" -> "ceilometer-delay_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-api_start_0 rhos6-node2" -> "ceilometer-api-clone_running_0" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node2" -> "ceilometer-api_monitor_60000 rhos6-node2" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node2" -> "ceilometer-delay_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-api_start_0 rhos6-node3" -> "ceilometer-api-clone_running_0" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node3" -> "ceilometer-api_monitor_60000 rhos6-node3" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node3" -> "ceilometer-delay_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-api_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-api_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node1" -> "ceilometer-api-clone_stopped_0" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node1" -> "ceilometer-api_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-api_stop_0 rhos6-node1" -> "ceilometer-collector_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"ceilometer-api_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node2" -> "ceilometer-api-clone_stopped_0" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node2" -> "ceilometer-api_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-api_stop_0 rhos6-node2" -> "ceilometer-collector_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"ceilometer-api_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node3" -> "ceilometer-api-clone_stopped_0" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node3" -> "ceilometer-api_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-api_stop_0 rhos6-node3" -> "ceilometer-collector_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-api_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"ceilometer-central_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-central_start_0 rhos6-node3" -> "ceilometer-central_monitor_60000 rhos6-node3" [ style = dashed] -+"ceilometer-central_start_0 rhos6-node3" -> "ceilometer-collector-clone_start_0" [ style = dashed] -+"ceilometer-central_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-central_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-central_stop_0 rhos6-node3" -> "ceilometer-central_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-central_stop_0 rhos6-node3" -> "keystone-clone_stop_0" [ style = bold] -+"ceilometer-central_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"ceilometer-collector-clone_running_0" -> "ceilometer-api-clone_start_0" [ style = dashed] -+"ceilometer-collector-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-collector-clone_start_0" -> "ceilometer-collector-clone_running_0" [ style = dashed] -+"ceilometer-collector-clone_start_0" -> "ceilometer-collector_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-collector-clone_start_0" -> "ceilometer-collector_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-collector-clone_start_0" -> "ceilometer-collector_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-collector-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-collector-clone_stop_0" -> "ceilometer-collector-clone_stopped_0" [ style = bold] -+"ceilometer-collector-clone_stop_0" -> "ceilometer-collector_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-collector-clone_stop_0" -> "ceilometer-collector_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-collector-clone_stop_0" -> "ceilometer-collector_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-collector-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-collector-clone_stopped_0" -> "ceilometer-central_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-collector-clone_stopped_0" -> "ceilometer-collector-clone_start_0" [ style = dashed] -+"ceilometer-collector-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-collector_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-collector_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-collector_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-collector_start_0 rhos6-node1" -> "ceilometer-api_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node1" -> "ceilometer-collector-clone_running_0" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node1" -> "ceilometer-collector_monitor_60000 rhos6-node1" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-collector_start_0 rhos6-node2" -> "ceilometer-api_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node2" -> "ceilometer-collector-clone_running_0" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node2" -> "ceilometer-collector_monitor_60000 rhos6-node2" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-collector_start_0 rhos6-node3" -> "ceilometer-api_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node3" -> "ceilometer-collector-clone_running_0" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node3" -> "ceilometer-collector_monitor_60000 rhos6-node3" [ style = dashed] -+"ceilometer-collector_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-collector_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"ceilometer-collector_stop_0 rhos6-node1" -> "ceilometer-collector-clone_stopped_0" [ style = bold] -+"ceilometer-collector_stop_0 rhos6-node1" -> "ceilometer-collector_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-collector_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"ceilometer-collector_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"ceilometer-collector_stop_0 rhos6-node2" -> "ceilometer-collector-clone_stopped_0" [ style = bold] -+"ceilometer-collector_stop_0 rhos6-node2" -> "ceilometer-collector_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-collector_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"ceilometer-collector_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-collector_stop_0 rhos6-node3" -> "ceilometer-collector-clone_stopped_0" [ style = bold] -+"ceilometer-collector_stop_0 rhos6-node3" -> "ceilometer-collector_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-collector_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"ceilometer-delay-clone_running_0" -> "ceilometer-alarm-evaluator-clone_start_0" [ style = dashed] -+"ceilometer-delay-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-delay-clone_start_0" -> "ceilometer-delay-clone_running_0" [ style = dashed] -+"ceilometer-delay-clone_start_0" -> "ceilometer-delay_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-delay-clone_start_0" -> "ceilometer-delay_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-delay-clone_start_0" -> "ceilometer-delay_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-delay-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-delay-clone_stop_0" -> "ceilometer-delay-clone_stopped_0" [ style = bold] -+"ceilometer-delay-clone_stop_0" -> "ceilometer-delay_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-delay-clone_stop_0" -> "ceilometer-delay_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-delay-clone_stop_0" -> "ceilometer-delay_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-delay-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-delay-clone_stopped_0" -> "ceilometer-api-clone_stop_0" [ style = bold] -+"ceilometer-delay-clone_stopped_0" -> "ceilometer-delay-clone_start_0" [ style = dashed] -+"ceilometer-delay-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-delay_monitor_10000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-delay_monitor_10000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-delay_monitor_10000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-delay_start_0 rhos6-node1" -> "ceilometer-alarm-evaluator_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node1" -> "ceilometer-delay-clone_running_0" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node1" -> "ceilometer-delay_monitor_10000 rhos6-node1" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-delay_start_0 rhos6-node2" -> "ceilometer-alarm-evaluator_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node2" -> "ceilometer-delay-clone_running_0" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node2" -> "ceilometer-delay_monitor_10000 rhos6-node2" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-delay_start_0 rhos6-node3" -> "ceilometer-alarm-evaluator_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node3" -> "ceilometer-delay-clone_running_0" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node3" -> "ceilometer-delay_monitor_10000 rhos6-node3" [ style = dashed] -+"ceilometer-delay_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-delay_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node1" -> "ceilometer-api_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node1" -> "ceilometer-delay-clone_stopped_0" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node1" -> "ceilometer-delay_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-delay_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"ceilometer-delay_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node2" -> "ceilometer-api_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node2" -> "ceilometer-delay-clone_stopped_0" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node2" -> "ceilometer-delay_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-delay_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"ceilometer-delay_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node3" -> "ceilometer-api_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node3" -> "ceilometer-delay-clone_stopped_0" [ style = bold] -+"ceilometer-delay_stop_0 rhos6-node3" -> "ceilometer-delay_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-delay_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"ceilometer-notification-clone_running_0" -> "heat-api-clone_start_0" [ style = dashed] -+"ceilometer-notification-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-notification-clone_start_0" -> "ceilometer-notification-clone_running_0" [ style = dashed] -+"ceilometer-notification-clone_start_0" -> "ceilometer-notification_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-notification-clone_start_0" -> "ceilometer-notification_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-notification-clone_start_0" -> "ceilometer-notification_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-notification-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"ceilometer-notification-clone_stop_0" -> "ceilometer-notification-clone_stopped_0" [ style = bold] -+"ceilometer-notification-clone_stop_0" -> "ceilometer-notification_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-notification-clone_stop_0" -> "ceilometer-notification_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-notification-clone_stop_0" -> "ceilometer-notification_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-notification-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-notification-clone_stopped_0" -> "ceilometer-alarm-notifier-clone_stop_0" [ style = bold] -+"ceilometer-notification-clone_stopped_0" -> "ceilometer-notification-clone_start_0" [ style = dashed] -+"ceilometer-notification-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"ceilometer-notification_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-notification_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-notification_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-notification_start_0 rhos6-node1" -> "ceilometer-notification-clone_running_0" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node1" -> "ceilometer-notification_monitor_60000 rhos6-node1" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node1" -> "heat-api_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-notification_start_0 rhos6-node2" -> "ceilometer-notification-clone_running_0" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node2" -> "ceilometer-notification_monitor_60000 rhos6-node2" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node2" -> "heat-api_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-notification_start_0 rhos6-node3" -> "ceilometer-notification-clone_running_0" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node3" -> "ceilometer-notification_monitor_60000 rhos6-node3" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node3" -> "heat-api_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-notification_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"ceilometer-notification_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node1" -> "ceilometer-alarm-notifier_stop_0 rhos6-node1" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node1" -> "ceilometer-notification-clone_stopped_0" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node1" -> "ceilometer-notification_start_0 rhos6-node1" [ style = dashed] -+"ceilometer-notification_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"ceilometer-notification_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node2" -> "ceilometer-alarm-notifier_stop_0 rhos6-node2" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node2" -> "ceilometer-notification-clone_stopped_0" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node2" -> "ceilometer-notification_start_0 rhos6-node2" [ style = dashed] -+"ceilometer-notification_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"ceilometer-notification_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node3" -> "ceilometer-alarm-notifier_stop_0 rhos6-node3" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node3" -> "ceilometer-notification-clone_stopped_0" [ style = bold] -+"ceilometer-notification_stop_0 rhos6-node3" -> "ceilometer-notification_start_0 rhos6-node3" [ style = dashed] -+"ceilometer-notification_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"cinder-api_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"cinder-api_start_0 rhos6-node1" -> "cinder-api_monitor_60000 rhos6-node1" [ style = dashed] -+"cinder-api_start_0 rhos6-node1" -> "cinder-scheduler_start_0 rhos6-node1" [ style = dashed] -+"cinder-api_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"cinder-api_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"cinder-api_stop_0 rhos6-node1" -> "cinder-api_start_0 rhos6-node1" [ style = dashed] -+"cinder-api_stop_0 rhos6-node1" -> "keystone-clone_stop_0" [ style = bold] -+"cinder-api_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"cinder-scheduler_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"cinder-scheduler_start_0 rhos6-node1" -> "cinder-scheduler_monitor_60000 rhos6-node1" [ style = dashed] -+"cinder-scheduler_start_0 rhos6-node1" -> "cinder-volume_start_0 rhos6-node1" [ style = dashed] -+"cinder-scheduler_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"cinder-scheduler_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"cinder-scheduler_stop_0 rhos6-node1" -> "cinder-api_stop_0 rhos6-node1" [ style = bold] -+"cinder-scheduler_stop_0 rhos6-node1" -> "cinder-scheduler_start_0 rhos6-node1" [ style = dashed] -+"cinder-scheduler_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"cinder-volume_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"cinder-volume_start_0 rhos6-node1" -> "cinder-volume_monitor_60000 rhos6-node1" [ style = dashed] -+"cinder-volume_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"cinder-volume_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"cinder-volume_stop_0 rhos6-node1" -> "cinder-scheduler_stop_0 rhos6-node1" [ style = bold] -+"cinder-volume_stop_0 rhos6-node1" -> "cinder-volume_start_0 rhos6-node1" [ style = dashed] -+"cinder-volume_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"glance-api-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"glance-api-clone_start_0" -> "glance-api-clone_running_0" [ style = dashed] -+"glance-api-clone_start_0" -> "glance-api_start_0 rhos6-node1" [ style = dashed] -+"glance-api-clone_start_0" -> "glance-api_start_0 rhos6-node2" [ style = dashed] -+"glance-api-clone_start_0" -> "glance-api_start_0 rhos6-node3" [ style = dashed] -+"glance-api-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"glance-api-clone_stop_0" -> "glance-api-clone_stopped_0" [ style = bold] -+"glance-api-clone_stop_0" -> "glance-api_stop_0 rhos6-node1" [ style = bold] -+"glance-api-clone_stop_0" -> "glance-api_stop_0 rhos6-node2" [ style = bold] -+"glance-api-clone_stop_0" -> "glance-api_stop_0 rhos6-node3" [ style = bold] -+"glance-api-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"glance-api-clone_stopped_0" -> "glance-api-clone_start_0" [ style = dashed] -+"glance-api-clone_stopped_0" -> "glance-registry-clone_stop_0" [ style = bold] -+"glance-api-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"glance-api_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"glance-api_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"glance-api_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"glance-api_start_0 rhos6-node1" -> "glance-api-clone_running_0" [ style = dashed] -+"glance-api_start_0 rhos6-node1" -> "glance-api_monitor_60000 rhos6-node1" [ style = dashed] -+"glance-api_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"glance-api_start_0 rhos6-node2" -> "glance-api-clone_running_0" [ style = dashed] -+"glance-api_start_0 rhos6-node2" -> "glance-api_monitor_60000 rhos6-node2" [ style = dashed] -+"glance-api_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"glance-api_start_0 rhos6-node3" -> "glance-api-clone_running_0" [ style = dashed] -+"glance-api_start_0 rhos6-node3" -> "glance-api_monitor_60000 rhos6-node3" [ style = dashed] -+"glance-api_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"glance-api_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"glance-api_stop_0 rhos6-node1" -> "glance-api-clone_stopped_0" [ style = bold] -+"glance-api_stop_0 rhos6-node1" -> "glance-api_start_0 rhos6-node1" [ style = dashed] -+"glance-api_stop_0 rhos6-node1" -> "glance-registry_stop_0 rhos6-node1" [ style = bold] -+"glance-api_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"glance-api_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"glance-api_stop_0 rhos6-node2" -> "glance-api-clone_stopped_0" [ style = bold] -+"glance-api_stop_0 rhos6-node2" -> "glance-api_start_0 rhos6-node2" [ style = dashed] -+"glance-api_stop_0 rhos6-node2" -> "glance-registry_stop_0 rhos6-node2" [ style = bold] -+"glance-api_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"glance-api_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"glance-api_stop_0 rhos6-node3" -> "glance-api-clone_stopped_0" [ style = bold] -+"glance-api_stop_0 rhos6-node3" -> "glance-api_start_0 rhos6-node3" [ style = dashed] -+"glance-api_stop_0 rhos6-node3" -> "glance-registry_stop_0 rhos6-node3" [ style = bold] -+"glance-api_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"glance-registry-clone_running_0" -> "glance-api-clone_start_0" [ style = dashed] -+"glance-registry-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"glance-registry-clone_start_0" -> "glance-registry-clone_running_0" [ style = dashed] -+"glance-registry-clone_start_0" -> "glance-registry_start_0 rhos6-node1" [ style = dashed] -+"glance-registry-clone_start_0" -> "glance-registry_start_0 rhos6-node2" [ style = dashed] -+"glance-registry-clone_start_0" -> "glance-registry_start_0 rhos6-node3" [ style = dashed] -+"glance-registry-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"glance-registry-clone_stop_0" -> "glance-registry-clone_stopped_0" [ style = bold] -+"glance-registry-clone_stop_0" -> "glance-registry_stop_0 rhos6-node1" [ style = bold] -+"glance-registry-clone_stop_0" -> "glance-registry_stop_0 rhos6-node2" [ style = bold] -+"glance-registry-clone_stop_0" -> "glance-registry_stop_0 rhos6-node3" [ style = bold] -+"glance-registry-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"glance-registry-clone_stopped_0" -> "glance-registry-clone_start_0" [ style = dashed] -+"glance-registry-clone_stopped_0" -> "keystone-clone_stop_0" [ style = bold] -+"glance-registry-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"glance-registry_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"glance-registry_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"glance-registry_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"glance-registry_start_0 rhos6-node1" -> "glance-registry-clone_running_0" [ style = dashed] -+"glance-registry_start_0 rhos6-node1" -> "glance-registry_monitor_60000 rhos6-node1" [ style = dashed] -+"glance-registry_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"glance-registry_start_0 rhos6-node2" -> "glance-registry-clone_running_0" [ style = dashed] -+"glance-registry_start_0 rhos6-node2" -> "glance-registry_monitor_60000 rhos6-node2" [ style = dashed] -+"glance-registry_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"glance-registry_start_0 rhos6-node3" -> "glance-registry-clone_running_0" [ style = dashed] -+"glance-registry_start_0 rhos6-node3" -> "glance-registry_monitor_60000 rhos6-node3" [ style = dashed] -+"glance-registry_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"glance-registry_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"glance-registry_stop_0 rhos6-node1" -> "glance-registry-clone_stopped_0" [ style = bold] -+"glance-registry_stop_0 rhos6-node1" -> "glance-registry_start_0 rhos6-node1" [ style = dashed] -+"glance-registry_stop_0 rhos6-node1" -> "keystone_stop_0 rhos6-node1" [ style = bold] -+"glance-registry_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"glance-registry_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"glance-registry_stop_0 rhos6-node2" -> "glance-registry-clone_stopped_0" [ style = bold] -+"glance-registry_stop_0 rhos6-node2" -> "glance-registry_start_0 rhos6-node2" [ style = dashed] -+"glance-registry_stop_0 rhos6-node2" -> "keystone_stop_0 rhos6-node2" [ style = bold] -+"glance-registry_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"glance-registry_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"glance-registry_stop_0 rhos6-node3" -> "glance-registry-clone_stopped_0" [ style = bold] -+"glance-registry_stop_0 rhos6-node3" -> "glance-registry_start_0 rhos6-node3" [ style = dashed] -+"glance-registry_stop_0 rhos6-node3" -> "keystone_stop_0 rhos6-node3" [ style = bold] -+"glance-registry_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"heat-api-cfn-clone_running_0" -> "heat-api-cloudwatch-clone_start_0" [ style = dashed] -+"heat-api-cfn-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"heat-api-cfn-clone_start_0" -> "heat-api-cfn-clone_running_0" [ style = dashed] -+"heat-api-cfn-clone_start_0" -> "heat-api-cfn_start_0 rhos6-node1" [ style = dashed] -+"heat-api-cfn-clone_start_0" -> "heat-api-cfn_start_0 rhos6-node2" [ style = dashed] -+"heat-api-cfn-clone_start_0" -> "heat-api-cfn_start_0 rhos6-node3" [ style = dashed] -+"heat-api-cfn-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"heat-api-cfn-clone_stop_0" -> "heat-api-cfn-clone_stopped_0" [ style = bold] -+"heat-api-cfn-clone_stop_0" -> "heat-api-cfn_stop_0 rhos6-node1" [ style = bold] -+"heat-api-cfn-clone_stop_0" -> "heat-api-cfn_stop_0 rhos6-node2" [ style = bold] -+"heat-api-cfn-clone_stop_0" -> "heat-api-cfn_stop_0 rhos6-node3" [ style = bold] -+"heat-api-cfn-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"heat-api-cfn-clone_stopped_0" -> "heat-api-cfn-clone_start_0" [ style = dashed] -+"heat-api-cfn-clone_stopped_0" -> "heat-api-clone_stop_0" [ style = bold] -+"heat-api-cfn-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"heat-api-cfn_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cfn_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cfn_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cfn_start_0 rhos6-node1" -> "heat-api-cfn-clone_running_0" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node1" -> "heat-api-cfn_monitor_60000 rhos6-node1" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node1" -> "heat-api-cloudwatch_start_0 rhos6-node1" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cfn_start_0 rhos6-node2" -> "heat-api-cfn-clone_running_0" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node2" -> "heat-api-cfn_monitor_60000 rhos6-node2" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node2" -> "heat-api-cloudwatch_start_0 rhos6-node2" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cfn_start_0 rhos6-node3" -> "heat-api-cfn-clone_running_0" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node3" -> "heat-api-cfn_monitor_60000 rhos6-node3" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node3" -> "heat-api-cloudwatch_start_0 rhos6-node3" [ style = dashed] -+"heat-api-cfn_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cfn_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node1" -> "heat-api-cfn-clone_stopped_0" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node1" -> "heat-api-cfn_start_0 rhos6-node1" [ style = dashed] -+"heat-api-cfn_stop_0 rhos6-node1" -> "heat-api_stop_0 rhos6-node1" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"heat-api-cfn_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node2" -> "heat-api-cfn-clone_stopped_0" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node2" -> "heat-api-cfn_start_0 rhos6-node2" [ style = dashed] -+"heat-api-cfn_stop_0 rhos6-node2" -> "heat-api_stop_0 rhos6-node2" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"heat-api-cfn_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node3" -> "heat-api-cfn-clone_stopped_0" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node3" -> "heat-api-cfn_start_0 rhos6-node3" [ style = dashed] -+"heat-api-cfn_stop_0 rhos6-node3" -> "heat-api_stop_0 rhos6-node3" [ style = bold] -+"heat-api-cfn_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"heat-api-clone_running_0" -> "heat-api-cfn-clone_start_0" [ style = dashed] -+"heat-api-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"heat-api-clone_start_0" -> "heat-api-clone_running_0" [ style = dashed] -+"heat-api-clone_start_0" -> "heat-api_start_0 rhos6-node1" [ style = dashed] -+"heat-api-clone_start_0" -> "heat-api_start_0 rhos6-node2" [ style = dashed] -+"heat-api-clone_start_0" -> "heat-api_start_0 rhos6-node3" [ style = dashed] -+"heat-api-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"heat-api-clone_stop_0" -> "heat-api-clone_stopped_0" [ style = bold] -+"heat-api-clone_stop_0" -> "heat-api_stop_0 rhos6-node1" [ style = bold] -+"heat-api-clone_stop_0" -> "heat-api_stop_0 rhos6-node2" [ style = bold] -+"heat-api-clone_stop_0" -> "heat-api_stop_0 rhos6-node3" [ style = bold] -+"heat-api-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"heat-api-clone_stopped_0" -> "ceilometer-notification-clone_stop_0" [ style = bold] -+"heat-api-clone_stopped_0" -> "heat-api-clone_start_0" [ style = dashed] -+"heat-api-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"heat-api-cloudwatch-clone_running_0" -> "heat-engine_start_0 rhos6-node2" [ style = dashed] -+"heat-api-cloudwatch-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"heat-api-cloudwatch-clone_start_0" -> "heat-api-cloudwatch-clone_running_0" [ style = dashed] -+"heat-api-cloudwatch-clone_start_0" -> "heat-api-cloudwatch_start_0 rhos6-node1" [ style = dashed] -+"heat-api-cloudwatch-clone_start_0" -> "heat-api-cloudwatch_start_0 rhos6-node2" [ style = dashed] -+"heat-api-cloudwatch-clone_start_0" -> "heat-api-cloudwatch_start_0 rhos6-node3" [ style = dashed] -+"heat-api-cloudwatch-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"heat-api-cloudwatch-clone_stop_0" -> "heat-api-cloudwatch-clone_stopped_0" [ style = bold] -+"heat-api-cloudwatch-clone_stop_0" -> "heat-api-cloudwatch_stop_0 rhos6-node1" [ style = bold] -+"heat-api-cloudwatch-clone_stop_0" -> "heat-api-cloudwatch_stop_0 rhos6-node2" [ style = bold] -+"heat-api-cloudwatch-clone_stop_0" -> "heat-api-cloudwatch_stop_0 rhos6-node3" [ style = bold] -+"heat-api-cloudwatch-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"heat-api-cloudwatch-clone_stopped_0" -> "heat-api-cfn-clone_stop_0" [ style = bold] -+"heat-api-cloudwatch-clone_stopped_0" -> "heat-api-cloudwatch-clone_start_0" [ style = dashed] -+"heat-api-cloudwatch-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"heat-api-cloudwatch_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cloudwatch_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cloudwatch_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cloudwatch_start_0 rhos6-node1" -> "heat-api-cloudwatch-clone_running_0" [ style = dashed] -+"heat-api-cloudwatch_start_0 rhos6-node1" -> "heat-api-cloudwatch_monitor_60000 rhos6-node1" [ style = dashed] -+"heat-api-cloudwatch_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cloudwatch_start_0 rhos6-node2" -> "heat-api-cloudwatch-clone_running_0" [ style = dashed] -+"heat-api-cloudwatch_start_0 rhos6-node2" -> "heat-api-cloudwatch_monitor_60000 rhos6-node2" [ style = dashed] -+"heat-api-cloudwatch_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cloudwatch_start_0 rhos6-node3" -> "heat-api-cloudwatch-clone_running_0" [ style = dashed] -+"heat-api-cloudwatch_start_0 rhos6-node3" -> "heat-api-cloudwatch_monitor_60000 rhos6-node3" [ style = dashed] -+"heat-api-cloudwatch_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"heat-api-cloudwatch_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node1" -> "heat-api-cfn_stop_0 rhos6-node1" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node1" -> "heat-api-cloudwatch-clone_stopped_0" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node1" -> "heat-api-cloudwatch_start_0 rhos6-node1" [ style = dashed] -+"heat-api-cloudwatch_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"heat-api-cloudwatch_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node2" -> "heat-api-cfn_stop_0 rhos6-node2" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node2" -> "heat-api-cloudwatch-clone_stopped_0" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node2" -> "heat-api-cloudwatch_start_0 rhos6-node2" [ style = dashed] -+"heat-api-cloudwatch_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"heat-api-cloudwatch_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node3" -> "heat-api-cfn_stop_0 rhos6-node3" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node3" -> "heat-api-cloudwatch-clone_stopped_0" [ style = bold] -+"heat-api-cloudwatch_stop_0 rhos6-node3" -> "heat-api-cloudwatch_start_0 rhos6-node3" [ style = dashed] -+"heat-api-cloudwatch_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"heat-api_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"heat-api_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-api_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"heat-api_start_0 rhos6-node1" -> "heat-api-cfn_start_0 rhos6-node1" [ style = dashed] -+"heat-api_start_0 rhos6-node1" -> "heat-api-clone_running_0" [ style = dashed] -+"heat-api_start_0 rhos6-node1" -> "heat-api_monitor_60000 rhos6-node1" [ style = dashed] -+"heat-api_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"heat-api_start_0 rhos6-node2" -> "heat-api-cfn_start_0 rhos6-node2" [ style = dashed] -+"heat-api_start_0 rhos6-node2" -> "heat-api-clone_running_0" [ style = dashed] -+"heat-api_start_0 rhos6-node2" -> "heat-api_monitor_60000 rhos6-node2" [ style = dashed] -+"heat-api_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-api_start_0 rhos6-node3" -> "heat-api-cfn_start_0 rhos6-node3" [ style = dashed] -+"heat-api_start_0 rhos6-node3" -> "heat-api-clone_running_0" [ style = dashed] -+"heat-api_start_0 rhos6-node3" -> "heat-api_monitor_60000 rhos6-node3" [ style = dashed] -+"heat-api_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"heat-api_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"heat-api_stop_0 rhos6-node1" -> "ceilometer-notification_stop_0 rhos6-node1" [ style = bold] -+"heat-api_stop_0 rhos6-node1" -> "heat-api-clone_stopped_0" [ style = bold] -+"heat-api_stop_0 rhos6-node1" -> "heat-api_start_0 rhos6-node1" [ style = dashed] -+"heat-api_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"heat-api_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"heat-api_stop_0 rhos6-node2" -> "ceilometer-notification_stop_0 rhos6-node2" [ style = bold] -+"heat-api_stop_0 rhos6-node2" -> "heat-api-clone_stopped_0" [ style = bold] -+"heat-api_stop_0 rhos6-node2" -> "heat-api_start_0 rhos6-node2" [ style = dashed] -+"heat-api_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"heat-api_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"heat-api_stop_0 rhos6-node3" -> "ceilometer-notification_stop_0 rhos6-node3" [ style = bold] -+"heat-api_stop_0 rhos6-node3" -> "heat-api-clone_stopped_0" [ style = bold] -+"heat-api_stop_0 rhos6-node3" -> "heat-api_start_0 rhos6-node3" [ style = dashed] -+"heat-api_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"heat-engine_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-engine_start_0 rhos6-node2" -> "heat-engine_monitor_60000 rhos6-node2" [ style = dashed] -+"heat-engine_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"heat-engine_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"heat-engine_stop_0 rhos6-node2" -> "heat-api-cloudwatch-clone_stop_0" [ style = bold] -+"heat-engine_stop_0 rhos6-node2" -> "heat-engine_start_0 rhos6-node2" [ style = dashed] -+"heat-engine_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"keystone-clone_stop_0" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone-clone_stop_0" -> "keystone_stop_0 rhos6-node1" [ style = bold] -+"keystone-clone_stop_0" -> "keystone_stop_0 rhos6-node2" [ style = bold] -+"keystone-clone_stop_0" -> "keystone_stop_0 rhos6-node3" [ style = bold] -+"keystone-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"keystone-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"keystone_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"keystone_stop_0 rhos6-node1" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"keystone_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"keystone_stop_0 rhos6-node2" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"keystone_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"keystone_stop_0 rhos6-node3" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-dhcp-agent-clone_running_0" -> "neutron-l3-agent-clone_start_0" [ style = dashed] -+"neutron-dhcp-agent-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-dhcp-agent-clone_start_0" -> "neutron-dhcp-agent-clone_running_0" [ style = dashed] -+"neutron-dhcp-agent-clone_start_0" -> "neutron-dhcp-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-dhcp-agent-clone_start_0" -> "neutron-dhcp-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-dhcp-agent-clone_start_0" -> "neutron-dhcp-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-dhcp-agent-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-dhcp-agent-clone_stop_0" -> "neutron-dhcp-agent-clone_stopped_0" [ style = bold] -+"neutron-dhcp-agent-clone_stop_0" -> "neutron-dhcp-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-dhcp-agent-clone_stop_0" -> "neutron-dhcp-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-dhcp-agent-clone_stop_0" -> "neutron-dhcp-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-dhcp-agent-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-dhcp-agent-clone_stopped_0" -> "neutron-dhcp-agent-clone_start_0" [ style = dashed] -+"neutron-dhcp-agent-clone_stopped_0" -> "neutron-openvswitch-agent-clone_stop_0" [ style = bold] -+"neutron-dhcp-agent-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-dhcp-agent_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-dhcp-agent_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-dhcp-agent_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-dhcp-agent_start_0 rhos6-node1" -> "neutron-dhcp-agent-clone_running_0" [ style = dashed] -+"neutron-dhcp-agent_start_0 rhos6-node1" -> "neutron-dhcp-agent_monitor_60000 rhos6-node1" [ style = dashed] -+"neutron-dhcp-agent_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-dhcp-agent_start_0 rhos6-node2" -> "neutron-dhcp-agent-clone_running_0" [ style = dashed] -+"neutron-dhcp-agent_start_0 rhos6-node2" -> "neutron-dhcp-agent_monitor_60000 rhos6-node2" [ style = dashed] -+"neutron-dhcp-agent_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-dhcp-agent_start_0 rhos6-node3" -> "neutron-dhcp-agent-clone_running_0" [ style = dashed] -+"neutron-dhcp-agent_start_0 rhos6-node3" -> "neutron-dhcp-agent_monitor_60000 rhos6-node3" [ style = dashed] -+"neutron-dhcp-agent_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-dhcp-agent_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node1" -> "neutron-dhcp-agent-clone_stopped_0" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node1" -> "neutron-dhcp-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-dhcp-agent_stop_0 rhos6-node1" -> "neutron-openvswitch-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-dhcp-agent_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node2" -> "neutron-dhcp-agent-clone_stopped_0" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node2" -> "neutron-dhcp-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-dhcp-agent_stop_0 rhos6-node2" -> "neutron-openvswitch-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-dhcp-agent_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node3" -> "neutron-dhcp-agent-clone_stopped_0" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node3" -> "neutron-dhcp-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-dhcp-agent_stop_0 rhos6-node3" -> "neutron-openvswitch-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-dhcp-agent_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-l3-agent-clone_running_0" -> "neutron-metadata-agent-clone_start_0" [ style = dashed] -+"neutron-l3-agent-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-l3-agent-clone_start_0" -> "neutron-l3-agent-clone_running_0" [ style = dashed] -+"neutron-l3-agent-clone_start_0" -> "neutron-l3-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-l3-agent-clone_start_0" -> "neutron-l3-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-l3-agent-clone_start_0" -> "neutron-l3-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-l3-agent-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-l3-agent-clone_stop_0" -> "neutron-l3-agent-clone_stopped_0" [ style = bold] -+"neutron-l3-agent-clone_stop_0" -> "neutron-l3-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-l3-agent-clone_stop_0" -> "neutron-l3-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-l3-agent-clone_stop_0" -> "neutron-l3-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-l3-agent-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-l3-agent-clone_stopped_0" -> "neutron-dhcp-agent-clone_stop_0" [ style = bold] -+"neutron-l3-agent-clone_stopped_0" -> "neutron-l3-agent-clone_start_0" [ style = dashed] -+"neutron-l3-agent-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-l3-agent_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-l3-agent_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-l3-agent_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-l3-agent_start_0 rhos6-node1" -> "neutron-l3-agent-clone_running_0" [ style = dashed] -+"neutron-l3-agent_start_0 rhos6-node1" -> "neutron-l3-agent_monitor_60000 rhos6-node1" [ style = dashed] -+"neutron-l3-agent_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-l3-agent_start_0 rhos6-node2" -> "neutron-l3-agent-clone_running_0" [ style = dashed] -+"neutron-l3-agent_start_0 rhos6-node2" -> "neutron-l3-agent_monitor_60000 rhos6-node2" [ style = dashed] -+"neutron-l3-agent_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-l3-agent_start_0 rhos6-node3" -> "neutron-l3-agent-clone_running_0" [ style = dashed] -+"neutron-l3-agent_start_0 rhos6-node3" -> "neutron-l3-agent_monitor_60000 rhos6-node3" [ style = dashed] -+"neutron-l3-agent_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-l3-agent_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node1" -> "neutron-dhcp-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node1" -> "neutron-l3-agent-clone_stopped_0" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node1" -> "neutron-l3-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-l3-agent_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-l3-agent_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node2" -> "neutron-dhcp-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node2" -> "neutron-l3-agent-clone_stopped_0" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node2" -> "neutron-l3-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-l3-agent_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-l3-agent_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node3" -> "neutron-dhcp-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node3" -> "neutron-l3-agent-clone_stopped_0" [ style = bold] -+"neutron-l3-agent_stop_0 rhos6-node3" -> "neutron-l3-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-l3-agent_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-metadata-agent-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-metadata-agent-clone_start_0" -> "neutron-metadata-agent-clone_running_0" [ style = dashed] -+"neutron-metadata-agent-clone_start_0" -> "neutron-metadata-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-metadata-agent-clone_start_0" -> "neutron-metadata-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-metadata-agent-clone_start_0" -> "neutron-metadata-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-metadata-agent-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-metadata-agent-clone_stop_0" -> "neutron-metadata-agent-clone_stopped_0" [ style = bold] -+"neutron-metadata-agent-clone_stop_0" -> "neutron-metadata-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-metadata-agent-clone_stop_0" -> "neutron-metadata-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-metadata-agent-clone_stop_0" -> "neutron-metadata-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-metadata-agent-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-metadata-agent-clone_stopped_0" -> "neutron-l3-agent-clone_stop_0" [ style = bold] -+"neutron-metadata-agent-clone_stopped_0" -> "neutron-metadata-agent-clone_start_0" [ style = dashed] -+"neutron-metadata-agent-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-metadata-agent_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-metadata-agent_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-metadata-agent_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-metadata-agent_start_0 rhos6-node1" -> "neutron-metadata-agent-clone_running_0" [ style = dashed] -+"neutron-metadata-agent_start_0 rhos6-node1" -> "neutron-metadata-agent_monitor_60000 rhos6-node1" [ style = dashed] -+"neutron-metadata-agent_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-metadata-agent_start_0 rhos6-node2" -> "neutron-metadata-agent-clone_running_0" [ style = dashed] -+"neutron-metadata-agent_start_0 rhos6-node2" -> "neutron-metadata-agent_monitor_60000 rhos6-node2" [ style = dashed] -+"neutron-metadata-agent_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-metadata-agent_start_0 rhos6-node3" -> "neutron-metadata-agent-clone_running_0" [ style = dashed] -+"neutron-metadata-agent_start_0 rhos6-node3" -> "neutron-metadata-agent_monitor_60000 rhos6-node3" [ style = dashed] -+"neutron-metadata-agent_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-metadata-agent_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node1" -> "neutron-l3-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node1" -> "neutron-metadata-agent-clone_stopped_0" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node1" -> "neutron-metadata-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-metadata-agent_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-metadata-agent_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node2" -> "neutron-l3-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node2" -> "neutron-metadata-agent-clone_stopped_0" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node2" -> "neutron-metadata-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-metadata-agent_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-metadata-agent_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node3" -> "neutron-l3-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node3" -> "neutron-metadata-agent-clone_stopped_0" [ style = bold] -+"neutron-metadata-agent_stop_0 rhos6-node3" -> "neutron-metadata-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-metadata-agent_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-netns-cleanup-clone_running_0" -> "neutron-openvswitch-agent-clone_start_0" [ style = dashed] -+"neutron-netns-cleanup-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-netns-cleanup-clone_start_0" -> "neutron-netns-cleanup-clone_running_0" [ style = dashed] -+"neutron-netns-cleanup-clone_start_0" -> "neutron-netns-cleanup_start_0 rhos6-node1" [ style = dashed] -+"neutron-netns-cleanup-clone_start_0" -> "neutron-netns-cleanup_start_0 rhos6-node2" [ style = dashed] -+"neutron-netns-cleanup-clone_start_0" -> "neutron-netns-cleanup_start_0 rhos6-node3" [ style = dashed] -+"neutron-netns-cleanup-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-netns-cleanup-clone_stop_0" -> "neutron-netns-cleanup-clone_stopped_0" [ style = bold] -+"neutron-netns-cleanup-clone_stop_0" -> "neutron-netns-cleanup_stop_0 rhos6-node1" [ style = bold] -+"neutron-netns-cleanup-clone_stop_0" -> "neutron-netns-cleanup_stop_0 rhos6-node2" [ style = bold] -+"neutron-netns-cleanup-clone_stop_0" -> "neutron-netns-cleanup_stop_0 rhos6-node3" [ style = bold] -+"neutron-netns-cleanup-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-netns-cleanup-clone_stopped_0" -> "neutron-netns-cleanup-clone_start_0" [ style = dashed] -+"neutron-netns-cleanup-clone_stopped_0" -> "neutron-ovs-cleanup-clone_stop_0" [ style = bold] -+"neutron-netns-cleanup-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-netns-cleanup_monitor_10000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-netns-cleanup_monitor_10000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-netns-cleanup_monitor_10000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-netns-cleanup_start_0 rhos6-node1" -> "neutron-netns-cleanup-clone_running_0" [ style = dashed] -+"neutron-netns-cleanup_start_0 rhos6-node1" -> "neutron-netns-cleanup_monitor_10000 rhos6-node1" [ style = dashed] -+"neutron-netns-cleanup_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-netns-cleanup_start_0 rhos6-node2" -> "neutron-netns-cleanup-clone_running_0" [ style = dashed] -+"neutron-netns-cleanup_start_0 rhos6-node2" -> "neutron-netns-cleanup_monitor_10000 rhos6-node2" [ style = dashed] -+"neutron-netns-cleanup_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-netns-cleanup_start_0 rhos6-node3" -> "neutron-netns-cleanup-clone_running_0" [ style = dashed] -+"neutron-netns-cleanup_start_0 rhos6-node3" -> "neutron-netns-cleanup_monitor_10000 rhos6-node3" [ style = dashed] -+"neutron-netns-cleanup_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-netns-cleanup_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node1" -> "neutron-netns-cleanup-clone_stopped_0" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node1" -> "neutron-netns-cleanup_start_0 rhos6-node1" [ style = dashed] -+"neutron-netns-cleanup_stop_0 rhos6-node1" -> "neutron-ovs-cleanup_stop_0 rhos6-node1" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-netns-cleanup_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node2" -> "neutron-netns-cleanup-clone_stopped_0" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node2" -> "neutron-netns-cleanup_start_0 rhos6-node2" [ style = dashed] -+"neutron-netns-cleanup_stop_0 rhos6-node2" -> "neutron-ovs-cleanup_stop_0 rhos6-node2" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-netns-cleanup_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node3" -> "neutron-netns-cleanup-clone_stopped_0" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node3" -> "neutron-netns-cleanup_start_0 rhos6-node3" [ style = dashed] -+"neutron-netns-cleanup_stop_0 rhos6-node3" -> "neutron-ovs-cleanup_stop_0 rhos6-node3" [ style = bold] -+"neutron-netns-cleanup_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-openvswitch-agent-clone_running_0" -> "neutron-dhcp-agent-clone_start_0" [ style = dashed] -+"neutron-openvswitch-agent-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-openvswitch-agent-clone_start_0" -> "neutron-openvswitch-agent-clone_running_0" [ style = dashed] -+"neutron-openvswitch-agent-clone_start_0" -> "neutron-openvswitch-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-openvswitch-agent-clone_start_0" -> "neutron-openvswitch-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-openvswitch-agent-clone_start_0" -> "neutron-openvswitch-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-openvswitch-agent-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-openvswitch-agent-clone_stop_0" -> "neutron-openvswitch-agent-clone_stopped_0" [ style = bold] -+"neutron-openvswitch-agent-clone_stop_0" -> "neutron-openvswitch-agent_stop_0 rhos6-node1" [ style = bold] -+"neutron-openvswitch-agent-clone_stop_0" -> "neutron-openvswitch-agent_stop_0 rhos6-node2" [ style = bold] -+"neutron-openvswitch-agent-clone_stop_0" -> "neutron-openvswitch-agent_stop_0 rhos6-node3" [ style = bold] -+"neutron-openvswitch-agent-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-openvswitch-agent-clone_stopped_0" -> "neutron-netns-cleanup-clone_stop_0" [ style = bold] -+"neutron-openvswitch-agent-clone_stopped_0" -> "neutron-openvswitch-agent-clone_start_0" [ style = dashed] -+"neutron-openvswitch-agent-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-openvswitch-agent_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-openvswitch-agent_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-openvswitch-agent_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-openvswitch-agent_start_0 rhos6-node1" -> "neutron-openvswitch-agent-clone_running_0" [ style = dashed] -+"neutron-openvswitch-agent_start_0 rhos6-node1" -> "neutron-openvswitch-agent_monitor_60000 rhos6-node1" [ style = dashed] -+"neutron-openvswitch-agent_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-openvswitch-agent_start_0 rhos6-node2" -> "neutron-openvswitch-agent-clone_running_0" [ style = dashed] -+"neutron-openvswitch-agent_start_0 rhos6-node2" -> "neutron-openvswitch-agent_monitor_60000 rhos6-node2" [ style = dashed] -+"neutron-openvswitch-agent_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-openvswitch-agent_start_0 rhos6-node3" -> "neutron-openvswitch-agent-clone_running_0" [ style = dashed] -+"neutron-openvswitch-agent_start_0 rhos6-node3" -> "neutron-openvswitch-agent_monitor_60000 rhos6-node3" [ style = dashed] -+"neutron-openvswitch-agent_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-openvswitch-agent_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node1" -> "neutron-netns-cleanup_stop_0 rhos6-node1" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node1" -> "neutron-openvswitch-agent-clone_stopped_0" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node1" -> "neutron-openvswitch-agent_start_0 rhos6-node1" [ style = dashed] -+"neutron-openvswitch-agent_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-openvswitch-agent_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node2" -> "neutron-netns-cleanup_stop_0 rhos6-node2" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node2" -> "neutron-openvswitch-agent-clone_stopped_0" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node2" -> "neutron-openvswitch-agent_start_0 rhos6-node2" [ style = dashed] -+"neutron-openvswitch-agent_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-openvswitch-agent_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node3" -> "neutron-netns-cleanup_stop_0 rhos6-node3" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node3" -> "neutron-openvswitch-agent-clone_stopped_0" [ style = bold] -+"neutron-openvswitch-agent_stop_0 rhos6-node3" -> "neutron-openvswitch-agent_start_0 rhos6-node3" [ style = dashed] -+"neutron-openvswitch-agent_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-ovs-cleanup-clone_running_0" -> "neutron-netns-cleanup-clone_start_0" [ style = dashed] -+"neutron-ovs-cleanup-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-ovs-cleanup-clone_start_0" -> "neutron-ovs-cleanup-clone_running_0" [ style = dashed] -+"neutron-ovs-cleanup-clone_start_0" -> "neutron-ovs-cleanup_start_0 rhos6-node1" [ style = dashed] -+"neutron-ovs-cleanup-clone_start_0" -> "neutron-ovs-cleanup_start_0 rhos6-node2" [ style = dashed] -+"neutron-ovs-cleanup-clone_start_0" -> "neutron-ovs-cleanup_start_0 rhos6-node3" [ style = dashed] -+"neutron-ovs-cleanup-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-ovs-cleanup-clone_stop_0" -> "neutron-ovs-cleanup-clone_stopped_0" [ style = bold] -+"neutron-ovs-cleanup-clone_stop_0" -> "neutron-ovs-cleanup_stop_0 rhos6-node1" [ style = bold] -+"neutron-ovs-cleanup-clone_stop_0" -> "neutron-ovs-cleanup_stop_0 rhos6-node2" [ style = bold] -+"neutron-ovs-cleanup-clone_stop_0" -> "neutron-ovs-cleanup_stop_0 rhos6-node3" [ style = bold] -+"neutron-ovs-cleanup-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-ovs-cleanup-clone_stopped_0" -> "neutron-ovs-cleanup-clone_start_0" [ style = dashed] -+"neutron-ovs-cleanup-clone_stopped_0" -> "neutron-scale-clone_stop_0" [ style = bold] -+"neutron-ovs-cleanup-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-ovs-cleanup_monitor_10000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-ovs-cleanup_monitor_10000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-ovs-cleanup_monitor_10000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-ovs-cleanup_start_0 rhos6-node1" -> "neutron-ovs-cleanup-clone_running_0" [ style = dashed] -+"neutron-ovs-cleanup_start_0 rhos6-node1" -> "neutron-ovs-cleanup_monitor_10000 rhos6-node1" [ style = dashed] -+"neutron-ovs-cleanup_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-ovs-cleanup_start_0 rhos6-node2" -> "neutron-ovs-cleanup-clone_running_0" [ style = dashed] -+"neutron-ovs-cleanup_start_0 rhos6-node2" -> "neutron-ovs-cleanup_monitor_10000 rhos6-node2" [ style = dashed] -+"neutron-ovs-cleanup_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-ovs-cleanup_start_0 rhos6-node3" -> "neutron-ovs-cleanup-clone_running_0" [ style = dashed] -+"neutron-ovs-cleanup_start_0 rhos6-node3" -> "neutron-ovs-cleanup_monitor_10000 rhos6-node3" [ style = dashed] -+"neutron-ovs-cleanup_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-ovs-cleanup_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node1" -> "neutron-ovs-cleanup-clone_stopped_0" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node1" -> "neutron-ovs-cleanup_start_0 rhos6-node1" [ style = dashed] -+"neutron-ovs-cleanup_stop_0 rhos6-node1" -> "neutron-scale:2_stop_0 rhos6-node1" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-ovs-cleanup_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node2" -> "neutron-ovs-cleanup-clone_stopped_0" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node2" -> "neutron-ovs-cleanup_start_0 rhos6-node2" [ style = dashed] -+"neutron-ovs-cleanup_stop_0 rhos6-node2" -> "neutron-scale:1_stop_0 rhos6-node2" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-ovs-cleanup_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node3" -> "neutron-ovs-cleanup-clone_stopped_0" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node3" -> "neutron-ovs-cleanup_start_0 rhos6-node3" [ style = dashed] -+"neutron-ovs-cleanup_stop_0 rhos6-node3" -> "neutron-scale:0_stop_0 rhos6-node3" [ style = bold] -+"neutron-ovs-cleanup_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-scale-clone_running_0" -> "neutron-ovs-cleanup-clone_start_0" [ style = dashed] -+"neutron-scale-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-scale-clone_start_0" -> "neutron-scale-clone_running_0" [ style = dashed] -+"neutron-scale-clone_start_0" -> "neutron-scale:0_start_0 rhos6-node3" [ style = dashed] -+"neutron-scale-clone_start_0" -> "neutron-scale:1_start_0 rhos6-node2" [ style = dashed] -+"neutron-scale-clone_start_0" -> "neutron-scale:2_start_0 rhos6-node1" [ style = dashed] -+"neutron-scale-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-scale-clone_stop_0" -> "neutron-scale-clone_stopped_0" [ style = bold] -+"neutron-scale-clone_stop_0" -> "neutron-scale:0_stop_0 rhos6-node3" [ style = bold] -+"neutron-scale-clone_stop_0" -> "neutron-scale:1_stop_0 rhos6-node2" [ style = bold] -+"neutron-scale-clone_stop_0" -> "neutron-scale:2_stop_0 rhos6-node1" [ style = bold] -+"neutron-scale-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-scale-clone_stopped_0" -> "neutron-scale-clone_start_0" [ style = dashed] -+"neutron-scale-clone_stopped_0" -> "neutron-server-clone_stop_0" [ style = bold] -+"neutron-scale-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-scale:0_monitor_10000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-scale:0_start_0 rhos6-node3" -> "neutron-scale-clone_running_0" [ style = dashed] -+"neutron-scale:0_start_0 rhos6-node3" -> "neutron-scale:0_monitor_10000 rhos6-node3" [ style = dashed] -+"neutron-scale:0_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-scale:0_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-scale:0_stop_0 rhos6-node3" -> "neutron-scale-clone_stopped_0" [ style = bold] -+"neutron-scale:0_stop_0 rhos6-node3" -> "neutron-scale:0_start_0 rhos6-node3" [ style = dashed] -+"neutron-scale:0_stop_0 rhos6-node3" -> "neutron-server_stop_0 rhos6-node3" [ style = bold] -+"neutron-scale:0_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"neutron-scale:1_monitor_10000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-scale:1_start_0 rhos6-node2" -> "neutron-scale-clone_running_0" [ style = dashed] -+"neutron-scale:1_start_0 rhos6-node2" -> "neutron-scale:1_monitor_10000 rhos6-node2" [ style = dashed] -+"neutron-scale:1_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-scale:1_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-scale:1_stop_0 rhos6-node2" -> "neutron-scale-clone_stopped_0" [ style = bold] -+"neutron-scale:1_stop_0 rhos6-node2" -> "neutron-scale:1_start_0 rhos6-node2" [ style = dashed] -+"neutron-scale:1_stop_0 rhos6-node2" -> "neutron-server_stop_0 rhos6-node2" [ style = bold] -+"neutron-scale:1_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-scale:2_monitor_10000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-scale:2_start_0 rhos6-node1" -> "neutron-scale-clone_running_0" [ style = dashed] -+"neutron-scale:2_start_0 rhos6-node1" -> "neutron-scale:2_monitor_10000 rhos6-node1" [ style = dashed] -+"neutron-scale:2_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-scale:2_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-scale:2_stop_0 rhos6-node1" -> "neutron-scale-clone_stopped_0" [ style = bold] -+"neutron-scale:2_stop_0 rhos6-node1" -> "neutron-scale:2_start_0 rhos6-node1" [ style = dashed] -+"neutron-scale:2_stop_0 rhos6-node1" -> "neutron-server_stop_0 rhos6-node1" [ style = bold] -+"neutron-scale:2_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-server-clone_running_0" -> "neutron-scale-clone_start_0" [ style = dashed] -+"neutron-server-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-server-clone_start_0" -> "neutron-server-clone_running_0" [ style = dashed] -+"neutron-server-clone_start_0" -> "neutron-server_start_0 rhos6-node1" [ style = dashed] -+"neutron-server-clone_start_0" -> "neutron-server_start_0 rhos6-node2" [ style = dashed] -+"neutron-server-clone_start_0" -> "neutron-server_start_0 rhos6-node3" [ style = dashed] -+"neutron-server-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"neutron-server-clone_stop_0" -> "neutron-server-clone_stopped_0" [ style = bold] -+"neutron-server-clone_stop_0" -> "neutron-server_stop_0 rhos6-node1" [ style = bold] -+"neutron-server-clone_stop_0" -> "neutron-server_stop_0 rhos6-node2" [ style = bold] -+"neutron-server-clone_stop_0" -> "neutron-server_stop_0 rhos6-node3" [ style = bold] -+"neutron-server-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-server-clone_stopped_0" -> "keystone-clone_stop_0" [ style = bold] -+"neutron-server-clone_stopped_0" -> "neutron-server-clone_start_0" [ style = dashed] -+"neutron-server-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"neutron-server_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-server_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-server_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-server_start_0 rhos6-node1" -> "neutron-server-clone_running_0" [ style = dashed] -+"neutron-server_start_0 rhos6-node1" -> "neutron-server_monitor_60000 rhos6-node1" [ style = dashed] -+"neutron-server_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"neutron-server_start_0 rhos6-node2" -> "neutron-server-clone_running_0" [ style = dashed] -+"neutron-server_start_0 rhos6-node2" -> "neutron-server_monitor_60000 rhos6-node2" [ style = dashed] -+"neutron-server_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"neutron-server_start_0 rhos6-node3" -> "neutron-server-clone_running_0" [ style = dashed] -+"neutron-server_start_0 rhos6-node3" -> "neutron-server_monitor_60000 rhos6-node3" [ style = dashed] -+"neutron-server_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"neutron-server_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"neutron-server_stop_0 rhos6-node1" -> "keystone_stop_0 rhos6-node1" [ style = bold] -+"neutron-server_stop_0 rhos6-node1" -> "neutron-server-clone_stopped_0" [ style = bold] -+"neutron-server_stop_0 rhos6-node1" -> "neutron-server_start_0 rhos6-node1" [ style = dashed] -+"neutron-server_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"neutron-server_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"neutron-server_stop_0 rhos6-node2" -> "keystone_stop_0 rhos6-node2" [ style = bold] -+"neutron-server_stop_0 rhos6-node2" -> "neutron-server-clone_stopped_0" [ style = bold] -+"neutron-server_stop_0 rhos6-node2" -> "neutron-server_start_0 rhos6-node2" [ style = dashed] -+"neutron-server_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"neutron-server_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"neutron-server_stop_0 rhos6-node3" -> "keystone_stop_0 rhos6-node3" [ style = bold] -+"neutron-server_stop_0 rhos6-node3" -> "neutron-server-clone_stopped_0" [ style = bold] -+"neutron-server_stop_0 rhos6-node3" -> "neutron-server_start_0 rhos6-node3" [ style = dashed] -+"neutron-server_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"nova-api-clone_running_0" -> "nova-scheduler-clone_start_0" [ style = dashed] -+"nova-api-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-api-clone_start_0" -> "nova-api-clone_running_0" [ style = dashed] -+"nova-api-clone_start_0" -> "nova-api_start_0 rhos6-node1" [ style = dashed] -+"nova-api-clone_start_0" -> "nova-api_start_0 rhos6-node2" [ style = dashed] -+"nova-api-clone_start_0" -> "nova-api_start_0 rhos6-node3" [ style = dashed] -+"nova-api-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-api-clone_stop_0" -> "nova-api-clone_stopped_0" [ style = bold] -+"nova-api-clone_stop_0" -> "nova-api_stop_0 rhos6-node1" [ style = bold] -+"nova-api-clone_stop_0" -> "nova-api_stop_0 rhos6-node2" [ style = bold] -+"nova-api-clone_stop_0" -> "nova-api_stop_0 rhos6-node3" [ style = bold] -+"nova-api-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"nova-api-clone_stopped_0" -> "nova-api-clone_start_0" [ style = dashed] -+"nova-api-clone_stopped_0" -> "nova-novncproxy-clone_stop_0" [ style = bold] -+"nova-api-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"nova-api_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-api_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-api_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-api_start_0 rhos6-node1" -> "nova-api-clone_running_0" [ style = dashed] -+"nova-api_start_0 rhos6-node1" -> "nova-api_monitor_60000 rhos6-node1" [ style = dashed] -+"nova-api_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-api_start_0 rhos6-node2" -> "nova-api-clone_running_0" [ style = dashed] -+"nova-api_start_0 rhos6-node2" -> "nova-api_monitor_60000 rhos6-node2" [ style = dashed] -+"nova-api_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-api_start_0 rhos6-node3" -> "nova-api-clone_running_0" [ style = dashed] -+"nova-api_start_0 rhos6-node3" -> "nova-api_monitor_60000 rhos6-node3" [ style = dashed] -+"nova-api_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-api_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"nova-api_stop_0 rhos6-node1" -> "nova-api-clone_stopped_0" [ style = bold] -+"nova-api_stop_0 rhos6-node1" -> "nova-api_start_0 rhos6-node1" [ style = dashed] -+"nova-api_stop_0 rhos6-node1" -> "nova-novncproxy_stop_0 rhos6-node1" [ style = bold] -+"nova-api_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"nova-api_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"nova-api_stop_0 rhos6-node2" -> "nova-api-clone_stopped_0" [ style = bold] -+"nova-api_stop_0 rhos6-node2" -> "nova-api_start_0 rhos6-node2" [ style = dashed] -+"nova-api_stop_0 rhos6-node2" -> "nova-novncproxy_stop_0 rhos6-node2" [ style = bold] -+"nova-api_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"nova-api_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"nova-api_stop_0 rhos6-node3" -> "nova-api-clone_stopped_0" [ style = bold] -+"nova-api_stop_0 rhos6-node3" -> "nova-api_start_0 rhos6-node3" [ style = dashed] -+"nova-api_stop_0 rhos6-node3" -> "nova-novncproxy_stop_0 rhos6-node3" [ style = bold] -+"nova-api_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"nova-conductor-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-conductor-clone_start_0" -> "nova-conductor-clone_running_0" [ style = dashed] -+"nova-conductor-clone_start_0" -> "nova-conductor_start_0 rhos6-node1" [ style = dashed] -+"nova-conductor-clone_start_0" -> "nova-conductor_start_0 rhos6-node2" [ style = dashed] -+"nova-conductor-clone_start_0" -> "nova-conductor_start_0 rhos6-node3" [ style = dashed] -+"nova-conductor-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-conductor-clone_stop_0" -> "nova-conductor-clone_stopped_0" [ style = bold] -+"nova-conductor-clone_stop_0" -> "nova-conductor_stop_0 rhos6-node1" [ style = bold] -+"nova-conductor-clone_stop_0" -> "nova-conductor_stop_0 rhos6-node2" [ style = bold] -+"nova-conductor-clone_stop_0" -> "nova-conductor_stop_0 rhos6-node3" [ style = bold] -+"nova-conductor-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"nova-conductor-clone_stopped_0" -> "nova-conductor-clone_start_0" [ style = dashed] -+"nova-conductor-clone_stopped_0" -> "nova-scheduler-clone_stop_0" [ style = bold] -+"nova-conductor-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"nova-conductor_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-conductor_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-conductor_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-conductor_start_0 rhos6-node1" -> "nova-conductor-clone_running_0" [ style = dashed] -+"nova-conductor_start_0 rhos6-node1" -> "nova-conductor_monitor_60000 rhos6-node1" [ style = dashed] -+"nova-conductor_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-conductor_start_0 rhos6-node2" -> "nova-conductor-clone_running_0" [ style = dashed] -+"nova-conductor_start_0 rhos6-node2" -> "nova-conductor_monitor_60000 rhos6-node2" [ style = dashed] -+"nova-conductor_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-conductor_start_0 rhos6-node3" -> "nova-conductor-clone_running_0" [ style = dashed] -+"nova-conductor_start_0 rhos6-node3" -> "nova-conductor_monitor_60000 rhos6-node3" [ style = dashed] -+"nova-conductor_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-conductor_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"nova-conductor_stop_0 rhos6-node1" -> "nova-conductor-clone_stopped_0" [ style = bold] -+"nova-conductor_stop_0 rhos6-node1" -> "nova-conductor_start_0 rhos6-node1" [ style = dashed] -+"nova-conductor_stop_0 rhos6-node1" -> "nova-scheduler_stop_0 rhos6-node1" [ style = bold] -+"nova-conductor_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"nova-conductor_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"nova-conductor_stop_0 rhos6-node2" -> "nova-conductor-clone_stopped_0" [ style = bold] -+"nova-conductor_stop_0 rhos6-node2" -> "nova-conductor_start_0 rhos6-node2" [ style = dashed] -+"nova-conductor_stop_0 rhos6-node2" -> "nova-scheduler_stop_0 rhos6-node2" [ style = bold] -+"nova-conductor_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"nova-conductor_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"nova-conductor_stop_0 rhos6-node3" -> "nova-conductor-clone_stopped_0" [ style = bold] -+"nova-conductor_stop_0 rhos6-node3" -> "nova-conductor_start_0 rhos6-node3" [ style = dashed] -+"nova-conductor_stop_0 rhos6-node3" -> "nova-scheduler_stop_0 rhos6-node3" [ style = bold] -+"nova-conductor_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"nova-consoleauth-clone_running_0" -> "nova-novncproxy-clone_start_0" [ style = dashed] -+"nova-consoleauth-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-consoleauth-clone_start_0" -> "nova-consoleauth-clone_running_0" [ style = dashed] -+"nova-consoleauth-clone_start_0" -> "nova-consoleauth_start_0 rhos6-node1" [ style = dashed] -+"nova-consoleauth-clone_start_0" -> "nova-consoleauth_start_0 rhos6-node2" [ style = dashed] -+"nova-consoleauth-clone_start_0" -> "nova-consoleauth_start_0 rhos6-node3" [ style = dashed] -+"nova-consoleauth-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-consoleauth-clone_stop_0" -> "nova-consoleauth-clone_stopped_0" [ style = bold] -+"nova-consoleauth-clone_stop_0" -> "nova-consoleauth_stop_0 rhos6-node1" [ style = bold] -+"nova-consoleauth-clone_stop_0" -> "nova-consoleauth_stop_0 rhos6-node2" [ style = bold] -+"nova-consoleauth-clone_stop_0" -> "nova-consoleauth_stop_0 rhos6-node3" [ style = bold] -+"nova-consoleauth-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"nova-consoleauth-clone_stopped_0" -> "keystone-clone_stop_0" [ style = bold] -+"nova-consoleauth-clone_stopped_0" -> "nova-consoleauth-clone_start_0" [ style = dashed] -+"nova-consoleauth-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"nova-consoleauth_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-consoleauth_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-consoleauth_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-consoleauth_start_0 rhos6-node1" -> "nova-consoleauth-clone_running_0" [ style = dashed] -+"nova-consoleauth_start_0 rhos6-node1" -> "nova-consoleauth_monitor_60000 rhos6-node1" [ style = dashed] -+"nova-consoleauth_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-consoleauth_start_0 rhos6-node2" -> "nova-consoleauth-clone_running_0" [ style = dashed] -+"nova-consoleauth_start_0 rhos6-node2" -> "nova-consoleauth_monitor_60000 rhos6-node2" [ style = dashed] -+"nova-consoleauth_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-consoleauth_start_0 rhos6-node3" -> "nova-consoleauth-clone_running_0" [ style = dashed] -+"nova-consoleauth_start_0 rhos6-node3" -> "nova-consoleauth_monitor_60000 rhos6-node3" [ style = dashed] -+"nova-consoleauth_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-consoleauth_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node1" -> "keystone_stop_0 rhos6-node1" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node1" -> "nova-consoleauth-clone_stopped_0" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node1" -> "nova-consoleauth_start_0 rhos6-node1" [ style = dashed] -+"nova-consoleauth_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"nova-consoleauth_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node2" -> "keystone_stop_0 rhos6-node2" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node2" -> "nova-consoleauth-clone_stopped_0" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node2" -> "nova-consoleauth_start_0 rhos6-node2" [ style = dashed] -+"nova-consoleauth_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"nova-consoleauth_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node3" -> "keystone_stop_0 rhos6-node3" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node3" -> "nova-consoleauth-clone_stopped_0" [ style = bold] -+"nova-consoleauth_stop_0 rhos6-node3" -> "nova-consoleauth_start_0 rhos6-node3" [ style = dashed] -+"nova-consoleauth_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"nova-novncproxy-clone_running_0" -> "nova-api-clone_start_0" [ style = dashed] -+"nova-novncproxy-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-novncproxy-clone_start_0" -> "nova-novncproxy-clone_running_0" [ style = dashed] -+"nova-novncproxy-clone_start_0" -> "nova-novncproxy_start_0 rhos6-node1" [ style = dashed] -+"nova-novncproxy-clone_start_0" -> "nova-novncproxy_start_0 rhos6-node2" [ style = dashed] -+"nova-novncproxy-clone_start_0" -> "nova-novncproxy_start_0 rhos6-node3" [ style = dashed] -+"nova-novncproxy-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-novncproxy-clone_stop_0" -> "nova-novncproxy-clone_stopped_0" [ style = bold] -+"nova-novncproxy-clone_stop_0" -> "nova-novncproxy_stop_0 rhos6-node1" [ style = bold] -+"nova-novncproxy-clone_stop_0" -> "nova-novncproxy_stop_0 rhos6-node2" [ style = bold] -+"nova-novncproxy-clone_stop_0" -> "nova-novncproxy_stop_0 rhos6-node3" [ style = bold] -+"nova-novncproxy-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"nova-novncproxy-clone_stopped_0" -> "nova-consoleauth-clone_stop_0" [ style = bold] -+"nova-novncproxy-clone_stopped_0" -> "nova-novncproxy-clone_start_0" [ style = dashed] -+"nova-novncproxy-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"nova-novncproxy_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-novncproxy_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-novncproxy_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-novncproxy_start_0 rhos6-node1" -> "nova-novncproxy-clone_running_0" [ style = dashed] -+"nova-novncproxy_start_0 rhos6-node1" -> "nova-novncproxy_monitor_60000 rhos6-node1" [ style = dashed] -+"nova-novncproxy_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-novncproxy_start_0 rhos6-node2" -> "nova-novncproxy-clone_running_0" [ style = dashed] -+"nova-novncproxy_start_0 rhos6-node2" -> "nova-novncproxy_monitor_60000 rhos6-node2" [ style = dashed] -+"nova-novncproxy_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-novncproxy_start_0 rhos6-node3" -> "nova-novncproxy-clone_running_0" [ style = dashed] -+"nova-novncproxy_start_0 rhos6-node3" -> "nova-novncproxy_monitor_60000 rhos6-node3" [ style = dashed] -+"nova-novncproxy_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-novncproxy_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node1" -> "nova-consoleauth_stop_0 rhos6-node1" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node1" -> "nova-novncproxy-clone_stopped_0" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node1" -> "nova-novncproxy_start_0 rhos6-node1" [ style = dashed] -+"nova-novncproxy_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"nova-novncproxy_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node2" -> "nova-consoleauth_stop_0 rhos6-node2" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node2" -> "nova-novncproxy-clone_stopped_0" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node2" -> "nova-novncproxy_start_0 rhos6-node2" [ style = dashed] -+"nova-novncproxy_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"nova-novncproxy_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node3" -> "nova-consoleauth_stop_0 rhos6-node3" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node3" -> "nova-novncproxy-clone_stopped_0" [ style = bold] -+"nova-novncproxy_stop_0 rhos6-node3" -> "nova-novncproxy_start_0 rhos6-node3" [ style = dashed] -+"nova-novncproxy_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"nova-scheduler-clone_running_0" -> "nova-conductor-clone_start_0" [ style = dashed] -+"nova-scheduler-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-scheduler-clone_start_0" -> "nova-scheduler-clone_running_0" [ style = dashed] -+"nova-scheduler-clone_start_0" -> "nova-scheduler_start_0 rhos6-node1" [ style = dashed] -+"nova-scheduler-clone_start_0" -> "nova-scheduler_start_0 rhos6-node2" [ style = dashed] -+"nova-scheduler-clone_start_0" -> "nova-scheduler_start_0 rhos6-node3" [ style = dashed] -+"nova-scheduler-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"nova-scheduler-clone_stop_0" -> "nova-scheduler-clone_stopped_0" [ style = bold] -+"nova-scheduler-clone_stop_0" -> "nova-scheduler_stop_0 rhos6-node1" [ style = bold] -+"nova-scheduler-clone_stop_0" -> "nova-scheduler_stop_0 rhos6-node2" [ style = bold] -+"nova-scheduler-clone_stop_0" -> "nova-scheduler_stop_0 rhos6-node3" [ style = bold] -+"nova-scheduler-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"nova-scheduler-clone_stopped_0" -> "nova-api-clone_stop_0" [ style = bold] -+"nova-scheduler-clone_stopped_0" -> "nova-scheduler-clone_start_0" [ style = dashed] -+"nova-scheduler-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"nova-scheduler_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-scheduler_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-scheduler_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-scheduler_start_0 rhos6-node1" -> "nova-scheduler-clone_running_0" [ style = dashed] -+"nova-scheduler_start_0 rhos6-node1" -> "nova-scheduler_monitor_60000 rhos6-node1" [ style = dashed] -+"nova-scheduler_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"nova-scheduler_start_0 rhos6-node2" -> "nova-scheduler-clone_running_0" [ style = dashed] -+"nova-scheduler_start_0 rhos6-node2" -> "nova-scheduler_monitor_60000 rhos6-node2" [ style = dashed] -+"nova-scheduler_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"nova-scheduler_start_0 rhos6-node3" -> "nova-scheduler-clone_running_0" [ style = dashed] -+"nova-scheduler_start_0 rhos6-node3" -> "nova-scheduler_monitor_60000 rhos6-node3" [ style = dashed] -+"nova-scheduler_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"nova-scheduler_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node1" -> "nova-api_stop_0 rhos6-node1" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node1" -> "nova-scheduler-clone_stopped_0" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node1" -> "nova-scheduler_start_0 rhos6-node1" [ style = dashed] -+"nova-scheduler_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"nova-scheduler_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node2" -> "nova-api_stop_0 rhos6-node2" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node2" -> "nova-scheduler-clone_stopped_0" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node2" -> "nova-scheduler_start_0 rhos6-node2" [ style = dashed] -+"nova-scheduler_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"nova-scheduler_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node3" -> "nova-api_stop_0 rhos6-node3" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node3" -> "nova-scheduler-clone_stopped_0" [ style = bold] -+"nova-scheduler_stop_0 rhos6-node3" -> "nova-scheduler_start_0 rhos6-node3" [ style = dashed] -+"nova-scheduler_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"swift-account-clone_running_0" -> "swift-container-clone_start_0" [ style = dashed] -+"swift-account-clone_running_0" -> "swift-proxy-clone_start_0" [ style = dashed] -+"swift-account-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-account-clone_start_0" -> "swift-account-clone_running_0" [ style = dashed] -+"swift-account-clone_start_0" -> "swift-account_start_0 rhos6-node1" [ style = dashed] -+"swift-account-clone_start_0" -> "swift-account_start_0 rhos6-node2" [ style = dashed] -+"swift-account-clone_start_0" -> "swift-account_start_0 rhos6-node3" [ style = dashed] -+"swift-account-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-account-clone_stop_0" -> "swift-account-clone_stopped_0" [ style = bold] -+"swift-account-clone_stop_0" -> "swift-account_stop_0 rhos6-node1" [ style = bold] -+"swift-account-clone_stop_0" -> "swift-account_stop_0 rhos6-node2" [ style = bold] -+"swift-account-clone_stop_0" -> "swift-account_stop_0 rhos6-node3" [ style = bold] -+"swift-account-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"swift-account-clone_stopped_0" -> "keystone-clone_stop_0" [ style = bold] -+"swift-account-clone_stopped_0" -> "swift-account-clone_start_0" [ style = dashed] -+"swift-account-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"swift-account_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-account_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-account_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-account_start_0 rhos6-node1" -> "swift-account-clone_running_0" [ style = dashed] -+"swift-account_start_0 rhos6-node1" -> "swift-account_monitor_60000 rhos6-node1" [ style = dashed] -+"swift-account_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-account_start_0 rhos6-node2" -> "swift-account-clone_running_0" [ style = dashed] -+"swift-account_start_0 rhos6-node2" -> "swift-account_monitor_60000 rhos6-node2" [ style = dashed] -+"swift-account_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-account_start_0 rhos6-node3" -> "swift-account-clone_running_0" [ style = dashed] -+"swift-account_start_0 rhos6-node3" -> "swift-account_monitor_60000 rhos6-node3" [ style = dashed] -+"swift-account_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-account_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"swift-account_stop_0 rhos6-node1" -> "keystone_stop_0 rhos6-node1" [ style = bold] -+"swift-account_stop_0 rhos6-node1" -> "swift-account-clone_stopped_0" [ style = bold] -+"swift-account_stop_0 rhos6-node1" -> "swift-account_start_0 rhos6-node1" [ style = dashed] -+"swift-account_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"swift-account_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"swift-account_stop_0 rhos6-node2" -> "keystone_stop_0 rhos6-node2" [ style = bold] -+"swift-account_stop_0 rhos6-node2" -> "swift-account-clone_stopped_0" [ style = bold] -+"swift-account_stop_0 rhos6-node2" -> "swift-account_start_0 rhos6-node2" [ style = dashed] -+"swift-account_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"swift-account_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"swift-account_stop_0 rhos6-node3" -> "keystone_stop_0 rhos6-node3" [ style = bold] -+"swift-account_stop_0 rhos6-node3" -> "swift-account-clone_stopped_0" [ style = bold] -+"swift-account_stop_0 rhos6-node3" -> "swift-account_start_0 rhos6-node3" [ style = dashed] -+"swift-account_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"swift-container-clone_running_0" -> "swift-object-clone_start_0" [ style = dashed] -+"swift-container-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-container-clone_start_0" -> "swift-container-clone_running_0" [ style = dashed] -+"swift-container-clone_start_0" -> "swift-container_start_0 rhos6-node1" [ style = dashed] -+"swift-container-clone_start_0" -> "swift-container_start_0 rhos6-node2" [ style = dashed] -+"swift-container-clone_start_0" -> "swift-container_start_0 rhos6-node3" [ style = dashed] -+"swift-container-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-container-clone_stop_0" -> "swift-container-clone_stopped_0" [ style = bold] -+"swift-container-clone_stop_0" -> "swift-container_stop_0 rhos6-node1" [ style = bold] -+"swift-container-clone_stop_0" -> "swift-container_stop_0 rhos6-node2" [ style = bold] -+"swift-container-clone_stop_0" -> "swift-container_stop_0 rhos6-node3" [ style = bold] -+"swift-container-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"swift-container-clone_stopped_0" -> "swift-account-clone_stop_0" [ style = bold] -+"swift-container-clone_stopped_0" -> "swift-container-clone_start_0" [ style = dashed] -+"swift-container-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"swift-container_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-container_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-container_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-container_start_0 rhos6-node1" -> "swift-container-clone_running_0" [ style = dashed] -+"swift-container_start_0 rhos6-node1" -> "swift-container_monitor_60000 rhos6-node1" [ style = dashed] -+"swift-container_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-container_start_0 rhos6-node2" -> "swift-container-clone_running_0" [ style = dashed] -+"swift-container_start_0 rhos6-node2" -> "swift-container_monitor_60000 rhos6-node2" [ style = dashed] -+"swift-container_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-container_start_0 rhos6-node3" -> "swift-container-clone_running_0" [ style = dashed] -+"swift-container_start_0 rhos6-node3" -> "swift-container_monitor_60000 rhos6-node3" [ style = dashed] -+"swift-container_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-container_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"swift-container_stop_0 rhos6-node1" -> "swift-account_stop_0 rhos6-node1" [ style = bold] -+"swift-container_stop_0 rhos6-node1" -> "swift-container-clone_stopped_0" [ style = bold] -+"swift-container_stop_0 rhos6-node1" -> "swift-container_start_0 rhos6-node1" [ style = dashed] -+"swift-container_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"swift-container_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"swift-container_stop_0 rhos6-node2" -> "swift-account_stop_0 rhos6-node2" [ style = bold] -+"swift-container_stop_0 rhos6-node2" -> "swift-container-clone_stopped_0" [ style = bold] -+"swift-container_stop_0 rhos6-node2" -> "swift-container_start_0 rhos6-node2" [ style = dashed] -+"swift-container_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"swift-container_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"swift-container_stop_0 rhos6-node3" -> "swift-account_stop_0 rhos6-node3" [ style = bold] -+"swift-container_stop_0 rhos6-node3" -> "swift-container-clone_stopped_0" [ style = bold] -+"swift-container_stop_0 rhos6-node3" -> "swift-container_start_0 rhos6-node3" [ style = dashed] -+"swift-container_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"swift-object-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-object-clone_start_0" -> "swift-object-clone_running_0" [ style = dashed] -+"swift-object-clone_start_0" -> "swift-object_start_0 rhos6-node1" [ style = dashed] -+"swift-object-clone_start_0" -> "swift-object_start_0 rhos6-node2" [ style = dashed] -+"swift-object-clone_start_0" -> "swift-object_start_0 rhos6-node3" [ style = dashed] -+"swift-object-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-object-clone_stop_0" -> "swift-object-clone_stopped_0" [ style = bold] -+"swift-object-clone_stop_0" -> "swift-object_stop_0 rhos6-node1" [ style = bold] -+"swift-object-clone_stop_0" -> "swift-object_stop_0 rhos6-node2" [ style = bold] -+"swift-object-clone_stop_0" -> "swift-object_stop_0 rhos6-node3" [ style = bold] -+"swift-object-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"swift-object-clone_stopped_0" -> "swift-container-clone_stop_0" [ style = bold] -+"swift-object-clone_stopped_0" -> "swift-object-clone_start_0" [ style = dashed] -+"swift-object-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"swift-object-expirer_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-object-expirer_start_0 rhos6-node2" -> "swift-object-expirer_monitor_60000 rhos6-node2" [ style = dashed] -+"swift-object-expirer_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-object-expirer_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"swift-object-expirer_stop_0 rhos6-node2" -> "swift-object-expirer_start_0 rhos6-node2" [ style = dashed] -+"swift-object-expirer_stop_0 rhos6-node2" -> "swift-proxy-clone_stop_0" [ style = bold] -+"swift-object-expirer_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"swift-object_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-object_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-object_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-object_start_0 rhos6-node1" -> "swift-object-clone_running_0" [ style = dashed] -+"swift-object_start_0 rhos6-node1" -> "swift-object_monitor_60000 rhos6-node1" [ style = dashed] -+"swift-object_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-object_start_0 rhos6-node2" -> "swift-object-clone_running_0" [ style = dashed] -+"swift-object_start_0 rhos6-node2" -> "swift-object_monitor_60000 rhos6-node2" [ style = dashed] -+"swift-object_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-object_start_0 rhos6-node3" -> "swift-object-clone_running_0" [ style = dashed] -+"swift-object_start_0 rhos6-node3" -> "swift-object_monitor_60000 rhos6-node3" [ style = dashed] -+"swift-object_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-object_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"swift-object_stop_0 rhos6-node1" -> "swift-container_stop_0 rhos6-node1" [ style = bold] -+"swift-object_stop_0 rhos6-node1" -> "swift-object-clone_stopped_0" [ style = bold] -+"swift-object_stop_0 rhos6-node1" -> "swift-object_start_0 rhos6-node1" [ style = dashed] -+"swift-object_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"swift-object_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"swift-object_stop_0 rhos6-node2" -> "swift-container_stop_0 rhos6-node2" [ style = bold] -+"swift-object_stop_0 rhos6-node2" -> "swift-object-clone_stopped_0" [ style = bold] -+"swift-object_stop_0 rhos6-node2" -> "swift-object_start_0 rhos6-node2" [ style = dashed] -+"swift-object_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"swift-object_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"swift-object_stop_0 rhos6-node3" -> "swift-container_stop_0 rhos6-node3" [ style = bold] -+"swift-object_stop_0 rhos6-node3" -> "swift-object-clone_stopped_0" [ style = bold] -+"swift-object_stop_0 rhos6-node3" -> "swift-object_start_0 rhos6-node3" [ style = dashed] -+"swift-object_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+"swift-proxy-clone_running_0" -> "swift-object-expirer_start_0 rhos6-node2" [ style = dashed] -+"swift-proxy-clone_running_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-proxy-clone_start_0" -> "swift-proxy-clone_running_0" [ style = dashed] -+"swift-proxy-clone_start_0" -> "swift-proxy_start_0 rhos6-node1" [ style = dashed] -+"swift-proxy-clone_start_0" -> "swift-proxy_start_0 rhos6-node2" [ style = dashed] -+"swift-proxy-clone_start_0" -> "swift-proxy_start_0 rhos6-node3" [ style = dashed] -+"swift-proxy-clone_start_0" [ style=dashed color="red" fontcolor="orange"] -+"swift-proxy-clone_stop_0" -> "swift-proxy-clone_stopped_0" [ style = bold] -+"swift-proxy-clone_stop_0" -> "swift-proxy_stop_0 rhos6-node1" [ style = bold] -+"swift-proxy-clone_stop_0" -> "swift-proxy_stop_0 rhos6-node2" [ style = bold] -+"swift-proxy-clone_stop_0" -> "swift-proxy_stop_0 rhos6-node3" [ style = bold] -+"swift-proxy-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"swift-proxy-clone_stopped_0" -> "swift-account-clone_stop_0" [ style = bold] -+"swift-proxy-clone_stopped_0" -> "swift-proxy-clone_start_0" [ style = dashed] -+"swift-proxy-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"swift-proxy_monitor_60000 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-proxy_monitor_60000 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-proxy_monitor_60000 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-proxy_start_0 rhos6-node1" -> "swift-proxy-clone_running_0" [ style = dashed] -+"swift-proxy_start_0 rhos6-node1" -> "swift-proxy_monitor_60000 rhos6-node1" [ style = dashed] -+"swift-proxy_start_0 rhos6-node1" [ style=dashed color="red" fontcolor="black"] -+"swift-proxy_start_0 rhos6-node2" -> "swift-proxy-clone_running_0" [ style = dashed] -+"swift-proxy_start_0 rhos6-node2" -> "swift-proxy_monitor_60000 rhos6-node2" [ style = dashed] -+"swift-proxy_start_0 rhos6-node2" [ style=dashed color="red" fontcolor="black"] -+"swift-proxy_start_0 rhos6-node3" -> "swift-proxy-clone_running_0" [ style = dashed] -+"swift-proxy_start_0 rhos6-node3" -> "swift-proxy_monitor_60000 rhos6-node3" [ style = dashed] -+"swift-proxy_start_0 rhos6-node3" [ style=dashed color="red" fontcolor="black"] -+"swift-proxy_stop_0 rhos6-node1" -> "all_stopped" [ style = bold] -+"swift-proxy_stop_0 rhos6-node1" -> "swift-account_stop_0 rhos6-node1" [ style = bold] -+"swift-proxy_stop_0 rhos6-node1" -> "swift-proxy-clone_stopped_0" [ style = bold] -+"swift-proxy_stop_0 rhos6-node1" -> "swift-proxy_start_0 rhos6-node1" [ style = dashed] -+"swift-proxy_stop_0 rhos6-node1" [ style=bold color="green" fontcolor="black"] -+"swift-proxy_stop_0 rhos6-node2" -> "all_stopped" [ style = bold] -+"swift-proxy_stop_0 rhos6-node2" -> "swift-account_stop_0 rhos6-node2" [ style = bold] -+"swift-proxy_stop_0 rhos6-node2" -> "swift-proxy-clone_stopped_0" [ style = bold] -+"swift-proxy_stop_0 rhos6-node2" -> "swift-proxy_start_0 rhos6-node2" [ style = dashed] -+"swift-proxy_stop_0 rhos6-node2" [ style=bold color="green" fontcolor="black"] -+"swift-proxy_stop_0 rhos6-node3" -> "all_stopped" [ style = bold] -+"swift-proxy_stop_0 rhos6-node3" -> "swift-account_stop_0 rhos6-node3" [ style = bold] -+"swift-proxy_stop_0 rhos6-node3" -> "swift-proxy-clone_stopped_0" [ style = bold] -+"swift-proxy_stop_0 rhos6-node3" -> "swift-proxy_start_0 rhos6-node3" [ style = dashed] -+"swift-proxy_stop_0 rhos6-node3" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/complex_enforce_colo.exp b/pengine/test10/complex_enforce_colo.exp -new file mode 100644 -index 0000000..c19c433 ---- /dev/null -+++ b/pengine/test10/complex_enforce_colo.exp -@@ -0,0 +1,2689 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/complex_enforce_colo.scores b/pengine/test10/complex_enforce_colo.scores -new file mode 100644 -index 0000000..9394084 ---- /dev/null -+++ b/pengine/test10/complex_enforce_colo.scores -@@ -0,0 +1,844 @@ -+Allocation scores: -+clone_color: ceilometer-alarm-evaluator-clone allocation score on rhos6-node1: 0 -+clone_color: ceilometer-alarm-evaluator-clone allocation score on rhos6-node2: 0 -+clone_color: ceilometer-alarm-evaluator-clone allocation score on rhos6-node3: 0 -+clone_color: ceilometer-alarm-evaluator:0 allocation score on rhos6-node1: 1 -+clone_color: ceilometer-alarm-evaluator:0 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-alarm-evaluator:0 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-alarm-evaluator:1 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-alarm-evaluator:1 allocation score on rhos6-node2: 1 -+clone_color: ceilometer-alarm-evaluator:1 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-alarm-evaluator:2 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-alarm-evaluator:2 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-alarm-evaluator:2 allocation score on rhos6-node3: 1 -+clone_color: ceilometer-alarm-notifier-clone allocation score on rhos6-node1: 0 -+clone_color: ceilometer-alarm-notifier-clone allocation score on rhos6-node2: 0 -+clone_color: ceilometer-alarm-notifier-clone allocation score on rhos6-node3: 0 -+clone_color: ceilometer-alarm-notifier:0 allocation score on rhos6-node1: 1 -+clone_color: ceilometer-alarm-notifier:0 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-alarm-notifier:0 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-alarm-notifier:1 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-alarm-notifier:1 allocation score on rhos6-node2: 1 -+clone_color: ceilometer-alarm-notifier:1 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-alarm-notifier:2 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-alarm-notifier:2 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-alarm-notifier:2 allocation score on rhos6-node3: 1 -+clone_color: ceilometer-api-clone allocation score on rhos6-node1: 0 -+clone_color: ceilometer-api-clone allocation score on rhos6-node2: 0 -+clone_color: ceilometer-api-clone allocation score on rhos6-node3: 0 -+clone_color: ceilometer-api:0 allocation score on rhos6-node1: 1 -+clone_color: ceilometer-api:0 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-api:0 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-api:1 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-api:1 allocation score on rhos6-node2: 1 -+clone_color: ceilometer-api:1 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-api:2 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-api:2 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-api:2 allocation score on rhos6-node3: 1 -+clone_color: ceilometer-collector-clone allocation score on rhos6-node1: 0 -+clone_color: ceilometer-collector-clone allocation score on rhos6-node2: 0 -+clone_color: ceilometer-collector-clone allocation score on rhos6-node3: 0 -+clone_color: ceilometer-collector:0 allocation score on rhos6-node1: 1 -+clone_color: ceilometer-collector:0 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-collector:0 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-collector:1 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-collector:1 allocation score on rhos6-node2: 1 -+clone_color: ceilometer-collector:1 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-collector:2 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-collector:2 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-collector:2 allocation score on rhos6-node3: 1 -+clone_color: ceilometer-delay-clone allocation score on rhos6-node1: 0 -+clone_color: ceilometer-delay-clone allocation score on rhos6-node2: 0 -+clone_color: ceilometer-delay-clone allocation score on rhos6-node3: 0 -+clone_color: ceilometer-delay:0 allocation score on rhos6-node1: 1 -+clone_color: ceilometer-delay:0 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-delay:0 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-delay:1 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-delay:1 allocation score on rhos6-node2: 1 -+clone_color: ceilometer-delay:1 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-delay:2 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-delay:2 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-delay:2 allocation score on rhos6-node3: 1 -+clone_color: ceilometer-notification-clone allocation score on rhos6-node1: 0 -+clone_color: ceilometer-notification-clone allocation score on rhos6-node2: 0 -+clone_color: ceilometer-notification-clone allocation score on rhos6-node3: 0 -+clone_color: ceilometer-notification:0 allocation score on rhos6-node1: 1 -+clone_color: ceilometer-notification:0 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-notification:0 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-notification:1 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-notification:1 allocation score on rhos6-node2: 1 -+clone_color: ceilometer-notification:1 allocation score on rhos6-node3: 0 -+clone_color: ceilometer-notification:2 allocation score on rhos6-node1: 0 -+clone_color: ceilometer-notification:2 allocation score on rhos6-node2: 0 -+clone_color: ceilometer-notification:2 allocation score on rhos6-node3: 1 -+clone_color: galera-master allocation score on rhos6-node1: 0 -+clone_color: galera-master allocation score on rhos6-node2: 0 -+clone_color: galera-master allocation score on rhos6-node3: 0 -+clone_color: galera:0 allocation score on rhos6-node1: 101 -+clone_color: galera:0 allocation score on rhos6-node2: 0 -+clone_color: galera:0 allocation score on rhos6-node3: 0 -+clone_color: galera:1 allocation score on rhos6-node1: 0 -+clone_color: galera:1 allocation score on rhos6-node2: 101 -+clone_color: galera:1 allocation score on rhos6-node3: 0 -+clone_color: galera:2 allocation score on rhos6-node1: 0 -+clone_color: galera:2 allocation score on rhos6-node2: 0 -+clone_color: galera:2 allocation score on rhos6-node3: 101 -+clone_color: glance-api-clone allocation score on rhos6-node1: 0 -+clone_color: glance-api-clone allocation score on rhos6-node2: 0 -+clone_color: glance-api-clone allocation score on rhos6-node3: 0 -+clone_color: glance-api:0 allocation score on rhos6-node1: 1 -+clone_color: glance-api:0 allocation score on rhos6-node2: 0 -+clone_color: glance-api:0 allocation score on rhos6-node3: 0 -+clone_color: glance-api:1 allocation score on rhos6-node1: 0 -+clone_color: glance-api:1 allocation score on rhos6-node2: 1 -+clone_color: glance-api:1 allocation score on rhos6-node3: 0 -+clone_color: glance-api:2 allocation score on rhos6-node1: 0 -+clone_color: glance-api:2 allocation score on rhos6-node2: 0 -+clone_color: glance-api:2 allocation score on rhos6-node3: 1 -+clone_color: glance-fs-clone allocation score on rhos6-node1: 0 -+clone_color: glance-fs-clone allocation score on rhos6-node2: 0 -+clone_color: glance-fs-clone allocation score on rhos6-node3: 0 -+clone_color: glance-fs:0 allocation score on rhos6-node1: 1 -+clone_color: glance-fs:0 allocation score on rhos6-node2: 0 -+clone_color: glance-fs:0 allocation score on rhos6-node3: 0 -+clone_color: glance-fs:1 allocation score on rhos6-node1: 0 -+clone_color: glance-fs:1 allocation score on rhos6-node2: 1 -+clone_color: glance-fs:1 allocation score on rhos6-node3: 0 -+clone_color: glance-fs:2 allocation score on rhos6-node1: 0 -+clone_color: glance-fs:2 allocation score on rhos6-node2: 0 -+clone_color: glance-fs:2 allocation score on rhos6-node3: 1 -+clone_color: glance-registry-clone allocation score on rhos6-node1: 0 -+clone_color: glance-registry-clone allocation score on rhos6-node2: 0 -+clone_color: glance-registry-clone allocation score on rhos6-node3: 0 -+clone_color: glance-registry:0 allocation score on rhos6-node1: 1 -+clone_color: glance-registry:0 allocation score on rhos6-node2: 0 -+clone_color: glance-registry:0 allocation score on rhos6-node3: 0 -+clone_color: glance-registry:1 allocation score on rhos6-node1: 0 -+clone_color: glance-registry:1 allocation score on rhos6-node2: 1 -+clone_color: glance-registry:1 allocation score on rhos6-node3: 0 -+clone_color: glance-registry:2 allocation score on rhos6-node1: 0 -+clone_color: glance-registry:2 allocation score on rhos6-node2: 0 -+clone_color: glance-registry:2 allocation score on rhos6-node3: 1 -+clone_color: heat-api-cfn-clone allocation score on rhos6-node1: 0 -+clone_color: heat-api-cfn-clone allocation score on rhos6-node2: 0 -+clone_color: heat-api-cfn-clone allocation score on rhos6-node3: 0 -+clone_color: heat-api-cfn:0 allocation score on rhos6-node1: 1 -+clone_color: heat-api-cfn:0 allocation score on rhos6-node2: 0 -+clone_color: heat-api-cfn:0 allocation score on rhos6-node3: 0 -+clone_color: heat-api-cfn:1 allocation score on rhos6-node1: 0 -+clone_color: heat-api-cfn:1 allocation score on rhos6-node2: 1 -+clone_color: heat-api-cfn:1 allocation score on rhos6-node3: 0 -+clone_color: heat-api-cfn:2 allocation score on rhos6-node1: 0 -+clone_color: heat-api-cfn:2 allocation score on rhos6-node2: 0 -+clone_color: heat-api-cfn:2 allocation score on rhos6-node3: 1 -+clone_color: heat-api-clone allocation score on rhos6-node1: 0 -+clone_color: heat-api-clone allocation score on rhos6-node2: 0 -+clone_color: heat-api-clone allocation score on rhos6-node3: 0 -+clone_color: heat-api-cloudwatch-clone allocation score on rhos6-node1: 0 -+clone_color: heat-api-cloudwatch-clone allocation score on rhos6-node2: 0 -+clone_color: heat-api-cloudwatch-clone allocation score on rhos6-node3: 0 -+clone_color: heat-api-cloudwatch:0 allocation score on rhos6-node1: 1 -+clone_color: heat-api-cloudwatch:0 allocation score on rhos6-node2: 0 -+clone_color: heat-api-cloudwatch:0 allocation score on rhos6-node3: 0 -+clone_color: heat-api-cloudwatch:1 allocation score on rhos6-node1: 0 -+clone_color: heat-api-cloudwatch:1 allocation score on rhos6-node2: 1 -+clone_color: heat-api-cloudwatch:1 allocation score on rhos6-node3: 0 -+clone_color: heat-api-cloudwatch:2 allocation score on rhos6-node1: 0 -+clone_color: heat-api-cloudwatch:2 allocation score on rhos6-node2: 0 -+clone_color: heat-api-cloudwatch:2 allocation score on rhos6-node3: 1 -+clone_color: heat-api:0 allocation score on rhos6-node1: 1 -+clone_color: heat-api:0 allocation score on rhos6-node2: 0 -+clone_color: heat-api:0 allocation score on rhos6-node3: 0 -+clone_color: heat-api:1 allocation score on rhos6-node1: 0 -+clone_color: heat-api:1 allocation score on rhos6-node2: 1 -+clone_color: heat-api:1 allocation score on rhos6-node3: 0 -+clone_color: heat-api:2 allocation score on rhos6-node1: 0 -+clone_color: heat-api:2 allocation score on rhos6-node2: 0 -+clone_color: heat-api:2 allocation score on rhos6-node3: 1 -+clone_color: horizon-clone allocation score on rhos6-node1: 0 -+clone_color: horizon-clone allocation score on rhos6-node2: 0 -+clone_color: horizon-clone allocation score on rhos6-node3: 0 -+clone_color: horizon:0 allocation score on rhos6-node1: 1 -+clone_color: horizon:0 allocation score on rhos6-node2: 0 -+clone_color: horizon:0 allocation score on rhos6-node3: 0 -+clone_color: horizon:1 allocation score on rhos6-node1: 0 -+clone_color: horizon:1 allocation score on rhos6-node2: 1 -+clone_color: horizon:1 allocation score on rhos6-node3: 0 -+clone_color: horizon:2 allocation score on rhos6-node1: 0 -+clone_color: horizon:2 allocation score on rhos6-node2: 0 -+clone_color: horizon:2 allocation score on rhos6-node3: 1 -+clone_color: keystone-clone allocation score on rhos6-node1: 0 -+clone_color: keystone-clone allocation score on rhos6-node2: 0 -+clone_color: keystone-clone allocation score on rhos6-node3: 0 -+clone_color: keystone:0 allocation score on rhos6-node1: 1 -+clone_color: keystone:0 allocation score on rhos6-node2: 0 -+clone_color: keystone:0 allocation score on rhos6-node3: 0 -+clone_color: keystone:1 allocation score on rhos6-node1: 0 -+clone_color: keystone:1 allocation score on rhos6-node2: 1 -+clone_color: keystone:1 allocation score on rhos6-node3: 0 -+clone_color: keystone:2 allocation score on rhos6-node1: 0 -+clone_color: keystone:2 allocation score on rhos6-node2: 0 -+clone_color: keystone:2 allocation score on rhos6-node3: 1 -+clone_color: lb-haproxy-clone allocation score on rhos6-node1: 0 -+clone_color: lb-haproxy-clone allocation score on rhos6-node2: 0 -+clone_color: lb-haproxy-clone allocation score on rhos6-node3: 0 -+clone_color: lb-haproxy:0 allocation score on rhos6-node1: 1 -+clone_color: lb-haproxy:0 allocation score on rhos6-node2: 0 -+clone_color: lb-haproxy:0 allocation score on rhos6-node3: 0 -+clone_color: lb-haproxy:1 allocation score on rhos6-node1: 0 -+clone_color: lb-haproxy:1 allocation score on rhos6-node2: 1 -+clone_color: lb-haproxy:1 allocation score on rhos6-node3: 0 -+clone_color: lb-haproxy:2 allocation score on rhos6-node1: 0 -+clone_color: lb-haproxy:2 allocation score on rhos6-node2: 0 -+clone_color: lb-haproxy:2 allocation score on rhos6-node3: 1 -+clone_color: memcached-clone allocation score on rhos6-node1: 0 -+clone_color: memcached-clone allocation score on rhos6-node2: 0 -+clone_color: memcached-clone allocation score on rhos6-node3: 0 -+clone_color: memcached:0 allocation score on rhos6-node1: 1 -+clone_color: memcached:0 allocation score on rhos6-node2: 0 -+clone_color: memcached:0 allocation score on rhos6-node3: 0 -+clone_color: memcached:1 allocation score on rhos6-node1: 0 -+clone_color: memcached:1 allocation score on rhos6-node2: 1 -+clone_color: memcached:1 allocation score on rhos6-node3: 0 -+clone_color: memcached:2 allocation score on rhos6-node1: 0 -+clone_color: memcached:2 allocation score on rhos6-node2: 0 -+clone_color: memcached:2 allocation score on rhos6-node3: 1 -+clone_color: mongodb-clone allocation score on rhos6-node1: 0 -+clone_color: mongodb-clone allocation score on rhos6-node2: 0 -+clone_color: mongodb-clone allocation score on rhos6-node3: 0 -+clone_color: mongodb:0 allocation score on rhos6-node1: 1 -+clone_color: mongodb:0 allocation score on rhos6-node2: 0 -+clone_color: mongodb:0 allocation score on rhos6-node3: 0 -+clone_color: mongodb:1 allocation score on rhos6-node1: 0 -+clone_color: mongodb:1 allocation score on rhos6-node2: 1 -+clone_color: mongodb:1 allocation score on rhos6-node3: 0 -+clone_color: mongodb:2 allocation score on rhos6-node1: 0 -+clone_color: mongodb:2 allocation score on rhos6-node2: 0 -+clone_color: mongodb:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-dhcp-agent-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-dhcp-agent-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-dhcp-agent-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-dhcp-agent:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-dhcp-agent:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-dhcp-agent:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-dhcp-agent:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-dhcp-agent:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-dhcp-agent:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-dhcp-agent:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-dhcp-agent:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-dhcp-agent:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-l3-agent-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-l3-agent-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-l3-agent-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-l3-agent:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-l3-agent:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-l3-agent:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-l3-agent:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-l3-agent:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-l3-agent:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-l3-agent:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-l3-agent:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-l3-agent:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-metadata-agent-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-metadata-agent-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-metadata-agent-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-metadata-agent:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-metadata-agent:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-metadata-agent:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-metadata-agent:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-metadata-agent:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-metadata-agent:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-metadata-agent:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-metadata-agent:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-metadata-agent:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-netns-cleanup-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-netns-cleanup-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-netns-cleanup-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-netns-cleanup:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-netns-cleanup:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-netns-cleanup:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-netns-cleanup:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-netns-cleanup:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-netns-cleanup:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-netns-cleanup:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-netns-cleanup:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-netns-cleanup:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-openvswitch-agent-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-openvswitch-agent-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-openvswitch-agent-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-openvswitch-agent:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-openvswitch-agent:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-openvswitch-agent:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-openvswitch-agent:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-openvswitch-agent:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-openvswitch-agent:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-openvswitch-agent:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-openvswitch-agent:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-openvswitch-agent:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-ovs-cleanup-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-ovs-cleanup-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-ovs-cleanup-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-ovs-cleanup:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-ovs-cleanup:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-ovs-cleanup:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-ovs-cleanup:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-ovs-cleanup:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-ovs-cleanup:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-ovs-cleanup:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-ovs-cleanup:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-ovs-cleanup:2 allocation score on rhos6-node3: 1 -+clone_color: neutron-scale-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-scale-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-scale-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-scale:0 allocation score on rhos6-node1: 0 -+clone_color: neutron-scale:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-scale:0 allocation score on rhos6-node3: 1 -+clone_color: neutron-scale:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-scale:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-scale:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-scale:2 allocation score on rhos6-node1: 1 -+clone_color: neutron-scale:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-scale:2 allocation score on rhos6-node3: 0 -+clone_color: neutron-server-clone allocation score on rhos6-node1: 0 -+clone_color: neutron-server-clone allocation score on rhos6-node2: 0 -+clone_color: neutron-server-clone allocation score on rhos6-node3: 0 -+clone_color: neutron-server:0 allocation score on rhos6-node1: 1 -+clone_color: neutron-server:0 allocation score on rhos6-node2: 0 -+clone_color: neutron-server:0 allocation score on rhos6-node3: 0 -+clone_color: neutron-server:1 allocation score on rhos6-node1: 0 -+clone_color: neutron-server:1 allocation score on rhos6-node2: 1 -+clone_color: neutron-server:1 allocation score on rhos6-node3: 0 -+clone_color: neutron-server:2 allocation score on rhos6-node1: 0 -+clone_color: neutron-server:2 allocation score on rhos6-node2: 0 -+clone_color: neutron-server:2 allocation score on rhos6-node3: 1 -+clone_color: nova-api-clone allocation score on rhos6-node1: 0 -+clone_color: nova-api-clone allocation score on rhos6-node2: 0 -+clone_color: nova-api-clone allocation score on rhos6-node3: 0 -+clone_color: nova-api:0 allocation score on rhos6-node1: 1 -+clone_color: nova-api:0 allocation score on rhos6-node2: 0 -+clone_color: nova-api:0 allocation score on rhos6-node3: 0 -+clone_color: nova-api:1 allocation score on rhos6-node1: 0 -+clone_color: nova-api:1 allocation score on rhos6-node2: 1 -+clone_color: nova-api:1 allocation score on rhos6-node3: 0 -+clone_color: nova-api:2 allocation score on rhos6-node1: 0 -+clone_color: nova-api:2 allocation score on rhos6-node2: 0 -+clone_color: nova-api:2 allocation score on rhos6-node3: 1 -+clone_color: nova-conductor-clone allocation score on rhos6-node1: 0 -+clone_color: nova-conductor-clone allocation score on rhos6-node2: 0 -+clone_color: nova-conductor-clone allocation score on rhos6-node3: 0 -+clone_color: nova-conductor:0 allocation score on rhos6-node1: 1 -+clone_color: nova-conductor:0 allocation score on rhos6-node2: 0 -+clone_color: nova-conductor:0 allocation score on rhos6-node3: 0 -+clone_color: nova-conductor:1 allocation score on rhos6-node1: 0 -+clone_color: nova-conductor:1 allocation score on rhos6-node2: 1 -+clone_color: nova-conductor:1 allocation score on rhos6-node3: 0 -+clone_color: nova-conductor:2 allocation score on rhos6-node1: 0 -+clone_color: nova-conductor:2 allocation score on rhos6-node2: 0 -+clone_color: nova-conductor:2 allocation score on rhos6-node3: 1 -+clone_color: nova-consoleauth-clone allocation score on rhos6-node1: 0 -+clone_color: nova-consoleauth-clone allocation score on rhos6-node2: 0 -+clone_color: nova-consoleauth-clone allocation score on rhos6-node3: 0 -+clone_color: nova-consoleauth:0 allocation score on rhos6-node1: 1 -+clone_color: nova-consoleauth:0 allocation score on rhos6-node2: 0 -+clone_color: nova-consoleauth:0 allocation score on rhos6-node3: 0 -+clone_color: nova-consoleauth:1 allocation score on rhos6-node1: 0 -+clone_color: nova-consoleauth:1 allocation score on rhos6-node2: 1 -+clone_color: nova-consoleauth:1 allocation score on rhos6-node3: 0 -+clone_color: nova-consoleauth:2 allocation score on rhos6-node1: 0 -+clone_color: nova-consoleauth:2 allocation score on rhos6-node2: 0 -+clone_color: nova-consoleauth:2 allocation score on rhos6-node3: 1 -+clone_color: nova-novncproxy-clone allocation score on rhos6-node1: 0 -+clone_color: nova-novncproxy-clone allocation score on rhos6-node2: 0 -+clone_color: nova-novncproxy-clone allocation score on rhos6-node3: 0 -+clone_color: nova-novncproxy:0 allocation score on rhos6-node1: 1 -+clone_color: nova-novncproxy:0 allocation score on rhos6-node2: 0 -+clone_color: nova-novncproxy:0 allocation score on rhos6-node3: 0 -+clone_color: nova-novncproxy:1 allocation score on rhos6-node1: 0 -+clone_color: nova-novncproxy:1 allocation score on rhos6-node2: 1 -+clone_color: nova-novncproxy:1 allocation score on rhos6-node3: 0 -+clone_color: nova-novncproxy:2 allocation score on rhos6-node1: 0 -+clone_color: nova-novncproxy:2 allocation score on rhos6-node2: 0 -+clone_color: nova-novncproxy:2 allocation score on rhos6-node3: 1 -+clone_color: nova-scheduler-clone allocation score on rhos6-node1: 0 -+clone_color: nova-scheduler-clone allocation score on rhos6-node2: 0 -+clone_color: nova-scheduler-clone allocation score on rhos6-node3: 0 -+clone_color: nova-scheduler:0 allocation score on rhos6-node1: 1 -+clone_color: nova-scheduler:0 allocation score on rhos6-node2: 0 -+clone_color: nova-scheduler:0 allocation score on rhos6-node3: 0 -+clone_color: nova-scheduler:1 allocation score on rhos6-node1: 0 -+clone_color: nova-scheduler:1 allocation score on rhos6-node2: 1 -+clone_color: nova-scheduler:1 allocation score on rhos6-node3: 0 -+clone_color: nova-scheduler:2 allocation score on rhos6-node1: 0 -+clone_color: nova-scheduler:2 allocation score on rhos6-node2: 0 -+clone_color: nova-scheduler:2 allocation score on rhos6-node3: 1 -+clone_color: rabbitmq-server-clone allocation score on rhos6-node1: 0 -+clone_color: rabbitmq-server-clone allocation score on rhos6-node2: 0 -+clone_color: rabbitmq-server-clone allocation score on rhos6-node3: 0 -+clone_color: rabbitmq-server:0 allocation score on rhos6-node1: 1 -+clone_color: rabbitmq-server:0 allocation score on rhos6-node2: 0 -+clone_color: rabbitmq-server:0 allocation score on rhos6-node3: 0 -+clone_color: rabbitmq-server:1 allocation score on rhos6-node1: 0 -+clone_color: rabbitmq-server:1 allocation score on rhos6-node2: 1 -+clone_color: rabbitmq-server:1 allocation score on rhos6-node3: 0 -+clone_color: rabbitmq-server:2 allocation score on rhos6-node1: 0 -+clone_color: rabbitmq-server:2 allocation score on rhos6-node2: 0 -+clone_color: rabbitmq-server:2 allocation score on rhos6-node3: 1 -+clone_color: swift-account-clone allocation score on rhos6-node1: 0 -+clone_color: swift-account-clone allocation score on rhos6-node2: 0 -+clone_color: swift-account-clone allocation score on rhos6-node3: 0 -+clone_color: swift-account:0 allocation score on rhos6-node1: 1 -+clone_color: swift-account:0 allocation score on rhos6-node2: 0 -+clone_color: swift-account:0 allocation score on rhos6-node3: 0 -+clone_color: swift-account:1 allocation score on rhos6-node1: 0 -+clone_color: swift-account:1 allocation score on rhos6-node2: 1 -+clone_color: swift-account:1 allocation score on rhos6-node3: 0 -+clone_color: swift-account:2 allocation score on rhos6-node1: 0 -+clone_color: swift-account:2 allocation score on rhos6-node2: 0 -+clone_color: swift-account:2 allocation score on rhos6-node3: 1 -+clone_color: swift-container-clone allocation score on rhos6-node1: 0 -+clone_color: swift-container-clone allocation score on rhos6-node2: 0 -+clone_color: swift-container-clone allocation score on rhos6-node3: 0 -+clone_color: swift-container:0 allocation score on rhos6-node1: 1 -+clone_color: swift-container:0 allocation score on rhos6-node2: 0 -+clone_color: swift-container:0 allocation score on rhos6-node3: 0 -+clone_color: swift-container:1 allocation score on rhos6-node1: 0 -+clone_color: swift-container:1 allocation score on rhos6-node2: 1 -+clone_color: swift-container:1 allocation score on rhos6-node3: 0 -+clone_color: swift-container:2 allocation score on rhos6-node1: 0 -+clone_color: swift-container:2 allocation score on rhos6-node2: 0 -+clone_color: swift-container:2 allocation score on rhos6-node3: 1 -+clone_color: swift-fs-clone allocation score on rhos6-node1: 0 -+clone_color: swift-fs-clone allocation score on rhos6-node2: 0 -+clone_color: swift-fs-clone allocation score on rhos6-node3: 0 -+clone_color: swift-fs:0 allocation score on rhos6-node1: 1 -+clone_color: swift-fs:0 allocation score on rhos6-node2: 0 -+clone_color: swift-fs:0 allocation score on rhos6-node3: 0 -+clone_color: swift-fs:1 allocation score on rhos6-node1: 0 -+clone_color: swift-fs:1 allocation score on rhos6-node2: 1 -+clone_color: swift-fs:1 allocation score on rhos6-node3: 0 -+clone_color: swift-fs:2 allocation score on rhos6-node1: 0 -+clone_color: swift-fs:2 allocation score on rhos6-node2: 0 -+clone_color: swift-fs:2 allocation score on rhos6-node3: 1 -+clone_color: swift-object-clone allocation score on rhos6-node1: 0 -+clone_color: swift-object-clone allocation score on rhos6-node2: 0 -+clone_color: swift-object-clone allocation score on rhos6-node3: 0 -+clone_color: swift-object:0 allocation score on rhos6-node1: 1 -+clone_color: swift-object:0 allocation score on rhos6-node2: 0 -+clone_color: swift-object:0 allocation score on rhos6-node3: 0 -+clone_color: swift-object:1 allocation score on rhos6-node1: 0 -+clone_color: swift-object:1 allocation score on rhos6-node2: 1 -+clone_color: swift-object:1 allocation score on rhos6-node3: 0 -+clone_color: swift-object:2 allocation score on rhos6-node1: 0 -+clone_color: swift-object:2 allocation score on rhos6-node2: 0 -+clone_color: swift-object:2 allocation score on rhos6-node3: 1 -+clone_color: swift-proxy-clone allocation score on rhos6-node1: 0 -+clone_color: swift-proxy-clone allocation score on rhos6-node2: 0 -+clone_color: swift-proxy-clone allocation score on rhos6-node3: 0 -+clone_color: swift-proxy:0 allocation score on rhos6-node1: 1 -+clone_color: swift-proxy:0 allocation score on rhos6-node2: 0 -+clone_color: swift-proxy:0 allocation score on rhos6-node3: 0 -+clone_color: swift-proxy:1 allocation score on rhos6-node1: 0 -+clone_color: swift-proxy:1 allocation score on rhos6-node2: 1 -+clone_color: swift-proxy:1 allocation score on rhos6-node3: 0 -+clone_color: swift-proxy:2 allocation score on rhos6-node1: 0 -+clone_color: swift-proxy:2 allocation score on rhos6-node2: 0 -+clone_color: swift-proxy:2 allocation score on rhos6-node3: 1 -+galera:0 promotion score on rhos6-node1: 100 -+galera:1 promotion score on rhos6-node2: 100 -+galera:2 promotion score on rhos6-node3: 100 -+native_color: ceilometer-alarm-evaluator:0 allocation score on rhos6-node1: 1 -+native_color: ceilometer-alarm-evaluator:0 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-alarm-evaluator:0 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-alarm-evaluator:1 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-alarm-evaluator:1 allocation score on rhos6-node2: 1 -+native_color: ceilometer-alarm-evaluator:1 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-alarm-evaluator:2 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-alarm-evaluator:2 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-alarm-evaluator:2 allocation score on rhos6-node3: 1 -+native_color: ceilometer-alarm-notifier:0 allocation score on rhos6-node1: 1 -+native_color: ceilometer-alarm-notifier:0 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-alarm-notifier:0 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-alarm-notifier:1 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-alarm-notifier:1 allocation score on rhos6-node2: 1 -+native_color: ceilometer-alarm-notifier:1 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-alarm-notifier:2 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-alarm-notifier:2 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-alarm-notifier:2 allocation score on rhos6-node3: 1 -+native_color: ceilometer-api:0 allocation score on rhos6-node1: 1 -+native_color: ceilometer-api:0 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-api:0 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-api:1 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-api:1 allocation score on rhos6-node2: 1 -+native_color: ceilometer-api:1 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-api:2 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-api:2 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-api:2 allocation score on rhos6-node3: 1 -+native_color: ceilometer-central allocation score on rhos6-node1: 0 -+native_color: ceilometer-central allocation score on rhos6-node2: 0 -+native_color: ceilometer-central allocation score on rhos6-node3: 0 -+native_color: ceilometer-collector:0 allocation score on rhos6-node1: 1 -+native_color: ceilometer-collector:0 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-collector:0 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-collector:1 allocation score on rhos6-node1: 0 -+native_color: ceilometer-collector:1 allocation score on rhos6-node2: 1 -+native_color: ceilometer-collector:1 allocation score on rhos6-node3: 0 -+native_color: ceilometer-collector:2 allocation score on rhos6-node1: 0 -+native_color: ceilometer-collector:2 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-collector:2 allocation score on rhos6-node3: 1 -+native_color: ceilometer-delay:0 allocation score on rhos6-node1: 1 -+native_color: ceilometer-delay:0 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-delay:0 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-delay:1 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-delay:1 allocation score on rhos6-node2: 1 -+native_color: ceilometer-delay:1 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-delay:2 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-delay:2 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-delay:2 allocation score on rhos6-node3: 1 -+native_color: ceilometer-notification:0 allocation score on rhos6-node1: 1 -+native_color: ceilometer-notification:0 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-notification:0 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-notification:1 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-notification:1 allocation score on rhos6-node2: 1 -+native_color: ceilometer-notification:1 allocation score on rhos6-node3: -INFINITY -+native_color: ceilometer-notification:2 allocation score on rhos6-node1: -INFINITY -+native_color: ceilometer-notification:2 allocation score on rhos6-node2: -INFINITY -+native_color: ceilometer-notification:2 allocation score on rhos6-node3: 1 -+native_color: cinder-api allocation score on rhos6-node1: 0 -+native_color: cinder-api allocation score on rhos6-node2: 0 -+native_color: cinder-api allocation score on rhos6-node3: 0 -+native_color: cinder-scheduler allocation score on rhos6-node1: 0 -+native_color: cinder-scheduler allocation score on rhos6-node2: -INFINITY -+native_color: cinder-scheduler allocation score on rhos6-node3: -INFINITY -+native_color: cinder-volume allocation score on rhos6-node1: 0 -+native_color: cinder-volume allocation score on rhos6-node2: -INFINITY -+native_color: cinder-volume allocation score on rhos6-node3: -INFINITY -+native_color: galera:0 allocation score on rhos6-node1: 101 -+native_color: galera:0 allocation score on rhos6-node2: 0 -+native_color: galera:0 allocation score on rhos6-node3: 0 -+native_color: galera:1 allocation score on rhos6-node1: -INFINITY -+native_color: galera:1 allocation score on rhos6-node2: 101 -+native_color: galera:1 allocation score on rhos6-node3: 0 -+native_color: galera:2 allocation score on rhos6-node1: -INFINITY -+native_color: galera:2 allocation score on rhos6-node2: -INFINITY -+native_color: galera:2 allocation score on rhos6-node3: 101 -+native_color: glance-api:0 allocation score on rhos6-node1: 1 -+native_color: glance-api:0 allocation score on rhos6-node2: -INFINITY -+native_color: glance-api:0 allocation score on rhos6-node3: -INFINITY -+native_color: glance-api:1 allocation score on rhos6-node1: -INFINITY -+native_color: glance-api:1 allocation score on rhos6-node2: 1 -+native_color: glance-api:1 allocation score on rhos6-node3: -INFINITY -+native_color: glance-api:2 allocation score on rhos6-node1: -INFINITY -+native_color: glance-api:2 allocation score on rhos6-node2: -INFINITY -+native_color: glance-api:2 allocation score on rhos6-node3: 1 -+native_color: glance-fs:0 allocation score on rhos6-node1: 1 -+native_color: glance-fs:0 allocation score on rhos6-node2: 0 -+native_color: glance-fs:0 allocation score on rhos6-node3: 0 -+native_color: glance-fs:1 allocation score on rhos6-node1: -INFINITY -+native_color: glance-fs:1 allocation score on rhos6-node2: 1 -+native_color: glance-fs:1 allocation score on rhos6-node3: 0 -+native_color: glance-fs:2 allocation score on rhos6-node1: -INFINITY -+native_color: glance-fs:2 allocation score on rhos6-node2: -INFINITY -+native_color: glance-fs:2 allocation score on rhos6-node3: 1 -+native_color: glance-registry:0 allocation score on rhos6-node1: 1 -+native_color: glance-registry:0 allocation score on rhos6-node2: -INFINITY -+native_color: glance-registry:0 allocation score on rhos6-node3: -INFINITY -+native_color: glance-registry:1 allocation score on rhos6-node1: -INFINITY -+native_color: glance-registry:1 allocation score on rhos6-node2: 1 -+native_color: glance-registry:1 allocation score on rhos6-node3: -INFINITY -+native_color: glance-registry:2 allocation score on rhos6-node1: -INFINITY -+native_color: glance-registry:2 allocation score on rhos6-node2: -INFINITY -+native_color: glance-registry:2 allocation score on rhos6-node3: 1 -+native_color: heat-api-cfn:0 allocation score on rhos6-node1: 1 -+native_color: heat-api-cfn:0 allocation score on rhos6-node2: -INFINITY -+native_color: heat-api-cfn:0 allocation score on rhos6-node3: -INFINITY -+native_color: heat-api-cfn:1 allocation score on rhos6-node1: -INFINITY -+native_color: heat-api-cfn:1 allocation score on rhos6-node2: 1 -+native_color: heat-api-cfn:1 allocation score on rhos6-node3: -INFINITY -+native_color: heat-api-cfn:2 allocation score on rhos6-node1: -INFINITY -+native_color: heat-api-cfn:2 allocation score on rhos6-node2: -INFINITY -+native_color: heat-api-cfn:2 allocation score on rhos6-node3: 1 -+native_color: heat-api-cloudwatch:0 allocation score on rhos6-node1: 1 -+native_color: heat-api-cloudwatch:0 allocation score on rhos6-node2: -INFINITY -+native_color: heat-api-cloudwatch:0 allocation score on rhos6-node3: -INFINITY -+native_color: heat-api-cloudwatch:1 allocation score on rhos6-node1: -INFINITY -+native_color: heat-api-cloudwatch:1 allocation score on rhos6-node2: 1 -+native_color: heat-api-cloudwatch:1 allocation score on rhos6-node3: -INFINITY -+native_color: heat-api-cloudwatch:2 allocation score on rhos6-node1: -INFINITY -+native_color: heat-api-cloudwatch:2 allocation score on rhos6-node2: -INFINITY -+native_color: heat-api-cloudwatch:2 allocation score on rhos6-node3: 1 -+native_color: heat-api:0 allocation score on rhos6-node1: 1 -+native_color: heat-api:0 allocation score on rhos6-node2: -INFINITY -+native_color: heat-api:0 allocation score on rhos6-node3: -INFINITY -+native_color: heat-api:1 allocation score on rhos6-node1: 0 -+native_color: heat-api:1 allocation score on rhos6-node2: 1 -+native_color: heat-api:1 allocation score on rhos6-node3: 0 -+native_color: heat-api:2 allocation score on rhos6-node1: 0 -+native_color: heat-api:2 allocation score on rhos6-node2: -INFINITY -+native_color: heat-api:2 allocation score on rhos6-node3: 1 -+native_color: heat-engine allocation score on rhos6-node1: 0 -+native_color: heat-engine allocation score on rhos6-node2: 0 -+native_color: heat-engine allocation score on rhos6-node3: 0 -+native_color: horizon:0 allocation score on rhos6-node1: 1 -+native_color: horizon:0 allocation score on rhos6-node2: -INFINITY -+native_color: horizon:0 allocation score on rhos6-node3: -INFINITY -+native_color: horizon:1 allocation score on rhos6-node1: 0 -+native_color: horizon:1 allocation score on rhos6-node2: 1 -+native_color: horizon:1 allocation score on rhos6-node3: -INFINITY -+native_color: horizon:2 allocation score on rhos6-node1: 0 -+native_color: horizon:2 allocation score on rhos6-node2: 0 -+native_color: horizon:2 allocation score on rhos6-node3: 1 -+native_color: keystone:0 allocation score on rhos6-node1: -INFINITY -+native_color: keystone:0 allocation score on rhos6-node2: -INFINITY -+native_color: keystone:0 allocation score on rhos6-node3: -INFINITY -+native_color: keystone:1 allocation score on rhos6-node1: -INFINITY -+native_color: keystone:1 allocation score on rhos6-node2: -INFINITY -+native_color: keystone:1 allocation score on rhos6-node3: -INFINITY -+native_color: keystone:2 allocation score on rhos6-node1: -INFINITY -+native_color: keystone:2 allocation score on rhos6-node2: -INFINITY -+native_color: keystone:2 allocation score on rhos6-node3: -INFINITY -+native_color: lb-haproxy:0 allocation score on rhos6-node1: 1 -+native_color: lb-haproxy:0 allocation score on rhos6-node2: 0 -+native_color: lb-haproxy:0 allocation score on rhos6-node3: 0 -+native_color: lb-haproxy:1 allocation score on rhos6-node1: -INFINITY -+native_color: lb-haproxy:1 allocation score on rhos6-node2: 1 -+native_color: lb-haproxy:1 allocation score on rhos6-node3: 0 -+native_color: lb-haproxy:2 allocation score on rhos6-node1: -INFINITY -+native_color: lb-haproxy:2 allocation score on rhos6-node2: -INFINITY -+native_color: lb-haproxy:2 allocation score on rhos6-node3: 1 -+native_color: memcached:0 allocation score on rhos6-node1: 1 -+native_color: memcached:0 allocation score on rhos6-node2: 0 -+native_color: memcached:0 allocation score on rhos6-node3: 0 -+native_color: memcached:1 allocation score on rhos6-node1: -INFINITY -+native_color: memcached:1 allocation score on rhos6-node2: 1 -+native_color: memcached:1 allocation score on rhos6-node3: 0 -+native_color: memcached:2 allocation score on rhos6-node1: -INFINITY -+native_color: memcached:2 allocation score on rhos6-node2: -INFINITY -+native_color: memcached:2 allocation score on rhos6-node3: 1 -+native_color: mongodb:0 allocation score on rhos6-node1: 1 -+native_color: mongodb:0 allocation score on rhos6-node2: 0 -+native_color: mongodb:0 allocation score on rhos6-node3: 0 -+native_color: mongodb:1 allocation score on rhos6-node1: -INFINITY -+native_color: mongodb:1 allocation score on rhos6-node2: 1 -+native_color: mongodb:1 allocation score on rhos6-node3: 0 -+native_color: mongodb:2 allocation score on rhos6-node1: -INFINITY -+native_color: mongodb:2 allocation score on rhos6-node2: -INFINITY -+native_color: mongodb:2 allocation score on rhos6-node3: 1 -+native_color: neutron-dhcp-agent:0 allocation score on rhos6-node1: 1 -+native_color: neutron-dhcp-agent:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-dhcp-agent:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-dhcp-agent:1 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-dhcp-agent:1 allocation score on rhos6-node2: 1 -+native_color: neutron-dhcp-agent:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-dhcp-agent:2 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-dhcp-agent:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-dhcp-agent:2 allocation score on rhos6-node3: 1 -+native_color: neutron-l3-agent:0 allocation score on rhos6-node1: 1 -+native_color: neutron-l3-agent:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-l3-agent:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-l3-agent:1 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-l3-agent:1 allocation score on rhos6-node2: 1 -+native_color: neutron-l3-agent:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-l3-agent:2 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-l3-agent:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-l3-agent:2 allocation score on rhos6-node3: 1 -+native_color: neutron-metadata-agent:0 allocation score on rhos6-node1: 1 -+native_color: neutron-metadata-agent:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-metadata-agent:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-metadata-agent:1 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-metadata-agent:1 allocation score on rhos6-node2: 1 -+native_color: neutron-metadata-agent:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-metadata-agent:2 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-metadata-agent:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-metadata-agent:2 allocation score on rhos6-node3: 1 -+native_color: neutron-netns-cleanup:0 allocation score on rhos6-node1: 1 -+native_color: neutron-netns-cleanup:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-netns-cleanup:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-netns-cleanup:1 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-netns-cleanup:1 allocation score on rhos6-node2: 1 -+native_color: neutron-netns-cleanup:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-netns-cleanup:2 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-netns-cleanup:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-netns-cleanup:2 allocation score on rhos6-node3: 1 -+native_color: neutron-openvswitch-agent:0 allocation score on rhos6-node1: 1 -+native_color: neutron-openvswitch-agent:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-openvswitch-agent:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-openvswitch-agent:1 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-openvswitch-agent:1 allocation score on rhos6-node2: 1 -+native_color: neutron-openvswitch-agent:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-openvswitch-agent:2 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-openvswitch-agent:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-openvswitch-agent:2 allocation score on rhos6-node3: 1 -+native_color: neutron-ovs-cleanup:0 allocation score on rhos6-node1: 1 -+native_color: neutron-ovs-cleanup:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-ovs-cleanup:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-ovs-cleanup:1 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-ovs-cleanup:1 allocation score on rhos6-node2: 1 -+native_color: neutron-ovs-cleanup:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-ovs-cleanup:2 allocation score on rhos6-node1: -INFINITY -+native_color: neutron-ovs-cleanup:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-ovs-cleanup:2 allocation score on rhos6-node3: 1 -+native_color: neutron-scale:0 allocation score on rhos6-node1: 0 -+native_color: neutron-scale:0 allocation score on rhos6-node2: 0 -+native_color: neutron-scale:0 allocation score on rhos6-node3: 1 -+native_color: neutron-scale:1 allocation score on rhos6-node1: 0 -+native_color: neutron-scale:1 allocation score on rhos6-node2: 1 -+native_color: neutron-scale:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-scale:2 allocation score on rhos6-node1: 1 -+native_color: neutron-scale:2 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-scale:2 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-server:0 allocation score on rhos6-node1: 1 -+native_color: neutron-server:0 allocation score on rhos6-node2: -INFINITY -+native_color: neutron-server:0 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-server:1 allocation score on rhos6-node1: 0 -+native_color: neutron-server:1 allocation score on rhos6-node2: 1 -+native_color: neutron-server:1 allocation score on rhos6-node3: -INFINITY -+native_color: neutron-server:2 allocation score on rhos6-node1: 0 -+native_color: neutron-server:2 allocation score on rhos6-node2: 0 -+native_color: neutron-server:2 allocation score on rhos6-node3: 1 -+native_color: node1-fence allocation score on rhos6-node1: 0 -+native_color: node1-fence allocation score on rhos6-node2: 0 -+native_color: node1-fence allocation score on rhos6-node3: 0 -+native_color: node2-fence allocation score on rhos6-node1: 0 -+native_color: node2-fence allocation score on rhos6-node2: 0 -+native_color: node2-fence allocation score on rhos6-node3: 0 -+native_color: node3-fence allocation score on rhos6-node1: 0 -+native_color: node3-fence allocation score on rhos6-node2: 0 -+native_color: node3-fence allocation score on rhos6-node3: 0 -+native_color: nova-api:0 allocation score on rhos6-node1: 1 -+native_color: nova-api:0 allocation score on rhos6-node2: -INFINITY -+native_color: nova-api:0 allocation score on rhos6-node3: -INFINITY -+native_color: nova-api:1 allocation score on rhos6-node1: -INFINITY -+native_color: nova-api:1 allocation score on rhos6-node2: 1 -+native_color: nova-api:1 allocation score on rhos6-node3: -INFINITY -+native_color: nova-api:2 allocation score on rhos6-node1: -INFINITY -+native_color: nova-api:2 allocation score on rhos6-node2: -INFINITY -+native_color: nova-api:2 allocation score on rhos6-node3: 1 -+native_color: nova-conductor:0 allocation score on rhos6-node1: 1 -+native_color: nova-conductor:0 allocation score on rhos6-node2: -INFINITY -+native_color: nova-conductor:0 allocation score on rhos6-node3: -INFINITY -+native_color: nova-conductor:1 allocation score on rhos6-node1: -INFINITY -+native_color: nova-conductor:1 allocation score on rhos6-node2: 1 -+native_color: nova-conductor:1 allocation score on rhos6-node3: -INFINITY -+native_color: nova-conductor:2 allocation score on rhos6-node1: -INFINITY -+native_color: nova-conductor:2 allocation score on rhos6-node2: -INFINITY -+native_color: nova-conductor:2 allocation score on rhos6-node3: 1 -+native_color: nova-consoleauth:0 allocation score on rhos6-node1: 1 -+native_color: nova-consoleauth:0 allocation score on rhos6-node2: -INFINITY -+native_color: nova-consoleauth:0 allocation score on rhos6-node3: -INFINITY -+native_color: nova-consoleauth:1 allocation score on rhos6-node1: 0 -+native_color: nova-consoleauth:1 allocation score on rhos6-node2: 1 -+native_color: nova-consoleauth:1 allocation score on rhos6-node3: -INFINITY -+native_color: nova-consoleauth:2 allocation score on rhos6-node1: 0 -+native_color: nova-consoleauth:2 allocation score on rhos6-node2: 0 -+native_color: nova-consoleauth:2 allocation score on rhos6-node3: 1 -+native_color: nova-novncproxy:0 allocation score on rhos6-node1: 1 -+native_color: nova-novncproxy:0 allocation score on rhos6-node2: -INFINITY -+native_color: nova-novncproxy:0 allocation score on rhos6-node3: -INFINITY -+native_color: nova-novncproxy:1 allocation score on rhos6-node1: -INFINITY -+native_color: nova-novncproxy:1 allocation score on rhos6-node2: 1 -+native_color: nova-novncproxy:1 allocation score on rhos6-node3: -INFINITY -+native_color: nova-novncproxy:2 allocation score on rhos6-node1: -INFINITY -+native_color: nova-novncproxy:2 allocation score on rhos6-node2: -INFINITY -+native_color: nova-novncproxy:2 allocation score on rhos6-node3: 1 -+native_color: nova-scheduler:0 allocation score on rhos6-node1: 1 -+native_color: nova-scheduler:0 allocation score on rhos6-node2: -INFINITY -+native_color: nova-scheduler:0 allocation score on rhos6-node3: -INFINITY -+native_color: nova-scheduler:1 allocation score on rhos6-node1: -INFINITY -+native_color: nova-scheduler:1 allocation score on rhos6-node2: 1 -+native_color: nova-scheduler:1 allocation score on rhos6-node3: -INFINITY -+native_color: nova-scheduler:2 allocation score on rhos6-node1: -INFINITY -+native_color: nova-scheduler:2 allocation score on rhos6-node2: -INFINITY -+native_color: nova-scheduler:2 allocation score on rhos6-node3: 1 -+native_color: rabbitmq-server:0 allocation score on rhos6-node1: 1 -+native_color: rabbitmq-server:0 allocation score on rhos6-node2: 0 -+native_color: rabbitmq-server:0 allocation score on rhos6-node3: 0 -+native_color: rabbitmq-server:1 allocation score on rhos6-node1: -INFINITY -+native_color: rabbitmq-server:1 allocation score on rhos6-node2: 1 -+native_color: rabbitmq-server:1 allocation score on rhos6-node3: 0 -+native_color: rabbitmq-server:2 allocation score on rhos6-node1: -INFINITY -+native_color: rabbitmq-server:2 allocation score on rhos6-node2: -INFINITY -+native_color: rabbitmq-server:2 allocation score on rhos6-node3: 1 -+native_color: swift-account:0 allocation score on rhos6-node1: 1 -+native_color: swift-account:0 allocation score on rhos6-node2: -INFINITY -+native_color: swift-account:0 allocation score on rhos6-node3: -INFINITY -+native_color: swift-account:1 allocation score on rhos6-node1: -INFINITY -+native_color: swift-account:1 allocation score on rhos6-node2: 1 -+native_color: swift-account:1 allocation score on rhos6-node3: -INFINITY -+native_color: swift-account:2 allocation score on rhos6-node1: -INFINITY -+native_color: swift-account:2 allocation score on rhos6-node2: -INFINITY -+native_color: swift-account:2 allocation score on rhos6-node3: 1 -+native_color: swift-container:0 allocation score on rhos6-node1: 1 -+native_color: swift-container:0 allocation score on rhos6-node2: -INFINITY -+native_color: swift-container:0 allocation score on rhos6-node3: -INFINITY -+native_color: swift-container:1 allocation score on rhos6-node1: -INFINITY -+native_color: swift-container:1 allocation score on rhos6-node2: 1 -+native_color: swift-container:1 allocation score on rhos6-node3: -INFINITY -+native_color: swift-container:2 allocation score on rhos6-node1: -INFINITY -+native_color: swift-container:2 allocation score on rhos6-node2: -INFINITY -+native_color: swift-container:2 allocation score on rhos6-node3: 1 -+native_color: swift-fs:0 allocation score on rhos6-node1: 1 -+native_color: swift-fs:0 allocation score on rhos6-node2: -INFINITY -+native_color: swift-fs:0 allocation score on rhos6-node3: -INFINITY -+native_color: swift-fs:1 allocation score on rhos6-node1: 0 -+native_color: swift-fs:1 allocation score on rhos6-node2: 1 -+native_color: swift-fs:1 allocation score on rhos6-node3: 0 -+native_color: swift-fs:2 allocation score on rhos6-node1: 0 -+native_color: swift-fs:2 allocation score on rhos6-node2: -INFINITY -+native_color: swift-fs:2 allocation score on rhos6-node3: 1 -+native_color: swift-object-expirer allocation score on rhos6-node1: 0 -+native_color: swift-object-expirer allocation score on rhos6-node2: 0 -+native_color: swift-object-expirer allocation score on rhos6-node3: 0 -+native_color: swift-object:0 allocation score on rhos6-node1: 1 -+native_color: swift-object:0 allocation score on rhos6-node2: -INFINITY -+native_color: swift-object:0 allocation score on rhos6-node3: -INFINITY -+native_color: swift-object:1 allocation score on rhos6-node1: -INFINITY -+native_color: swift-object:1 allocation score on rhos6-node2: 1 -+native_color: swift-object:1 allocation score on rhos6-node3: -INFINITY -+native_color: swift-object:2 allocation score on rhos6-node1: -INFINITY -+native_color: swift-object:2 allocation score on rhos6-node2: -INFINITY -+native_color: swift-object:2 allocation score on rhos6-node3: 1 -+native_color: swift-proxy:0 allocation score on rhos6-node1: 1 -+native_color: swift-proxy:0 allocation score on rhos6-node2: -INFINITY -+native_color: swift-proxy:0 allocation score on rhos6-node3: -INFINITY -+native_color: swift-proxy:1 allocation score on rhos6-node1: 0 -+native_color: swift-proxy:1 allocation score on rhos6-node2: 1 -+native_color: swift-proxy:1 allocation score on rhos6-node3: 0 -+native_color: swift-proxy:2 allocation score on rhos6-node1: 0 -+native_color: swift-proxy:2 allocation score on rhos6-node2: -INFINITY -+native_color: swift-proxy:2 allocation score on rhos6-node3: 1 -+native_color: vip-ceilometer allocation score on rhos6-node1: 0 -+native_color: vip-ceilometer allocation score on rhos6-node2: 0 -+native_color: vip-ceilometer allocation score on rhos6-node3: 0 -+native_color: vip-cinder allocation score on rhos6-node1: 0 -+native_color: vip-cinder allocation score on rhos6-node2: 0 -+native_color: vip-cinder allocation score on rhos6-node3: 0 -+native_color: vip-db allocation score on rhos6-node1: 0 -+native_color: vip-db allocation score on rhos6-node2: 0 -+native_color: vip-db allocation score on rhos6-node3: 0 -+native_color: vip-glance allocation score on rhos6-node1: 0 -+native_color: vip-glance allocation score on rhos6-node2: 0 -+native_color: vip-glance allocation score on rhos6-node3: 0 -+native_color: vip-heat allocation score on rhos6-node1: 0 -+native_color: vip-heat allocation score on rhos6-node2: 0 -+native_color: vip-heat allocation score on rhos6-node3: 0 -+native_color: vip-horizon allocation score on rhos6-node1: 0 -+native_color: vip-horizon allocation score on rhos6-node2: 0 -+native_color: vip-horizon allocation score on rhos6-node3: 0 -+native_color: vip-keystone allocation score on rhos6-node1: 0 -+native_color: vip-keystone allocation score on rhos6-node2: 0 -+native_color: vip-keystone allocation score on rhos6-node3: 0 -+native_color: vip-neutron allocation score on rhos6-node1: 0 -+native_color: vip-neutron allocation score on rhos6-node2: 0 -+native_color: vip-neutron allocation score on rhos6-node3: 0 -+native_color: vip-nova allocation score on rhos6-node1: 0 -+native_color: vip-nova allocation score on rhos6-node2: 0 -+native_color: vip-nova allocation score on rhos6-node3: 0 -+native_color: vip-qpid allocation score on rhos6-node1: 0 -+native_color: vip-qpid allocation score on rhos6-node2: 0 -+native_color: vip-qpid allocation score on rhos6-node3: 0 -+native_color: vip-rabbitmq allocation score on rhos6-node1: 0 -+native_color: vip-rabbitmq allocation score on rhos6-node2: 0 -+native_color: vip-rabbitmq allocation score on rhos6-node3: 0 -+native_color: vip-swift allocation score on rhos6-node1: 0 -+native_color: vip-swift allocation score on rhos6-node2: 0 -+native_color: vip-swift allocation score on rhos6-node3: 0 -diff --git a/pengine/test10/complex_enforce_colo.summary b/pengine/test10/complex_enforce_colo.summary -new file mode 100644 -index 0000000..6f64364 ---- /dev/null -+++ b/pengine/test10/complex_enforce_colo.summary -@@ -0,0 +1,452 @@ -+ -+Current cluster status: -+Online: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ -+ node1-fence (stonith:fence_xvm): Started rhos6-node1 -+ node2-fence (stonith:fence_xvm): Started rhos6-node2 -+ node3-fence (stonith:fence_xvm): Started rhos6-node3 -+ Clone Set: lb-haproxy-clone [lb-haproxy] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ vip-db (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-rabbitmq (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-qpid (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ vip-keystone (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-glance (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-cinder (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ vip-swift (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-neutron (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-nova (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ vip-horizon (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-heat (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-ceilometer (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ Master/Slave Set: galera-master [galera] -+ Masters: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: rabbitmq-server-clone [rabbitmq-server] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: memcached-clone [memcached] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: mongodb-clone [mongodb] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: keystone-clone [keystone] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: glance-fs-clone [glance-fs] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: glance-registry-clone [glance-registry] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: glance-api-clone [glance-api] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ cinder-api (systemd:openstack-cinder-api): Started rhos6-node1 -+ cinder-scheduler (systemd:openstack-cinder-scheduler): Started rhos6-node1 -+ cinder-volume (systemd:openstack-cinder-volume): Started rhos6-node1 -+ Clone Set: swift-fs-clone [swift-fs] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-account-clone [swift-account] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-container-clone [swift-container] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-object-clone [swift-object] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-proxy-clone [swift-proxy] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ swift-object-expirer (systemd:openstack-swift-object-expirer): Started rhos6-node2 -+ Clone Set: neutron-server-clone [neutron-server] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-scale-clone [neutron-scale] (unique) -+ neutron-scale:0 (ocf::neutron:NeutronScale): Started rhos6-node3 -+ neutron-scale:1 (ocf::neutron:NeutronScale): Started rhos6-node2 -+ neutron-scale:2 (ocf::neutron:NeutronScale): Started rhos6-node1 -+ Clone Set: neutron-ovs-cleanup-clone [neutron-ovs-cleanup] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-netns-cleanup-clone [neutron-netns-cleanup] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-openvswitch-agent-clone [neutron-openvswitch-agent] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-dhcp-agent-clone [neutron-dhcp-agent] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-l3-agent-clone [neutron-l3-agent] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-metadata-agent-clone [neutron-metadata-agent] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-consoleauth-clone [nova-consoleauth] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-novncproxy-clone [nova-novncproxy] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-api-clone [nova-api] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-scheduler-clone [nova-scheduler] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-conductor-clone [nova-conductor] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ ceilometer-central (systemd:openstack-ceilometer-central): Started rhos6-node3 -+ Clone Set: ceilometer-collector-clone [ceilometer-collector] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-api-clone [ceilometer-api] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-delay-clone [ceilometer-delay] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-alarm-evaluator-clone [ceilometer-alarm-evaluator] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-alarm-notifier-clone [ceilometer-alarm-notifier] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-notification-clone [ceilometer-notification] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: heat-api-clone [heat-api] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: heat-api-cfn-clone [heat-api-cfn] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: heat-api-cloudwatch-clone [heat-api-cloudwatch] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ heat-engine (systemd:openstack-heat-engine): Started rhos6-node2 -+ Clone Set: horizon-clone [horizon] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ -+Transition Summary: -+ * Stop keystone:0 (rhos6-node1) -+ * Stop keystone:1 (rhos6-node2) -+ * Stop keystone:2 (rhos6-node3) -+ * Stop glance-registry:0 (rhos6-node1) -+ * Stop glance-registry:1 (rhos6-node2) -+ * Stop glance-registry:2 (rhos6-node3) -+ * Stop glance-api:0 (rhos6-node1) -+ * Stop glance-api:1 (rhos6-node2) -+ * Stop glance-api:2 (rhos6-node3) -+ * Stop cinder-api (Started rhos6-node1) -+ * Stop cinder-scheduler (Started rhos6-node1) -+ * Stop cinder-volume (Started rhos6-node1) -+ * Stop swift-account:0 (rhos6-node1) -+ * Stop swift-account:1 (rhos6-node2) -+ * Stop swift-account:2 (rhos6-node3) -+ * Stop swift-container:0 (rhos6-node1) -+ * Stop swift-container:1 (rhos6-node2) -+ * Stop swift-container:2 (rhos6-node3) -+ * Stop swift-object:0 (rhos6-node1) -+ * Stop swift-object:1 (rhos6-node2) -+ * Stop swift-object:2 (rhos6-node3) -+ * Stop swift-proxy:0 (rhos6-node1) -+ * Stop swift-proxy:1 (rhos6-node2) -+ * Stop swift-proxy:2 (rhos6-node3) -+ * Stop swift-object-expirer (Started rhos6-node2) -+ * Stop neutron-server:0 (rhos6-node1) -+ * Stop neutron-server:1 (rhos6-node2) -+ * Stop neutron-server:2 (rhos6-node3) -+ * Stop neutron-scale:0 (rhos6-node3) -+ * Stop neutron-scale:1 (rhos6-node2) -+ * Stop neutron-scale:2 (rhos6-node1) -+ * Stop neutron-ovs-cleanup:0 (rhos6-node1) -+ * Stop neutron-ovs-cleanup:1 (rhos6-node2) -+ * Stop neutron-ovs-cleanup:2 (rhos6-node3) -+ * Stop neutron-netns-cleanup:0 (rhos6-node1) -+ * Stop neutron-netns-cleanup:1 (rhos6-node2) -+ * Stop neutron-netns-cleanup:2 (rhos6-node3) -+ * Stop neutron-openvswitch-agent:0 (rhos6-node1) -+ * Stop neutron-openvswitch-agent:1 (rhos6-node2) -+ * Stop neutron-openvswitch-agent:2 (rhos6-node3) -+ * Stop neutron-dhcp-agent:0 (rhos6-node1) -+ * Stop neutron-dhcp-agent:1 (rhos6-node2) -+ * Stop neutron-dhcp-agent:2 (rhos6-node3) -+ * Stop neutron-l3-agent:0 (rhos6-node1) -+ * Stop neutron-l3-agent:1 (rhos6-node2) -+ * Stop neutron-l3-agent:2 (rhos6-node3) -+ * Stop neutron-metadata-agent:0 (rhos6-node1) -+ * Stop neutron-metadata-agent:1 (rhos6-node2) -+ * Stop neutron-metadata-agent:2 (rhos6-node3) -+ * Stop nova-consoleauth:0 (rhos6-node1) -+ * Stop nova-consoleauth:1 (rhos6-node2) -+ * Stop nova-consoleauth:2 (rhos6-node3) -+ * Stop nova-novncproxy:0 (rhos6-node1) -+ * Stop nova-novncproxy:1 (rhos6-node2) -+ * Stop nova-novncproxy:2 (rhos6-node3) -+ * Stop nova-api:0 (rhos6-node1) -+ * Stop nova-api:1 (rhos6-node2) -+ * Stop nova-api:2 (rhos6-node3) -+ * Stop nova-scheduler:0 (rhos6-node1) -+ * Stop nova-scheduler:1 (rhos6-node2) -+ * Stop nova-scheduler:2 (rhos6-node3) -+ * Stop nova-conductor:0 (rhos6-node1) -+ * Stop nova-conductor:1 (rhos6-node2) -+ * Stop nova-conductor:2 (rhos6-node3) -+ * Stop ceilometer-central (Started rhos6-node3) -+ * Stop ceilometer-collector:0 (Started rhos6-node1) -+ * Stop ceilometer-collector:1 (Started rhos6-node2) -+ * Stop ceilometer-collector:2 (Started rhos6-node3) -+ * Stop ceilometer-api:0 (Started rhos6-node1) -+ * Stop ceilometer-api:1 (Started rhos6-node2) -+ * Stop ceilometer-api:2 (Started rhos6-node3) -+ * Stop ceilometer-delay:0 (Started rhos6-node1) -+ * Stop ceilometer-delay:1 (Started rhos6-node2) -+ * Stop ceilometer-delay:2 (Started rhos6-node3) -+ * Stop ceilometer-alarm-evaluator:0 (Started rhos6-node1) -+ * Stop ceilometer-alarm-evaluator:1 (Started rhos6-node2) -+ * Stop ceilometer-alarm-evaluator:2 (Started rhos6-node3) -+ * Stop ceilometer-alarm-notifier:0 (Started rhos6-node1) -+ * Stop ceilometer-alarm-notifier:1 (Started rhos6-node2) -+ * Stop ceilometer-alarm-notifier:2 (Started rhos6-node3) -+ * Stop ceilometer-notification:0 (Started rhos6-node1) -+ * Stop ceilometer-notification:1 (Started rhos6-node2) -+ * Stop ceilometer-notification:2 (Started rhos6-node3) -+ * Stop heat-api:0 (Started rhos6-node1) -+ * Stop heat-api:1 (Started rhos6-node2) -+ * Stop heat-api:2 (Started rhos6-node3) -+ * Stop heat-api-cfn:0 (Started rhos6-node1) -+ * Stop heat-api-cfn:1 (Started rhos6-node2) -+ * Stop heat-api-cfn:2 (Started rhos6-node3) -+ * Stop heat-api-cloudwatch:0 (Started rhos6-node1) -+ * Stop heat-api-cloudwatch:1 (Started rhos6-node2) -+ * Stop heat-api-cloudwatch:2 (Started rhos6-node3) -+ * Stop heat-engine (Started rhos6-node2) -+ -+Executing cluster transition: -+ * Pseudo action: glance-api-clone_stop_0 -+ * Resource action: cinder-volume stop on rhos6-node1 -+ * Pseudo action: swift-object-clone_stop_0 -+ * Resource action: swift-object-expirer stop on rhos6-node2 -+ * Pseudo action: neutron-metadata-agent-clone_stop_0 -+ * Pseudo action: nova-conductor-clone_stop_0 -+ * Resource action: heat-engine stop on rhos6-node2 -+ * Resource action: glance-api stop on rhos6-node1 -+ * Resource action: glance-api stop on rhos6-node2 -+ * Resource action: glance-api stop on rhos6-node3 -+ * Pseudo action: glance-api-clone_stopped_0 -+ * Resource action: cinder-scheduler stop on rhos6-node1 -+ * Resource action: swift-object stop on rhos6-node1 -+ * Resource action: swift-object stop on rhos6-node2 -+ * Resource action: swift-object stop on rhos6-node3 -+ * Pseudo action: swift-object-clone_stopped_0 -+ * Pseudo action: swift-proxy-clone_stop_0 -+ * Resource action: neutron-metadata-agent stop on rhos6-node1 -+ * Resource action: neutron-metadata-agent stop on rhos6-node2 -+ * Resource action: neutron-metadata-agent stop on rhos6-node3 -+ * Pseudo action: neutron-metadata-agent-clone_stopped_0 -+ * Resource action: nova-conductor stop on rhos6-node1 -+ * Resource action: nova-conductor stop on rhos6-node2 -+ * Resource action: nova-conductor stop on rhos6-node3 -+ * Pseudo action: nova-conductor-clone_stopped_0 -+ * Pseudo action: heat-api-cloudwatch-clone_stop_0 -+ * Pseudo action: glance-registry-clone_stop_0 -+ * Resource action: cinder-api stop on rhos6-node1 -+ * Pseudo action: swift-container-clone_stop_0 -+ * Resource action: swift-proxy stop on rhos6-node1 -+ * Resource action: swift-proxy stop on rhos6-node2 -+ * Resource action: swift-proxy stop on rhos6-node3 -+ * Pseudo action: swift-proxy-clone_stopped_0 -+ * Pseudo action: neutron-l3-agent-clone_stop_0 -+ * Pseudo action: nova-scheduler-clone_stop_0 -+ * Resource action: heat-api-cloudwatch stop on rhos6-node1 -+ * Resource action: heat-api-cloudwatch stop on rhos6-node2 -+ * Resource action: heat-api-cloudwatch stop on rhos6-node3 -+ * Pseudo action: heat-api-cloudwatch-clone_stopped_0 -+ * Resource action: glance-registry stop on rhos6-node1 -+ * Resource action: glance-registry stop on rhos6-node2 -+ * Resource action: glance-registry stop on rhos6-node3 -+ * Pseudo action: glance-registry-clone_stopped_0 -+ * Resource action: swift-container stop on rhos6-node1 -+ * Resource action: swift-container stop on rhos6-node2 -+ * Resource action: swift-container stop on rhos6-node3 -+ * Pseudo action: swift-container-clone_stopped_0 -+ * Resource action: neutron-l3-agent stop on rhos6-node1 -+ * Resource action: neutron-l3-agent stop on rhos6-node2 -+ * Resource action: neutron-l3-agent stop on rhos6-node3 -+ * Pseudo action: neutron-l3-agent-clone_stopped_0 -+ * Resource action: nova-scheduler stop on rhos6-node1 -+ * Resource action: nova-scheduler stop on rhos6-node2 -+ * Resource action: nova-scheduler stop on rhos6-node3 -+ * Pseudo action: nova-scheduler-clone_stopped_0 -+ * Pseudo action: heat-api-cfn-clone_stop_0 -+ * Pseudo action: swift-account-clone_stop_0 -+ * Pseudo action: neutron-dhcp-agent-clone_stop_0 -+ * Pseudo action: nova-api-clone_stop_0 -+ * Resource action: heat-api-cfn stop on rhos6-node1 -+ * Resource action: heat-api-cfn stop on rhos6-node2 -+ * Resource action: heat-api-cfn stop on rhos6-node3 -+ * Pseudo action: heat-api-cfn-clone_stopped_0 -+ * Resource action: swift-account stop on rhos6-node1 -+ * Resource action: swift-account stop on rhos6-node2 -+ * Resource action: swift-account stop on rhos6-node3 -+ * Pseudo action: swift-account-clone_stopped_0 -+ * Resource action: neutron-dhcp-agent stop on rhos6-node1 -+ * Resource action: neutron-dhcp-agent stop on rhos6-node2 -+ * Resource action: neutron-dhcp-agent stop on rhos6-node3 -+ * Pseudo action: neutron-dhcp-agent-clone_stopped_0 -+ * Resource action: nova-api stop on rhos6-node1 -+ * Resource action: nova-api stop on rhos6-node2 -+ * Resource action: nova-api stop on rhos6-node3 -+ * Pseudo action: nova-api-clone_stopped_0 -+ * Pseudo action: heat-api-clone_stop_0 -+ * Pseudo action: neutron-openvswitch-agent-clone_stop_0 -+ * Pseudo action: nova-novncproxy-clone_stop_0 -+ * Resource action: heat-api stop on rhos6-node1 -+ * Resource action: heat-api stop on rhos6-node2 -+ * Resource action: heat-api stop on rhos6-node3 -+ * Pseudo action: heat-api-clone_stopped_0 -+ * Resource action: neutron-openvswitch-agent stop on rhos6-node1 -+ * Resource action: neutron-openvswitch-agent stop on rhos6-node2 -+ * Resource action: neutron-openvswitch-agent stop on rhos6-node3 -+ * Pseudo action: neutron-openvswitch-agent-clone_stopped_0 -+ * Resource action: nova-novncproxy stop on rhos6-node1 -+ * Resource action: nova-novncproxy stop on rhos6-node2 -+ * Resource action: nova-novncproxy stop on rhos6-node3 -+ * Pseudo action: nova-novncproxy-clone_stopped_0 -+ * Pseudo action: ceilometer-notification-clone_stop_0 -+ * Pseudo action: neutron-netns-cleanup-clone_stop_0 -+ * Pseudo action: nova-consoleauth-clone_stop_0 -+ * Resource action: ceilometer-notification stop on rhos6-node1 -+ * Resource action: ceilometer-notification stop on rhos6-node2 -+ * Resource action: ceilometer-notification stop on rhos6-node3 -+ * Pseudo action: ceilometer-notification-clone_stopped_0 -+ * Resource action: neutron-netns-cleanup stop on rhos6-node1 -+ * Resource action: neutron-netns-cleanup stop on rhos6-node2 -+ * Resource action: neutron-netns-cleanup stop on rhos6-node3 -+ * Pseudo action: neutron-netns-cleanup-clone_stopped_0 -+ * Resource action: nova-consoleauth stop on rhos6-node1 -+ * Resource action: nova-consoleauth stop on rhos6-node2 -+ * Resource action: nova-consoleauth stop on rhos6-node3 -+ * Pseudo action: nova-consoleauth-clone_stopped_0 -+ * Pseudo action: ceilometer-alarm-notifier-clone_stop_0 -+ * Pseudo action: neutron-ovs-cleanup-clone_stop_0 -+ * Resource action: ceilometer-alarm-notifier stop on rhos6-node1 -+ * Resource action: ceilometer-alarm-notifier stop on rhos6-node2 -+ * Resource action: ceilometer-alarm-notifier stop on rhos6-node3 -+ * Pseudo action: ceilometer-alarm-notifier-clone_stopped_0 -+ * Resource action: neutron-ovs-cleanup stop on rhos6-node1 -+ * Resource action: neutron-ovs-cleanup stop on rhos6-node2 -+ * Resource action: neutron-ovs-cleanup stop on rhos6-node3 -+ * Pseudo action: neutron-ovs-cleanup-clone_stopped_0 -+ * Pseudo action: ceilometer-alarm-evaluator-clone_stop_0 -+ * Pseudo action: neutron-scale-clone_stop_0 -+ * Resource action: ceilometer-alarm-evaluator stop on rhos6-node1 -+ * Resource action: ceilometer-alarm-evaluator stop on rhos6-node2 -+ * Resource action: ceilometer-alarm-evaluator stop on rhos6-node3 -+ * Pseudo action: ceilometer-alarm-evaluator-clone_stopped_0 -+ * Resource action: neutron-scale:0 stop on rhos6-node3 -+ * Resource action: neutron-scale:1 stop on rhos6-node2 -+ * Resource action: neutron-scale:2 stop on rhos6-node1 -+ * Pseudo action: neutron-scale-clone_stopped_0 -+ * Pseudo action: ceilometer-delay-clone_stop_0 -+ * Pseudo action: neutron-server-clone_stop_0 -+ * Resource action: ceilometer-delay stop on rhos6-node1 -+ * Resource action: ceilometer-delay stop on rhos6-node2 -+ * Resource action: ceilometer-delay stop on rhos6-node3 -+ * Pseudo action: ceilometer-delay-clone_stopped_0 -+ * Resource action: neutron-server stop on rhos6-node1 -+ * Resource action: neutron-server stop on rhos6-node2 -+ * Resource action: neutron-server stop on rhos6-node3 -+ * Pseudo action: neutron-server-clone_stopped_0 -+ * Pseudo action: ceilometer-api-clone_stop_0 -+ * Resource action: ceilometer-api stop on rhos6-node1 -+ * Resource action: ceilometer-api stop on rhos6-node2 -+ * Resource action: ceilometer-api stop on rhos6-node3 -+ * Pseudo action: ceilometer-api-clone_stopped_0 -+ * Pseudo action: ceilometer-collector-clone_stop_0 -+ * Resource action: ceilometer-collector stop on rhos6-node1 -+ * Resource action: ceilometer-collector stop on rhos6-node2 -+ * Resource action: ceilometer-collector stop on rhos6-node3 -+ * Pseudo action: ceilometer-collector-clone_stopped_0 -+ * Resource action: ceilometer-central stop on rhos6-node3 -+ * Pseudo action: keystone-clone_stop_0 -+ * Resource action: keystone stop on rhos6-node1 -+ * Resource action: keystone stop on rhos6-node2 -+ * Resource action: keystone stop on rhos6-node3 -+ * Pseudo action: keystone-clone_stopped_0 -+ * Pseudo action: all_stopped -+ -+Revised cluster status: -+Online: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ -+ node1-fence (stonith:fence_xvm): Started rhos6-node1 -+ node2-fence (stonith:fence_xvm): Started rhos6-node2 -+ node3-fence (stonith:fence_xvm): Started rhos6-node3 -+ Clone Set: lb-haproxy-clone [lb-haproxy] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ vip-db (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-rabbitmq (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-qpid (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ vip-keystone (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-glance (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-cinder (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ vip-swift (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-neutron (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-nova (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ vip-horizon (ocf::heartbeat:IPaddr2): Started rhos6-node1 -+ vip-heat (ocf::heartbeat:IPaddr2): Started rhos6-node2 -+ vip-ceilometer (ocf::heartbeat:IPaddr2): Started rhos6-node3 -+ Master/Slave Set: galera-master [galera] -+ Masters: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: rabbitmq-server-clone [rabbitmq-server] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: memcached-clone [memcached] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: mongodb-clone [mongodb] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: keystone-clone [keystone] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: glance-fs-clone [glance-fs] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: glance-registry-clone [glance-registry] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: glance-api-clone [glance-api] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ cinder-api (systemd:openstack-cinder-api): Stopped -+ cinder-scheduler (systemd:openstack-cinder-scheduler): Stopped -+ cinder-volume (systemd:openstack-cinder-volume): Stopped -+ Clone Set: swift-fs-clone [swift-fs] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-account-clone [swift-account] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-container-clone [swift-container] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-object-clone [swift-object] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: swift-proxy-clone [swift-proxy] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ swift-object-expirer (systemd:openstack-swift-object-expirer): Stopped -+ Clone Set: neutron-server-clone [neutron-server] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-scale-clone [neutron-scale] (unique) -+ neutron-scale:0 (ocf::neutron:NeutronScale): Stopped -+ neutron-scale:1 (ocf::neutron:NeutronScale): Stopped -+ neutron-scale:2 (ocf::neutron:NeutronScale): Stopped -+ Clone Set: neutron-ovs-cleanup-clone [neutron-ovs-cleanup] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-netns-cleanup-clone [neutron-netns-cleanup] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-openvswitch-agent-clone [neutron-openvswitch-agent] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-dhcp-agent-clone [neutron-dhcp-agent] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-l3-agent-clone [neutron-l3-agent] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: neutron-metadata-agent-clone [neutron-metadata-agent] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-consoleauth-clone [nova-consoleauth] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-novncproxy-clone [nova-novncproxy] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-api-clone [nova-api] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-scheduler-clone [nova-scheduler] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: nova-conductor-clone [nova-conductor] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ ceilometer-central (systemd:openstack-ceilometer-central): Stopped -+ Clone Set: ceilometer-collector-clone [ceilometer-collector] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-api-clone [ceilometer-api] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-delay-clone [ceilometer-delay] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-alarm-evaluator-clone [ceilometer-alarm-evaluator] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-alarm-notifier-clone [ceilometer-alarm-notifier] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: ceilometer-notification-clone [ceilometer-notification] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: heat-api-clone [heat-api] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: heat-api-cfn-clone [heat-api-cfn] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ Clone Set: heat-api-cloudwatch-clone [heat-api-cloudwatch] -+ Stopped: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ heat-engine (systemd:openstack-heat-engine): Stopped -+ Clone Set: horizon-clone [horizon] -+ Started: [ rhos6-node1 rhos6-node2 rhos6-node3 ] -+ -diff --git a/pengine/test10/complex_enforce_colo.xml b/pengine/test10/complex_enforce_colo.xml -new file mode 100644 -index 0000000..a6f9526 ---- /dev/null -+++ b/pengine/test10/complex_enforce_colo.xml -@@ -0,0 +1,1461 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/enforce-colo1.dot b/pengine/test10/enforce-colo1.dot -new file mode 100644 -index 0000000..68200fe ---- /dev/null -+++ b/pengine/test10/enforce-colo1.dot -@@ -0,0 +1,31 @@ -+ digraph "g" { -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"central_monitor_10000 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"central_start_0 rhel7-auto3" -> "central_monitor_10000 rhel7-auto3" [ style = dashed] -+"central_start_0 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"central_stop_0 rhel7-auto3" -> "all_stopped" [ style = bold] -+"central_stop_0 rhel7-auto3" -> "central_start_0 rhel7-auto3" [ style = dashed] -+"central_stop_0 rhel7-auto3" -> "keystone-clone_stop_0" [ style = bold] -+"central_stop_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"engine_monitor_10000 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"engine_start_0 rhel7-auto3" -> "engine_monitor_10000 rhel7-auto3" [ style = dashed] -+"engine_start_0 rhel7-auto3" [ style=dashed color="red" fontcolor="black"] -+"engine_stop_0 rhel7-auto3" -> "all_stopped" [ style = bold] -+"engine_stop_0 rhel7-auto3" -> "engine_start_0 rhel7-auto3" [ style = dashed] -+"engine_stop_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+"keystone-clone_stop_0" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone-clone_stop_0" -> "keystone_stop_0 rhel7-auto1" [ style = bold] -+"keystone-clone_stop_0" -> "keystone_stop_0 rhel7-auto2" [ style = bold] -+"keystone-clone_stop_0" -> "keystone_stop_0 rhel7-auto3" [ style = bold] -+"keystone-clone_stop_0" [ style=bold color="green" fontcolor="orange"] -+"keystone-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] -+"keystone_stop_0 rhel7-auto1" -> "all_stopped" [ style = bold] -+"keystone_stop_0 rhel7-auto1" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone_stop_0 rhel7-auto1" [ style=bold color="green" fontcolor="black"] -+"keystone_stop_0 rhel7-auto2" -> "all_stopped" [ style = bold] -+"keystone_stop_0 rhel7-auto2" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone_stop_0 rhel7-auto2" [ style=bold color="green" fontcolor="black"] -+"keystone_stop_0 rhel7-auto3" -> "all_stopped" [ style = bold] -+"keystone_stop_0 rhel7-auto3" -> "keystone-clone_stopped_0" [ style = bold] -+"keystone_stop_0 rhel7-auto3" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/enforce-colo1.exp b/pengine/test10/enforce-colo1.exp -new file mode 100644 -index 0000000..ea87443 ---- /dev/null -+++ b/pengine/test10/enforce-colo1.exp -@@ -0,0 +1,116 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/enforce-colo1.scores b/pengine/test10/enforce-colo1.scores -new file mode 100644 -index 0000000..b3dee71 ---- /dev/null -+++ b/pengine/test10/enforce-colo1.scores -@@ -0,0 +1,31 @@ -+Allocation scores: -+clone_color: keystone-clone allocation score on rhel7-auto1: 0 -+clone_color: keystone-clone allocation score on rhel7-auto2: 0 -+clone_color: keystone-clone allocation score on rhel7-auto3: 0 -+clone_color: keystone:0 allocation score on rhel7-auto1: 0 -+clone_color: keystone:0 allocation score on rhel7-auto2: 1 -+clone_color: keystone:0 allocation score on rhel7-auto3: 0 -+clone_color: keystone:1 allocation score on rhel7-auto1: 0 -+clone_color: keystone:1 allocation score on rhel7-auto2: 0 -+clone_color: keystone:1 allocation score on rhel7-auto3: 1 -+clone_color: keystone:2 allocation score on rhel7-auto1: 1 -+clone_color: keystone:2 allocation score on rhel7-auto2: 0 -+clone_color: keystone:2 allocation score on rhel7-auto3: 0 -+native_color: central allocation score on rhel7-auto1: 0 -+native_color: central allocation score on rhel7-auto2: 0 -+native_color: central allocation score on rhel7-auto3: 0 -+native_color: engine allocation score on rhel7-auto1: -INFINITY -+native_color: engine allocation score on rhel7-auto2: -INFINITY -+native_color: engine allocation score on rhel7-auto3: 0 -+native_color: keystone:0 allocation score on rhel7-auto1: -INFINITY -+native_color: keystone:0 allocation score on rhel7-auto2: -INFINITY -+native_color: keystone:0 allocation score on rhel7-auto3: -INFINITY -+native_color: keystone:1 allocation score on rhel7-auto1: -INFINITY -+native_color: keystone:1 allocation score on rhel7-auto2: -INFINITY -+native_color: keystone:1 allocation score on rhel7-auto3: -INFINITY -+native_color: keystone:2 allocation score on rhel7-auto1: -INFINITY -+native_color: keystone:2 allocation score on rhel7-auto2: -INFINITY -+native_color: keystone:2 allocation score on rhel7-auto3: -INFINITY -+native_color: shooter allocation score on rhel7-auto1: 0 -+native_color: shooter allocation score on rhel7-auto2: 0 -+native_color: shooter allocation score on rhel7-auto3: 0 -diff --git a/pengine/test10/enforce-colo1.summary b/pengine/test10/enforce-colo1.summary -new file mode 100644 -index 0000000..d8b16ed ---- /dev/null -+++ b/pengine/test10/enforce-colo1.summary -@@ -0,0 +1,36 @@ -+ -+Current cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto2 -+ engine (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ Clone Set: keystone-clone [keystone] -+ Started: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ central (ocf::heartbeat:Dummy): Started rhel7-auto3 -+ -+Transition Summary: -+ * Stop engine (Started rhel7-auto3) -+ * Stop keystone:0 (rhel7-auto2) -+ * Stop keystone:1 (rhel7-auto3) -+ * Stop keystone:2 (rhel7-auto1) -+ * Stop central (Started rhel7-auto3) -+ -+Executing cluster transition: -+ * Resource action: engine stop on rhel7-auto3 -+ * Resource action: central stop on rhel7-auto3 -+ * Pseudo action: keystone-clone_stop_0 -+ * Resource action: keystone stop on rhel7-auto2 -+ * Resource action: keystone stop on rhel7-auto3 -+ * Resource action: keystone stop on rhel7-auto1 -+ * Pseudo action: keystone-clone_stopped_0 -+ * Pseudo action: all_stopped -+ -+Revised cluster status: -+Online: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ -+ shooter (stonith:fence_xvm): Started rhel7-auto2 -+ engine (ocf::heartbeat:Dummy): Stopped -+ Clone Set: keystone-clone [keystone] -+ Stopped: [ rhel7-auto1 rhel7-auto2 rhel7-auto3 ] -+ central (ocf::heartbeat:Dummy): Stopped -+ -diff --git a/pengine/test10/enforce-colo1.xml b/pengine/test10/enforce-colo1.xml -new file mode 100644 -index 0000000..0378f34 ---- /dev/null -+++ b/pengine/test10/enforce-colo1.xml -@@ -0,0 +1,150 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-3414f1cd3ebcc2e6f787ea14d8e31510f36fbe4a-update-membership.patch b/SOURCES/pacemaker-3414f1cd3ebcc2e6f787ea14d8e31510f36fbe4a-update-membership.patch deleted file mode 100644 index 2b4c369..0000000 --- a/SOURCES/pacemaker-3414f1cd3ebcc2e6f787ea14d8e31510f36fbe4a-update-membership.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 3414f1cd3ebcc2e6f787ea14d8e31510f36fbe4a Mon Sep 17 00:00:00 2001 -From: Hideo Yamauchi -Date: Tue, 6 Jan 2015 16:05:34 +0900 -Subject: [PATCH] Update membership.c - ---- - crmd/membership.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/crmd/membership.c b/crmd/membership.c -index 946cde0..e1414df 100644 ---- a/crmd/membership.c -+++ b/crmd/membership.c -@@ -378,17 +378,13 @@ populate_cib_nodes(enum node_update_flags flags, const char *source) - - g_hash_table_iter_init(&iter, crm_peer_cache); - while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { -- xmlNode *update = NULL; -- update = do_update_node_cib(node, flags, node_list, source); -- free_xml(update); -+ do_update_node_cib(node, flags, node_list, source); - } - - if (crm_remote_peer_cache) { - g_hash_table_iter_init(&iter, crm_remote_peer_cache); - while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { -- xmlNode *update = NULL; -- update = do_update_node_cib(node, flags, node_list, source); -- free_xml(update); -+ do_update_node_cib(node, flags, node_list, source); - } - } - --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-5147bbf46b81708a1ac544a4cfd204b50938c67c-crmd-memleak.patch b/SOURCES/pacemaker-5147bbf46b81708a1ac544a4cfd204b50938c67c-crmd-memleak.patch deleted file mode 100644 index c3a9967..0000000 --- a/SOURCES/pacemaker-5147bbf46b81708a1ac544a4cfd204b50938c67c-crmd-memleak.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5147bbf46b81708a1ac544a4cfd204b50938c67c Mon Sep 17 00:00:00 2001 -From: Hideo Yamauchi -Date: Tue, 6 Jan 2015 13:45:19 +0900 -Subject: [PATCH] Fix: crmd: resolves memory leak in crmd. - ---- - crmd/membership.c | 10 ++++++++-- - crmd/pengine.c | 1 + - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/crmd/membership.c b/crmd/membership.c -index 9a58339..946cde0 100644 ---- a/crmd/membership.c -+++ b/crmd/membership.c -@@ -215,9 +215,11 @@ search_conflicting_node_callback(xmlNode * msg, int call_id, int rc, - crm_notice("Searching conflicting nodes for %s failed: %s (%d)", - new_node_uuid, pcmk_strerror(rc), rc); - } -+ free(new_node_uuid); - return; - - } else if (output == NULL) { -+ free(new_node_uuid); - return; - } - -@@ -376,13 +378,17 @@ populate_cib_nodes(enum node_update_flags flags, const char *source) - - g_hash_table_iter_init(&iter, crm_peer_cache); - while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { -- do_update_node_cib(node, flags, node_list, source); -+ xmlNode *update = NULL; -+ update = do_update_node_cib(node, flags, node_list, source); -+ free_xml(update); - } - - if (crm_remote_peer_cache) { - g_hash_table_iter_init(&iter, crm_remote_peer_cache); - while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { -- do_update_node_cib(node, flags, node_list, source); -+ xmlNode *update = NULL; -+ update = do_update_node_cib(node, flags, node_list, source); -+ free_xml(update); - } - } - -diff --git a/crmd/pengine.c b/crmd/pengine.c -index 2f7513f..35f35c6 100644 ---- a/crmd/pengine.c -+++ b/crmd/pengine.c -@@ -277,6 +277,7 @@ force_local_option(xmlNode *xml, const char *attr_name, const char *attr_value) - - free(attr_id); - } -+ freeXpathObject(xpathObj); - } - - void --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-6d482cf1c1226f75e59569b930cf916ccb0d350f-pcmk-remote-timer-fix.patch b/SOURCES/pacemaker-6d482cf1c1226f75e59569b930cf916ccb0d350f-pcmk-remote-timer-fix.patch deleted file mode 100644 index 701b54f..0000000 --- a/SOURCES/pacemaker-6d482cf1c1226f75e59569b930cf916ccb0d350f-pcmk-remote-timer-fix.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6d482cf1c1226f75e59569b930cf916ccb0d350f Mon Sep 17 00:00:00 2001 -From: Hideo Yamauchi -Date: Fri, 10 Oct 2014 13:11:01 +0900 -Subject: [PATCH] Mistake of the set of the variable. - ---- - crmd/remote_lrmd_ra.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/crmd/remote_lrmd_ra.c b/crmd/remote_lrmd_ra.c -index f3dedeb..929b3f8 100644 ---- a/crmd/remote_lrmd_ra.c -+++ b/crmd/remote_lrmd_ra.c -@@ -573,7 +573,7 @@ handle_remote_ra_exec(gpointer user_data) - * cleared which will require all the resources running in the remote-node - * to be explicitly re-detected via probe actions. If the takeover does occur - * successfully, then we can leave the status section intact. */ -- cmd->monitor_timeout_id = g_timeout_add((cmd->timeout/2), connection_takeover_timeout_cb, cmd); -+ cmd->takeover_timeout_id = g_timeout_add((cmd->timeout/2), connection_takeover_timeout_cb, cmd); - ra_data->cur_cmd = cmd; - return TRUE; - } --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-7170ed-fix-acl-correctly-implement-the-reference-acl-direct.patch b/SOURCES/pacemaker-7170ed-fix-acl-correctly-implement-the-reference-acl-direct.patch deleted file mode 100644 index 4489278..0000000 --- a/SOURCES/pacemaker-7170ed-fix-acl-correctly-implement-the-reference-acl-direct.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 7170ed6129d7381f3adab964d8295f00f7c4b776 Mon Sep 17 00:00:00 2001 -From: Andrew Beekhof -Date: Mon, 12 Jan 2015 13:45:17 +1100 -Subject: [PATCH] Fix: acl: Correctly implement the 'reference' acl directive - ---- - lib/common/xml.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/lib/common/xml.c b/lib/common/xml.c -index 54f1aa7..2c476dc 100644 ---- a/lib/common/xml.c -+++ b/lib/common/xml.c -@@ -653,8 +653,7 @@ __xml_acl_create(xmlNode * xml, xmlNode *target, enum xml_private_flags mode) - if(tag) { - offset += snprintf(buffer + offset, XML_BUFFER_SIZE - offset, "//%s", tag); - } else { -- /* Is this even legal xpath syntax? */ -- offset += snprintf(buffer + offset, XML_BUFFER_SIZE - offset, "*"); -+ offset += snprintf(buffer + offset, XML_BUFFER_SIZE - offset, "//*"); - } - - if(ref || attr) { --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-8805f9-fix-ensure-b-with-a.patch b/SOURCES/pacemaker-8805f9-fix-ensure-b-with-a.patch deleted file mode 100644 index 9a16753..0000000 --- a/SOURCES/pacemaker-8805f9-fix-ensure-b-with-a.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 8805f9c1a6663da7732637ed60a8b42c360492cd Mon Sep 17 00:00:00 2001 -From: David Vossel -Date: Wed, 18 Feb 2015 13:45:07 -0500 -Subject: [PATCH] Fix: ensure if B is colocated with A, B can never run without - A - ---- - pengine/allocate.c | 2 ++ - pengine/graph.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+) - -diff --git a/pengine/allocate.c b/pengine/allocate.c -index 7dd70f1..0994a87 100644 ---- a/pengine/allocate.c -+++ b/pengine/allocate.c -@@ -1620,6 +1620,7 @@ rsc_order_first(resource_t * lh_rsc, order_constraint_t * order, pe_working_set_ - } - - extern gboolean update_action(action_t * action); -+extern void update_colo_start_chain(action_t * action); - - static void - apply_remote_node_ordering(pe_working_set_t *data_set) -@@ -1805,6 +1806,7 @@ stage7(pe_working_set_t * data_set) - for (; gIter != NULL; gIter = gIter->next) { - action_t *action = (action_t *) gIter->data; - -+ update_colo_start_chain(action); - update_action(action); - } - -diff --git a/pengine/graph.c b/pengine/graph.c -index 7160bbf..8decd51 100644 ---- a/pengine/graph.c -+++ b/pengine/graph.c -@@ -30,6 +30,7 @@ - #include - - gboolean update_action(action_t * action); -+void update_colo_start_chain(action_t * action); - gboolean rsc_update_action(action_t * first, action_t * then, enum pe_ordering type); - - static enum pe_action_flags -@@ -389,6 +390,57 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac - return changed; - } - -+static void -+mark_start_blocked(resource_t *rsc) -+{ -+ GListPtr gIter = rsc->actions; -+ -+ for (; gIter != NULL; gIter = gIter->next) { -+ action_t *action = (action_t *) gIter->data; -+ -+ if (safe_str_neq(action->task, RSC_START)) { -+ continue; -+ } -+ if (is_set(action->flags, pe_action_runnable)) { -+ clear_bit(action->flags, pe_action_runnable); -+ update_colo_start_chain(action); -+ update_action(action); -+ } -+ } -+} -+ -+void -+update_colo_start_chain(action_t *action) -+{ -+ GListPtr gIter = NULL; -+ resource_t *rsc = NULL; -+ -+ if (is_not_set(action->flags, pe_action_runnable) && safe_str_eq(action->task, RSC_START)) { -+ rsc = uber_parent(action->rsc); -+ } -+ -+ if (rsc == NULL || rsc->rsc_cons_lhs == NULL) { -+ return; -+ } -+ -+ /* if rsc has children, all the children need to have start set to -+ * unrunnable before we follow the colo chain for the parent. */ -+ for (gIter = rsc->children; gIter != NULL; gIter = gIter->next) { -+ resource_t *child = (resource_t *)gIter->data; -+ action_t *start = find_first_action(child->actions, NULL, RSC_START, NULL); -+ if (start == NULL || is_set(start->flags, pe_action_runnable)) { -+ return; -+ } -+ } -+ -+ for (gIter = rsc->rsc_cons_lhs; gIter != NULL; gIter = gIter->next) { -+ rsc_colocation_t *colocate_with = (rsc_colocation_t *)gIter->data; -+ if (colocate_with->score == INFINITY) { -+ mark_start_blocked(colocate_with->rsc_lh); -+ } -+ } -+} -+ - gboolean - update_action(action_t * then) - { -@@ -547,6 +599,9 @@ update_action(action_t * then) - pe_action_pseudo) ? "pseudo" : then->node ? then->node->details-> - uname : ""); - -+ if (is_set(last_flags, pe_action_runnable) && is_not_set(then->flags, pe_action_runnable)) { -+ update_colo_start_chain(then); -+ } - update_action(then); - for (lpc = then->actions_after; lpc != NULL; lpc = lpc->next) { - action_wrapper_t *other = (action_wrapper_t *) lpc->data; --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-8ffcf86bcab8bf98d5477a68b73e5062eb0c0fad-pacemakerd-memleak.patch b/SOURCES/pacemaker-8ffcf86bcab8bf98d5477a68b73e5062eb0c0fad-pacemakerd-memleak.patch deleted file mode 100644 index 234331d..0000000 --- a/SOURCES/pacemaker-8ffcf86bcab8bf98d5477a68b73e5062eb0c0fad-pacemakerd-memleak.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8ffcf86bcab8bf98d5477a68b73e5062eb0c0fad Mon Sep 17 00:00:00 2001 -From: Hideo Yamauchi -Date: Wed, 24 Dec 2014 09:37:52 +0900 -Subject: [PATCH] Fix: pacemakerd: resolves memory leak of xml structure in - pacemakerd - ---- - mcp/pacemaker.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/mcp/pacemaker.c b/mcp/pacemaker.c -index fa2c707..5235ba6 100644 ---- a/mcp/pacemaker.c -+++ b/mcp/pacemaker.c -@@ -828,6 +828,10 @@ mcp_cpg_deliver(cpg_handle_t handle, - name = crm_element_value(xml, XML_ATTR_UNAME); - reap_crm_member(id, name); - } -+ -+ if (xml != NULL) { -+ free_xml(xml); -+ } - } - - static void --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-async-systemd-reload.patch b/SOURCES/pacemaker-async-systemd-reload.patch deleted file mode 100644 index 6398fc0..0000000 --- a/SOURCES/pacemaker-async-systemd-reload.patch +++ /dev/null @@ -1,665 +0,0 @@ -diff --git a/include/crm/common/logging.h b/include/crm/common/logging.h -index 5b8e47f..642fa92 100644 ---- a/include/crm/common/logging.h -+++ b/include/crm/common/logging.h -@@ -157,7 +157,7 @@ unsigned int get_crm_log_level(void); - } \ - } while(0) - --# define do_crm_log_always(level, fmt, args...) qb_log(level, "%s: " fmt, __FUNCTION__ , ##args) -+# define do_crm_log_always(level, fmt, args...) qb_log(level, fmt , ##args) - - # define crm_perror(level, fmt, args...) do { \ - const char *err = strerror(errno); \ -diff --git a/include/crm/services.h b/include/crm/services.h -index 5310709..1a02656 100644 ---- a/include/crm/services.h -+++ b/include/crm/services.h -@@ -262,8 +262,9 @@ enum nagios_exitcode { - */ - svc_action_t *services_action_create_generic(const char *exec, const char *args[]); - -- void -- services_action_free(svc_action_t * op); -+ void services_action_cleanup(svc_action_t * op); -+ -+ void services_action_free(svc_action_t * op); - - gboolean services_action_sync(svc_action_t * op); - -diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c -index 15b354b..ea37c4b 100644 ---- a/lib/cib/cib_utils.c -+++ b/lib/cib/cib_utils.c -@@ -112,8 +112,13 @@ get_cib_copy(cib_t * cib) - { - xmlNode *xml_cib; - int options = cib_scope_local | cib_sync_call; -- int rc = cib->cmds->query(cib, NULL, &xml_cib, options); -+ int rc = pcmk_ok; -+ -+ if (cib->state == cib_disconnected) { -+ return NULL; -+ } - -+ rc = cib->cmds->query(cib, NULL, &xml_cib, options); - if (rc == -EACCES) { - return NULL; - -diff --git a/lib/services/dbus.c b/lib/services/dbus.c -index c0153b5..f44b590 100644 ---- a/lib/services/dbus.c -+++ b/lib/services/dbus.c -@@ -145,7 +145,7 @@ DBusMessage *pcmk_dbus_send_recv(DBusMessage *msg, DBusConnection *connection, D - return reply; - } - --bool pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, -+DBusPendingCall* pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, - void(*done)(DBusPendingCall *pending, void *user_data), void *user_data) - { - DBusError error; -@@ -161,27 +161,30 @@ bool pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, - // send message and get a handle for a reply - if (!dbus_connection_send_with_reply (connection, msg, &pending, -1/* aka. DBUS_TIMEOUT_USE_DEFAULT */)) { // -1 is default timeout - crm_err("Send with reply failed for %s", method); -- return FALSE; -+ return NULL; - - } else if (pending == NULL) { - crm_err("No pending call found for %s", method); -- return FALSE; -- -+ return NULL; - } - -+ crm_trace("DBus %s call sent", method); - if (dbus_pending_call_get_completed(pending)) { -- crm_info("DBus %s call completed too soon"); --#if 1 -+ crm_info("DBus %s call completed too soon", method); -+ if(done) { -+#if 0 - /* This sounds like a good idea, but allegedly it breaks things */ - done(pending, user_data); -+ pending = NULL; - #else - CRM_ASSERT(dbus_pending_call_set_notify(pending, done, user_data, NULL)); - #endif -+ } - -- } else { -+ } else if(done) { - CRM_ASSERT(dbus_pending_call_set_notify(pending, done, user_data, NULL)); - } -- return TRUE; -+ return pending; - } - - bool pcmk_dbus_type_check(DBusMessage *msg, DBusMessageIter *field, int expected, const char *function, int line) -@@ -286,6 +289,11 @@ pcmk_dbus_lookup_result(DBusMessage *reply, struct db_getall_data *data) - dbus_message_iter_next (&dict); - } - -+ if(data->name && data->callback) { -+ crm_trace("No value for property %s[%s]", data->object, data->name); -+ data->callback(data->name, NULL, data->userdata); -+ } -+ - cleanup: - free(data->target); - free(data->object); -@@ -306,6 +314,9 @@ pcmk_dbus_lookup_cb(DBusPendingCall *pending, void *user_data) - - pcmk_dbus_lookup_result(reply, user_data); - -+ if(pending) { -+ dbus_pending_call_unref(pending); -+ } - if(reply) { - dbus_message_unref(reply); - } -@@ -375,20 +386,59 @@ static void pcmk_dbus_connection_dispatch(DBusConnection *connection, DBusDispat - crm_trace("status %d for %p", new_status, data); - if (new_status == DBUS_DISPATCH_DATA_REMAINS){ - dbus_connection_dispatch(connection); -+ -+ while (dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS) { -+ dbus_connection_dispatch(connection); -+ } - } - } - -+/* Copied from dbus-watch.c */ -+ -+static const char* -+dbus_watch_flags_to_string (int flags) -+{ -+ const char *watch_type; -+ -+ if ((flags & DBUS_WATCH_READABLE) && -+ (flags & DBUS_WATCH_WRITABLE)) -+ watch_type = "readwrite"; -+ else if (flags & DBUS_WATCH_READABLE) -+ watch_type = "read"; -+ else if (flags & DBUS_WATCH_WRITABLE) -+ watch_type = "write"; -+ else -+ watch_type = "not read or write"; -+ return watch_type; -+} -+ - static int - pcmk_dbus_watch_dispatch(gpointer userdata) - { -+ bool oom = FALSE; - DBusWatch *watch = userdata; - int flags = dbus_watch_get_flags(watch); -+ bool enabled = dbus_watch_get_enabled (watch); -+ mainloop_io_t *client = dbus_watch_get_data(watch); - -- crm_trace("Dispatching %p with flags %d", watch, flags); -- if(flags & DBUS_WATCH_READABLE) { -- dbus_watch_handle(watch, DBUS_WATCH_READABLE); -- } else { -- dbus_watch_handle(watch, DBUS_WATCH_ERROR); -+ crm_trace("Dispatching client %p: %s", client, dbus_watch_flags_to_string(flags)); -+ if (enabled && is_set(flags, DBUS_WATCH_READABLE)) { -+ oom = !dbus_watch_handle(watch, flags); -+ -+ } else if (enabled && is_set(flags, DBUS_WATCH_READABLE)) { -+ oom = !dbus_watch_handle(watch, flags); -+ -+ } else if(enabled) { -+ oom = !dbus_watch_handle(watch, DBUS_WATCH_ERROR); -+ } -+ -+ if(flags != dbus_watch_get_flags(watch)) { -+ flags = dbus_watch_get_flags(watch); -+ crm_trace("Dispatched client %p: %s (%d)", client, dbus_watch_flags_to_string(flags), flags); -+ } -+ -+ if(oom) { -+ crm_err("DBus encountered OOM while attempting to dispatch %p (%s)", client, dbus_watch_flags_to_string(flags)); - } - return 0; - } -@@ -396,7 +446,8 @@ pcmk_dbus_watch_dispatch(gpointer userdata) - static void - pcmk_dbus_watch_destroy(gpointer userdata) - { -- crm_trace("Destroyed %p", userdata); -+ mainloop_io_t *client = dbus_watch_get_data(userdata); -+ crm_trace("Destroyed %p", client); - } - - -@@ -412,7 +463,7 @@ pcmk_dbus_watch_add(DBusWatch *watch, void *data){ - mainloop_io_t *client = mainloop_add_fd( - "dbus", G_PRIORITY_DEFAULT, fd, watch, &pcmk_dbus_cb); - -- crm_trace("Added %p with fd=%d", watch, fd); -+ crm_trace("Added watch %p with fd=%d to client %p", watch, fd, client); - dbus_watch_set_data(watch, client, NULL); - return TRUE; - } -@@ -429,14 +480,14 @@ static void - pcmk_dbus_watch_remove(DBusWatch *watch, void *data){ - mainloop_io_t *client = dbus_watch_get_data(watch); - -- crm_trace("Removed %p", watch); -+ crm_trace("Removed client %p (%p)", client, data); - mainloop_del_fd(client); - } - - static gboolean - pcmk_dbus_timeout_dispatch(gpointer data) - { -- crm_trace("Timeout for %p"); -+ crm_info("Timeout %p expired", data); - dbus_timeout_handle(data); - return FALSE; - } -@@ -445,6 +496,8 @@ static dbus_bool_t - pcmk_dbus_timeout_add(DBusTimeout *timeout, void *data){ - guint id = g_timeout_add(dbus_timeout_get_interval(timeout), pcmk_dbus_timeout_dispatch, timeout); - -+ crm_trace("Adding timeout %p (%ld)", timeout, dbus_timeout_get_interval(timeout)); -+ - if(id) { - dbus_timeout_set_data(timeout, GUINT_TO_POINTER(id), NULL); - } -@@ -456,6 +509,8 @@ pcmk_dbus_timeout_remove(DBusTimeout *timeout, void *data){ - void *vid = dbus_timeout_get_data(timeout); - guint id = GPOINTER_TO_UINT(vid); - -+ crm_trace("Removing timeout %p (%p)", timeout, data); -+ - if(id) { - g_source_remove(id); - dbus_timeout_set_data(timeout, 0, NULL); -@@ -464,7 +519,11 @@ pcmk_dbus_timeout_remove(DBusTimeout *timeout, void *data){ - - static void - pcmk_dbus_timeout_toggle(DBusTimeout *timeout, void *data){ -- if(dbus_timeout_get_enabled(timeout)) { -+ bool enabled = dbus_timeout_get_enabled(timeout); -+ -+ crm_trace("Toggling timeout for %p to %s", timeout, enabled?"off":"on"); -+ -+ if(enabled) { - pcmk_dbus_timeout_add(timeout, data); - } else { - pcmk_dbus_timeout_remove(timeout, data); -diff --git a/lib/services/pcmk-dbus.h b/lib/services/pcmk-dbus.h -index ed80c5f..468020e 100644 ---- a/lib/services/pcmk-dbus.h -+++ b/lib/services/pcmk-dbus.h -@@ -2,7 +2,7 @@ DBusConnection *pcmk_dbus_connect(void); - void pcmk_dbus_connection_setup_with_select(DBusConnection *c); - void pcmk_dbus_disconnect(DBusConnection *connection); - --bool pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, -+DBusPendingCall *pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, - void(*done)(DBusPendingCall *pending, void *user_data), void *user_data); - DBusMessage *pcmk_dbus_send_recv(DBusMessage *msg, DBusConnection *connection, DBusError *error); - bool pcmk_dbus_type_check(DBusMessage *msg, DBusMessageIter *field, int expected, const char *function, int line); -diff --git a/lib/services/services.c b/lib/services/services.c -index 9936c72..582fbe1 100644 ---- a/lib/services/services.c -+++ b/lib/services/services.c -@@ -303,18 +303,24 @@ services_action_create_generic(const char *exec, const char *args[]) - } - - void --services_action_free(svc_action_t * op) -+services_action_cleanup(svc_action_t * op) - { -- unsigned int i; -- -- if (op == NULL) { -- return; -+ if(op->opaque->timerid != 0) { -+ crm_trace("Removing timer for call %s to %s", op->action, op->rsc); -+ g_source_remove(op->opaque->timerid); -+ op->opaque->timerid = 0; - } - -- if (op->opaque->repeat_timer) { -- g_source_remove(op->opaque->repeat_timer); -- op->opaque->repeat_timer = 0; -+ if(op->opaque->pending) { -+ crm_trace("Cleaning up pending dbus call %p %s for %s", op->opaque->pending, op->action, op->rsc); -+ if(dbus_pending_call_get_completed(op->opaque->pending)) { -+ crm_warn("Pending dbus call %s for %s did not complete", op->action, op->rsc); -+ } -+ dbus_pending_call_cancel(op->opaque->pending); -+ dbus_pending_call_unref(op->opaque->pending); -+ op->opaque->pending = NULL; - } -+ - if (op->opaque->stderr_gsource) { - mainloop_del_fd(op->opaque->stderr_gsource); - op->opaque->stderr_gsource = NULL; -@@ -324,6 +330,23 @@ services_action_free(svc_action_t * op) - mainloop_del_fd(op->opaque->stdout_gsource); - op->opaque->stdout_gsource = NULL; - } -+} -+ -+void -+services_action_free(svc_action_t * op) -+{ -+ unsigned int i; -+ -+ if (op == NULL) { -+ return; -+ } -+ -+ services_action_cleanup(op); -+ -+ if (op->opaque->repeat_timer) { -+ g_source_remove(op->opaque->repeat_timer); -+ op->opaque->repeat_timer = 0; -+ } - - free(op->id); - free(op->opaque->exec); -diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c -index 2279e4e..8d6f450 100644 ---- a/lib/services/services_linux.c -+++ b/lib/services/services_linux.c -@@ -264,6 +264,8 @@ operation_finalize(svc_action_t * op) - services_action_free(op); - return TRUE; - } -+ -+ services_action_cleanup(op); - return FALSE; - } - -diff --git a/lib/services/services_private.h b/lib/services/services_private.h -index dd759e3..bcf882c 100644 ---- a/lib/services/services_private.h -+++ b/lib/services/services_private.h -@@ -19,6 +19,10 @@ - #ifndef __MH_SERVICES_PRIVATE_H__ - # define __MH_SERVICES_PRIVATE_H__ - -+#if SUPPORT_DBUS -+# include -+#endif -+ - struct svc_action_private_s { - char *exec; - char *args[255]; -@@ -31,6 +35,10 @@ struct svc_action_private_s { - - int stdout_fd; - mainloop_io_t *stdout_gsource; -+#if SUPPORT_DBUS -+ DBusPendingCall* pending; -+ unsigned timerid; -+#endif - }; - - GList *services_os_get_directory_list(const char *root, gboolean files, gboolean executable); -diff --git a/lib/services/systemd.c b/lib/services/systemd.c -index 9a7b078..51ade44 100644 ---- a/lib/services/systemd.c -+++ b/lib/services/systemd.c -@@ -110,20 +110,48 @@ systemd_service_name(const char *name) - return g_strdup_printf("%s.service", name); - } - --static bool --systemd_daemon_reload(void) -+static void -+systemd_daemon_reload_complete(DBusPendingCall *pending, void *user_data) - { -- /* TODO: Make this asynchronous */ -- const char *method = "Reload"; -+ DBusError error; - DBusMessage *reply = NULL; -- DBusMessage *msg = systemd_new_method(BUS_NAME".Manager", method); -+ unsigned int reload_count = GPOINTER_TO_UINT(user_data); - -- CRM_ASSERT(msg != NULL); -- reply = pcmk_dbus_send_recv(msg, systemd_proxy, NULL); -- dbus_message_unref(msg); -+ dbus_error_init(&error); -+ if(pending) { -+ reply = dbus_pending_call_steal_reply(pending); -+ } -+ -+ if(pcmk_dbus_find_error("Reload", pending, reply, &error)) { -+ crm_err("Could not issue systemd reload %d: %s", reload_count, error.message); -+ -+ } else { -+ crm_trace("Reload %d complete", reload_count); -+ } -+ -+ if(pending) { -+ dbus_pending_call_unref(pending); -+ } - if(reply) { - dbus_message_unref(reply); - } -+} -+ -+static bool -+systemd_daemon_reload(void) -+{ -+ static unsigned int reload_count = 0; -+ const char *method = "Reload"; -+ -+ -+ reload_count++; -+ if(reload_count % 10 == 0) { -+ DBusMessage *msg = systemd_new_method(BUS_NAME".Manager", method); -+ -+ CRM_ASSERT(msg != NULL); -+ pcmk_dbus_send(msg, systemd_proxy, systemd_daemon_reload_complete, GUINT_TO_POINTER(reload_count)); -+ dbus_message_unref(msg); -+ } - return TRUE; - } - -@@ -155,13 +183,22 @@ static void - systemd_loadunit_cb(DBusPendingCall *pending, void *user_data) - { - DBusMessage *reply = NULL; -+ svc_action_t * op = user_data; - - if(pending) { - reply = dbus_pending_call_steal_reply(pending); - } - -+ if(op) { -+ crm_trace("Got result: %p for %p for %s, %s", reply, pending, op->rsc, op->action); -+ } else { -+ crm_trace("Got result: %p for %p", reply, pending); -+ } - systemd_loadunit_result(reply, user_data); - -+ if(pending) { -+ dbus_pending_call_unref(pending); -+ } - if(reply) { - dbus_message_unref(reply); - } -@@ -213,6 +250,7 @@ systemd_unit_by_name(const gchar * arg_name, svc_action_t *op) - } - - pcmk_dbus_send(msg, systemd_proxy, systemd_loadunit_cb, op); -+ dbus_message_unref(msg); - return NULL; - } - -@@ -421,6 +459,12 @@ systemd_async_dispatch(DBusPendingCall *pending, void *user_data) - reply = dbus_pending_call_steal_reply(pending); - } - -+ if(op) { -+ crm_trace("Got result: %p for %p for %s, %s", reply, pending, op->rsc, op->action); -+ } else { -+ crm_trace("Got result: %p for %p", reply, pending); -+ } -+ op->opaque->pending = NULL; - systemd_exec_result(reply, op); - - if(pending) { -@@ -437,10 +481,13 @@ static void - systemd_unit_check(const char *name, const char *state, void *userdata) - { - svc_action_t * op = userdata; -- -- CRM_ASSERT(state != NULL); - -- if (g_strcmp0(state, "active") == 0) { -+ crm_trace("Resource %s has %s='%s'", op->rsc, name, state); -+ -+ if(state == NULL) { -+ op->rc = PCMK_OCF_NOT_RUNNING; -+ -+ } else if (g_strcmp0(state, "active") == 0) { - op->rc = PCMK_OCF_OK; - } else if (g_strcmp0(state, "activating") == 0) { - op->rc = PCMK_OCF_PENDING; -@@ -449,6 +496,7 @@ systemd_unit_check(const char *name, const char *state, void *userdata) - } - - if (op->synchronous == FALSE) { -+ op->opaque->pending = NULL; - operation_finalize(op); - } - } -@@ -539,28 +587,29 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - } - - if (op->synchronous == FALSE) { -- return pcmk_dbus_send(msg, systemd_proxy, systemd_async_dispatch, op); -+ DBusPendingCall* pending = pcmk_dbus_send(msg, systemd_proxy, systemd_async_dispatch, op); -+ -+ dbus_message_unref(msg); -+ if(pending) { -+ dbus_pending_call_ref(pending); -+ op->opaque->pending = pending; -+ return TRUE; -+ } -+ return FALSE; - - } else { - DBusError error; - - reply = pcmk_dbus_send_recv(msg, systemd_proxy, &error); -+ dbus_message_unref(msg); - systemd_exec_result(reply, op); - - if(reply) { - dbus_message_unref(reply); - } -- if(msg) { -- dbus_message_unref(msg); -- } -- - return FALSE; - } - -- if(msg) { -- dbus_message_unref(msg); -- } -- - cleanup: - if (op->synchronous == FALSE) { - operation_finalize(op); -@@ -570,6 +619,18 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - return op->rc == PCMK_OCF_OK; - } - -+static gboolean -+systemd_timeout_callback(gpointer p) -+{ -+ svc_action_t * op = p; -+ -+ op->opaque->timerid = 0; -+ crm_warn("%s operation on systemd unit %s named '%s' timed out", op->action, op->agent, op->rsc); -+ operation_finalize(op); -+ -+ return FALSE; -+} -+ - gboolean - systemd_unit_exec(svc_action_t * op) - { -@@ -596,6 +657,7 @@ systemd_unit_exec(svc_action_t * op) - free(unit); - - if (op->synchronous == FALSE) { -+ op->opaque->timerid = g_timeout_add(op->timeout + 5000, systemd_timeout_callback, op); - return TRUE; - } - -diff --git a/lib/services/upstart.c b/lib/services/upstart.c -index 4c7211d..01ff817 100644 ---- a/lib/services/upstart.c -+++ b/lib/services/upstart.c -@@ -513,8 +513,15 @@ upstart_job_exec(svc_action_t * op, gboolean synchronous) - CRM_LOG_ASSERT(dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg_wait, DBUS_TYPE_INVALID)); - - if (op->synchronous == FALSE) { -+ DBusPendingCall* pending = pcmk_dbus_send(msg, upstart_proxy, upstart_async_dispatch, op); - free(job); -- return pcmk_dbus_send(msg, upstart_proxy, upstart_async_dispatch, op); -+ -+ if(pending) { -+ dbus_pending_call_ref(pending); -+ op->opaque->pending = pending; -+ return TRUE; -+ } -+ return FALSE; - } - - dbus_error_init(&error); -diff --git a/lrmd/regression.py.in b/lrmd/regression.py.in -index a9a32ef..649c984 100755 ---- a/lrmd/regression.py.in -+++ b/lrmd/regression.py.in -@@ -27,12 +27,12 @@ build_dir="@abs_top_builddir@" - test_dir=sys.path[0] - - new_path=os.environ['PATH'] -- - if os.path.exists("%s/regression.py.in" % test_dir): - print "Running tests from the source tree: %s (%s)" % (build_dir, test_dir) - new_path = "%s/lrmd:%s" % (build_dir, new_path) # For lrmd, lrmd_test and pacemaker_remoted - new_path = "%s/tools:%s" % (build_dir, new_path) # For crm_resource - new_path = "%s/fencing:%s" % (build_dir, new_path) # For stonithd -+ - else: - print "Running tests from the install tree: @CRM_DAEMON_DIR@ (not %s)" % test_dir - new_path = "@CRM_DAEMON_DIR@:%s" % (new_path) # For stonithd, lrmd, lrmd_test and pacemaker_remoted -@@ -434,13 +434,15 @@ if __name__ == "__main__": - for ra in [ "Dummy", "Stateful", "ping" ]: - os.system("cp %s/extra/resources/%s @OCF_RA_DIR@/pacemaker/%s" % (build_dir, ra, ra)) - os.system("chmod a+x @OCF_RA_DIR@/pacemaker/%s" % (ra)) -- else: -- # Assume it's installed -- print "Using @datadir@/@PACKAGE@/tests/cts/LSBDummy" -- os.system("cp @datadir@/@PACKAGE@/tests/cts/LSBDummy /etc/init.d/LSBDummy") - -- os.system("chmod a+x /etc/init.d/LSBDummy") -- os.system("ls -al /etc/init.d/LSBDummy") -+ else: -+ # Assume it's installed -+ print "Using @datadir@/@PACKAGE@/tests/cts/LSBDummy" -+ os.system("cp @datadir@/@PACKAGE@/tests/cts/LSBDummy /etc/init.d/LSBDummy") -+ -+ os.system("chmod a+x /etc/init.d/LSBDummy") -+ os.system("ls -al /etc/init.d/LSBDummy") -+ - os.system("mkdir -p @CRM_CORE_DIR@/root") - - if os.path.exists("/bin/systemctl"): -@@ -747,6 +749,33 @@ if __name__ == "__main__": - test.add_cmd("-c unregister_rsc -r \"test_rsc\" "+self.action_timeout+ - "-l \"NEW_EVENT event_type:unregister rsc_id:test_rsc action:none rc:ok op_status:complete\" ") - -+ ### stress tests ### -+ def build_stress_tests(self): -+ timeout = "-t 20000" -+ iterations = 25 -+ -+ test = self.new_test("ocf_stress", "Verify systemd dbus connection works under load") -+ for i in range(iterations): -+ test.add_cmd("-c register_rsc -r rsc_%s %s -C ocf -P heartbeat -T Dummy -l \"NEW_EVENT event_type:register rsc_id:rsc_%s action:none rc:ok op_status:complete\"" % (i, timeout, i)) -+ test.add_cmd("-c exec -r rsc_%s -a start %s -l \"NEW_EVENT event_type:exec_complete rsc_id:rsc_%s action:start rc:ok op_status:complete\"" % (i, timeout, i)) -+ test.add_cmd("-c exec -r rsc_%s -a monitor %s -i 1000 -l \"NEW_EVENT event_type:exec_complete rsc_id:rsc_%s action:monitor rc:ok op_status:complete\"" % (i, timeout, i)) -+ for i in range(iterations): -+ test.add_cmd("-c exec -r rsc_%s -a stop %s -l \"NEW_EVENT event_type:exec_complete rsc_id:rsc_%s action:stop rc:ok op_status:complete\"" % (i, timeout, i)) -+ test.add_cmd("-c unregister_rsc -r rsc_%s %s -l \"NEW_EVENT event_type:unregister rsc_id:rsc_%s action:none rc:ok op_status:complete\"" % (i, timeout, i)) -+ -+ -+ if "systemd" in self.rsc_classes: -+ test = self.new_test("systemd_stress", "Verify systemd dbus connection works under load") -+ for i in range(iterations): -+ test.add_cmd("-c register_rsc -r rsc_%s %s -C systemd -T lrmd_dummy_daemon -l \"NEW_EVENT event_type:register rsc_id:rsc_%s action:none rc:ok op_status:complete\"" % (i, timeout, i)) -+ test.add_cmd("-c exec -r rsc_%s -a start %s -l \"NEW_EVENT event_type:exec_complete rsc_id:rsc_%s action:start rc:ok op_status:complete\"" % (i, timeout, i)) -+ test.add_cmd("-c exec -r rsc_%s -a monitor %s -i 1000 -l \"NEW_EVENT event_type:exec_complete rsc_id:rsc_%s action:monitor rc:ok op_status:complete\"" % (i, timeout, i)) -+ -+ for i in range(iterations): -+ test.add_cmd("-c exec -r rsc_%s -a stop %s -l \"NEW_EVENT event_type:exec_complete rsc_id:rsc_%s action:stop rc:ok op_status:complete\"" % (i, timeout, i)) -+ test.add_cmd("-c unregister_rsc -r rsc_%s %s -l \"NEW_EVENT event_type:unregister rsc_id:rsc_%s action:none rc:ok op_status:complete\"" % (i, timeout, i)) -+ -+ - ### These are tests that target specific cases ### - def build_custom_tests(self): - -@@ -1016,6 +1045,7 @@ def main(argv): - tests.build_multi_rsc_tests() - tests.build_negative_tests() - tests.build_custom_tests() -+ tests.build_stress_tests() - - tests.setup_test_environment() - diff --git a/SOURCES/pacemaker-attrd-updater-other-nodes.patch b/SOURCES/pacemaker-attrd-updater-other-nodes.patch deleted file mode 100644 index 91df385..0000000 --- a/SOURCES/pacemaker-attrd-updater-other-nodes.patch +++ /dev/null @@ -1,45 +0,0 @@ -commit 7652cce56196ee039245c21f8a7f8d5e55149358 -Author: Andrew Beekhof -Date: Wed Jan 14 12:05:38 2015 +1100 - - Feature: attrd_updater: Allow attributes to be set for other nodes - -diff --git a/tools/attrd_updater.c b/tools/attrd_updater.c -index 54b2c60..703f7f9 100644 ---- a/tools/attrd_updater.c -+++ b/tools/attrd_updater.c -@@ -32,6 +32,7 @@ - - #include - -+const char *attr_node = NULL; - const char *attr_name = NULL; - const char *attr_value = NULL; - const char *attr_set = NULL; -@@ -59,6 +60,7 @@ static struct crm_option long_options[] = { - {"lifetime",1, 0, 'l', "Lifetime of the node attribute. Allowed values: forever, reboot"}, - {"delay", 1, 0, 'd', "The time to wait (dampening) in seconds further changes occur"}, - {"set", 1, 0, 's', "(Advanced) The attribute set in which to place the value"}, -+ {"node", 1, 0, 'N', "Set the attribute for the named node (instead of the local one)"}, - - /* Legacy options */ - {"update", 1, 0, 'v', NULL, 1}, -@@ -108,6 +110,9 @@ main(int argc, char **argv) - case 'S': - attr_section = strdup(optarg); - break; -+ case 'N': -+ attr_node = strdup(optarg); -+ break; - case 'q': - break; - case 'Q': -@@ -141,7 +146,7 @@ main(int argc, char **argv) - crm_help('?', EX_USAGE); - - } else { -- int rc = attrd_update_delegate(NULL, command, NULL, attr_name, attr_value, attr_section, -+ int rc = attrd_update_delegate(NULL, command, attr_node, attr_name, attr_value, attr_section, - attr_set, attr_dampen, NULL, FALSE); - if (rc != pcmk_ok) { - fprintf(stderr, "Could not update %s=%s: %s (%d)\n", attr_name, attr_value, pcmk_strerror(rc), rc); diff --git a/SOURCES/pacemaker-cb0f29d4.patch b/SOURCES/pacemaker-cb0f29d4.patch deleted file mode 100644 index 10c99ed..0000000 --- a/SOURCES/pacemaker-cb0f29d4.patch +++ /dev/null @@ -1,149 +0,0 @@ -From cb0f29d437ded2557d8ae35970fdadf9da7392c1 Mon Sep 17 00:00:00 2001 -From: David Vossel -Date: Fri, 6 Mar 2015 13:19:43 -0500 -Subject: [PATCH] Fix: systemd: fix crash caused when canceling in-flight - operation - ---- - lib/services/dbus.c | 8 ++++++-- - lib/services/pcmk-dbus.h | 3 ++- - lib/services/systemd.c | 21 +++++++++++++++++---- - lib/services/upstart.c | 14 ++++++++++++-- - 4 files changed, 37 insertions(+), 9 deletions(-) - -diff --git a/lib/services/dbus.c b/lib/services/dbus.c -index f44b590..637f749 100644 ---- a/lib/services/dbus.c -+++ b/lib/services/dbus.c -@@ -325,7 +325,7 @@ pcmk_dbus_lookup_cb(DBusPendingCall *pending, void *user_data) - char * - pcmk_dbus_get_property( - DBusConnection *connection, const char *target, const char *obj, const gchar * iface, const char *name, -- void (*callback)(const char *name, const char *value, void *userdata), void *userdata) -+ void (*callback)(const char *name, const char *value, void *userdata), void *userdata, DBusPendingCall **pending) - { - DBusMessage *msg; - const char *method = "GetAll"; -@@ -365,7 +365,11 @@ pcmk_dbus_get_property( - } - - if(query_data->callback) { -- pcmk_dbus_send(msg, connection, pcmk_dbus_lookup_cb, query_data); -+ DBusPendingCall* _pending; -+ _pending = pcmk_dbus_send(msg, connection, pcmk_dbus_lookup_cb, query_data); -+ if (pending != NULL) { -+ *pending = _pending; -+ } - - } else { - DBusMessage *reply = pcmk_dbus_send_recv(msg, connection, NULL); -diff --git a/lib/services/pcmk-dbus.h b/lib/services/pcmk-dbus.h -index 468020e..63910f6 100644 ---- a/lib/services/pcmk-dbus.h -+++ b/lib/services/pcmk-dbus.h -@@ -8,7 +8,8 @@ DBusMessage *pcmk_dbus_send_recv(DBusMessage *msg, DBusConnection *connection, D - bool pcmk_dbus_type_check(DBusMessage *msg, DBusMessageIter *field, int expected, const char *function, int line); - char *pcmk_dbus_get_property( - DBusConnection *connection, const char *target, const char *obj, const gchar * iface, const char *name, -- void (*callback)(const char *name, const char *value, void *userdata), void *userdata); -+ void (*callback)(const char *name, const char *value, void *userdata), void *userdata, -+ DBusPendingCall **pending); - - bool pcmk_dbus_find_error(const char *method, DBusPendingCall* pending, DBusMessage *reply, DBusError *error); - -diff --git a/lib/services/systemd.c b/lib/services/systemd.c -index c0a1721..10c605a 100644 ---- a/lib/services/systemd.c -+++ b/lib/services/systemd.c -@@ -363,7 +363,7 @@ systemd_unit_metadata(const char *name) - - if (path) { - /* TODO: Worth a making blocking call for? Probably not. Possibly if cached. */ -- desc = pcmk_dbus_get_property(systemd_proxy, BUS_NAME, path, BUS_NAME ".Unit", "Description", NULL, NULL); -+ desc = pcmk_dbus_get_property(systemd_proxy, BUS_NAME, path, BUS_NAME ".Unit", "Description", NULL, NULL, NULL); - } else { - desc = g_strdup_printf("Systemd unit file for %s", name); - } -@@ -499,6 +499,9 @@ systemd_unit_check(const char *name, const char *state, void *userdata) - } - - if (op->synchronous == FALSE) { -+ if (op->opaque->pending) { -+ dbus_pending_call_unref(op->opaque->pending); -+ } - op->opaque->pending = NULL; - operation_finalize(op); - } -@@ -521,14 +524,24 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - } - - if (safe_str_eq(op->action, "monitor") || safe_str_eq(method, "status")) { -- char *state = pcmk_dbus_get_property(systemd_proxy, BUS_NAME, unit, BUS_NAME ".Unit", "ActiveState", -- op->synchronous?NULL:systemd_unit_check, op); -+ DBusPendingCall *pending = NULL; -+ char *state; -+ -+ state = pcmk_dbus_get_property(systemd_proxy, BUS_NAME, unit, -+ BUS_NAME ".Unit", "ActiveState", -+ op->synchronous?NULL:systemd_unit_check, -+ op, op->synchronous?NULL:&pending); - if (op->synchronous) { - systemd_unit_check("ActiveState", state, op); - free(state); - return op->rc == PCMK_OCF_OK; -+ } else if (pending) { -+ dbus_pending_call_ref(pending); -+ op->opaque->pending = pending; -+ return TRUE; - } -- return TRUE; -+ -+ return FALSE; - - } else if (g_strcmp0(method, "start") == 0) { - FILE *file_strm = NULL; -diff --git a/lib/services/upstart.c b/lib/services/upstart.c -index 01ff817..9894430 100644 ---- a/lib/services/upstart.c -+++ b/lib/services/upstart.c -@@ -322,6 +322,10 @@ upstart_job_check(const char *name, const char *state, void *userdata) - } - - if (op->synchronous == FALSE) { -+ if (op->opaque->pending) { -+ dbus_pending_call_unref(op->opaque->pending); -+ } -+ op->opaque->pending = NULL; - operation_finalize(op); - } - } -@@ -465,9 +469,11 @@ upstart_job_exec(svc_action_t * op, gboolean synchronous) - - op->rc = PCMK_OCF_NOT_RUNNING; - if(path) { -+ DBusPendingCall *pending = NULL; - char *state = pcmk_dbus_get_property( - upstart_proxy, BUS_NAME, path, UPSTART_06_API ".Instance", "state", -- op->synchronous?NULL:upstart_job_check, op); -+ op->synchronous?NULL:upstart_job_check, op, -+ op->synchronous?NULL:&pending); - - free(job); - free(path); -@@ -476,8 +482,12 @@ upstart_job_exec(svc_action_t * op, gboolean synchronous) - upstart_job_check("state", state, op); - free(state); - return op->rc == PCMK_OCF_OK; -+ } else if (pending) { -+ dbus_pending_call_ref(pending); -+ op->opaque->pending = pending; -+ return TRUE; - } -- return TRUE; -+ return FALSE; - } - goto cleanup; - --- -1.8.4.2 - diff --git a/SOURCES/pacemaker-coverity-fixes.patch b/SOURCES/pacemaker-coverity-fixes.patch deleted file mode 100644 index 4ca19cd..0000000 --- a/SOURCES/pacemaker-coverity-fixes.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff --git a/crmd/control.c b/crmd/control.c -index 8989859..0332f10 100644 ---- a/crmd/control.c -+++ b/crmd/control.c -@@ -951,7 +951,6 @@ config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void - value = crmd_pref(config_hash, "stonith-watchdog-timeout"); - } - -- value = crmd_pref(config_hash, "stonith-watchdog-timeout"); - if(crm_get_msec(value) > 0 && !daemon_option_enabled(crm_system_name, "watchdog")) { - do_crm_log_always(LOG_EMERG, "Shutting down pacemaker, no watchdog device configured"); - crmd_exit(DAEMON_RESPAWN_STOP); -diff --git a/crmd/lrm.c b/crmd/lrm.c -index 44634fb..b68f657 100644 ---- a/crmd/lrm.c -+++ b/crmd/lrm.c -@@ -1377,7 +1377,6 @@ do_lrm_invoke(long long action, - } else if (safe_str_eq(operation, CRM_OP_REPROBE) || safe_str_eq(crm_op, CRM_OP_REPROBE)) { - GHashTableIter gIter; - rsc_history_t *entry = NULL; -- gboolean unregister = is_remote_lrmd_ra(NULL, NULL, entry->id) ? FALSE : TRUE; - - crm_notice("Forcing the status of all resources to be redetected"); - -@@ -1386,6 +1385,8 @@ do_lrm_invoke(long long action, - /* only unregister the resource during a reprobe if it is not a remote connection - * resource. otherwise unregistering the connection will terminate remote-node - * membership */ -+ gboolean unregister = is_remote_lrmd_ra(NULL, NULL, entry->id) ? FALSE : TRUE; -+ - delete_resource(lrm_state, entry->id, &entry->rsc, &gIter, from_sys, from_host, - user_name, NULL, unregister); - } -diff --git a/lib/services/dbus.c b/lib/services/dbus.c -index f4632f2..c0153b5 100644 ---- a/lib/services/dbus.c -+++ b/lib/services/dbus.c -@@ -338,6 +338,11 @@ pcmk_dbus_get_property( - CRM_LOG_ASSERT(dbus_message_append_args(msg, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID)); - - query_data = malloc(sizeof(struct db_getall_data)); -+ if(query_data == NULL) { -+ crm_err("Call to %s failed: malloc failed", method); -+ return NULL; -+ } -+ - query_data->target = strdup(target); - query_data->object = strdup(obj); - query_data->callback = callback; -@@ -355,10 +360,6 @@ pcmk_dbus_get_property( - DBusMessage *reply = pcmk_dbus_send_recv(msg, connection, NULL); - - output = pcmk_dbus_lookup_result(reply, query_data); -- free(query_data->target); -- free(query_data->object); -- free(query_data->name); -- free(query_data); - - if(reply) { - dbus_message_unref(reply); -diff --git a/lib/services/services.c b/lib/services/services.c -index 753e257..9936c72 100644 ---- a/lib/services/services.c -+++ b/lib/services/services.c -@@ -506,12 +506,13 @@ services_action_sync(svc_action_t * op) - { - gboolean rc = TRUE; - -- op->synchronous = true; - if (op == NULL) { - crm_trace("No operation to execute"); - return FALSE; -+ } - -- } else if (op->standard && strcasecmp(op->standard, "upstart") == 0) { -+ op->synchronous = true; -+ if (op->standard && strcasecmp(op->standard, "upstart") == 0) { - #if SUPPORT_UPSTART - rc = upstart_job_exec(op, TRUE); - #endif diff --git a/SOURCES/pacemaker-f43678b-to-fe1ef5c-acl-fix.patch b/SOURCES/pacemaker-f43678b-to-fe1ef5c-acl-fix.patch deleted file mode 100644 index 649da8d..0000000 --- a/SOURCES/pacemaker-f43678b-to-fe1ef5c-acl-fix.patch +++ /dev/null @@ -1,1186 +0,0 @@ -diff --git a/lib/cib/cib_file.c b/lib/cib/cib_file.c -index 5562e9e..aa68679 100644 ---- a/lib/cib/cib_file.c -+++ b/lib/cib/cib_file.c -@@ -310,6 +310,12 @@ cib_file_perform_op_delegate(cib_t * cib, const char *op, const char *host, cons - } - crm_trace("Performing %s operation as %s", op, user_name); - #endif -+ -+ /* Mirror the logic in cib_prepare_common() */ -+ if (section != NULL && data != NULL && crm_str_eq(crm_element_name(data), XML_TAG_CIB, TRUE)) { -+ data = get_object_root(section, data); -+ } -+ - rc = cib_perform_op(op, call_options, fn, query, - section, request, data, TRUE, &changed, in_mem_cib, &result_cib, &cib_diff, - &output); -diff --git a/lib/common/xml.c b/lib/common/xml.c -index f7779f5..54f1aa7 100644 ---- a/lib/common/xml.c -+++ b/lib/common/xml.c -@@ -4848,8 +4848,13 @@ replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update, gboolean - - xml_accept_changes(tmp); - old = xmlReplaceNode(child, tmp); -- xml_calculate_changes(old, tmp); - -+ if(xml_tracking_changes(tmp)) { -+ /* Replaced sections may have included relevant ACLs */ -+ __xml_acl_apply(tmp); -+ } -+ -+ xml_calculate_changes(old, tmp); - xmlDocSetRootElement(doc, old); - free_xml(old); - } -diff --git a/tools/regression.acls.exp b/tools/regression.acls.exp -index 2cea125..e05e339 100644 ---- a/tools/regression.acls.exp -+++ b/tools/regression.acls.exp -@@ -17,11 +17,18 @@ A new shadow instance was created. To begin using it paste the following into y - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -47,11 +54,18 @@ A new shadow instance was created. To begin using it paste the following into y - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -78,11 +92,18 @@ A new shadow instance was created. To begin using it paste the following into y - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -109,11 +130,18 @@ A new shadow instance was created. To begin using it paste the following into y - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -143,11 +171,18 @@ A new shadow instance was created. To begin using it paste the following into y - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -180,11 +215,18 @@ A new shadow instance was created. To begin using it paste the following into y - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -255,11 +297,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -301,11 +350,18 @@ __xml_acl_post_process: Creation of nvpair=cib-bootstrap-options-stonith-enable - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -345,11 +401,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -384,11 +447,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -425,11 +495,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -486,11 +563,18 @@ __xml_acl_post_process: Creation of nvpair=dummy-meta_attributes-target-role is - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -535,11 +619,18 @@ Stopped - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -582,11 +673,18 @@ Deleted dummy option: id=dummy-meta_attributes-target-role name=target-role - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -631,11 +729,18 @@ __xml_acl_post_process: Creation of nvpair=dummy-meta_attributes-target-role is - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -730,11 +835,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -778,11 +890,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -794,12 +913,12 @@ Call failed: Permission denied - - - --=#=#=#= Begin test: niceguy: Replace - modify attribute =#=#=#= -+=#=#=#= Begin test: niceguy: Replace - modify attribute (deny) =#=#=#= - __xml_acl_check: 400 access denied to /cib[@epoch]: default - __xml_acl_check: 400 access denied to /cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options']/nvpair[@id='cib-bootstrap-options-enable-acl'][@value]: default - Call failed: Permission denied --=#=#=#= End test: niceguy: Replace - modify attribute - Permission denied (13) =#=#=#= --* Passed: cibadmin - niceguy: Replace - modify attribute -+=#=#=#= End test: niceguy: Replace - modify attribute (deny) - Permission denied (13) =#=#=#= -+* Passed: cibadmin - niceguy: Replace - modify attribute (deny) - - - -@@ -825,11 +944,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -841,12 +967,12 @@ Call failed: Permission denied - - - --=#=#=#= Begin test: niceguy: Replace - delete attribute =#=#=#= -+=#=#=#= Begin test: niceguy: Replace - delete attribute (deny) =#=#=#= - __xml_acl_check: 400 access denied to /cib[@epoch]: default - __xml_acl_check: 400 access denied to /cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options']/nvpair[@id='cib-bootstrap-options-enable-acl']: default - Call failed: Permission denied --=#=#=#= End test: niceguy: Replace - delete attribute - Permission denied (13) =#=#=#= --* Passed: cibadmin - niceguy: Replace - delete attribute -+=#=#=#= End test: niceguy: Replace - delete attribute (deny) - Permission denied (13) =#=#=#= -+* Passed: cibadmin - niceguy: Replace - delete attribute (deny) - - - -@@ -872,11 +998,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -888,12 +1021,161 @@ Call failed: Permission denied - - - --=#=#=#= Begin test: niceguy: Replace - create attribute =#=#=#= -+=#=#=#= Begin test: niceguy: Replace - create attribute (deny) =#=#=#= - __xml_acl_check: 400 access denied to /cib[@epoch]: default - __xml_acl_check: 400 access denied to /cib/configuration/resources/primitive[@id='dummy'][@description]: default - Call failed: Permission denied --=#=#=#= End test: niceguy: Replace - create attribute - Permission denied (13) =#=#=#= --* Passed: cibadmin - niceguy: Replace - create attribute -+=#=#=#= End test: niceguy: Replace - create attribute (deny) - Permission denied (13) =#=#=#= -+* Passed: cibadmin - niceguy: Replace - create attribute (deny) -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+=#=#=#= Begin test: bob: Replace - create attribute (allow) =#=#=#= -+=#=#=#= End test: bob: Replace - create attribute (allow) - OK (0) =#=#=#= -+* Passed: cibadmin - bob: Replace - create attribute (allow) -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+=#=#=#= Begin test: bob: Replace - modify attribute (allow) =#=#=#= -+=#=#=#= End test: bob: Replace - modify attribute (allow) - OK (0) =#=#=#= -+* Passed: cibadmin - bob: Replace - modify attribute (allow) -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+=#=#=#= Begin test: bob: Replace - delete attribute (allow) =#=#=#= -+=#=#=#= End test: bob: Replace - delete attribute (allow) - OK (0) =#=#=#= -+* Passed: cibadmin - bob: Replace - delete attribute (allow) - - - !#!#!#!#! Upgrading to pacemaker-2.0 and retesting !#!#!#!#! -@@ -901,6 +1183,8 @@ Call failed: Permission denied - __xml_acl_post_process: Creation of acl_permission=observer-read-1 is allowed - __xml_acl_post_process: Creation of acl_permission=observer-write-1 is allowed - __xml_acl_post_process: Creation of acl_permission=observer-write-2 is allowed -+__xml_acl_post_process: Creation of acl_permission=admin-read-1 is allowed -+__xml_acl_post_process: Creation of acl_permission=admin-write-1 is allowed - __xml_acl_post_process: Creation of acl_permission=crook-nothing is allowed - __xml_acl_post_process: Creation of acl_permission=badidea-resources is allowed - __xml_acl_post_process: Creation of acl_permission=betteridea-nothing is allowed -@@ -917,11 +1201,7 @@ __xml_acl_post_process: Creation of acl_permission=betteridea-resources is allo - - - -- -- -- -- -- -+ - - - -@@ -934,11 +1214,18 @@ __xml_acl_post_process: Creation of acl_permission=betteridea-resources is allo - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1019,11 +1306,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1073,11 +1367,18 @@ Error setting enable-acl=false (section=crm_config, set=): Permission deni - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1126,11 +1427,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1174,11 +1482,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1224,11 +1539,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1294,11 +1616,18 @@ __xml_acl_post_process: Creation of nvpair=dummy-meta_attributes-target-role is - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1352,11 +1681,18 @@ Stopped - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1408,11 +1744,18 @@ Deleted dummy option: id=dummy-meta_attributes-target-role name=target-role - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1466,11 +1809,18 @@ __xml_acl_post_process: Creation of nvpair=dummy-meta_attributes-target-role is - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1574,11 +1924,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1631,11 +1988,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1653,12 +2017,12 @@ Call failed: Permission denied - - - --=#=#=#= Begin test: niceguy: Replace - modify attribute =#=#=#= -+=#=#=#= Begin test: niceguy: Replace - modify attribute (deny) =#=#=#= - __xml_acl_check: 400 access denied to /cib[@epoch]: default - __xml_acl_check: 400 access denied to /cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options']/nvpair[@id='cib-bootstrap-options-enable-acl'][@value]: default - Call failed: Permission denied --=#=#=#= End test: niceguy: Replace - modify attribute - Permission denied (13) =#=#=#= --* Passed: cibadmin - niceguy: Replace - modify attribute -+=#=#=#= End test: niceguy: Replace - modify attribute (deny) - Permission denied (13) =#=#=#= -+* Passed: cibadmin - niceguy: Replace - modify attribute (deny) - - - -@@ -1687,11 +2051,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1709,12 +2080,12 @@ Call failed: Permission denied - - - --=#=#=#= Begin test: niceguy: Replace - delete attribute =#=#=#= -+=#=#=#= Begin test: niceguy: Replace - delete attribute (deny) =#=#=#= - __xml_acl_check: 400 access denied to /cib[@epoch]: default - __xml_acl_check: 400 access denied to /cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options']/nvpair[@id='cib-bootstrap-options-enable-acl']: default - Call failed: Permission denied --=#=#=#= End test: niceguy: Replace - delete attribute - Permission denied (13) =#=#=#= --* Passed: cibadmin - niceguy: Replace - delete attribute -+=#=#=#= End test: niceguy: Replace - delete attribute (deny) - Permission denied (13) =#=#=#= -+* Passed: cibadmin - niceguy: Replace - delete attribute (deny) - - - -@@ -1743,11 +2114,18 @@ Call failed: Permission denied - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - - -@@ -1765,9 +2143,185 @@ Call failed: Permission denied - - - --=#=#=#= Begin test: niceguy: Replace - create attribute =#=#=#= -+=#=#=#= Begin test: niceguy: Replace - create attribute (deny) =#=#=#= - __xml_acl_check: 400 access denied to /cib[@epoch]: default - __xml_acl_check: 400 access denied to /cib/configuration/resources/primitive[@id='dummy'][@description]: default - Call failed: Permission denied --=#=#=#= End test: niceguy: Replace - create attribute - Permission denied (13) =#=#=#= --* Passed: cibadmin - niceguy: Replace - create attribute -+=#=#=#= End test: niceguy: Replace - create attribute (deny) - Permission denied (13) =#=#=#= -+* Passed: cibadmin - niceguy: Replace - create attribute (deny) -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+=#=#=#= Begin test: bob: Replace - create attribute (allow) =#=#=#= -+=#=#=#= End test: bob: Replace - create attribute (allow) - OK (0) =#=#=#= -+* Passed: cibadmin - bob: Replace - create attribute (allow) -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+=#=#=#= Begin test: bob: Replace - modify attribute (allow) =#=#=#= -+=#=#=#= End test: bob: Replace - modify attribute (allow) - OK (0) =#=#=#= -+* Passed: cibadmin - bob: Replace - modify attribute (allow) -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+=#=#=#= Begin test: bob: Replace - delete attribute (allow) =#=#=#= -+=#=#=#= End test: bob: Replace - delete attribute (allow) - OK (0) =#=#=#= -+* Passed: cibadmin - bob: Replace - delete attribute (allow) -diff --git a/tools/regression.sh b/tools/regression.sh -index 0c4896c..63f4445 100755 ---- a/tools/regression.sh -+++ b/tools/regression.sh -@@ -487,7 +487,7 @@ function test_acl_loop() { - CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" crm_attribute -n enable-acl -v false - CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin -Ql - -- desc="$CIB_user: Replace - modify attribute" -+ desc="$CIB_user: Replace - modify attribute (deny)" - cmd="cibadmin --replace --xml-file /tmp/$$.haxor.xml" - test_assert 13 0 - -@@ -495,7 +495,7 @@ function test_acl_loop() { - CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin --replace --xml-text '' - CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin -Ql - -- desc="$CIB_user: Replace - delete attribute" -+ desc="$CIB_user: Replace - delete attribute (deny)" - cmd="cibadmin --replace --xml-file /tmp/$$.haxor.xml" - test_assert 13 0 - -@@ -503,10 +503,36 @@ function test_acl_loop() { - CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin --modify --xml-text '' - CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin -Ql - -- desc="$CIB_user: Replace - create attribute" -+ desc="$CIB_user: Replace - create attribute (deny)" - cmd="cibadmin --replace --xml-file /tmp/$$.haxor.xml" - test_assert 13 0 - rm -rf /tmp/$$.haxor.xml -+ -+ -+ CIB_user=bob -+ CIB_user=root cibadmin -Q > /tmp/$$.haxor.xml -+ CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin --modify --xml-text '' -+ CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin -Ql -+ -+ desc="$CIB_user: Replace - create attribute (allow)" -+ cmd="cibadmin --replace -o resources --xml-file /tmp/$$.haxor.xml" -+ test_assert 0 0 -+ -+ CIB_user=root cibadmin -Q > /tmp/$$.haxor.xml -+ CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin --modify --xml-text '' -+ CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin -Ql -+ -+ desc="$CIB_user: Replace - modify attribute (allow)" -+ cmd="cibadmin --replace -o resources --xml-file /tmp/$$.haxor.xml" -+ test_assert 0 0 -+ -+ CIB_user=root cibadmin -Q > /tmp/$$.haxor.xml -+ CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin --replace -o resources --xml-text '' -+ CIB_user=root CIB_file=/tmp/$$.haxor.xml CIB_shadow="" cibadmin -Ql -+ -+ desc="$CIB_user: Replace - delete attribute (allow)" -+ cmd="cibadmin --replace -o resources --xml-file /tmp/$$.haxor.xml" -+ test_assert 0 0 - } - - function test_acls() { -@@ -522,11 +548,18 @@ function test_acls() { - - - -+ -+ -+ - - - - - -+ -+ -+ -+ - - EOF - diff --git a/SOURCES/pacemaker-no-quorum-log.patch b/SOURCES/pacemaker-no-quorum-log.patch deleted file mode 100644 index db5804f..0000000 --- a/SOURCES/pacemaker-no-quorum-log.patch +++ /dev/null @@ -1,19 +0,0 @@ -commit af02935f3e53223d7ffc3413dcf1e38ce7f86915 -Author: Andrew Beekhof -Date: Fri Oct 24 14:23:39 2014 +1100 - - Log: PE: Reduce 'no quorum' logging severity - -diff --git a/lib/pengine/status.c b/lib/pengine/status.c -index a1c5630..b986987 100644 ---- a/lib/pengine/status.c -+++ b/lib/pengine/status.c -@@ -91,7 +91,7 @@ cluster_status(pe_working_set_t * data_set) - if (is_not_set(data_set->flags, pe_flag_quick_location) - && is_not_set(data_set->flags, pe_flag_have_quorum) - && data_set->no_quorum_policy != no_quorum_ignore) { -- crm_warn("We do not have quorum - fencing and resource management disabled"); -+ crm_notice("We do not have quorum - fencing and resource management disabled"); - } - - unpack_nodes(cib_nodes, data_set); diff --git a/SOURCES/pacemaker-resource-restart-segfault.patch b/SOURCES/pacemaker-resource-restart-segfault.patch deleted file mode 100644 index a1ee40a..0000000 --- a/SOURCES/pacemaker-resource-restart-segfault.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit cbdcd47aa56dd4a1ad369b1fa403588261421f33 -Author: Andrew Beekhof -Date: Thu Jan 15 14:11:45 2015 +1100 - - Fix: crm_resource: Use-after-free when restarting a resource - -diff --git a/tools/crm_resource.c b/tools/crm_resource.c -index 968683a..3cb3fc3 100644 ---- a/tools/crm_resource.c -+++ b/tools/crm_resource.c -@@ -1415,6 +1415,9 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate) - goto cleanup; - } - -+ if(data_set->input) { -+ free_xml(data_set->input); -+ } - set_working_set_defaults(data_set); - data_set->input = cib_xml_copy; - data_set->now = crm_time_new(NULL); -@@ -1452,8 +1455,8 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate) - } - - cleanup: -+ /* Do not free 'cib_xml_copy' here, we need rsc->xml to be valid later on */ - cib_delete(shadow_cib); -- free_xml(cib_xml_copy); - free(pid); - - if(shadow_file) { -@@ -1782,7 +1785,7 @@ static struct crm_option long_options[] = { - {"-spacer-", 1, 0, '-', "\nAdvanced Commands:"}, - {"delete", 0, 0, 'D', "\t\t(Advanced) Delete a resource from the CIB"}, - {"fail", 0, 0, 'F', "\t\t(Advanced) Tell the cluster this resource has failed"}, -- {"restart", 0, 0, 0, NULL, 1}, -+ {"restart", 0, 0, 0, "\t\t(Advanced) Tell the cluster to restart this resource and anything that depends on it"}, - {"force-stop", 0, 0, 0, "\t(Advanced) Bypass the cluster and stop a resource on the local node. Additional detail with -V"}, - {"force-start",0, 0, 0, "\t(Advanced) Bypass the cluster and start a resource on the local node. Additional detail with -V"}, - {"force-check",0, 0, 0, "\t(Advanced) Bypass the cluster and check the state of a resource on the local node. Additional detail with -V\n"}, diff --git a/SOURCES/pacemaker-resource-restart.patch b/SOURCES/pacemaker-resource-restart.patch deleted file mode 100644 index aa31e76..0000000 --- a/SOURCES/pacemaker-resource-restart.patch +++ /dev/null @@ -1,4667 +0,0 @@ -diff --git a/cts/patterns.py b/cts/patterns.py -index e734f40..13307e5 100644 ---- a/cts/patterns.py -+++ b/cts/patterns.py -@@ -180,6 +180,9 @@ class crm_cs_v0(BasePatterns): - r"error: log_operation:.*Operation 'reboot' .* with device 'FencingFail' returned:", - r"Child process .* terminated with signal 9", - r"getinfo response error: 1$", -+ "sbd.* error: inquisitor_child: DEBUG MODE IS ACTIVE", -+ "sbd.* pcmk: error: crm_ipc_read: Connection to cib_ro failed", -+ "sbd.* pcmk: error: mainloop_gio_callback: Connection to cib_ro.* closed .I/O condition=17", - ] - - self.BadNews = [ -diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c -index 7423af1..baf6cb9 100644 ---- a/lib/pengine/utils.c -+++ b/lib/pengine/utils.c -@@ -74,6 +74,7 @@ node_copy(node_t * this_node) - - crm_trace("Copying %p (%s) to %p", this_node, this_node->details->uname, new_node); - -+ new_node->rsc_discover_mode = this_node->rsc_discover_mode; - new_node->weight = this_node->weight; - new_node->fixed = this_node->fixed; - new_node->details = this_node->details; -diff --git a/lib/services/systemd.c b/lib/services/systemd.c -index 51ade44..a8bf1b4 100644 ---- a/lib/services/systemd.c -+++ b/lib/services/systemd.c -@@ -461,10 +461,10 @@ systemd_async_dispatch(DBusPendingCall *pending, void *user_data) - - if(op) { - crm_trace("Got result: %p for %p for %s, %s", reply, pending, op->rsc, op->action); -+ op->opaque->pending = NULL; - } else { - crm_trace("Got result: %p for %p", reply, pending); - } -- op->opaque->pending = NULL; - systemd_exec_result(reply, op); - - if(pending) { -diff --git a/pengine/allocate.c b/pengine/allocate.c -index e708e26..45e2212 100644 ---- a/pengine/allocate.c -+++ b/pengine/allocate.c -@@ -948,6 +948,28 @@ probe_resources(pe_working_set_t * data_set) - return TRUE; - } - -+static void -+rsc_discover_filter(resource_t *rsc, node_t *node) -+{ -+ GListPtr gIter = rsc->children; -+ resource_t *top = uber_parent(rsc); -+ node_t *match; -+ -+ if (rsc->exclusive_discover == FALSE && top->exclusive_discover == FALSE) { -+ return; -+ } -+ -+ for (; gIter != NULL; gIter = gIter->next) { -+ resource_t *child_rsc = (resource_t *) gIter->data; -+ rsc_discover_filter(child_rsc, node); -+ } -+ -+ match = g_hash_table_lookup(rsc->allowed_nodes, node->details->id); -+ if (match && match->rsc_discover_mode != discover_exclusive) { -+ match->weight = -INFINITY; -+ } -+} -+ - /* - * Count how many valid nodes we have (so we know the maximum number of - * colors we can resolve). -@@ -986,6 +1008,7 @@ stage2(pe_working_set_t * data_set) - resource_t *rsc = (resource_t *) gIter2->data; - - common_apply_stickiness(rsc, node, data_set); -+ rsc_discover_filter(rsc, node); - } - } - -diff --git a/pengine/native.c b/pengine/native.c -index 3dca702..6d62010 100644 ---- a/pengine/native.c -+++ b/pengine/native.c -@@ -2103,6 +2103,9 @@ native_rsc_location(resource_t * rsc, rsc_to_node_t * constraint) - } - - if (other_node->rsc_discover_mode < constraint->discover_mode) { -+ if (constraint->discover_mode == discover_exclusive) { -+ rsc->exclusive_discover = TRUE; -+ } - /* exclusive > never > always... always is default */ - other_node->rsc_discover_mode = constraint->discover_mode; - } -diff --git a/pengine/test10/resource-discovery.dot b/pengine/test10/resource-discovery.dot -index efb2434..5b1aab9 100644 ---- a/pengine/test10/resource-discovery.dot -+++ b/pengine/test10/resource-discovery.dot -@@ -1,41 +1,26 @@ - digraph "g" { --"FAKE1_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] --"FAKE1_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] --"FAKE1_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] --"FAKE1_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] --"FAKE1_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] --"FAKE1_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] --"FAKE1_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] --"FAKE1_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] - "FAKE1_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] - "FAKE1_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] --"FAKE1_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] --"FAKE1_start_0 18node2" -> "FAKE1_monitor_60000 18node2" [ style = bold] --"FAKE1_start_0 18node2" [ style=bold color="green" fontcolor="black"] --"FAKE2_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] --"FAKE2_start_0 18node3" -> "FAKE2_monitor_60000 18node3" [ style = bold] --"FAKE2_start_0 18node3" [ style=bold color="green" fontcolor="black"] --"FAKE2_stop_0 18node2" -> "FAKE2_start_0 18node3" [ style = bold] --"FAKE2_stop_0 18node2" -> "all_stopped" [ style = bold] --"FAKE2_stop_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE1_start_0 18node4" -> "FAKE1_monitor_60000 18node4" [ style = bold] -+"FAKE1_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE2_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE2_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE2_start_0 18node2" -> "FAKE2_monitor_60000 18node2" [ style = bold] -+"FAKE2_start_0 18node2" [ style=bold color="green" fontcolor="black"] - "FAKE3_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] - "FAKE3_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] - "FAKE3_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] - "FAKE3_start_0 18node3" -> "FAKE3_monitor_60000 18node3" [ style = bold] - "FAKE3_start_0 18node3" [ style=bold color="green" fontcolor="black"] --"FAKE3_stop_0 18builder" -> "FAKE3_start_0 18node3" [ style = bold] --"FAKE3_stop_0 18builder" -> "all_stopped" [ style = bold] --"FAKE3_stop_0 18builder" [ style=bold color="green" fontcolor="black"] - "FAKE4_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] - "FAKE4_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] - "FAKE4_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] - "FAKE4_start_0 18node4" -> "FAKE4_monitor_60000 18node4" [ style = bold] - "FAKE4_start_0 18node4" [ style=bold color="green" fontcolor="black"] --"FAKE4_stop_0 18node1" -> "FAKE4_start_0 18node4" [ style = bold] --"FAKE4_stop_0 18node1" -> "all_stopped" [ style = bold] --"FAKE4_stop_0 18node1" [ style=bold color="green" fontcolor="black"] --"FAKE5_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] --"FAKE5_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] - "FAKE5_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] - "FAKE5_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] - "FAKE5_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -@@ -49,56 +34,54 @@ - "FAKE5_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] - "FAKE5_start_0 remote1" -> "FAKE5_monitor_60000 remote1" [ style = bold] - "FAKE5_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE6_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE6_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE6_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE6_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE6_monitor_10000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE6_start_0 18node1" -> "FAKE6_monitor_10000 18node1" [ style = bold] -+"FAKE6_start_0 18node1" -> "FAKE7_start_0 18node1" [ style = bold] -+"FAKE6_start_0 18node1" -> "FAKEGROUP_running_0" [ style = bold] -+"FAKE6_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE7_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE7_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE7_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE7_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE7_monitor_10000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE7_start_0 18node1" -> "FAKE7_monitor_10000 18node1" [ style = bold] -+"FAKE7_start_0 18node1" -> "FAKEGROUP_running_0" [ style = bold] -+"FAKE7_start_0 18node1" [ style=bold color="green" fontcolor="black"] - "FAKECLONE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] - "FAKECLONE1-clone_start_0" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1-clone_start_0" -> "FAKECLONE1:0_start_0 18builder" [ style = bold] --"FAKECLONE1-clone_start_0" -> "FAKECLONE1:1_start_0 18node1" [ style = bold] --"FAKECLONE1-clone_start_0" -> "FAKECLONE1:2_start_0 18node2" [ style = bold] --"FAKECLONE1-clone_start_0" -> "FAKECLONE1:3_start_0 18node4" [ style = bold] --"FAKECLONE1-clone_start_0" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] --"FAKECLONE1-clone_start_0" -> "FAKECLONE1:5_start_0 18node3" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:0_start_0 18node1" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:1_start_0 remote1" [ style = bold] - "FAKECLONE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] --"FAKECLONE1:0_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:0_start_0 18builder" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1:0_start_0 18builder" -> "FAKECLONE1:0_monitor_60000 18builder" [ style = bold] --"FAKECLONE1:0_start_0 18builder" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:1_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:1_start_0 18node1" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1:1_start_0 18node1" -> "FAKECLONE1:1_monitor_60000 18node1" [ style = bold] --"FAKECLONE1:1_start_0 18node1" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:2_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:2_start_0 18node2" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1:2_start_0 18node2" -> "FAKECLONE1:2_monitor_60000 18node2" [ style = bold] --"FAKECLONE1:2_start_0 18node2" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:3_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:3_start_0 18node4" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1:3_start_0 18node4" -> "FAKECLONE1:3_monitor_60000 18node4" [ style = bold] --"FAKECLONE1:3_start_0 18node4" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:4_monitor_0 remote1" -> "probe_complete remote1" [ style = bold] --"FAKECLONE1:4_monitor_0 remote1" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:4_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:4_start_0 remote1" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1:4_start_0 remote1" -> "FAKECLONE1:4_monitor_60000 remote1" [ style = bold] --"FAKECLONE1:4_start_0 remote1" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:5_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] --"FAKECLONE1:5_start_0 18node3" -> "FAKECLONE1-clone_running_0" [ style = bold] --"FAKECLONE1:5_start_0 18node3" -> "FAKECLONE1:5_monitor_60000 18node3" [ style = bold] --"FAKECLONE1:5_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:0_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKECLONE1:0_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:0_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:0_start_0 18node1" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:0_start_0 18node1" -> "FAKECLONE1:0_monitor_60000 18node1" [ style = bold] -+"FAKECLONE1:0_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_monitor_0 remote1" -> "probe_complete remote1" [ style = bold] -+"FAKECLONE1:1_monitor_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_start_0 remote1" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:1_start_0 remote1" -> "FAKECLONE1:1_monitor_60000 remote1" [ style = bold] -+"FAKECLONE1:1_start_0 remote1" [ style=bold color="green" fontcolor="black"] - "FAKECLONE2-clone_running_0" [ style=bold color="green" fontcolor="orange"] - "FAKECLONE2-clone_start_0" -> "FAKECLONE2-clone_running_0" [ style = bold] --"FAKECLONE2-clone_start_0" -> "FAKECLONE2:0_start_0 18builder" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:0_start_0 18node3" [ style = bold] - "FAKECLONE2-clone_start_0" -> "FAKECLONE2:1_start_0 18node1" [ style = bold] - "FAKECLONE2-clone_start_0" -> "FAKECLONE2:2_start_0 18node2" [ style = bold] - "FAKECLONE2-clone_start_0" -> "FAKECLONE2:3_start_0 18node4" [ style = bold] - "FAKECLONE2-clone_start_0" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] --"FAKECLONE2-clone_start_0" -> "FAKECLONE2:5_start_0 18node3" [ style = bold] - "FAKECLONE2-clone_start_0" [ style=bold color="green" fontcolor="orange"] --"FAKECLONE2:0_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] --"FAKECLONE2:0_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] --"FAKECLONE2:0_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] --"FAKECLONE2:0_start_0 18builder" -> "FAKECLONE2-clone_running_0" [ style = bold] --"FAKECLONE2:0_start_0 18builder" -> "FAKECLONE2:0_monitor_60000 18builder" [ style = bold] --"FAKECLONE2:0_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKECLONE2:0_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_start_0 18node3" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:0_start_0 18node3" -> "FAKECLONE2:0_monitor_60000 18node3" [ style = bold] -+"FAKECLONE2:0_start_0 18node3" [ style=bold color="green" fontcolor="black"] - "FAKECLONE2:1_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] - "FAKECLONE2:1_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] - "FAKECLONE2:1_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -@@ -121,15 +104,11 @@ - "FAKECLONE2:4_start_0 remote1" -> "FAKECLONE2-clone_running_0" [ style = bold] - "FAKECLONE2:4_start_0 remote1" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] - "FAKECLONE2:4_start_0 remote1" [ style=bold color="green" fontcolor="black"] --"FAKECLONE2:5_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] --"FAKECLONE2:5_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] --"FAKECLONE2:5_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] --"FAKECLONE2:5_start_0 18node3" -> "FAKECLONE2-clone_running_0" [ style = bold] --"FAKECLONE2:5_start_0 18node3" -> "FAKECLONE2:5_monitor_60000 18node3" [ style = bold] --"FAKECLONE2:5_start_0 18node3" [ style=bold color="green" fontcolor="black"] --"all_stopped" [ style=bold color="green" fontcolor="orange"] --"probe_complete 18builder" -> "probe_nodes_complete" [ style = bold] --"probe_complete 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKEGROUP_running_0" [ style=bold color="green" fontcolor="orange"] -+"FAKEGROUP_start_0" -> "FAKE6_start_0 18node1" [ style = bold] -+"FAKEGROUP_start_0" -> "FAKE7_start_0 18node1" [ style = bold] -+"FAKEGROUP_start_0" -> "FAKEGROUP_running_0" [ style = bold] -+"FAKEGROUP_start_0" [ style=bold color="green" fontcolor="orange"] - "probe_complete 18node1" -> "probe_nodes_complete" [ style = bold] - "probe_complete 18node1" [ style=bold color="green" fontcolor="black"] - "probe_complete 18node2" -> "probe_nodes_complete" [ style = bold] -@@ -140,46 +119,53 @@ - "probe_complete 18node4" [ style=bold color="green" fontcolor="black"] - "probe_complete remote1" -> "probe_complete" [ style = bold] - "probe_complete remote1" [ style=bold color="green" fontcolor="black"] --"probe_complete" -> "FAKE1_start_0 18node2" [ style = bold] --"probe_complete" -> "FAKE2_stop_0 18node2" [ style = bold] -+"probe_complete" -> "FAKE1_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKE2_start_0 18node2" [ style = bold] - "probe_complete" -> "FAKE3_start_0 18node3" [ style = bold] --"probe_complete" -> "FAKE3_stop_0 18builder" [ style = bold] - "probe_complete" -> "FAKE4_start_0 18node4" [ style = bold] --"probe_complete" -> "FAKE4_stop_0 18node1" [ style = bold] - "probe_complete" -> "FAKE5_start_0 remote1" [ style = bold] --"probe_complete" -> "FAKECLONE1:0_start_0 18builder" [ style = bold] --"probe_complete" -> "FAKECLONE1:1_start_0 18node1" [ style = bold] --"probe_complete" -> "FAKECLONE1:2_start_0 18node2" [ style = bold] --"probe_complete" -> "FAKECLONE1:3_start_0 18node4" [ style = bold] --"probe_complete" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] --"probe_complete" -> "FAKECLONE1:5_start_0 18node3" [ style = bold] --"probe_complete" -> "FAKECLONE2:0_start_0 18builder" [ style = bold] -+"probe_complete" -> "FAKE6_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKE7_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:0_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:1_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKECLONE2:0_start_0 18node3" [ style = bold] - "probe_complete" -> "FAKECLONE2:1_start_0 18node1" [ style = bold] - "probe_complete" -> "FAKECLONE2:2_start_0 18node2" [ style = bold] - "probe_complete" -> "FAKECLONE2:3_start_0 18node4" [ style = bold] - "probe_complete" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] --"probe_complete" -> "FAKECLONE2:5_start_0 18node3" [ style = bold] -+"probe_complete" -> "shooter_start_0 18node2" [ style = bold] - "probe_complete" [ style=bold color="green" fontcolor="orange"] --"probe_nodes_complete" -> "remote1_start_0 18builder" [ style = bold] -+"probe_nodes_complete" -> "remote1_start_0 18node1" [ style = bold] - "probe_nodes_complete" [ style=bold color="green" fontcolor="orange"] -+"remote1_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"remote1_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"remote1_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"remote1_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] - "remote1_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] - "remote1_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] - "remote1_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] - "remote1_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] --"remote1_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] --"remote1_start_0 18builder" -> "FAKE5_monitor_0 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKE5_monitor_60000 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKE5_start_0 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKECLONE1:4_monitor_0 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKECLONE1:4_monitor_60000 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKECLONE2:4_monitor_0 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] --"remote1_start_0 18builder" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] --"remote1_start_0 18builder" -> "remote1_monitor_60000 18builder" [ style = bold] --"remote1_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"remote1_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -+"remote1_start_0 18node1" -> "FAKE5_monitor_0 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKE5_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKE5_start_0 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKECLONE1:1_monitor_0 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKECLONE1:1_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKECLONE1:1_start_0 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKECLONE2:4_monitor_0 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"remote1_start_0 18node1" -> "remote1_monitor_60000 18node1" [ style = bold] -+"remote1_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"shooter_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"shooter_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] - "shooter_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] - "shooter_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] - "shooter_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] - "shooter_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"shooter_start_0 18node2" -> "shooter_monitor_60000 18node2" [ style = bold] -+"shooter_start_0 18node2" [ style=bold color="green" fontcolor="black"] - } -diff --git a/pengine/test10/resource-discovery.exp b/pengine/test10/resource-discovery.exp -index 2770f4e..5459bd7 100644 ---- a/pengine/test10/resource-discovery.exp -+++ b/pengine/test10/resource-discovery.exp -@@ -1,52 +1,52 @@ - - - -- -+ - -- -+ - - -- -+ -+ -+ -+ -+ - - - -- -+ - -- -+ - - -- -+ -+ -+ -+ -+ - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -+ - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -+ - - - -- -- -+ -+ - - - -@@ -54,8 +54,8 @@ - - - -- -- -+ -+ - - - -@@ -63,34 +63,34 @@ - - - -- -- -+ -+ - - - - - -- -+ - - - - - -- -- -+ -+ - - - - - -- -+ - - - - - -- -- -+ -+ - - - -@@ -98,8 +98,8 @@ - - - -- -- -+ -+ - - - -@@ -107,8 +107,8 @@ - - - -- -- -+ -+ - - - -@@ -116,8 +116,8 @@ - - - -- -- -+ -+ - - - -@@ -125,95 +125,110 @@ - - - -- -+ - -- -- -- -- -- -- -- -- -- - - - - - -- -+ - - - -- -+ - -- -- -+ -+ - - - - - -- -+ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -+ - -- -+ - - - - -- -+ - - - - - -- -- -- -+ -+ -+ - - - - -- -+ - - - - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - -- -+ - - - - -- -- -- -- -+ - - - -- -+ - -- -+ - - - - - - -- -+ - - - -- -+ - - - -@@ -222,49 +237,33 @@ - - - -- -+ - -- -+ - - - - - - -- -+ - - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -+ - -- -+ - - - - - - -- -+ - - - -- -+ - - - -@@ -273,63 +272,54 @@ - - - -- -+ - -- -+ - - - - - - -- -+ - - -- -+ - - - -- -+ - -- -+ - - - - - - -- -+ - - -- -+ - - - -- -+ - -- -+ - - - - - - -- -+ - - - -- -- -- -- -- -- -- -- -- - - -- -+ - - - -@@ -338,7 +328,7 @@ - - - -- -+ - - - -@@ -347,7 +337,7 @@ - - - -- -+ - - - -@@ -356,7 +346,7 @@ - - - -- -+ - - - -@@ -365,517 +355,480 @@ - - - -- -+ - -- -+ - - - - -- -+ - - - - - -- -+ - -- -+ - - - - -- -+ - - -- -+ - - - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -+ - - - -- -+ - -- -+ - - - - -- -+ - - -- -+ - - - - - -- -- -- -+ -+ -+ - - - - -- -+ - -- -- -- -- -- -- -- -- -- -- - -- -+ - - -- -+ - - - -- -+ - -- -- -- -+ -+ -+ - - - - -- -+ - - - -- -+ - -- -- -- -- -+ -+ -+ - - - -- -+ - - -- -+ -+ -+ -+ - - - -+ -+ -+ -+ -+ -+ -+ -+ - - -- -- -- -+ -+ -+ - - - - -- -- -- -- -+ - - - - - -- -- -- -+ -+ -+ - - - - -- -+ - - -- -- -- -- -+ - - - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -+ - - - -- -- -- -+ -+ -+ - - - - -- -+ - - - - - -- -- -- -+ -+ -+ - - - - -- -+ - - -- -+ - - - -- -+ - -- -- -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -- -- -- -- -- -- -- -- -- -- -- -- -- -+ - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - -- -+ - - -- -+ - - - -- -- -- -- -- -- -- -- -- -+ - -- -- -- -+ -+ -+ - - - - -- -+ - - - -- -+ - -- -- -- -+ -+ -+ - - - - -- -+ - - -- -+ - - - -- -+ - -- -- -- -+ -+ -+ - - - - -- -+ - -- -- -- -+ -+ -+ - - - - -- -+ -+ -+ -+ - - - -- -+ - -- -- -- -+ -+ -+ - - - - -- -+ -+ -+ -+ - - -- -+ - - - -- -- -- -- -- -- -- -- -- - - -- -- -- -+ -+ -+ - - - - -- -+ - - - -- -+ - -- -- -- -- -+ -+ -+ - - - -- -+ -+ -+ -+ -+ -+ -+ - - -- -+ -+ -+ -+ -+ -+ -+ - - - - - -- -- -- -- -+ -+ -+ - -- -- -- -- -- -+ - - - -- -- -- -- -+ -+ -+ - - - -- -+ -+ -+ -+ - - -- -+ - - - - - -- -- -- -- -+ -+ -+ - - - - - -- -- -- -+ -+ -+ - - - - -- -- -- -- -+ - - - - - -- -- -- -+ -+ -+ - - - - -- -- -- -- -+ - - -- -+ - - - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -+ - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -+ - - - -- -- -- -+ -+ -+ - - - - -- -- -- -- -+ - - - - - -- -- -- -+ -+ -+ - - -- -- -- -- -- -- -- -- - - -- -- -- -- -+ - - -- -+ - - -- -- -- -- -- -- -- -- -- -- -+ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -- -- -+ -+ -+ -+ - - - - - -- -+ - - - - - -- -+ - - -- -+ - - -- -+ - - - -@@ -908,19 +861,16 @@ - - - -- -+ - - - - - -- -- -- -- -+ - - -- -+ - - - -@@ -929,112 +879,100 @@ - - - -- -+ - - - - - -- -+ - - - - - -- -+ - - -- -+ -+ -+ -+ - -- -- -- -- -- -- -- -- -- - -- -+ - - -- -+ - - -- -+ - - - -- -+ - -- -+ - - - - - -- -+ - - -- -+ - - -- -+ - -- -- -- -- -- -- -- -- -- - -- -+ - - -- -+ - - -- -+ - - -- -+ - - -- -+ - - - -- -+ - -- -+ - - - - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -- -+ - -- -+ - - - - - -- -- -- -- -- -- -- -+ - - - -diff --git a/pengine/test10/resource-discovery.scores b/pengine/test10/resource-discovery.scores -index e1fa78e..9b56b96 100644 ---- a/pengine/test10/resource-discovery.scores -+++ b/pengine/test10/resource-discovery.scores -@@ -1,197 +1,169 @@ - Allocation scores: --clone_color: FAKECLONE1-clone allocation score on 18builder: 0 - clone_color: FAKECLONE1-clone allocation score on 18node1: 0 --clone_color: FAKECLONE1-clone allocation score on 18node2: 0 --clone_color: FAKECLONE1-clone allocation score on 18node3: 0 --clone_color: FAKECLONE1-clone allocation score on 18node4: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node2: -INFINITY -+clone_color: FAKECLONE1-clone allocation score on 18node3: -INFINITY -+clone_color: FAKECLONE1-clone allocation score on 18node4: -INFINITY - clone_color: FAKECLONE1-clone allocation score on remote1: 0 --clone_color: FAKECLONE1:0 allocation score on 18builder: 0 - clone_color: FAKECLONE1:0 allocation score on 18node1: 0 --clone_color: FAKECLONE1:0 allocation score on 18node2: 0 --clone_color: FAKECLONE1:0 allocation score on 18node3: 0 --clone_color: FAKECLONE1:0 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node2: -INFINITY -+clone_color: FAKECLONE1:0 allocation score on 18node3: -INFINITY -+clone_color: FAKECLONE1:0 allocation score on 18node4: -INFINITY - clone_color: FAKECLONE1:0 allocation score on remote1: 0 --clone_color: FAKECLONE1:1 allocation score on 18builder: 0 - clone_color: FAKECLONE1:1 allocation score on 18node1: 0 --clone_color: FAKECLONE1:1 allocation score on 18node2: 0 --clone_color: FAKECLONE1:1 allocation score on 18node3: 0 --clone_color: FAKECLONE1:1 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node2: -INFINITY -+clone_color: FAKECLONE1:1 allocation score on 18node3: -INFINITY -+clone_color: FAKECLONE1:1 allocation score on 18node4: -INFINITY - clone_color: FAKECLONE1:1 allocation score on remote1: 0 --clone_color: FAKECLONE1:2 allocation score on 18builder: 0 - clone_color: FAKECLONE1:2 allocation score on 18node1: 0 --clone_color: FAKECLONE1:2 allocation score on 18node2: 0 --clone_color: FAKECLONE1:2 allocation score on 18node3: 0 --clone_color: FAKECLONE1:2 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node2: -INFINITY -+clone_color: FAKECLONE1:2 allocation score on 18node3: -INFINITY -+clone_color: FAKECLONE1:2 allocation score on 18node4: -INFINITY - clone_color: FAKECLONE1:2 allocation score on remote1: 0 --clone_color: FAKECLONE1:3 allocation score on 18builder: 0 - clone_color: FAKECLONE1:3 allocation score on 18node1: 0 --clone_color: FAKECLONE1:3 allocation score on 18node2: 0 --clone_color: FAKECLONE1:3 allocation score on 18node3: 0 --clone_color: FAKECLONE1:3 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node2: -INFINITY -+clone_color: FAKECLONE1:3 allocation score on 18node3: -INFINITY -+clone_color: FAKECLONE1:3 allocation score on 18node4: -INFINITY - clone_color: FAKECLONE1:3 allocation score on remote1: 0 --clone_color: FAKECLONE1:4 allocation score on 18builder: 0 - clone_color: FAKECLONE1:4 allocation score on 18node1: 0 --clone_color: FAKECLONE1:4 allocation score on 18node2: 0 --clone_color: FAKECLONE1:4 allocation score on 18node3: 0 --clone_color: FAKECLONE1:4 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node2: -INFINITY -+clone_color: FAKECLONE1:4 allocation score on 18node3: -INFINITY -+clone_color: FAKECLONE1:4 allocation score on 18node4: -INFINITY - clone_color: FAKECLONE1:4 allocation score on remote1: 0 --clone_color: FAKECLONE1:5 allocation score on 18builder: 0 --clone_color: FAKECLONE1:5 allocation score on 18node1: 0 --clone_color: FAKECLONE1:5 allocation score on 18node2: 0 --clone_color: FAKECLONE1:5 allocation score on 18node3: 0 --clone_color: FAKECLONE1:5 allocation score on 18node4: 0 --clone_color: FAKECLONE1:5 allocation score on remote1: 0 --clone_color: FAKECLONE2-clone allocation score on 18builder: 0 - clone_color: FAKECLONE2-clone allocation score on 18node1: 0 - clone_color: FAKECLONE2-clone allocation score on 18node2: 0 - clone_color: FAKECLONE2-clone allocation score on 18node3: 0 - clone_color: FAKECLONE2-clone allocation score on 18node4: 0 - clone_color: FAKECLONE2-clone allocation score on remote1: 0 --clone_color: FAKECLONE2:0 allocation score on 18builder: 0 - clone_color: FAKECLONE2:0 allocation score on 18node1: 0 - clone_color: FAKECLONE2:0 allocation score on 18node2: 0 - clone_color: FAKECLONE2:0 allocation score on 18node3: 0 - clone_color: FAKECLONE2:0 allocation score on 18node4: 0 - clone_color: FAKECLONE2:0 allocation score on remote1: 0 --clone_color: FAKECLONE2:1 allocation score on 18builder: 0 - clone_color: FAKECLONE2:1 allocation score on 18node1: 0 - clone_color: FAKECLONE2:1 allocation score on 18node2: 0 - clone_color: FAKECLONE2:1 allocation score on 18node3: 0 - clone_color: FAKECLONE2:1 allocation score on 18node4: 0 - clone_color: FAKECLONE2:1 allocation score on remote1: 0 --clone_color: FAKECLONE2:2 allocation score on 18builder: 0 - clone_color: FAKECLONE2:2 allocation score on 18node1: 0 - clone_color: FAKECLONE2:2 allocation score on 18node2: 0 - clone_color: FAKECLONE2:2 allocation score on 18node3: 0 - clone_color: FAKECLONE2:2 allocation score on 18node4: 0 - clone_color: FAKECLONE2:2 allocation score on remote1: 0 --clone_color: FAKECLONE2:3 allocation score on 18builder: 0 - clone_color: FAKECLONE2:3 allocation score on 18node1: 0 - clone_color: FAKECLONE2:3 allocation score on 18node2: 0 - clone_color: FAKECLONE2:3 allocation score on 18node3: 0 - clone_color: FAKECLONE2:3 allocation score on 18node4: 0 - clone_color: FAKECLONE2:3 allocation score on remote1: 0 --clone_color: FAKECLONE2:4 allocation score on 18builder: 0 - clone_color: FAKECLONE2:4 allocation score on 18node1: 0 - clone_color: FAKECLONE2:4 allocation score on 18node2: 0 - clone_color: FAKECLONE2:4 allocation score on 18node3: 0 - clone_color: FAKECLONE2:4 allocation score on 18node4: 0 - clone_color: FAKECLONE2:4 allocation score on remote1: 0 --clone_color: FAKECLONE2:5 allocation score on 18builder: 0 --clone_color: FAKECLONE2:5 allocation score on 18node1: 0 --clone_color: FAKECLONE2:5 allocation score on 18node2: 0 --clone_color: FAKECLONE2:5 allocation score on 18node3: 0 --clone_color: FAKECLONE2:5 allocation score on 18node4: 0 --clone_color: FAKECLONE2:5 allocation score on remote1: 0 --native_color: FAKE1 allocation score on 18builder: 0 --native_color: FAKE1 allocation score on 18node1: 0 --native_color: FAKE1 allocation score on 18node2: 0 --native_color: FAKE1 allocation score on 18node3: 0 -+group_color: FAKE6 allocation score on 18node1: 0 -+group_color: FAKE6 allocation score on 18node2: 0 -+group_color: FAKE6 allocation score on 18node3: -INFINITY -+group_color: FAKE6 allocation score on 18node4: -INFINITY -+group_color: FAKE6 allocation score on remote1: -INFINITY -+group_color: FAKE7 allocation score on 18node1: 0 -+group_color: FAKE7 allocation score on 18node2: 0 -+group_color: FAKE7 allocation score on 18node3: -INFINITY -+group_color: FAKE7 allocation score on 18node4: -INFINITY -+group_color: FAKE7 allocation score on remote1: -INFINITY -+group_color: FAKEGROUP allocation score on 18node1: 0 -+group_color: FAKEGROUP allocation score on 18node2: 0 -+group_color: FAKEGROUP allocation score on 18node3: -INFINITY -+group_color: FAKEGROUP allocation score on 18node4: -INFINITY -+group_color: FAKEGROUP allocation score on remote1: -INFINITY -+native_color: FAKE1 allocation score on 18node1: -INFINITY -+native_color: FAKE1 allocation score on 18node2: -INFINITY -+native_color: FAKE1 allocation score on 18node3: -INFINITY - native_color: FAKE1 allocation score on 18node4: 0 - native_color: FAKE1 allocation score on remote1: -INFINITY --native_color: FAKE2 allocation score on 18builder: 0 --native_color: FAKE2 allocation score on 18node1: 0 --native_color: FAKE2 allocation score on 18node2: -INFINITY --native_color: FAKE2 allocation score on 18node3: 0 --native_color: FAKE2 allocation score on 18node4: 0 --native_color: FAKE2 allocation score on remote1: 0 --native_color: FAKE3 allocation score on 18builder: 0 --native_color: FAKE3 allocation score on 18node1: 0 --native_color: FAKE3 allocation score on 18node2: 0 -+native_color: FAKE2 allocation score on 18node1: 10 -+native_color: FAKE2 allocation score on 18node2: 100 -+native_color: FAKE2 allocation score on 18node3: -INFINITY -+native_color: FAKE2 allocation score on 18node4: -INFINITY -+native_color: FAKE2 allocation score on remote1: -INFINITY -+native_color: FAKE3 allocation score on 18node1: -INFINITY -+native_color: FAKE3 allocation score on 18node2: -INFINITY - native_color: FAKE3 allocation score on 18node3: INFINITY --native_color: FAKE3 allocation score on 18node4: 0 --native_color: FAKE3 allocation score on remote1: 0 --native_color: FAKE4 allocation score on 18builder: 0 --native_color: FAKE4 allocation score on 18node1: 0 --native_color: FAKE4 allocation score on 18node2: 0 --native_color: FAKE4 allocation score on 18node3: 0 -+native_color: FAKE3 allocation score on 18node4: -INFINITY -+native_color: FAKE3 allocation score on remote1: -INFINITY -+native_color: FAKE4 allocation score on 18node1: -INFINITY -+native_color: FAKE4 allocation score on 18node2: -INFINITY -+native_color: FAKE4 allocation score on 18node3: -INFINITY - native_color: FAKE4 allocation score on 18node4: 0 --native_color: FAKE4 allocation score on remote1: 0 --native_color: FAKE5 allocation score on 18builder: 0 -+native_color: FAKE4 allocation score on remote1: -INFINITY - native_color: FAKE5 allocation score on 18node1: 0 - native_color: FAKE5 allocation score on 18node2: 0 - native_color: FAKE5 allocation score on 18node3: 0 - native_color: FAKE5 allocation score on 18node4: 0 - native_color: FAKE5 allocation score on remote1: 0 --native_color: FAKECLONE1:0 allocation score on 18builder: 0 -+native_color: FAKE6 allocation score on 18node1: 0 -+native_color: FAKE6 allocation score on 18node2: 0 -+native_color: FAKE6 allocation score on 18node3: -INFINITY -+native_color: FAKE6 allocation score on 18node4: -INFINITY -+native_color: FAKE6 allocation score on remote1: -INFINITY -+native_color: FAKE7 allocation score on 18node1: 0 -+native_color: FAKE7 allocation score on 18node2: -INFINITY -+native_color: FAKE7 allocation score on 18node3: -INFINITY -+native_color: FAKE7 allocation score on 18node4: -INFINITY -+native_color: FAKE7 allocation score on remote1: -INFINITY - native_color: FAKECLONE1:0 allocation score on 18node1: 0 --native_color: FAKECLONE1:0 allocation score on 18node2: 0 --native_color: FAKECLONE1:0 allocation score on 18node3: 0 --native_color: FAKECLONE1:0 allocation score on 18node4: 0 -+native_color: FAKECLONE1:0 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:0 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:0 allocation score on 18node4: -INFINITY - native_color: FAKECLONE1:0 allocation score on remote1: 0 --native_color: FAKECLONE1:1 allocation score on 18builder: -INFINITY --native_color: FAKECLONE1:1 allocation score on 18node1: 0 --native_color: FAKECLONE1:1 allocation score on 18node2: 0 --native_color: FAKECLONE1:1 allocation score on 18node3: 0 --native_color: FAKECLONE1:1 allocation score on 18node4: 0 -+native_color: FAKECLONE1:1 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:1 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:1 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:1 allocation score on 18node4: -INFINITY - native_color: FAKECLONE1:1 allocation score on remote1: 0 --native_color: FAKECLONE1:2 allocation score on 18builder: -INFINITY - native_color: FAKECLONE1:2 allocation score on 18node1: -INFINITY --native_color: FAKECLONE1:2 allocation score on 18node2: 0 --native_color: FAKECLONE1:2 allocation score on 18node3: 0 --native_color: FAKECLONE1:2 allocation score on 18node4: 0 --native_color: FAKECLONE1:2 allocation score on remote1: 0 --native_color: FAKECLONE1:3 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE1:2 allocation score on remote1: -INFINITY - native_color: FAKECLONE1:3 allocation score on 18node1: -INFINITY - native_color: FAKECLONE1:3 allocation score on 18node2: -INFINITY --native_color: FAKECLONE1:3 allocation score on 18node3: 0 --native_color: FAKECLONE1:3 allocation score on 18node4: 0 --native_color: FAKECLONE1:3 allocation score on remote1: 0 --native_color: FAKECLONE1:4 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE1:3 allocation score on remote1: -INFINITY - native_color: FAKECLONE1:4 allocation score on 18node1: -INFINITY - native_color: FAKECLONE1:4 allocation score on 18node2: -INFINITY --native_color: FAKECLONE1:4 allocation score on 18node3: 0 -+native_color: FAKECLONE1:4 allocation score on 18node3: -INFINITY - native_color: FAKECLONE1:4 allocation score on 18node4: -INFINITY --native_color: FAKECLONE1:4 allocation score on remote1: 0 --native_color: FAKECLONE1:5 allocation score on 18builder: -INFINITY --native_color: FAKECLONE1:5 allocation score on 18node1: -INFINITY --native_color: FAKECLONE1:5 allocation score on 18node2: -INFINITY --native_color: FAKECLONE1:5 allocation score on 18node3: 0 --native_color: FAKECLONE1:5 allocation score on 18node4: -INFINITY --native_color: FAKECLONE1:5 allocation score on remote1: -INFINITY --native_color: FAKECLONE2:0 allocation score on 18builder: 0 -+native_color: FAKECLONE1:4 allocation score on remote1: -INFINITY - native_color: FAKECLONE2:0 allocation score on 18node1: 0 - native_color: FAKECLONE2:0 allocation score on 18node2: 0 - native_color: FAKECLONE2:0 allocation score on 18node3: 0 - native_color: FAKECLONE2:0 allocation score on 18node4: 0 - native_color: FAKECLONE2:0 allocation score on remote1: 0 --native_color: FAKECLONE2:1 allocation score on 18builder: -INFINITY - native_color: FAKECLONE2:1 allocation score on 18node1: 0 - native_color: FAKECLONE2:1 allocation score on 18node2: 0 --native_color: FAKECLONE2:1 allocation score on 18node3: 0 -+native_color: FAKECLONE2:1 allocation score on 18node3: -INFINITY - native_color: FAKECLONE2:1 allocation score on 18node4: 0 - native_color: FAKECLONE2:1 allocation score on remote1: 0 --native_color: FAKECLONE2:2 allocation score on 18builder: -INFINITY - native_color: FAKECLONE2:2 allocation score on 18node1: -INFINITY - native_color: FAKECLONE2:2 allocation score on 18node2: 0 --native_color: FAKECLONE2:2 allocation score on 18node3: 0 -+native_color: FAKECLONE2:2 allocation score on 18node3: -INFINITY - native_color: FAKECLONE2:2 allocation score on 18node4: 0 - native_color: FAKECLONE2:2 allocation score on remote1: 0 --native_color: FAKECLONE2:3 allocation score on 18builder: -INFINITY - native_color: FAKECLONE2:3 allocation score on 18node1: -INFINITY - native_color: FAKECLONE2:3 allocation score on 18node2: -INFINITY --native_color: FAKECLONE2:3 allocation score on 18node3: 0 -+native_color: FAKECLONE2:3 allocation score on 18node3: -INFINITY - native_color: FAKECLONE2:3 allocation score on 18node4: 0 - native_color: FAKECLONE2:3 allocation score on remote1: 0 --native_color: FAKECLONE2:4 allocation score on 18builder: -INFINITY - native_color: FAKECLONE2:4 allocation score on 18node1: -INFINITY - native_color: FAKECLONE2:4 allocation score on 18node2: -INFINITY --native_color: FAKECLONE2:4 allocation score on 18node3: 0 -+native_color: FAKECLONE2:4 allocation score on 18node3: -INFINITY - native_color: FAKECLONE2:4 allocation score on 18node4: -INFINITY - native_color: FAKECLONE2:4 allocation score on remote1: 0 --native_color: FAKECLONE2:5 allocation score on 18builder: -INFINITY --native_color: FAKECLONE2:5 allocation score on 18node1: -INFINITY --native_color: FAKECLONE2:5 allocation score on 18node2: -INFINITY --native_color: FAKECLONE2:5 allocation score on 18node3: 0 --native_color: FAKECLONE2:5 allocation score on 18node4: -INFINITY --native_color: FAKECLONE2:5 allocation score on remote1: -INFINITY --native_color: remote1 allocation score on 18builder: 0 - native_color: remote1 allocation score on 18node1: 0 - native_color: remote1 allocation score on 18node2: 0 - native_color: remote1 allocation score on 18node3: 0 - native_color: remote1 allocation score on 18node4: 0 - native_color: remote1 allocation score on remote1: -INFINITY --native_color: shooter allocation score on 18builder: 0 - native_color: shooter allocation score on 18node1: 0 - native_color: shooter allocation score on 18node2: 0 - native_color: shooter allocation score on 18node3: 0 -diff --git a/pengine/test10/resource-discovery.summary b/pengine/test10/resource-discovery.summary -index af0e5b3..e3d23a5 100644 ---- a/pengine/test10/resource-discovery.summary -+++ b/pengine/test10/resource-discovery.summary -@@ -1,124 +1,128 @@ - - Current cluster status: --Online: [ 18builder 18node1 18node2 18node3 18node4 ] -+Online: [ 18node1 18node2 18node3 18node4 ] - RemoteOFFLINE: [ remote1 ] - -- shooter (stonith:fence_xvm): Started 18node1 -+ shooter (stonith:fence_xvm): Stopped - remote1 (ocf::pacemaker:remote): Stopped - FAKE1 (ocf::heartbeat:Dummy): Stopped -- FAKE2 (ocf::heartbeat:Dummy): Started 18node2 -- FAKE3 (ocf::heartbeat:Dummy): Started 18builder -- FAKE4 (ocf::heartbeat:Dummy): Started 18node1 -+ FAKE2 (ocf::heartbeat:Dummy): Stopped -+ FAKE3 (ocf::heartbeat:Dummy): Stopped -+ FAKE4 (ocf::heartbeat:Dummy): Stopped - FAKE5 (ocf::heartbeat:Dummy): Stopped - Clone Set: FAKECLONE1-clone [FAKECLONE1] -- Stopped: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Stopped: [ 18node1 18node2 18node3 18node4 remote1 ] - Clone Set: FAKECLONE2-clone [FAKECLONE2] -- Stopped: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Stopped: [ 18node1 18node2 18node3 18node4 remote1 ] -+ Resource Group: FAKEGROUP -+ FAKE6 (ocf::heartbeat:Dummy): Stopped -+ FAKE7 (ocf::heartbeat:Dummy): Stopped - - Transition Summary: -- * Start remote1 (18builder) -- * Start FAKE1 (18node2) -- * Move FAKE2 (Started 18node2 -> 18node3) -- * Move FAKE3 (Started 18builder -> 18node3) -- * Move FAKE4 (Started 18node1 -> 18node4) -+ * Start shooter (18node2) -+ * Start remote1 (18node1) -+ * Start FAKE1 (18node4) -+ * Start FAKE2 (18node2) -+ * Start FAKE3 (18node3) -+ * Start FAKE4 (18node4) - * Start FAKE5 (remote1) -- * Start FAKECLONE1:0 (18builder) -- * Start FAKECLONE1:1 (18node1) -- * Start FAKECLONE1:2 (18node2) -- * Start FAKECLONE1:3 (18node4) -- * Start FAKECLONE1:4 (remote1) -- * Start FAKECLONE1:5 (18node3) -- * Start FAKECLONE2:0 (18builder) -+ * Start FAKECLONE1:0 (18node1) -+ * Start FAKECLONE1:1 (remote1) -+ * Start FAKECLONE2:0 (18node3) - * Start FAKECLONE2:1 (18node1) - * Start FAKECLONE2:2 (18node2) - * Start FAKECLONE2:3 (18node4) - * Start FAKECLONE2:4 (remote1) -- * Start FAKECLONE2:5 (18node3) -+ * Start FAKE6 (18node1) -+ * Start FAKE7 (18node1) - - Executing cluster transition: - * Resource action: shooter monitor on 18node4 - * Resource action: shooter monitor on 18node3 -+ * Resource action: shooter monitor on 18node2 -+ * Resource action: shooter monitor on 18node1 - * Resource action: remote1 monitor on 18node4 - * Resource action: remote1 monitor on 18node3 -+ * Resource action: remote1 monitor on 18node2 -+ * Resource action: remote1 monitor on 18node1 - * Resource action: FAKE1 monitor on 18node4 -- * Resource action: FAKE1 monitor on 18node3 -- * Resource action: FAKE1 monitor on 18node2 -- * Resource action: FAKE1 monitor on 18node1 -- * Resource action: FAKE1 monitor on 18builder -+ * Resource action: FAKE2 monitor on 18node2 -+ * Resource action: FAKE2 monitor on 18node1 - * Resource action: FAKE3 monitor on 18node3 - * Resource action: FAKE4 monitor on 18node4 - * Resource action: FAKE5 monitor on 18node4 - * Resource action: FAKE5 monitor on 18node3 - * Resource action: FAKE5 monitor on 18node2 - * Resource action: FAKE5 monitor on 18node1 -- * Resource action: FAKE5 monitor on 18builder -+ * Resource action: FAKECLONE1:0 monitor on 18node1 - * Pseudo action: FAKECLONE1-clone_start_0 -- * Resource action: FAKECLONE2:0 monitor on 18builder -+ * Resource action: FAKECLONE2:0 monitor on 18node3 - * Resource action: FAKECLONE2:1 monitor on 18node1 - * Resource action: FAKECLONE2:3 monitor on 18node4 -- * Resource action: FAKECLONE2:5 monitor on 18node3 - * Pseudo action: FAKECLONE2-clone_start_0 -+ * Pseudo action: FAKEGROUP_start_0 -+ * Resource action: FAKE6 monitor on 18node2 -+ * Resource action: FAKE6 monitor on 18node1 -+ * Resource action: FAKE7 monitor on 18node2 -+ * Resource action: FAKE7 monitor on 18node1 - * Pseudo action: probe_nodes_complete -- * Resource action: remote1 start on 18builder -+ * Resource action: remote1 start on 18node1 - * Resource action: FAKE5 monitor on remote1 -- * Resource action: FAKECLONE1:4 monitor on remote1 -+ * Resource action: FAKECLONE1:1 monitor on remote1 - * Resource action: FAKECLONE2:4 monitor on remote1 - * Pseudo action: probe_complete -- * Resource action: remote1 monitor=60000 on 18builder -- * Resource action: FAKE1 start on 18node2 -- * Resource action: FAKE2 stop on 18node2 -- * Resource action: FAKE3 stop on 18builder -- * Resource action: FAKE4 stop on 18node1 -+ * Resource action: shooter start on 18node2 -+ * Resource action: remote1 monitor=60000 on 18node1 -+ * Resource action: FAKE1 start on 18node4 -+ * Resource action: FAKE2 start on 18node2 -+ * Resource action: FAKE3 start on 18node3 -+ * Resource action: FAKE4 start on 18node4 - * Resource action: FAKE5 start on remote1 -- * Resource action: FAKECLONE1:0 start on 18builder -- * Resource action: FAKECLONE1:1 start on 18node1 -- * Resource action: FAKECLONE1:2 start on 18node2 -- * Resource action: FAKECLONE1:3 start on 18node4 -- * Resource action: FAKECLONE1:4 start on remote1 -- * Resource action: FAKECLONE1:5 start on 18node3 -+ * Resource action: FAKECLONE1:0 start on 18node1 -+ * Resource action: FAKECLONE1:1 start on remote1 - * Pseudo action: FAKECLONE1-clone_running_0 -- * Resource action: FAKECLONE2:0 start on 18builder -+ * Resource action: FAKECLONE2:0 start on 18node3 - * Resource action: FAKECLONE2:1 start on 18node1 - * Resource action: FAKECLONE2:2 start on 18node2 - * Resource action: FAKECLONE2:3 start on 18node4 - * Resource action: FAKECLONE2:4 start on remote1 -- * Resource action: FAKECLONE2:5 start on 18node3 - * Pseudo action: FAKECLONE2-clone_running_0 -- * Pseudo action: all_stopped -- * Resource action: FAKE1 monitor=60000 on 18node2 -- * Resource action: FAKE2 start on 18node3 -- * Resource action: FAKE3 start on 18node3 -- * Resource action: FAKE4 start on 18node4 -+ * Resource action: FAKE6 start on 18node1 -+ * Resource action: FAKE7 start on 18node1 -+ * Resource action: shooter monitor=60000 on 18node2 -+ * Resource action: FAKE1 monitor=60000 on 18node4 -+ * Resource action: FAKE2 monitor=60000 on 18node2 -+ * Resource action: FAKE3 monitor=60000 on 18node3 -+ * Resource action: FAKE4 monitor=60000 on 18node4 - * Resource action: FAKE5 monitor=60000 on remote1 -- * Resource action: FAKECLONE1:0 monitor=60000 on 18builder -- * Resource action: FAKECLONE1:1 monitor=60000 on 18node1 -- * Resource action: FAKECLONE1:2 monitor=60000 on 18node2 -- * Resource action: FAKECLONE1:3 monitor=60000 on 18node4 -- * Resource action: FAKECLONE1:4 monitor=60000 on remote1 -- * Resource action: FAKECLONE1:5 monitor=60000 on 18node3 -- * Resource action: FAKECLONE2:0 monitor=60000 on 18builder -+ * Resource action: FAKECLONE1:0 monitor=60000 on 18node1 -+ * Resource action: FAKECLONE1:1 monitor=60000 on remote1 -+ * Resource action: FAKECLONE2:0 monitor=60000 on 18node3 - * Resource action: FAKECLONE2:1 monitor=60000 on 18node1 - * Resource action: FAKECLONE2:2 monitor=60000 on 18node2 - * Resource action: FAKECLONE2:3 monitor=60000 on 18node4 - * Resource action: FAKECLONE2:4 monitor=60000 on remote1 -- * Resource action: FAKECLONE2:5 monitor=60000 on 18node3 -- * Resource action: FAKE2 monitor=60000 on 18node3 -- * Resource action: FAKE3 monitor=60000 on 18node3 -- * Resource action: FAKE4 monitor=60000 on 18node4 -+ * Pseudo action: FAKEGROUP_running_0 -+ * Resource action: FAKE6 monitor=10000 on 18node1 -+ * Resource action: FAKE7 monitor=10000 on 18node1 - - Revised cluster status: --Online: [ 18builder 18node1 18node2 18node3 18node4 ] -+Online: [ 18node1 18node2 18node3 18node4 ] - RemoteOnline: [ remote1 ] - -- shooter (stonith:fence_xvm): Started 18node1 -- remote1 (ocf::pacemaker:remote): Started 18builder -- FAKE1 (ocf::heartbeat:Dummy): Started 18node2 -- FAKE2 (ocf::heartbeat:Dummy): Started 18node3 -+ shooter (stonith:fence_xvm): Started 18node2 -+ remote1 (ocf::pacemaker:remote): Started 18node1 -+ FAKE1 (ocf::heartbeat:Dummy): Started 18node4 -+ FAKE2 (ocf::heartbeat:Dummy): Started 18node2 - FAKE3 (ocf::heartbeat:Dummy): Started 18node3 - FAKE4 (ocf::heartbeat:Dummy): Started 18node4 - FAKE5 (ocf::heartbeat:Dummy): Started remote1 - Clone Set: FAKECLONE1-clone [FAKECLONE1] -- Started: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Started: [ 18node1 remote1 ] -+ Stopped: [ 18node2 18node3 18node4 ] - Clone Set: FAKECLONE2-clone [FAKECLONE2] -- Started: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Started: [ 18node1 18node2 18node3 18node4 remote1 ] -+ Resource Group: FAKEGROUP -+ FAKE6 (ocf::heartbeat:Dummy): Started 18node1 -+ FAKE7 (ocf::heartbeat:Dummy): Started 18node1 - -diff --git a/pengine/test10/resource-discovery.xml b/pengine/test10/resource-discovery.xml -index 5836804..8b517df 100644 ---- a/pengine/test10/resource-discovery.xml -+++ b/pengine/test10/resource-discovery.xml -@@ -1,4 +1,4 @@ -- -+ - - - -@@ -11,7 +11,6 @@ - - - -- - - - -@@ -29,16 +28,14 @@ - - - -- -- -+ - - - - - - -- -- -+ - - - -@@ -77,109 +74,70 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -- -- -- -- -- -- -- -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -+ -+ -+ - - -- -+ - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -+ - -- -- -- -- - -- -+ - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -+ - -- -- -- -- - -- -- -- -- -- -- -- -+ -+ -+ -+ - -+ -+ -+ -+ - - -diff --git a/tools/Makefile.am b/tools/Makefile.am -index 5142b29..74b69e3 100644 ---- a/tools/Makefile.am -+++ b/tools/Makefile.am -@@ -77,7 +77,7 @@ crm_node_SOURCES = crm_node.c - crm_node_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la \ - $(COMMONLIBS) $(CLUSTERLIBS) - --crm_simulate_SOURCES = crm_simulate.c -+crm_simulate_SOURCES = crm_simulate.c fake_transition.c - crm_simulate_CFLAGS = -I$(top_srcdir)/pengine - - crm_simulate_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \ -@@ -105,12 +105,14 @@ crm_verify_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \ - crm_attribute_SOURCES = crm_attribute.c - crm_attribute_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la $(COMMONLIBS) - --crm_resource_SOURCES = crm_resource.c --crm_resource_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \ -- $(top_builddir)/lib/lrmd/liblrmd.la \ -- $(top_builddir)/lib/services/libcrmservice.la \ -- $(top_builddir)/lib/pengine/libpe_status.la \ -- $(top_builddir)/pengine/libpengine.la \ -+crm_resource_SOURCES = crm_resource.c fake_transition.c -+crm_resource_CFLAGS = -I$(top_srcdir)/pengine -+crm_resource_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \ -+ $(top_builddir)/lib/lrmd/liblrmd.la \ -+ $(top_builddir)/lib/services/libcrmservice.la \ -+ $(top_builddir)/lib/pengine/libpe_status.la \ -+ $(top_builddir)/pengine/libpengine.la \ -+ $(top_builddir)/lib/transition/libtransitioner.la \ - $(COMMONLIBS) - - iso8601_SOURCES = test.iso8601.c -diff --git a/tools/crm_failcount b/tools/crm_failcount -index 94a8400..ed697e9 100755 ---- a/tools/crm_failcount -+++ b/tools/crm_failcount -@@ -1,5 +1,6 @@ - #!/bin/bash - -+resource="" - options="" - target=`crm_node -n` - -@@ -11,15 +12,7 @@ if [ $? != 0 ] ; then echo "crm_failcount - A convenience wrapper for crm_attrib - # Note the quotes around `$TEMP': they are essential! - eval set -- "$TEMP" - --while true ; do -- case "$1" in -- -N|--node) target="$2"; shift; shift;; -- -U|--uname) target="$2"; shift; shift;; -- -v|--attr-value|-i|--attr-id) options="$options $1 $2"; shift; shift;; -- -Q|--quiet|-D|--delete-attr|-G|--get-value|-V) options="$options $1"; shift;; -- -r|--resource-id) options="$options -n fail-count-$2"; shift; shift;; -- --version) crm_attribute --version; exit 0;; -- --help) -+function show_help() { - echo "crm_failcount - A convenience wrapper for crm_attribute"; - echo ""; - echo "Set, update or remove the failcount for the specified resource on the named node"; -@@ -43,10 +36,27 @@ while true ; do - echo " -l, --lifetime=value Until when should the setting take affect." - echo " Valid values: reboot, forever" - echo " -i, --id=value (Advanced) The ID used to identify the attribute" -+} -+ -+while true ; do -+ case "$1" in -+ -N|--node) target="$2"; shift; shift;; -+ -U|--uname) target="$2"; shift; shift;; -+ -v|--attr-value|-i|--attr-id) options="$options $1 $2"; shift; shift;; -+ -Q|--quiet|-D|--delete-attr|-G|--get-value|-V) options="$options $1"; shift;; -+ -r|--resource-id) options="$options -n fail-count-$2"; resource="$2"; shift; shift;; -+ --version) crm_attribute --version; exit 0;; -+ --help) -+ show_help - exit 0;; - --) shift ; break ;; - *) echo "Unknown option: $1. See --help for details." exit 1;; - esac - done - -+if [ "x$resource" = x ]; then -+ echo "You must supply a resource name to check. See 'crm_failcount --help' for details" -+ exit 1 -+fi -+ - crm_attribute -N $target $options -t status -d 0 -diff --git a/tools/crm_resource.c b/tools/crm_resource.c -index ff5effd..6e510e1 100644 ---- a/tools/crm_resource.c -+++ b/tools/crm_resource.c -@@ -43,6 +43,9 @@ - #include - #include - -+#include "fake_transition.h" -+extern xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now); -+ - bool scope_master = FALSE; - gboolean do_force = FALSE; - gboolean BE_QUIET = FALSE; -@@ -1300,6 +1303,373 @@ generate_resource_params(resource_t * rsc, pe_working_set_t * data_set) - return combined; - } - -+static bool resource_is_running_on(resource_t *rsc, const char *host) -+{ -+ bool found = TRUE; -+ GListPtr hIter = NULL; -+ GListPtr hosts = NULL; -+ -+ if(rsc == NULL) { -+ return FALSE; -+ } -+ -+ rsc->fns->location(rsc, &hosts, TRUE); -+ for (hIter = hosts; host != NULL && hIter != NULL; hIter = hIter->next) { -+ pe_node_t *node = (pe_node_t *) hIter->data; -+ -+ if(strcmp(host, node->details->uname) == 0) { -+ crm_trace("Resource %s is running on %s\n", rsc->id, host); -+ goto done; -+ } else if(strcmp(host, node->details->id) == 0) { -+ crm_trace("Resource %s is running on %s\n", rsc->id, host); -+ goto done; -+ } -+ } -+ -+ if(host != NULL) { -+ crm_trace("Resource %s is not running on: %s\n", rsc->id, host); -+ found = FALSE; -+ -+ } else if(host == NULL && hosts == NULL) { -+ crm_trace("Resource %s is not running\n", rsc->id); -+ found = FALSE; -+ } -+ -+ done: -+ -+ g_list_free(hosts); -+ return found; -+} -+ -+static GList *get_active_resources(const char *host, pe_working_set_t *data_set) -+{ -+ GList *rIter = NULL; -+ GList *active = NULL; -+ -+ for (rIter = data_set->resources; rIter != NULL; rIter = rIter->next) { -+ resource_t *rsc = (resource_t *) rIter->data; -+ -+ if(resource_is_running_on(rsc, host)) { -+ active = g_list_append(active, strdup(rsc->id)); -+ } -+ } -+ -+ return active; -+} -+ -+static GList *subtract_lists(GList *from, GList *items) -+{ -+ GList *item = NULL; -+ GList *result = g_list_copy(from); -+ -+ for (item = items; item != NULL; item = item->next) { -+ GList *candidate = NULL; -+ for (candidate = from; candidate != NULL; candidate = candidate->next) { -+ crm_info("Comparing %s with %s", candidate->data, item->data); -+ if(strcmp(candidate->data, item->data) == 0) { -+ result = g_list_remove(result, candidate->data); -+ break; -+ } -+ } -+ } -+ -+ return result; -+} -+ -+static void dump_list(GList *items, const char *tag) -+{ -+ int lpc = 0; -+ GList *item = NULL; -+ -+ for (item = items; item != NULL; item = item->next) { -+ crm_trace("%s[%d]: %s", tag, lpc, item->data); -+ lpc++; -+ } -+} -+ -+static void display_list(GList *items, const char *tag) -+{ -+ GList *item = NULL; -+ -+ for (item = items; item != NULL; item = item->next) { -+ fprintf(stdout, "%s%s\n", tag, (const char *)item->data); -+ } -+} -+ -+static int -+update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate) -+{ -+ xmlNode *cib_xml_copy = NULL; -+ int rc = cib->cmds->query(cib, NULL, &cib_xml_copy, cib_scope_local | cib_sync_call); -+ -+ if(rc != pcmk_ok) { -+ fprintf(stdout, "Could not obtain the current CIB: %s (%d)\n", pcmk_strerror(rc), rc); -+ return crm_exit(rc); -+ -+ } else if (cli_config_update(&cib_xml_copy, NULL, FALSE) == FALSE) { -+ fprintf(stderr, "Could not upgrade the current CIB\n"); -+ return -ENOKEY; -+ } -+ -+ set_working_set_defaults(data_set); -+ data_set->input = cib_xml_copy; -+ data_set->now = crm_time_new(NULL); -+ -+ if(simulate) { -+ char *pid = crm_itoa(getpid()); -+ cib_t *shadow_cib = cib_shadow_new(pid); -+ char *shadow_file = get_shadow_file(pid); -+ -+ if (shadow_cib == NULL) { -+ fprintf(stderr, "Could not create shadow cib: '%s'\n", pid); -+ crm_exit(-ENXIO); -+ } -+ -+ rc = write_xml_file(cib_xml_copy, shadow_file, FALSE); -+ -+ if (rc < 0) { -+ fprintf(stderr, "Could not populate shadow cib: %s (%d)\n", pcmk_strerror(rc), rc); -+ free_xml(cib_xml_copy); -+ return rc; -+ } -+ -+ rc = shadow_cib->cmds->signon(shadow_cib, crm_system_name, cib_command); -+ if(rc != pcmk_ok) { -+ fprintf(stderr, "Could not connect to shadow cib: %s (%d)\n", pcmk_strerror(rc), rc); -+ free_xml(cib_xml_copy); -+ return rc; -+ } -+ -+ do_calculations(data_set, cib_xml_copy, NULL); -+ run_simulation(data_set, shadow_cib, NULL, TRUE); -+ rc = update_dataset(shadow_cib, data_set, FALSE); -+ -+ cib_delete(shadow_cib); -+ /* unlink(shadow_file); */ -+ free(shadow_file); -+ -+ } else { -+ cluster_status(data_set); -+ } -+ -+ return rc; -+} -+ -+static int -+max_delay_in(pe_working_set_t * data_set, GList *resources) -+{ -+ int max_delay = 0; -+ GList *item = NULL; -+ -+ for (item = resources; item != NULL; item = item->next) { -+ resource_t *rsc = pe_find_resource(data_set->resources, (const char *)item->data); -+ -+ if(rsc) { -+ char *key = g_strdup_printf("%s_%s_0", rsc->id, RSC_STOP); -+ action_t *stop = custom_action(rsc, key, RSC_STOP, NULL, TRUE, FALSE, data_set); -+ const char *value = g_hash_table_lookup(stop->meta, XML_ATTR_TIMEOUT); -+ int delay = crm_int_helper(value, NULL); -+ -+ if(delay > max_delay) { -+ crm_trace("Calculated new delay of %s ms due to %s", value, rsc->id); -+ max_delay = delay; -+ } -+ -+ pe_free_action(stop); -+ } -+ } -+ -+ -+ return 5 + (max_delay / 1000); -+} -+ -+static int -+resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib) -+{ -+ int rc = 0; -+ int lpc = 0; -+ int before = 0; -+ int step_timeout_s = 0; -+ int sleep_interval = 2; -+ int timeout = timeout_ms / 1000; -+ -+ bool is_clone = FALSE; -+ char *rsc_id = NULL; -+ -+ GList *list_delta = NULL; -+ GList *target_active = NULL; -+ GList *current_active = NULL; -+ GList *restart_target_active = NULL; -+ -+ pe_working_set_t data_set; -+ -+ if(resource_is_running_on(rsc, host) == FALSE) { -+ return -ENXIO; -+ } -+ -+ -+ rsc_id = strdup(rsc->id); -+ if(rsc->variant > pe_group) { -+ is_clone = TRUE; -+ } -+ -+ /* -+ grab full cib -+ determine resource state of list -+ disable or ban -+ poll and and watch for resources to get stopped -+ without --wait, calculate the stop timeout for each step and wait for that -+ if we hit --wait or the service timeout, re-enable or un-ban, report failure and indicate which resources we couldn't take down -+ if everything stopped, re-enable or un-ban -+ poll and and watch for resources to get stopped -+ without --wait, calculate the start timeout for each step and wait for that -+ if we hit --wait or the service timeout, report (different) failure and indicate which resources we couldn't bring back up -+ report success -+ -+ Optimizations: -+ - use constraints to determine ordered list of affected resources -+ - Allow a --no-deps option (aka. --force-restart) -+ */ -+ -+ -+ set_working_set_defaults(&data_set); -+ rc = update_dataset(cib, &data_set, FALSE); -+ if(rc != pcmk_ok) { -+ fprintf(stdout, "Could not get new resource list: %s (%d)\n", pcmk_strerror(rc), rc); -+ return rc; -+ } -+ -+ restart_target_active = get_active_resources(host, &data_set); -+ current_active = get_active_resources(host, &data_set); -+ -+ dump_list(current_active, "Origin"); -+ -+ if(is_clone && host) { -+ BE_QUIET = TRUE; -+ rc = ban_resource(rsc_id, host, NULL, cib); -+ -+ } else { -+ rc = set_resource_attr(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, RSC_STOPPED, FALSE, cib, &data_set); -+ } -+ if(rc != pcmk_ok) { -+ fprintf(stderr, "Could not set target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc); -+ return crm_exit(rc); -+ } -+ -+ rc = update_dataset(cib, &data_set, TRUE); -+ if(rc != pcmk_ok) { -+ fprintf(stderr, "Could not determine which resources would be stopped\n"); -+ goto failure; -+ } -+ -+ target_active = get_active_resources(host, &data_set); -+ dump_list(target_active, "Target"); -+ -+ list_delta = subtract_lists(current_active, target_active); -+ fprintf(stdout, "Waiting for %d resources to stop:\n", g_list_length(list_delta)); -+ display_list(list_delta, " * "); -+ -+ step_timeout_s = timeout / sleep_interval; -+ while(g_list_length(list_delta) > 0) { -+ before = g_list_length(list_delta); -+ if(timeout_ms == 0) { -+ step_timeout_s = max_delay_in(&data_set, list_delta) / sleep_interval; -+ } -+ -+ /* We probably don't need the entire step timeout */ -+ for(lpc = 0; lpc < step_timeout_s && g_list_length(list_delta) > 0; lpc++) { -+ sleep(sleep_interval); -+ if(timeout) { -+ timeout -= sleep_interval; -+ crm_trace("%ds remaining", timeout); -+ } -+ rc = update_dataset(cib, &data_set, FALSE); -+ if(rc != pcmk_ok) { -+ fprintf(stderr, "Could not determine which resources were stopped\n"); -+ goto failure; -+ } -+ -+ current_active = get_active_resources(host, &data_set); -+ list_delta = subtract_lists(current_active, target_active); -+ dump_list(current_active, "Current"); -+ dump_list(list_delta, "Delta"); -+ } -+ -+ crm_trace("%d (was %d) resources remaining", before, g_list_length(list_delta)); -+ if(before == g_list_length(list_delta)) { -+ /* aborted during stop phase, print the contents of list_delta */ -+ fprintf(stderr, "Could not complete shutdown of %s, %d resources remaining\n", rsc_id, g_list_length(list_delta)); -+ display_list(list_delta, " * "); -+ rc = -ETIME; -+ goto failure; -+ } -+ -+ } -+ -+ if(is_clone && host) { -+ rc = clear_resource(rsc_id, host, NULL, cib); -+ -+ } else { -+ rc = delete_resource_attr(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set); -+ } -+ -+ if(rc != pcmk_ok) { -+ fprintf(stderr, "Could not unset target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc); -+ return crm_exit(rc); -+ } -+ -+ target_active = restart_target_active; -+ list_delta = subtract_lists(target_active, current_active); -+ fprintf(stdout, "Waiting for %d resources to start again:\n", g_list_length(list_delta)); -+ display_list(list_delta, " * "); -+ -+ step_timeout_s = timeout / sleep_interval; -+ while(g_list_length(list_delta) > 0) { -+ if(timeout_ms == 0) { -+ step_timeout_s = max_delay_in(&data_set, list_delta) / sleep_interval; -+ } -+ -+ /* We probably don't need the entire step timeout */ -+ for(lpc = 0; lpc < step_timeout_s && g_list_length(list_delta) > 0; lpc++) { -+ sleep(sleep_interval); -+ if(timeout) { -+ timeout -= sleep_interval; -+ crm_trace("%ds remaining", timeout); -+ } -+ -+ rc = update_dataset(cib, &data_set, FALSE); -+ if(rc != pcmk_ok) { -+ fprintf(stderr, "Could not determine which resources were started\n"); -+ goto failure; -+ } -+ -+ current_active = get_active_resources(host, &data_set); -+ list_delta = subtract_lists(target_active, current_active); -+ dump_list(current_active, "Current"); -+ dump_list(list_delta, "Delta"); -+ } -+ -+ if(before == g_list_length(list_delta)) { -+ /* aborted during start phase, print the contents of list_delta */ -+ fprintf(stdout, "Could not complete restart of %s, %d resources remaining\n", rsc_id, g_list_length(list_delta)); -+ display_list(list_delta, " * "); -+ rc = -ETIME; -+ goto failure; -+ } -+ -+ } while(g_list_length(list_delta) > 0); -+ -+ return pcmk_ok; -+ -+ failure: -+ if(is_clone && host) { -+ clear_resource(rsc_id, host, NULL, cib); -+ -+ } else { -+ delete_resource_attr(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set); -+ } -+ return rc; -+} - - /* *INDENT-OFF* */ - static struct crm_option long_options[] = { -@@ -1371,6 +1741,7 @@ static struct crm_option long_options[] = { - {"-spacer-", 1, 0, '-', "\nAdvanced Commands:"}, - {"delete", 0, 0, 'D', "\t\t(Advanced) Delete a resource from the CIB"}, - {"fail", 0, 0, 'F', "\t\t(Advanced) Tell the cluster this resource has failed"}, -+ {"restart", 0, 0, 0, NULL, 1}, - {"force-stop", 0, 0, 0, "\t(Advanced) Bypass the cluster and stop a resource on the local node. Additional detail with -V"}, - {"force-start",0, 0, 0, "\t(Advanced) Bypass the cluster and start a resource on the local node. Additional detail with -V"}, - {"force-check",0, 0, 0, "\t(Advanced) Bypass the cluster and check the state of a resource on the local node. Additional detail with -V\n"}, -@@ -1384,6 +1755,7 @@ static struct crm_option long_options[] = { - {"utilization", 0, 0, 'z', "\tModify a resource's utilization attribute. For use with -p, -g, -d"}, - {"set-name", 1, 0, 's', "\t(Advanced) ID of the instance_attributes object to change"}, - {"nvpair", 1, 0, 'i', "\t(Advanced) ID of the nvpair object to change/delete"}, -+ {"timeout", 1, 0, 'T', "\t(Advanced) How long to wait for --restart to take effect", 1}, - {"force", 0, 0, 'f', "\n" /* Is this actually true anymore? - "\t\tForce the resource to move by creating a rule for the current location and a score of -INFINITY" - "\n\t\tThis should be used if the resource's stickiness and constraint scores total more than INFINITY (Currently 100,000)" -@@ -1444,6 +1816,7 @@ main(int argc, char **argv) - - int rc = pcmk_ok; - int option_index = 0; -+ int timeout_ms = 0; - int argerr = 0; - int flag; - -@@ -1469,6 +1842,7 @@ main(int argc, char **argv) - recursive = TRUE; - - } else if (safe_str_eq("force-stop", longname) -+ || safe_str_eq("restart", longname) - || safe_str_eq("force-start", longname) - || safe_str_eq("force-check", longname)) { - rsc_cmd = flag; -@@ -1618,6 +1992,9 @@ main(int argc, char **argv) - case 't': - rsc_type = optarg; - break; -+ case 'T': -+ timeout_ms = crm_get_msec(optarg); -+ break; - case 'C': - case 'R': - case 'P': -@@ -1769,6 +2146,11 @@ main(int argc, char **argv) - goto bail; - } - -+ } else if (rsc_cmd == 0 && rsc_long_cmd && safe_str_eq(rsc_long_cmd, "restart")) { -+ resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); -+ -+ rc = resource_restart(rsc, host_uname, timeout_ms, cib_conn); -+ - } else if (rsc_cmd == 0 && rsc_long_cmd) { - svc_action_t *op = NULL; - const char *rtype = NULL; -@@ -1801,6 +2183,16 @@ main(int argc, char **argv) - action = "monitor"; - } - -+ if(rsc->variant == pe_clone || rsc->variant == pe_master) { -+ /* Grab the first child resource in the hope its not a group */ -+ rsc = rsc->children->data; -+ } -+ -+ if(rsc->variant == pe_group) { -+ CMD_ERR("Sorry, --%s doesn't support group resources\n", rsc_long_cmd); -+ crm_exit(EOPNOTSUPP); -+ } -+ - rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); - rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE); -diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c -index 7c0dcc7..d4e2238 100644 ---- a/tools/crm_simulate.c -+++ b/tools/crm_simulate.c -@@ -34,19 +34,14 @@ - #include - #include - #include -+#include "fake_transition.h" - - cib_t *global_cib = NULL; - GListPtr op_fail = NULL; - gboolean quiet = FALSE; --gboolean bringing_nodes_online = FALSE; - gboolean print_pending = FALSE; - char *temp_shadow = NULL; -- --#define new_node_template "//"XML_CIB_TAG_NODE"[@uname='%s']" --#define node_template "//"XML_CIB_TAG_STATE"[@uname='%s']" --#define rsc_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']" --#define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s']" --/* #define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s' and @"XML_LRM_ATTR_CALLID"='%d']" */ -+extern gboolean bringing_nodes_online; - - #define quiet_log(fmt, args...) do { \ - if(quiet == FALSE) { \ -@@ -68,472 +63,6 @@ get_date(void) - return NULL; - } - --static xmlNode * --find_resource(xmlNode * cib_node, const char *resource) --{ -- char *xpath = NULL; -- xmlNode *match = NULL; -- const char *node = crm_element_value(cib_node, XML_ATTR_UNAME); -- int max = strlen(rsc_template) + strlen(resource) + strlen(node) + 1; -- -- xpath = calloc(1, max); -- -- snprintf(xpath, max, rsc_template, node, resource); -- match = get_xpath_object(xpath, cib_node, LOG_DEBUG_2); -- -- free(xpath); -- return match; --} -- --static void --create_node_entry(cib_t * cib_conn, const char *node) --{ -- int rc = pcmk_ok; -- int max = strlen(new_node_template) + strlen(node) + 1; -- char *xpath = NULL; -- -- xpath = calloc(1, max); -- -- snprintf(xpath, max, new_node_template, node); -- rc = cib_conn->cmds->query(cib_conn, xpath, NULL, cib_xpath | cib_sync_call | cib_scope_local); -- -- if (rc == -ENXIO) { -- xmlNode *cib_object = create_xml_node(NULL, XML_CIB_TAG_NODE); -- -- /* Using node uname as uuid ala corosync/openais */ -- crm_xml_add(cib_object, XML_ATTR_ID, node); -- crm_xml_add(cib_object, XML_ATTR_UNAME, node); -- cib_conn->cmds->create(cib_conn, XML_CIB_TAG_NODES, cib_object, -- cib_sync_call | cib_scope_local); -- /* Not bothering with subsequent query to see if it exists, -- we'll bomb out later in the call to query_node_uuid()... */ -- -- free_xml(cib_object); -- } -- -- free(xpath); --} -- --static xmlNode * --inject_node_state(cib_t * cib_conn, const char *node, const char *uuid) --{ -- int rc = pcmk_ok; -- int max = strlen(rsc_template) + strlen(node) + 1; -- char *xpath = NULL; -- xmlNode *cib_object = NULL; -- -- xpath = calloc(1, max); -- -- if (bringing_nodes_online) { -- create_node_entry(cib_conn, node); -- } -- -- snprintf(xpath, max, node_template, node); -- rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, -- cib_xpath | cib_sync_call | cib_scope_local); -- -- if (cib_object && ID(cib_object) == NULL) { -- crm_err("Detected multiple node_state entries for xpath=%s, bailing", xpath); -- crm_log_xml_warn(cib_object, "Duplicates"); -- crm_exit(ENOTUNIQ); -- } -- -- if (rc == -ENXIO) { -- char *found_uuid = NULL; -- -- if (uuid == NULL) { -- query_node_uuid(cib_conn, node, &found_uuid, NULL); -- } else { -- found_uuid = strdup(uuid); -- } -- -- cib_object = create_xml_node(NULL, XML_CIB_TAG_STATE); -- crm_xml_add(cib_object, XML_ATTR_UUID, found_uuid); -- crm_xml_add(cib_object, XML_ATTR_UNAME, node); -- cib_conn->cmds->create(cib_conn, XML_CIB_TAG_STATUS, cib_object, -- cib_sync_call | cib_scope_local); -- free_xml(cib_object); -- free(found_uuid); -- -- rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, -- cib_xpath | cib_sync_call | cib_scope_local); -- crm_trace("injecting node state for %s. rc is %d", node, rc); -- } -- -- free(xpath); -- CRM_ASSERT(rc == pcmk_ok); -- return cib_object; --} -- --static xmlNode * --modify_node(cib_t * cib_conn, char *node, gboolean up) --{ -- xmlNode *cib_node = inject_node_state(cib_conn, node, NULL); -- -- if (up) { -- crm_xml_add(cib_node, XML_NODE_IN_CLUSTER, XML_BOOLEAN_YES); -- crm_xml_add(cib_node, XML_NODE_IS_PEER, ONLINESTATUS); -- crm_xml_add(cib_node, XML_NODE_JOIN_STATE, CRMD_JOINSTATE_MEMBER); -- crm_xml_add(cib_node, XML_NODE_EXPECTED, CRMD_JOINSTATE_MEMBER); -- -- } else { -- crm_xml_add(cib_node, XML_NODE_IN_CLUSTER, XML_BOOLEAN_NO); -- crm_xml_add(cib_node, XML_NODE_IS_PEER, OFFLINESTATUS); -- crm_xml_add(cib_node, XML_NODE_JOIN_STATE, CRMD_JOINSTATE_DOWN); -- crm_xml_add(cib_node, XML_NODE_EXPECTED, CRMD_JOINSTATE_DOWN); -- } -- -- crm_xml_add(cib_node, XML_ATTR_ORIGIN, crm_system_name); -- return cib_node; --} -- --static void --inject_transient_attr(xmlNode * cib_node, const char *name, const char *value) --{ -- xmlNode *attrs = NULL; -- xmlNode *container = NULL; -- xmlNode *nvp = NULL; -- const char *node_uuid = ID(cib_node); -- char *nvp_id = crm_concat(name, node_uuid, '-'); -- -- crm_info("Injecting attribute %s=%s into %s '%s'", name, value, xmlGetNodePath(cib_node), -- ID(cib_node)); -- -- attrs = first_named_child(cib_node, XML_TAG_TRANSIENT_NODEATTRS); -- if (attrs == NULL) { -- attrs = create_xml_node(cib_node, XML_TAG_TRANSIENT_NODEATTRS); -- crm_xml_add(attrs, XML_ATTR_ID, node_uuid); -- } -- -- container = first_named_child(attrs, XML_TAG_ATTR_SETS); -- if (container == NULL) { -- container = create_xml_node(attrs, XML_TAG_ATTR_SETS); -- crm_xml_add(container, XML_ATTR_ID, node_uuid); -- } -- -- nvp = create_xml_node(container, XML_CIB_TAG_NVPAIR); -- crm_xml_add(nvp, XML_ATTR_ID, nvp_id); -- crm_xml_add(nvp, XML_NVPAIR_ATTR_NAME, name); -- crm_xml_add(nvp, XML_NVPAIR_ATTR_VALUE, value); -- -- free(nvp_id); --} -- --static xmlNode * --inject_resource(xmlNode * cib_node, const char *resource, const char *rclass, const char *rtype, -- const char *rprovider) --{ -- xmlNode *lrm = NULL; -- xmlNode *container = NULL; -- xmlNode *cib_resource = NULL; -- char *xpath = NULL; -- -- cib_resource = find_resource(cib_node, resource); -- if (cib_resource != NULL) { -- return cib_resource; -- } -- -- /* One day, add query for class, provider, type */ -- -- if (rclass == NULL || rtype == NULL) { -- fprintf(stderr, "Resource %s not found in the status section of %s." -- " Please supply the class and type to continue\n", resource, ID(cib_node)); -- return NULL; -- -- } else if (safe_str_neq(rclass, "ocf") -- && safe_str_neq(rclass, "stonith") -- && safe_str_neq(rclass, "heartbeat") -- && safe_str_neq(rclass, "service") -- && safe_str_neq(rclass, "upstart") -- && safe_str_neq(rclass, "systemd") -- && safe_str_neq(rclass, "lsb")) { -- fprintf(stderr, "Invalid class for %s: %s\n", resource, rclass); -- return NULL; -- -- } else if (safe_str_eq(rclass, "ocf") && rprovider == NULL) { -- fprintf(stderr, "Please specify the provider for resource %s\n", resource); -- return NULL; -- } -- -- xpath = (char *)xmlGetNodePath(cib_node); -- crm_info("Injecting new resource %s into %s '%s'", resource, xpath, ID(cib_node)); -- free(xpath); -- -- lrm = first_named_child(cib_node, XML_CIB_TAG_LRM); -- if (lrm == NULL) { -- const char *node_uuid = ID(cib_node); -- -- lrm = create_xml_node(cib_node, XML_CIB_TAG_LRM); -- crm_xml_add(lrm, XML_ATTR_ID, node_uuid); -- } -- -- container = first_named_child(lrm, XML_LRM_TAG_RESOURCES); -- if (container == NULL) { -- container = create_xml_node(lrm, XML_LRM_TAG_RESOURCES); -- } -- -- cib_resource = create_xml_node(container, XML_LRM_TAG_RESOURCE); -- crm_xml_add(cib_resource, XML_ATTR_ID, resource); -- -- crm_xml_add(cib_resource, XML_AGENT_ATTR_CLASS, rclass); -- crm_xml_add(cib_resource, XML_AGENT_ATTR_PROVIDER, rprovider); -- crm_xml_add(cib_resource, XML_ATTR_TYPE, rtype); -- -- return cib_resource; --} -- --static lrmd_event_data_t * --create_op(xmlNode * cib_resource, const char *task, int interval, int outcome) --{ -- lrmd_event_data_t *op = NULL; -- xmlNode *xop = NULL; -- -- op = calloc(1, sizeof(lrmd_event_data_t)); -- -- op->rsc_id = strdup(ID(cib_resource)); -- op->interval = interval; -- op->op_type = strdup(task); -- -- op->rc = outcome; -- op->op_status = 0; -- op->params = NULL; /* TODO: Fill me in */ -- op->t_run = time(NULL); -- op->t_rcchange = op->t_run; -- -- op->call_id = 0; -- for (xop = __xml_first_child(cib_resource); xop != NULL; xop = __xml_next(xop)) { -- int tmp = 0; -- -- crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp); -- if (tmp > op->call_id) { -- op->call_id = tmp; -- } -- } -- op->call_id++; -- -- return op; --} -- --static xmlNode * --inject_op(xmlNode * cib_resource, lrmd_event_data_t * op, int target_rc) --{ -- return create_operation_update(cib_resource, op, CRM_FEATURE_SET, target_rc, crm_system_name, -- LOG_DEBUG_2); --} -- --static void --update_failcounts(xmlNode * cib_node, const char *resource, int interval, int rc) --{ -- if (rc == 0) { -- return; -- -- } else if (rc == 7 && interval == 0) { -- return; -- -- } else { -- char *name = NULL; -- char *now = crm_itoa(time(NULL)); -- -- name = crm_concat("fail-count", resource, '-'); -- inject_transient_attr(cib_node, name, "value++"); -- -- name = crm_concat("last-failure", resource, '-'); -- inject_transient_attr(cib_node, name, now); -- -- free(name); -- free(now); -- } --} -- --static gboolean --exec_pseudo_action(crm_graph_t * graph, crm_action_t * action) --{ -- const char *node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); -- const char *task = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY); -- -- action->confirmed = TRUE; -- -- quiet_log(" * Pseudo action: %s%s%s\n", task, node ? " on " : "", node ? node : ""); -- update_graph(graph, action); -- return TRUE; --} -- --GListPtr resource_list = NULL; -- --static gboolean --exec_rsc_action(crm_graph_t * graph, crm_action_t * action) --{ -- int rc = 0; -- GListPtr gIter = NULL; -- lrmd_event_data_t *op = NULL; -- int target_outcome = 0; -- gboolean uname_is_uuid = FALSE; -- -- const char *rtype = NULL; -- const char *rclass = NULL; -- const char *resource = NULL; -- const char *rprovider = NULL; -- const char *operation = crm_element_value(action->xml, "operation"); -- const char *target_rc_s = crm_meta_value(action->params, XML_ATTR_TE_TARGET_RC); -- -- xmlNode *cib_node = NULL; -- xmlNode *cib_resource = NULL; -- xmlNode *action_rsc = first_named_child(action->xml, XML_CIB_TAG_RESOURCE); -- -- char *node = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET); -- char *uuid = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET_UUID); -- const char *router_node = crm_element_value(action->xml, XML_LRM_ATTR_ROUTER_NODE); -- -- if (safe_str_eq(operation, CRM_OP_PROBED) -- || safe_str_eq(operation, CRM_OP_REPROBE)) { -- crm_info("Skipping %s op for %s\n", operation, node); -- goto done; -- } -- -- if (action_rsc == NULL) { -- crm_log_xml_err(action->xml, "Bad"); -- free(node); free(uuid); -- return FALSE; -- } -- -- /* Look for the preferred name -- * If not found, try the expected 'local' name -- * If not found use the preferred name anyway -- */ -- resource = crm_element_value(action_rsc, XML_ATTR_ID); -- if (pe_find_resource(resource_list, resource) == NULL) { -- const char *longname = crm_element_value(action_rsc, XML_ATTR_ID_LONG); -- -- if (pe_find_resource(resource_list, longname)) { -- resource = longname; -- } -- } -- -- if (safe_str_eq(operation, "delete")) { -- quiet_log(" * Resource action: %-15s delete on %s\n", resource, node); -- goto done; -- } -- -- rclass = crm_element_value(action_rsc, XML_AGENT_ATTR_CLASS); -- rtype = crm_element_value(action_rsc, XML_ATTR_TYPE); -- rprovider = crm_element_value(action_rsc, XML_AGENT_ATTR_PROVIDER); -- -- if (target_rc_s != NULL) { -- target_outcome = crm_parse_int(target_rc_s, "0"); -- } -- -- CRM_ASSERT(global_cib->cmds->query(global_cib, NULL, NULL, cib_sync_call | cib_scope_local) == -- pcmk_ok); -- -- if (router_node) { -- uname_is_uuid = TRUE; -- } -- -- cib_node = inject_node_state(global_cib, node, uname_is_uuid ? node : uuid); -- CRM_ASSERT(cib_node != NULL); -- -- cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); -- CRM_ASSERT(cib_resource != NULL); -- -- op = convert_graph_action(cib_resource, action, 0, target_outcome); -- if (op->interval) { -- quiet_log(" * Resource action: %-15s %s=%d on %s\n", resource, op->op_type, op->interval, -- node); -- } else { -- quiet_log(" * Resource action: %-15s %s on %s\n", resource, op->op_type, node); -- } -- -- for (gIter = op_fail; gIter != NULL; gIter = gIter->next) { -- char *spec = (char *)gIter->data; -- char *key = NULL; -- -- key = calloc(1, 1 + strlen(spec)); -- snprintf(key, strlen(spec), "%s_%s_%d@%s=", resource, op->op_type, op->interval, node); -- -- if (strncasecmp(key, spec, strlen(key)) == 0) { -- sscanf(spec, "%*[^=]=%d", (int *)&op->rc); -- -- action->failed = TRUE; -- graph->abort_priority = INFINITY; -- printf("\tPretending action %d failed with rc=%d\n", action->id, op->rc); -- update_failcounts(cib_node, resource, op->interval, op->rc); -- free(key); -- break; -- } -- free(key); -- } -- -- inject_op(cib_resource, op, target_outcome); -- lrmd_free_event(op); -- -- rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, -- cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- -- done: -- free(node); free(uuid); -- free_xml(cib_node); -- action->confirmed = TRUE; -- update_graph(graph, action); -- return TRUE; --} -- --static gboolean --exec_crmd_action(crm_graph_t * graph, crm_action_t * action) --{ -- const char *node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); -- const char *task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); -- xmlNode *rsc = first_named_child(action->xml, XML_CIB_TAG_RESOURCE); -- -- action->confirmed = TRUE; -- -- if(rsc) { -- quiet_log(" * Cluster action: %s for %s on %s\n", task, ID(rsc), node); -- } else { -- quiet_log(" * Cluster action: %s on %s\n", task, node); -- } -- update_graph(graph, action); -- return TRUE; --} -- --#define STATUS_PATH_MAX 512 --static gboolean --exec_stonith_action(crm_graph_t * graph, crm_action_t * action) --{ -- const char *op = crm_meta_value(action->params, "stonith_action"); -- char *target = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET); -- -- quiet_log(" * Fencing %s (%s)\n", target, op); -- if(safe_str_neq(op, "on")) { -- int rc = 0; -- char xpath[STATUS_PATH_MAX]; -- xmlNode *cib_node = modify_node(global_cib, target, FALSE); -- -- crm_xml_add(cib_node, XML_ATTR_ORIGIN, __FUNCTION__); -- CRM_ASSERT(cib_node != NULL); -- -- rc = global_cib->cmds->replace(global_cib, XML_CIB_TAG_STATUS, cib_node, -- cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- -- snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, XML_CIB_TAG_LRM); -- global_cib->cmds->delete(global_cib, xpath, NULL, -- cib_xpath | cib_sync_call | cib_scope_local); -- -- snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, -- XML_TAG_TRANSIENT_NODEATTRS); -- global_cib->cmds->delete(global_cib, xpath, NULL, -- cib_xpath | cib_sync_call | cib_scope_local); -- -- free_xml(cib_node); -- } -- -- action->confirmed = TRUE; -- update_graph(graph, action); -- free(target); -- return TRUE; --} -- - static void - print_cluster_status(pe_working_set_t * data_set, long options) - { -@@ -657,62 +186,6 @@ print_cluster_status(pe_working_set_t * data_set, long options) - fprintf(stdout, "\n"); - } - --static int --run_simulation(pe_working_set_t * data_set) --{ -- crm_graph_t *transition = NULL; -- enum transition_status graph_rc = -1; -- -- crm_graph_functions_t exec_fns = { -- exec_pseudo_action, -- exec_rsc_action, -- exec_crmd_action, -- exec_stonith_action, -- }; -- -- set_graph_functions(&exec_fns); -- -- quiet_log("\nExecuting cluster transition:\n"); -- transition = unpack_graph(data_set->graph, crm_system_name); -- print_graph(LOG_DEBUG, transition); -- -- resource_list = data_set->resources; -- do { -- graph_rc = run_graph(transition); -- -- } while (graph_rc == transition_active); -- resource_list = NULL; -- -- if (graph_rc != transition_complete) { -- fprintf(stdout, "Transition failed: %s\n", transition_status(graph_rc)); -- print_graph(LOG_ERR, transition); -- } -- destroy_graph(transition); -- if (graph_rc != transition_complete) { -- fprintf(stdout, "An invalid transition was produced\n"); -- } -- -- if (quiet == FALSE) { -- xmlNode *cib_object = NULL; -- int rc = -- global_cib->cmds->query(global_cib, NULL, &cib_object, cib_sync_call | cib_scope_local); -- -- CRM_ASSERT(rc == pcmk_ok); -- quiet_log("\nRevised cluster status:\n"); -- cleanup_alloc_calculations(data_set); -- data_set->input = cib_object; -- data_set->now = get_date(); -- -- cluster_status(data_set); -- print_cluster_status(data_set, 0); -- } -- -- if (graph_rc != transition_complete) { -- return graph_rc; -- } -- return 0; --} -- - static char * - create_action_name(action_t * action) - { -@@ -883,274 +356,6 @@ create_dotfile(pe_working_set_t * data_set, const char *dot_file, gboolean all_a - } - } - --static int --find_ticket_state(cib_t * the_cib, const char *ticket_id, xmlNode ** ticket_state_xml) --{ -- int offset = 0; -- static int xpath_max = 1024; -- int rc = pcmk_ok; -- xmlNode *xml_search = NULL; -- -- char *xpath_string = NULL; -- -- CRM_ASSERT(ticket_state_xml != NULL); -- *ticket_state_xml = NULL; -- -- xpath_string = calloc(1, xpath_max); -- offset += snprintf(xpath_string + offset, xpath_max - offset, "%s", "/cib/status/tickets"); -- -- if (ticket_id) { -- offset += snprintf(xpath_string + offset, xpath_max - offset, "/%s[@id=\"%s\"]", -- XML_CIB_TAG_TICKET_STATE, ticket_id); -- } -- CRM_LOG_ASSERT(offset > 0); -- rc = the_cib->cmds->query(the_cib, xpath_string, &xml_search, -- cib_sync_call | cib_scope_local | cib_xpath); -- -- if (rc != pcmk_ok) { -- goto bail; -- } -- -- crm_log_xml_debug(xml_search, "Match"); -- if (xml_has_children(xml_search)) { -- if (ticket_id) { -- fprintf(stdout, "Multiple ticket_states match ticket_id=%s\n", ticket_id); -- } -- *ticket_state_xml = xml_search; -- } else { -- *ticket_state_xml = xml_search; -- } -- -- bail: -- free(xpath_string); -- return rc; --} -- --static int --set_ticket_state_attr(const char *ticket_id, const char *attr_name, -- const char *attr_value, cib_t * cib, int cib_options) --{ -- int rc = pcmk_ok; -- xmlNode *xml_top = NULL; -- xmlNode *ticket_state_xml = NULL; -- -- rc = find_ticket_state(cib, ticket_id, &ticket_state_xml); -- if (rc == pcmk_ok) { -- crm_debug("Found a match state for ticket: id=%s", ticket_id); -- xml_top = ticket_state_xml; -- -- } else if (rc != -ENXIO) { -- return rc; -- -- } else { -- xmlNode *xml_obj = NULL; -- -- xml_top = create_xml_node(NULL, XML_CIB_TAG_STATUS); -- xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS); -- ticket_state_xml = create_xml_node(xml_obj, XML_CIB_TAG_TICKET_STATE); -- crm_xml_add(ticket_state_xml, XML_ATTR_ID, ticket_id); -- } -- -- crm_xml_add(ticket_state_xml, attr_name, attr_value); -- -- crm_log_xml_debug(xml_top, "Update"); -- -- rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, xml_top, cib_options); -- -- free_xml(xml_top); -- -- return rc; --} -- --static void --modify_configuration(pe_working_set_t * data_set, -- const char *quorum, const char *watchdog, GListPtr node_up, GListPtr node_down, GListPtr node_fail, -- GListPtr op_inject, GListPtr ticket_grant, GListPtr ticket_revoke, -- GListPtr ticket_standby, GListPtr ticket_activate) --{ -- int rc = pcmk_ok; -- GListPtr gIter = NULL; -- -- xmlNode *cib_op = NULL; -- xmlNode *cib_node = NULL; -- xmlNode *cib_resource = NULL; -- -- lrmd_event_data_t *op = NULL; -- -- if (quorum) { -- xmlNode *top = create_xml_node(NULL, XML_TAG_CIB); -- -- quiet_log(" + Setting quorum: %s\n", quorum); -- /* crm_xml_add(top, XML_ATTR_DC_UUID, dc_uuid); */ -- crm_xml_add(top, XML_ATTR_HAVE_QUORUM, quorum); -- -- rc = global_cib->cmds->modify(global_cib, NULL, top, cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- } -- -- if (watchdog) { -- quiet_log(" + Setting watchdog: %s\n", watchdog); -- -- rc = update_attr_delegate(global_cib, cib_sync_call | cib_scope_local, -- XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, -- XML_ATTR_HAVE_WATCHDOG, watchdog, FALSE, NULL, NULL); -- -- CRM_ASSERT(rc == pcmk_ok); -- } -- -- for (gIter = node_up; gIter != NULL; gIter = gIter->next) { -- char *node = (char *)gIter->data; -- -- quiet_log(" + Bringing node %s online\n", node); -- cib_node = modify_node(global_cib, node, TRUE); -- CRM_ASSERT(cib_node != NULL); -- -- rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, -- cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- free_xml(cib_node); -- } -- -- for (gIter = node_down; gIter != NULL; gIter = gIter->next) { -- char xpath[STATUS_PATH_MAX]; -- char *node = (char *)gIter->data; -- -- quiet_log(" + Taking node %s offline\n", node); -- cib_node = modify_node(global_cib, node, FALSE); -- CRM_ASSERT(cib_node != NULL); -- -- rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, -- cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- free_xml(cib_node); -- -- snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", node, XML_CIB_TAG_LRM); -- global_cib->cmds->delete(global_cib, xpath, NULL, -- cib_xpath | cib_sync_call | cib_scope_local); -- -- snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", node, -- XML_TAG_TRANSIENT_NODEATTRS); -- global_cib->cmds->delete(global_cib, xpath, NULL, -- cib_xpath | cib_sync_call | cib_scope_local); -- -- } -- -- for (gIter = node_fail; gIter != NULL; gIter = gIter->next) { -- char *node = (char *)gIter->data; -- -- quiet_log(" + Failing node %s\n", node); -- cib_node = modify_node(global_cib, node, TRUE); -- crm_xml_add(cib_node, XML_NODE_IN_CLUSTER, XML_BOOLEAN_NO); -- CRM_ASSERT(cib_node != NULL); -- -- rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, -- cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- free_xml(cib_node); -- } -- -- for (gIter = ticket_grant; gIter != NULL; gIter = gIter->next) { -- char *ticket_id = (char *)gIter->data; -- -- quiet_log(" + Granting ticket %s\n", ticket_id); -- rc = set_ticket_state_attr(ticket_id, "granted", "true", -- global_cib, cib_sync_call | cib_scope_local); -- -- CRM_ASSERT(rc == pcmk_ok); -- } -- -- for (gIter = ticket_revoke; gIter != NULL; gIter = gIter->next) { -- char *ticket_id = (char *)gIter->data; -- -- quiet_log(" + Revoking ticket %s\n", ticket_id); -- rc = set_ticket_state_attr(ticket_id, "granted", "false", -- global_cib, cib_sync_call | cib_scope_local); -- -- CRM_ASSERT(rc == pcmk_ok); -- } -- -- for (gIter = ticket_standby; gIter != NULL; gIter = gIter->next) { -- char *ticket_id = (char *)gIter->data; -- -- quiet_log(" + Making ticket %s standby\n", ticket_id); -- rc = set_ticket_state_attr(ticket_id, "standby", "true", -- global_cib, cib_sync_call | cib_scope_local); -- -- CRM_ASSERT(rc == pcmk_ok); -- } -- -- for (gIter = ticket_activate; gIter != NULL; gIter = gIter->next) { -- char *ticket_id = (char *)gIter->data; -- -- quiet_log(" + Activating ticket %s\n", ticket_id); -- rc = set_ticket_state_attr(ticket_id, "standby", "false", -- global_cib, cib_sync_call | cib_scope_local); -- -- CRM_ASSERT(rc == pcmk_ok); -- } -- -- for (gIter = op_inject; gIter != NULL; gIter = gIter->next) { -- char *spec = (char *)gIter->data; -- -- int rc = 0; -- int outcome = 0; -- int interval = 0; -- -- char *key = NULL; -- char *node = NULL; -- char *task = NULL; -- char *resource = NULL; -- -- const char *rtype = NULL; -- const char *rclass = NULL; -- const char *rprovider = NULL; -- -- resource_t *rsc = NULL; -- -- quiet_log(" + Injecting %s into the configuration\n", spec); -- -- key = calloc(1, strlen(spec) + 1); -- node = calloc(1, strlen(spec) + 1); -- rc = sscanf(spec, "%[^@]@%[^=]=%d", key, node, &outcome); -- CRM_CHECK(rc == 3, -- fprintf(stderr, "Invalid operation spec: %s. Only found %d fields\n", spec, rc); -- continue); -- -- parse_op_key(key, &resource, &task, &interval); -- -- rsc = pe_find_resource(data_set->resources, resource); -- if (rsc == NULL) { -- fprintf(stderr, " - Invalid resource name: %s\n", resource); -- } else { -- rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); -- rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE); -- rprovider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); -- -- cib_node = inject_node_state(global_cib, node, NULL); -- CRM_ASSERT(cib_node != NULL); -- -- update_failcounts(cib_node, resource, interval, outcome); -- -- cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); -- CRM_ASSERT(cib_resource != NULL); -- -- op = create_op(cib_resource, task, interval, outcome); -- CRM_ASSERT(op != NULL); -- -- cib_op = inject_op(cib_resource, op, 0); -- CRM_ASSERT(cib_op != NULL); -- lrmd_free_event(op); -- -- rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, -- cib_sync_call | cib_scope_local); -- CRM_ASSERT(rc == pcmk_ok); -- } -- free(task); -- free(node); -- free(key); -- } --} -- - static void - setup_input(const char *input, const char *output) - { -@@ -1571,7 +776,7 @@ main(int argc, char **argv) - - if (modified) { - quiet_log("Performing requested modifications\n"); -- modify_configuration(&data_set, quorum, watchdog, node_up, node_down, node_fail, op_inject, -+ modify_configuration(&data_set, global_cib, quorum, watchdog, node_up, node_down, node_fail, op_inject, - ticket_grant, ticket_revoke, ticket_standby, ticket_activate); - - rc = global_cib->cmds->query(global_cib, NULL, &input, cib_sync_call); -@@ -1632,7 +837,14 @@ main(int argc, char **argv) - } - - if (simulate) { -- rc = run_simulation(&data_set); -+ rc = run_simulation(&data_set, global_cib, op_fail, quiet); -+ if(quiet == FALSE) { -+ data_set.now = get_date(); -+ -+ quiet_log("\nRevised cluster status:\n"); -+ cluster_status(&data_set); -+ print_cluster_status(&data_set, 0); -+ } - } - - done: -diff --git a/tools/fake_transition.c b/tools/fake_transition.c -new file mode 100644 -index 0000000..d6d71eb ---- /dev/null -+++ b/tools/fake_transition.c -@@ -0,0 +1,846 @@ -+/* -+ * Copyright (C) 2009 Andrew Beekhof -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This software is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "fake_transition.h" -+ -+static bool fake_quiet = FALSE; -+static cib_t *fake_cib = NULL; -+static GListPtr fake_resource_list = NULL; -+static GListPtr fake_op_fail_list = NULL; -+gboolean bringing_nodes_online = FALSE; -+ -+#define STATUS_PATH_MAX 512 -+ -+#define quiet_log(fmt, args...) do { \ -+ if(fake_quiet) { \ -+ crm_trace(fmt, ##args); \ -+ } else { \ -+ printf(fmt , ##args); \ -+ } \ -+ } while(0) -+ -+#define new_node_template "//"XML_CIB_TAG_NODE"[@uname='%s']" -+#define node_template "//"XML_CIB_TAG_STATE"[@uname='%s']" -+#define rsc_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']" -+#define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s']" -+/* #define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s' and @"XML_LRM_ATTR_CALLID"='%d']" */ -+ -+ -+static void -+inject_transient_attr(xmlNode * cib_node, const char *name, const char *value) -+{ -+ xmlNode *attrs = NULL; -+ xmlNode *container = NULL; -+ xmlNode *nvp = NULL; -+ const char *node_uuid = ID(cib_node); -+ char *nvp_id = crm_concat(name, node_uuid, '-'); -+ -+ quiet_log("Injecting attribute %s=%s into %s '%s'", name, value, xmlGetNodePath(cib_node), -+ ID(cib_node)); -+ -+ attrs = first_named_child(cib_node, XML_TAG_TRANSIENT_NODEATTRS); -+ if (attrs == NULL) { -+ attrs = create_xml_node(cib_node, XML_TAG_TRANSIENT_NODEATTRS); -+ crm_xml_add(attrs, XML_ATTR_ID, node_uuid); -+ } -+ -+ container = first_named_child(attrs, XML_TAG_ATTR_SETS); -+ if (container == NULL) { -+ container = create_xml_node(attrs, XML_TAG_ATTR_SETS); -+ crm_xml_add(container, XML_ATTR_ID, node_uuid); -+ } -+ -+ nvp = create_xml_node(container, XML_CIB_TAG_NVPAIR); -+ crm_xml_add(nvp, XML_ATTR_ID, nvp_id); -+ crm_xml_add(nvp, XML_NVPAIR_ATTR_NAME, name); -+ crm_xml_add(nvp, XML_NVPAIR_ATTR_VALUE, value); -+ -+ free(nvp_id); -+} -+ -+static void -+update_failcounts(xmlNode * cib_node, const char *resource, int interval, int rc) -+{ -+ if (rc == 0) { -+ return; -+ -+ } else if (rc == 7 && interval == 0) { -+ return; -+ -+ } else { -+ char *name = NULL; -+ char *now = crm_itoa(time(NULL)); -+ -+ name = crm_concat("fail-count", resource, '-'); -+ inject_transient_attr(cib_node, name, "value++"); -+ -+ name = crm_concat("last-failure", resource, '-'); -+ inject_transient_attr(cib_node, name, now); -+ -+ free(name); -+ free(now); -+ } -+} -+ -+static void -+create_node_entry(cib_t * cib_conn, const char *node) -+{ -+ int rc = pcmk_ok; -+ int max = strlen(new_node_template) + strlen(node) + 1; -+ char *xpath = NULL; -+ -+ xpath = calloc(1, max); -+ -+ snprintf(xpath, max, new_node_template, node); -+ rc = cib_conn->cmds->query(cib_conn, xpath, NULL, cib_xpath | cib_sync_call | cib_scope_local); -+ -+ if (rc == -ENXIO) { -+ xmlNode *cib_object = create_xml_node(NULL, XML_CIB_TAG_NODE); -+ -+ /* Using node uname as uuid ala corosync/openais */ -+ crm_xml_add(cib_object, XML_ATTR_ID, node); -+ crm_xml_add(cib_object, XML_ATTR_UNAME, node); -+ cib_conn->cmds->create(cib_conn, XML_CIB_TAG_NODES, cib_object, -+ cib_sync_call | cib_scope_local); -+ /* Not bothering with subsequent query to see if it exists, -+ we'll bomb out later in the call to query_node_uuid()... */ -+ -+ free_xml(cib_object); -+ } -+ -+ free(xpath); -+} -+ -+static lrmd_event_data_t * -+create_op(xmlNode * cib_resource, const char *task, int interval, int outcome) -+{ -+ lrmd_event_data_t *op = NULL; -+ xmlNode *xop = NULL; -+ -+ op = calloc(1, sizeof(lrmd_event_data_t)); -+ -+ op->rsc_id = strdup(ID(cib_resource)); -+ op->interval = interval; -+ op->op_type = strdup(task); -+ -+ op->rc = outcome; -+ op->op_status = 0; -+ op->params = NULL; /* TODO: Fill me in */ -+ op->t_run = time(NULL); -+ op->t_rcchange = op->t_run; -+ -+ op->call_id = 0; -+ for (xop = __xml_first_child(cib_resource); xop != NULL; xop = __xml_next(xop)) { -+ int tmp = 0; -+ -+ crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp); -+ if (tmp > op->call_id) { -+ op->call_id = tmp; -+ } -+ } -+ op->call_id++; -+ -+ return op; -+} -+ -+static xmlNode * -+inject_op(xmlNode * cib_resource, lrmd_event_data_t * op, int target_rc) -+{ -+ return create_operation_update(cib_resource, op, CRM_FEATURE_SET, target_rc, crm_system_name, -+ LOG_DEBUG_2); -+} -+ -+static xmlNode * -+inject_node_state(cib_t * cib_conn, const char *node, const char *uuid) -+{ -+ int rc = pcmk_ok; -+ int max = strlen(rsc_template) + strlen(node) + 1; -+ char *xpath = NULL; -+ xmlNode *cib_object = NULL; -+ -+ xpath = calloc(1, max); -+ -+ if (bringing_nodes_online) { -+ create_node_entry(cib_conn, node); -+ } -+ -+ snprintf(xpath, max, node_template, node); -+ rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, -+ cib_xpath | cib_sync_call | cib_scope_local); -+ -+ if (cib_object && ID(cib_object) == NULL) { -+ crm_err("Detected multiple node_state entries for xpath=%s, bailing", xpath); -+ crm_log_xml_warn(cib_object, "Duplicates"); -+ crm_exit(ENOTUNIQ); -+ } -+ -+ if (rc == -ENXIO) { -+ char *found_uuid = NULL; -+ -+ if (uuid == NULL) { -+ query_node_uuid(cib_conn, node, &found_uuid, NULL); -+ } else { -+ found_uuid = strdup(uuid); -+ } -+ -+ cib_object = create_xml_node(NULL, XML_CIB_TAG_STATE); -+ crm_xml_add(cib_object, XML_ATTR_UUID, found_uuid); -+ crm_xml_add(cib_object, XML_ATTR_UNAME, node); -+ cib_conn->cmds->create(cib_conn, XML_CIB_TAG_STATUS, cib_object, -+ cib_sync_call | cib_scope_local); -+ free_xml(cib_object); -+ free(found_uuid); -+ -+ rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, -+ cib_xpath | cib_sync_call | cib_scope_local); -+ crm_trace("injecting node state for %s. rc is %d", node, rc); -+ } -+ -+ free(xpath); -+ CRM_ASSERT(rc == pcmk_ok); -+ return cib_object; -+} -+ -+static xmlNode * -+modify_node(cib_t * cib_conn, char *node, gboolean up) -+{ -+ xmlNode *cib_node = inject_node_state(cib_conn, node, NULL); -+ -+ if (up) { -+ crm_xml_add(cib_node, XML_NODE_IN_CLUSTER, XML_BOOLEAN_YES); -+ crm_xml_add(cib_node, XML_NODE_IS_PEER, ONLINESTATUS); -+ crm_xml_add(cib_node, XML_NODE_JOIN_STATE, CRMD_JOINSTATE_MEMBER); -+ crm_xml_add(cib_node, XML_NODE_EXPECTED, CRMD_JOINSTATE_MEMBER); -+ -+ } else { -+ crm_xml_add(cib_node, XML_NODE_IN_CLUSTER, XML_BOOLEAN_NO); -+ crm_xml_add(cib_node, XML_NODE_IS_PEER, OFFLINESTATUS); -+ crm_xml_add(cib_node, XML_NODE_JOIN_STATE, CRMD_JOINSTATE_DOWN); -+ crm_xml_add(cib_node, XML_NODE_EXPECTED, CRMD_JOINSTATE_DOWN); -+ } -+ -+ crm_xml_add(cib_node, XML_ATTR_ORIGIN, crm_system_name); -+ return cib_node; -+} -+ -+static xmlNode * -+find_resource_xml(xmlNode * cib_node, const char *resource) -+{ -+ char *xpath = NULL; -+ xmlNode *match = NULL; -+ const char *node = crm_element_value(cib_node, XML_ATTR_UNAME); -+ int max = strlen(rsc_template) + strlen(resource) + strlen(node) + 1; -+ -+ xpath = calloc(1, max); -+ -+ snprintf(xpath, max, rsc_template, node, resource); -+ match = get_xpath_object(xpath, cib_node, LOG_DEBUG_2); -+ -+ free(xpath); -+ return match; -+} -+ -+ -+static xmlNode * -+inject_resource(xmlNode * cib_node, const char *resource, const char *rclass, const char *rtype, -+ const char *rprovider) -+{ -+ xmlNode *lrm = NULL; -+ xmlNode *container = NULL; -+ xmlNode *cib_resource = NULL; -+ char *xpath = NULL; -+ -+ cib_resource = find_resource_xml(cib_node, resource); -+ if (cib_resource != NULL) { -+ return cib_resource; -+ } -+ -+ /* One day, add query for class, provider, type */ -+ -+ if (rclass == NULL || rtype == NULL) { -+ fprintf(stderr, "Resource %s not found in the status section of %s." -+ " Please supply the class and type to continue\n", resource, ID(cib_node)); -+ return NULL; -+ -+ } else if (safe_str_neq(rclass, "ocf") -+ && safe_str_neq(rclass, "stonith") -+ && safe_str_neq(rclass, "heartbeat") -+ && safe_str_neq(rclass, "service") -+ && safe_str_neq(rclass, "upstart") -+ && safe_str_neq(rclass, "systemd") -+ && safe_str_neq(rclass, "lsb")) { -+ fprintf(stderr, "Invalid class for %s: %s\n", resource, rclass); -+ return NULL; -+ -+ } else if (safe_str_eq(rclass, "ocf") && rprovider == NULL) { -+ fprintf(stderr, "Please specify the provider for resource %s\n", resource); -+ return NULL; -+ } -+ -+ xpath = (char *)xmlGetNodePath(cib_node); -+ crm_info("Injecting new resource %s into %s '%s'", resource, xpath, ID(cib_node)); -+ free(xpath); -+ -+ lrm = first_named_child(cib_node, XML_CIB_TAG_LRM); -+ if (lrm == NULL) { -+ const char *node_uuid = ID(cib_node); -+ -+ lrm = create_xml_node(cib_node, XML_CIB_TAG_LRM); -+ crm_xml_add(lrm, XML_ATTR_ID, node_uuid); -+ } -+ -+ container = first_named_child(lrm, XML_LRM_TAG_RESOURCES); -+ if (container == NULL) { -+ container = create_xml_node(lrm, XML_LRM_TAG_RESOURCES); -+ } -+ -+ cib_resource = create_xml_node(container, XML_LRM_TAG_RESOURCE); -+ crm_xml_add(cib_resource, XML_ATTR_ID, resource); -+ -+ crm_xml_add(cib_resource, XML_AGENT_ATTR_CLASS, rclass); -+ crm_xml_add(cib_resource, XML_AGENT_ATTR_PROVIDER, rprovider); -+ crm_xml_add(cib_resource, XML_ATTR_TYPE, rtype); -+ -+ return cib_resource; -+} -+ -+static int -+find_ticket_state(cib_t * the_cib, const char *ticket_id, xmlNode ** ticket_state_xml) -+{ -+ int offset = 0; -+ static int xpath_max = 1024; -+ int rc = pcmk_ok; -+ xmlNode *xml_search = NULL; -+ -+ char *xpath_string = NULL; -+ -+ CRM_ASSERT(ticket_state_xml != NULL); -+ *ticket_state_xml = NULL; -+ -+ xpath_string = calloc(1, xpath_max); -+ offset += snprintf(xpath_string + offset, xpath_max - offset, "%s", "/cib/status/tickets"); -+ -+ if (ticket_id) { -+ offset += snprintf(xpath_string + offset, xpath_max - offset, "/%s[@id=\"%s\"]", -+ XML_CIB_TAG_TICKET_STATE, ticket_id); -+ } -+ CRM_LOG_ASSERT(offset > 0); -+ rc = the_cib->cmds->query(the_cib, xpath_string, &xml_search, -+ cib_sync_call | cib_scope_local | cib_xpath); -+ -+ if (rc != pcmk_ok) { -+ goto bail; -+ } -+ -+ crm_log_xml_debug(xml_search, "Match"); -+ if (xml_has_children(xml_search)) { -+ if (ticket_id) { -+ fprintf(stdout, "Multiple ticket_states match ticket_id=%s\n", ticket_id); -+ } -+ *ticket_state_xml = xml_search; -+ } else { -+ *ticket_state_xml = xml_search; -+ } -+ -+ bail: -+ free(xpath_string); -+ return rc; -+} -+ -+static int -+set_ticket_state_attr(const char *ticket_id, const char *attr_name, -+ const char *attr_value, cib_t * cib, int cib_options) -+{ -+ int rc = pcmk_ok; -+ xmlNode *xml_top = NULL; -+ xmlNode *ticket_state_xml = NULL; -+ -+ rc = find_ticket_state(cib, ticket_id, &ticket_state_xml); -+ if (rc == pcmk_ok) { -+ crm_debug("Found a match state for ticket: id=%s", ticket_id); -+ xml_top = ticket_state_xml; -+ -+ } else if (rc != -ENXIO) { -+ return rc; -+ -+ } else { -+ xmlNode *xml_obj = NULL; -+ -+ xml_top = create_xml_node(NULL, XML_CIB_TAG_STATUS); -+ xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS); -+ ticket_state_xml = create_xml_node(xml_obj, XML_CIB_TAG_TICKET_STATE); -+ crm_xml_add(ticket_state_xml, XML_ATTR_ID, ticket_id); -+ } -+ -+ crm_xml_add(ticket_state_xml, attr_name, attr_value); -+ -+ crm_log_xml_debug(xml_top, "Update"); -+ -+ rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, xml_top, cib_options); -+ -+ free_xml(xml_top); -+ -+ return rc; -+} -+ -+void -+modify_configuration(pe_working_set_t * data_set, cib_t *cib, -+ const char *quorum, const char *watchdog, GListPtr node_up, GListPtr node_down, GListPtr node_fail, -+ GListPtr op_inject, GListPtr ticket_grant, GListPtr ticket_revoke, -+ GListPtr ticket_standby, GListPtr ticket_activate) -+{ -+ int rc = pcmk_ok; -+ GListPtr gIter = NULL; -+ -+ xmlNode *cib_op = NULL; -+ xmlNode *cib_node = NULL; -+ xmlNode *cib_resource = NULL; -+ -+ lrmd_event_data_t *op = NULL; -+ -+ if (quorum) { -+ xmlNode *top = create_xml_node(NULL, XML_TAG_CIB); -+ -+ quiet_log(" + Setting quorum: %s\n", quorum); -+ /* crm_xml_add(top, XML_ATTR_DC_UUID, dc_uuid); */ -+ crm_xml_add(top, XML_ATTR_HAVE_QUORUM, quorum); -+ -+ rc = cib->cmds->modify(cib, NULL, top, cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ -+ if (watchdog) { -+ quiet_log(" + Setting watchdog: %s\n", watchdog); -+ -+ rc = update_attr_delegate(cib, cib_sync_call | cib_scope_local, -+ XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, -+ XML_ATTR_HAVE_WATCHDOG, watchdog, FALSE, NULL, NULL); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ -+ for (gIter = node_up; gIter != NULL; gIter = gIter->next) { -+ char *node = (char *)gIter->data; -+ -+ quiet_log(" + Bringing node %s online\n", node); -+ cib_node = modify_node(cib, node, TRUE); -+ CRM_ASSERT(cib_node != NULL); -+ -+ rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node, -+ cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ free_xml(cib_node); -+ } -+ -+ for (gIter = node_down; gIter != NULL; gIter = gIter->next) { -+ char xpath[STATUS_PATH_MAX]; -+ char *node = (char *)gIter->data; -+ -+ quiet_log(" + Taking node %s offline\n", node); -+ cib_node = modify_node(cib, node, FALSE); -+ CRM_ASSERT(cib_node != NULL); -+ -+ rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node, -+ cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ free_xml(cib_node); -+ -+ snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", node, XML_CIB_TAG_LRM); -+ cib->cmds->delete(cib, xpath, NULL, -+ cib_xpath | cib_sync_call | cib_scope_local); -+ -+ snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", node, -+ XML_TAG_TRANSIENT_NODEATTRS); -+ cib->cmds->delete(cib, xpath, NULL, -+ cib_xpath | cib_sync_call | cib_scope_local); -+ -+ } -+ -+ for (gIter = node_fail; gIter != NULL; gIter = gIter->next) { -+ char *node = (char *)gIter->data; -+ -+ quiet_log(" + Failing node %s\n", node); -+ cib_node = modify_node(cib, node, TRUE); -+ crm_xml_add(cib_node, XML_NODE_IN_CLUSTER, XML_BOOLEAN_NO); -+ CRM_ASSERT(cib_node != NULL); -+ -+ rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node, -+ cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ free_xml(cib_node); -+ } -+ -+ for (gIter = ticket_grant; gIter != NULL; gIter = gIter->next) { -+ char *ticket_id = (char *)gIter->data; -+ -+ quiet_log(" + Granting ticket %s\n", ticket_id); -+ rc = set_ticket_state_attr(ticket_id, "granted", "true", -+ cib, cib_sync_call | cib_scope_local); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ -+ for (gIter = ticket_revoke; gIter != NULL; gIter = gIter->next) { -+ char *ticket_id = (char *)gIter->data; -+ -+ quiet_log(" + Revoking ticket %s\n", ticket_id); -+ rc = set_ticket_state_attr(ticket_id, "granted", "false", -+ cib, cib_sync_call | cib_scope_local); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ -+ for (gIter = ticket_standby; gIter != NULL; gIter = gIter->next) { -+ char *ticket_id = (char *)gIter->data; -+ -+ quiet_log(" + Making ticket %s standby\n", ticket_id); -+ rc = set_ticket_state_attr(ticket_id, "standby", "true", -+ cib, cib_sync_call | cib_scope_local); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ -+ for (gIter = ticket_activate; gIter != NULL; gIter = gIter->next) { -+ char *ticket_id = (char *)gIter->data; -+ -+ quiet_log(" + Activating ticket %s\n", ticket_id); -+ rc = set_ticket_state_attr(ticket_id, "standby", "false", -+ cib, cib_sync_call | cib_scope_local); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ -+ for (gIter = op_inject; gIter != NULL; gIter = gIter->next) { -+ char *spec = (char *)gIter->data; -+ -+ int rc = 0; -+ int outcome = 0; -+ int interval = 0; -+ -+ char *key = NULL; -+ char *node = NULL; -+ char *task = NULL; -+ char *resource = NULL; -+ -+ const char *rtype = NULL; -+ const char *rclass = NULL; -+ const char *rprovider = NULL; -+ -+ resource_t *rsc = NULL; -+ -+ quiet_log(" + Injecting %s into the configuration\n", spec); -+ -+ key = calloc(1, strlen(spec) + 1); -+ node = calloc(1, strlen(spec) + 1); -+ rc = sscanf(spec, "%[^@]@%[^=]=%d", key, node, &outcome); -+ CRM_CHECK(rc == 3, -+ fprintf(stderr, "Invalid operation spec: %s. Only found %d fields\n", spec, rc); -+ continue); -+ -+ parse_op_key(key, &resource, &task, &interval); -+ -+ rsc = pe_find_resource(data_set->resources, resource); -+ if (rsc == NULL) { -+ fprintf(stderr, " - Invalid resource name: %s\n", resource); -+ } else { -+ rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); -+ rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE); -+ rprovider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); -+ -+ cib_node = inject_node_state(cib, node, NULL); -+ CRM_ASSERT(cib_node != NULL); -+ -+ update_failcounts(cib_node, resource, interval, outcome); -+ -+ cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); -+ CRM_ASSERT(cib_resource != NULL); -+ -+ op = create_op(cib_resource, task, interval, outcome); -+ CRM_ASSERT(op != NULL); -+ -+ cib_op = inject_op(cib_resource, op, 0); -+ CRM_ASSERT(cib_op != NULL); -+ lrmd_free_event(op); -+ -+ rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node, -+ cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ free(task); -+ free(node); -+ free(key); -+ } -+} -+ -+static gboolean -+exec_pseudo_action(crm_graph_t * graph, crm_action_t * action) -+{ -+ const char *node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); -+ const char *task = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY); -+ -+ action->confirmed = TRUE; -+ -+ quiet_log(" * Pseudo action: %s%s%s\n", task, node ? " on " : "", node ? node : ""); -+ update_graph(graph, action); -+ return TRUE; -+} -+ -+static gboolean -+exec_rsc_action(crm_graph_t * graph, crm_action_t * action) -+{ -+ int rc = 0; -+ GListPtr gIter = NULL; -+ lrmd_event_data_t *op = NULL; -+ int target_outcome = 0; -+ gboolean uname_is_uuid = FALSE; -+ -+ const char *rtype = NULL; -+ const char *rclass = NULL; -+ const char *resource = NULL; -+ const char *rprovider = NULL; -+ const char *operation = crm_element_value(action->xml, "operation"); -+ const char *target_rc_s = crm_meta_value(action->params, XML_ATTR_TE_TARGET_RC); -+ -+ xmlNode *cib_node = NULL; -+ xmlNode *cib_resource = NULL; -+ xmlNode *action_rsc = first_named_child(action->xml, XML_CIB_TAG_RESOURCE); -+ -+ char *node = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET); -+ char *uuid = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET_UUID); -+ const char *router_node = crm_element_value(action->xml, XML_LRM_ATTR_ROUTER_NODE); -+ -+ if (safe_str_eq(operation, CRM_OP_PROBED) -+ || safe_str_eq(operation, CRM_OP_REPROBE)) { -+ crm_info("Skipping %s op for %s\n", operation, node); -+ goto done; -+ } -+ -+ if (action_rsc == NULL) { -+ crm_log_xml_err(action->xml, "Bad"); -+ free(node); free(uuid); -+ return FALSE; -+ } -+ -+ /* Look for the preferred name -+ * If not found, try the expected 'local' name -+ * If not found use the preferred name anyway -+ */ -+ resource = crm_element_value(action_rsc, XML_ATTR_ID); -+ if (pe_find_resource(fake_resource_list, resource) == NULL) { -+ const char *longname = crm_element_value(action_rsc, XML_ATTR_ID_LONG); -+ -+ if (pe_find_resource(fake_resource_list, longname)) { -+ resource = longname; -+ } -+ } -+ -+ if (safe_str_eq(operation, "delete")) { -+ quiet_log(" * Resource action: %-15s delete on %s\n", resource, node); -+ goto done; -+ } -+ -+ rclass = crm_element_value(action_rsc, XML_AGENT_ATTR_CLASS); -+ rtype = crm_element_value(action_rsc, XML_ATTR_TYPE); -+ rprovider = crm_element_value(action_rsc, XML_AGENT_ATTR_PROVIDER); -+ -+ if (target_rc_s != NULL) { -+ target_outcome = crm_parse_int(target_rc_s, "0"); -+ } -+ -+ CRM_ASSERT(fake_cib->cmds->query(fake_cib, NULL, NULL, cib_sync_call | cib_scope_local) == -+ pcmk_ok); -+ -+ if (router_node) { -+ uname_is_uuid = TRUE; -+ } -+ -+ cib_node = inject_node_state(fake_cib, node, uname_is_uuid ? node : uuid); -+ CRM_ASSERT(cib_node != NULL); -+ -+ cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); -+ CRM_ASSERT(cib_resource != NULL); -+ -+ op = convert_graph_action(cib_resource, action, 0, target_outcome); -+ if (op->interval) { -+ quiet_log(" * Resource action: %-15s %s=%d on %s\n", resource, op->op_type, op->interval, -+ node); -+ } else { -+ quiet_log(" * Resource action: %-15s %s on %s\n", resource, op->op_type, node); -+ } -+ -+ for (gIter = fake_op_fail_list; gIter != NULL; gIter = gIter->next) { -+ char *spec = (char *)gIter->data; -+ char *key = NULL; -+ -+ key = calloc(1, 1 + strlen(spec)); -+ snprintf(key, strlen(spec), "%s_%s_%d@%s=", resource, op->op_type, op->interval, node); -+ -+ if (strncasecmp(key, spec, strlen(key)) == 0) { -+ sscanf(spec, "%*[^=]=%d", (int *)&op->rc); -+ -+ action->failed = TRUE; -+ graph->abort_priority = INFINITY; -+ printf("\tPretending action %d failed with rc=%d\n", action->id, op->rc); -+ update_failcounts(cib_node, resource, op->interval, op->rc); -+ free(key); -+ break; -+ } -+ free(key); -+ } -+ -+ inject_op(cib_resource, op, target_outcome); -+ lrmd_free_event(op); -+ -+ rc = fake_cib->cmds->modify(fake_cib, XML_CIB_TAG_STATUS, cib_node, -+ cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ -+ done: -+ free(node); free(uuid); -+ free_xml(cib_node); -+ action->confirmed = TRUE; -+ update_graph(graph, action); -+ return TRUE; -+} -+ -+static gboolean -+exec_crmd_action(crm_graph_t * graph, crm_action_t * action) -+{ -+ const char *node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); -+ const char *task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); -+ xmlNode *rsc = first_named_child(action->xml, XML_CIB_TAG_RESOURCE); -+ -+ action->confirmed = TRUE; -+ -+ if(rsc) { -+ quiet_log(" * Cluster action: %s for %s on %s\n", task, ID(rsc), node); -+ } else { -+ quiet_log(" * Cluster action: %s on %s\n", task, node); -+ } -+ update_graph(graph, action); -+ return TRUE; -+} -+ -+static gboolean -+exec_stonith_action(crm_graph_t * graph, crm_action_t * action) -+{ -+ const char *op = crm_meta_value(action->params, "stonith_action"); -+ char *target = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET); -+ -+ quiet_log(" * Fencing %s (%s)\n", target, op); -+ if(safe_str_neq(op, "on")) { -+ int rc = 0; -+ char xpath[STATUS_PATH_MAX]; -+ xmlNode *cib_node = modify_node(fake_cib, target, FALSE); -+ -+ crm_xml_add(cib_node, XML_ATTR_ORIGIN, __FUNCTION__); -+ CRM_ASSERT(cib_node != NULL); -+ -+ rc = fake_cib->cmds->replace(fake_cib, XML_CIB_TAG_STATUS, cib_node, -+ cib_sync_call | cib_scope_local); -+ CRM_ASSERT(rc == pcmk_ok); -+ -+ snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, XML_CIB_TAG_LRM); -+ fake_cib->cmds->delete(fake_cib, xpath, NULL, -+ cib_xpath | cib_sync_call | cib_scope_local); -+ -+ snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, -+ XML_TAG_TRANSIENT_NODEATTRS); -+ fake_cib->cmds->delete(fake_cib, xpath, NULL, -+ cib_xpath | cib_sync_call | cib_scope_local); -+ -+ free_xml(cib_node); -+ } -+ -+ action->confirmed = TRUE; -+ update_graph(graph, action); -+ free(target); -+ return TRUE; -+} -+ -+int -+run_simulation(pe_working_set_t * data_set, cib_t *cib, GListPtr op_fail_list, bool quiet) -+{ -+ crm_graph_t *transition = NULL; -+ enum transition_status graph_rc = -1; -+ -+ crm_graph_functions_t exec_fns = { -+ exec_pseudo_action, -+ exec_rsc_action, -+ exec_crmd_action, -+ exec_stonith_action, -+ }; -+ -+ fake_cib = cib; -+ fake_quiet = quiet; -+ fake_op_fail_list = op_fail_list; -+ -+ quiet_log("\nExecuting cluster transition:\n"); -+ -+ set_graph_functions(&exec_fns); -+ transition = unpack_graph(data_set->graph, crm_system_name); -+ print_graph(LOG_DEBUG, transition); -+ -+ fake_resource_list = data_set->resources; -+ do { -+ graph_rc = run_graph(transition); -+ -+ } while (graph_rc == transition_active); -+ fake_resource_list = NULL; -+ -+ if (graph_rc != transition_complete) { -+ fprintf(stdout, "Transition failed: %s\n", transition_status(graph_rc)); -+ print_graph(LOG_ERR, transition); -+ } -+ destroy_graph(transition); -+ if (graph_rc != transition_complete) { -+ fprintf(stdout, "An invalid transition was produced\n"); -+ } -+ -+ if (quiet == FALSE) { -+ xmlNode *cib_object = NULL; -+ int rc = fake_cib->cmds->query(fake_cib, NULL, &cib_object, cib_sync_call | cib_scope_local); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ cleanup_alloc_calculations(data_set); -+ data_set->input = cib_object; -+ } -+ -+ if (graph_rc != transition_complete) { -+ return graph_rc; -+ } -+ return 0; -+} -diff --git a/tools/fake_transition.h b/tools/fake_transition.h -new file mode 100644 -index 0000000..2ee7af9 ---- /dev/null -+++ b/tools/fake_transition.h -@@ -0,0 +1,8 @@ -+void modify_configuration( -+ pe_working_set_t * data_set, cib_t *cib, -+ const char *quorum, const char *watchdog, GListPtr node_up, GListPtr node_down, GListPtr node_fail, -+ GListPtr op_inject, GListPtr ticket_grant, GListPtr ticket_revoke, -+ GListPtr ticket_standby, GListPtr ticket_activate); -+ -+int run_simulation(pe_working_set_t * data_set, cib_t *cib, GListPtr op_fail_list, bool quiet); -+ diff --git a/SOURCES/pacemaker-rollup-031e46c.patch b/SOURCES/pacemaker-rollup-031e46c.patch deleted file mode 100644 index 20a130e..0000000 --- a/SOURCES/pacemaker-rollup-031e46c.patch +++ /dev/null @@ -1,6369 +0,0 @@ -diff --git a/GNUmakefile b/GNUmakefile -index b17fb4c..f28dea8 100644 ---- a/GNUmakefile -+++ b/GNUmakefile -@@ -58,6 +58,8 @@ BUILD_COUNTER ?= build.counter - LAST_COUNT = $(shell test ! -e $(BUILD_COUNTER) && echo 0; test -e $(BUILD_COUNTER) && cat $(BUILD_COUNTER)) - COUNT = $(shell expr 1 + $(LAST_COUNT)) - -+SPECVERSION ?= $(COUNT) -+ - init: - ./autogen.sh - -@@ -144,7 +146,7 @@ srpm-%: export $(PACKAGE)-%.spec - if [ -e $(BUILD_COUNTER) ]; then \ - echo $(COUNT) > $(BUILD_COUNTER); \ - fi -- sed -i 's/global\ specversion.*/global\ specversion\ $(COUNT)/' $(PACKAGE).spec -+ sed -i 's/global\ specversion.*/global\ specversion\ $(SPECVERSION)/' $(PACKAGE).spec - sed -i 's/global\ commit.*/global\ commit\ $(TAG)/' $(PACKAGE).spec - case "$(WITH)" in \ - *pre_release*) \ -diff --git a/attrd/commands.c b/attrd/commands.c -index c48ef1b..12771ee 100644 ---- a/attrd/commands.c -+++ b/attrd/commands.c -@@ -202,21 +202,27 @@ attrd_client_message(crm_client_t *client, xmlNode *xml) - crm_debug("Setting %s to %s", regex, value); - if (regcomp(r_patt, regex, REG_EXTENDED)) { - crm_err("Bad regex '%s' for update", regex); -- regfree(r_patt); -- free(r_patt); -- return; -- } - -- g_hash_table_iter_init(&aIter, attributes); -- while (g_hash_table_iter_next(&aIter, (gpointer *) & attr, NULL)) { -- int status = regexec(r_patt, attr, 0, NULL, 0); -+ } else { - -- if(status == 0) { -- crm_trace("Matched %s with %s", attr, regex); -- crm_xml_add(xml, F_ATTRD_ATTRIBUTE, attr); -- send_attrd_message(NULL, xml); -+ g_hash_table_iter_init(&aIter, attributes); -+ while (g_hash_table_iter_next(&aIter, (gpointer *) & attr, NULL)) { -+ int status = regexec(r_patt, attr, 0, NULL, 0); -+ -+ if(status == 0) { -+ crm_trace("Matched %s with %s", attr, regex); -+ crm_xml_add(xml, F_ATTRD_ATTRIBUTE, attr); -+ send_attrd_message(NULL, xml); -+ } - } - } -+ -+ free(key); -+ free(set); -+ free(host); -+ -+ regfree(r_patt); -+ free(r_patt); - return; - - } else if(host == NULL) { -diff --git a/cib/callbacks.c b/cib/callbacks.c -index 610aa0a..9fb2de9 100644 ---- a/cib/callbacks.c -+++ b/cib/callbacks.c -@@ -382,6 +382,9 @@ do_local_notify(xmlNode * notify_src, const char *client_id, - /* send callback to originating child */ - crm_client_t *client_obj = NULL; - int local_rc = pcmk_ok; -+ int call_id = 0; -+ -+ crm_element_value_int(notify_src, F_CIB_CALLID, &call_id); - - if (client_id != NULL) { - client_obj = crm_client_get_by_id(client_id); -@@ -389,7 +392,7 @@ do_local_notify(xmlNode * notify_src, const char *client_id, - - if (client_obj == NULL) { - local_rc = -ECONNRESET; -- crm_trace("No client to sent the response to. F_CIB_CLIENTID not set."); -+ crm_trace("No client to sent response %d to, F_CIB_CLIENTID not set.", call_id); - - } else { - int rid = 0; -@@ -405,13 +408,13 @@ do_local_notify(xmlNode * notify_src, const char *client_id, - rid, client_obj->name, - from_peer ? "(originator of delegated request)" : ""); - } else { -- crm_trace("Sending response to %s %s", -- client_obj->name, from_peer ? "(originator of delegated request)" : ""); -+ crm_trace("Sending response [call %d] to %s %s", -+ call_id, client_obj->name, from_peer ? "(originator of delegated request)" : ""); - } - - } else { -- crm_trace("Sending an event to %s %s", -- client_obj->name, from_peer ? "(originator of delegated request)" : ""); -+ crm_trace("Sending event %d to %s %s", -+ call_id, client_obj->name, from_peer ? "(originator of delegated request)" : ""); - } - - switch (client_obj->kind) { -diff --git a/crmd/control.c b/crmd/control.c -index 99ef659..8989859 100644 ---- a/crmd/control.c -+++ b/crmd/control.c -@@ -945,17 +945,23 @@ config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void - throttle_load_target = strtof(value, NULL) / 100; - } - -+ value = getenv("SBD_WATCHDOG_TIMEOUT"); -+ -+ if(value == NULL) { -+ value = crmd_pref(config_hash, "stonith-watchdog-timeout"); -+ } -+ - value = crmd_pref(config_hash, "stonith-watchdog-timeout"); -- if(crm_get_msec(value) > 0 && daemon_option("watchdog") == NULL) { -+ if(crm_get_msec(value) > 0 && !daemon_option_enabled(crm_system_name, "watchdog")) { - do_crm_log_always(LOG_EMERG, "Shutting down pacemaker, no watchdog device configured"); - crmd_exit(DAEMON_RESPAWN_STOP); - -- } else if(crm_get_msec(value) <= 0 && daemon_option("watchdog")) { -+ } else if(crm_get_msec(value) <= 0 && daemon_option_enabled(crm_system_name, "watchdog")) { - crm_warn("Watchdog enabled but no stonith-watchdog-timeout configured"); - } - - value = crmd_pref(config_hash, "no-quorum-policy"); -- if (safe_str_eq(value, "suicide") && daemon_option("watchdog")) { -+ if (safe_str_eq(value, "suicide") && daemon_option_enabled(crm_system_name, "watchdog")) { - no_quorum_suicide_escalation = TRUE; - } - -diff --git a/crmd/election.c b/crmd/election.c -index e0bd6c4..a4f2e99 100644 ---- a/crmd/election.c -+++ b/crmd/election.c -@@ -208,6 +208,9 @@ do_dc_takeover(long long action, - fsa_register_cib_callback(rc, FALSE, NULL, feature_update_callback); - - update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, -+ XML_ATTR_HAVE_WATCHDOG, daemon_option("watchdog"), FALSE, NULL, NULL); -+ -+ update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, - "dc-version", VERSION "-" BUILD_VERSION, FALSE, NULL, NULL); - - update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, -diff --git a/crmd/pengine.c b/crmd/pengine.c -index ab426be..2f7513f 100644 ---- a/crmd/pengine.c -+++ b/crmd/pengine.c -@@ -237,6 +237,48 @@ do_pe_invoke(long long action, - fsa_register_cib_callback(fsa_pe_query, FALSE, NULL, do_pe_invoke_callback); - } - -+static void -+force_local_option(xmlNode *xml, const char *attr_name, const char *attr_value) -+{ -+ int max = 0; -+ int lpc = 0; -+ int xpath_max = 1024; -+ char *xpath_string = NULL; -+ xmlXPathObjectPtr xpathObj = NULL; -+ -+ xpath_string = calloc(1, xpath_max); -+ lpc = snprintf(xpath_string, xpath_max, "%.128s//%s//nvpair[@name='%.128s']", -+ get_object_path(XML_CIB_TAG_CRMCONFIG), XML_CIB_TAG_PROPSET, attr_name); -+ CRM_LOG_ASSERT(lpc > 0); -+ -+ xpathObj = xpath_search(xml, xpath_string); -+ max = numXpathResults(xpathObj); -+ free(xpath_string); -+ -+ for (lpc = 0; lpc < max; lpc++) { -+ xmlNode *match = getXpathResult(xpathObj, lpc); -+ crm_trace("Forcing %s/%s = %s", ID(match), attr_name, attr_value); -+ crm_xml_add(match, XML_NVPAIR_ATTR_VALUE, attr_value); -+ } -+ -+ if(max == 0) { -+ char *attr_id = crm_concat(CIB_OPTIONS_FIRST, attr_name, '-'); -+ -+ crm_trace("Creating %s/%s = %s", attr_id, attr_name, attr_value); -+ xml = create_xml_node(xml, XML_CIB_TAG_CRMCONFIG); -+ xml = create_xml_node(xml, XML_CIB_TAG_PROPSET); -+ crm_xml_add(xml, XML_ATTR_ID, CIB_OPTIONS_FIRST); -+ -+ xml = create_xml_node(xml, XML_CIB_TAG_NVPAIR); -+ -+ crm_xml_add(xml, XML_ATTR_ID, attr_id); -+ crm_xml_add(xml, XML_NVPAIR_ATTR_NAME, attr_name); -+ crm_xml_add(xml, XML_NVPAIR_ATTR_VALUE, attr_value); -+ -+ free(attr_id); -+ } -+} -+ - void - do_pe_invoke_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) - { -@@ -279,6 +321,7 @@ do_pe_invoke_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void - - crm_xml_add(output, XML_ATTR_DC_UUID, fsa_our_uuid); - crm_xml_add_int(output, XML_ATTR_HAVE_QUORUM, fsa_has_quorum); -+ force_local_option(output, XML_ATTR_HAVE_WATCHDOG, daemon_option("watchdog")); - - if (ever_had_quorum && crm_have_quorum == FALSE) { - crm_xml_add_int(output, XML_ATTR_QUORUM_PANIC, 1); -diff --git a/crmd/remote_lrmd_ra.c b/crmd/remote_lrmd_ra.c -index f3dedeb..2f658ee 100644 ---- a/crmd/remote_lrmd_ra.c -+++ b/crmd/remote_lrmd_ra.c -@@ -140,8 +140,6 @@ recurring_helper(gpointer data) - - ra_data->recurring_cmds = g_list_remove(ra_data->recurring_cmds, cmd); - -- cmd->call_id = generate_callid(); -- - ra_data->cmds = g_list_append(ra_data->cmds, cmd); - mainloop_set_trigger(ra_data->work); - } -@@ -177,6 +175,24 @@ report_remote_ra_result(remote_ra_cmd_t * cmd) - op.interval = cmd->interval; - op.rc = cmd->rc; - op.op_status = cmd->op_status; -+ op.t_run = cmd->start_time; -+ op.t_rcchange = cmd->start_time; -+ if (cmd->reported_success && cmd->rc != PCMK_OCF_OK) { -+ op.t_rcchange = time(NULL); -+ /* This edge case will likely never ever occur, but if it does the -+ * result is that a failure will not be processed correctly. This is only -+ * remotely possible because we are able to detect a connection resource's tcp -+ * connection has failed at any moment after start has completed. The actual -+ * recurring operation is just a connectivity ping. -+ * -+ * basically, we are not guaranteed that the first successful monitor op and -+ * a subsequent failed monitor op will not occur in the same timestamp. We have to -+ * make it look like the operations occurred at separate times though. */ -+ if (op.t_rcchange == op.t_run) { -+ op.t_rcchange++; -+ } -+ } -+ - if (cmd->params) { - lrmd_key_value_t *tmp; - -diff --git a/crmd/te_utils.c b/crmd/te_utils.c -index 66ed1da..69c22e3 100644 ---- a/crmd/te_utils.c -+++ b/crmd/te_utils.c -@@ -126,19 +126,19 @@ tengine_stonith_notify(stonith_t * st, stonith_event_t * st_event) - - if (st_event->result == pcmk_ok && safe_str_eq("on", st_event->action)) { - crm_notice("%s was successfully unfenced by %s (at the request of %s)", -- st_event->target, st_event->executioner, st_event->origin); -+ st_event->target, st_event->executioner ? st_event->executioner : "", st_event->origin); - /* TODO: Hook up st_event->device */ - return; - - } else if (safe_str_eq("on", st_event->action)) { - crm_err("Unfencing of %s by %s failed: %s (%d)", -- st_event->target, st_event->executioner, -+ st_event->target, st_event->executioner ? st_event->executioner : "", - pcmk_strerror(st_event->result), st_event->result); - return; - - } else if (st_event->result == pcmk_ok && crm_str_eq(st_event->target, fsa_our_uname, TRUE)) { - crm_crit("We were allegedly just fenced by %s for %s!", -- st_event->executioner, st_event->origin); /* Dumps blackbox if enabled */ -+ st_event->executioner ? st_event->executioner : "", st_event->origin); /* Dumps blackbox if enabled */ - - qb_log_fini(); /* Try to get the above log message to disk - somehow */ - -diff --git a/cts/CIB.py b/cts/CIB.py -index 6ce38e9..d26efdb 100644 ---- a/cts/CIB.py -+++ b/cts/CIB.py -@@ -177,6 +177,8 @@ class CIB11(ConfigBase): - for node in self.CM.Env["nodes"]: - ftype = self.CM.Env.RandomGen.choice(["levels-and", "levels-or ", "broadcast "]) - self.CM.log(" - Using %s fencing for node: %s" % (ftype, node)) -+ # for baremetal remote node tests -+ stt_nodes.append("remote_%s" % node) - if ftype == "levels-and": - stl.level(1, node, "FencingPass,Fencing") - stt_nodes.append(node) -diff --git a/cts/CTStests.py b/cts/CTStests.py -index cd5b7ce..d2b7668 100644 ---- a/cts/CTStests.py -+++ b/cts/CTStests.py -@@ -453,8 +453,8 @@ class StonithdTest(CTSTest): - is_dc = self.CM.is_node_dc(node) - - watchpats = [] -- watchpats.append("Operation .* for host '%s' with device .* returned: 0" % node) -- watchpats.append("tengine_stonith_notify:.*Peer %s was terminated .*: OK" % node) -+ watchpats.append(self.templates["Pat:FenceOpOK"] % node) -+ watchpats.append(self.templates["Pat:NodeFenced"] % node) - - if self.Env["at-boot"] == 0: - self.debug("Expecting %s to stay down" % node) -@@ -2634,11 +2634,11 @@ AllTestClasses.append(RemoteLXC) - - - ################################################################### --class RemoteBaremetal(CTSTest): -+class RemoteDriver(CTSTest): - ################################################################### - def __init__(self, cm): - CTSTest.__init__(self,cm) -- self.name = "RemoteBaremetal" -+ self.name = "RemoteDriver" - self.is_docker_unsafe = 1 - self.start = StartTest(cm) - self.startall = SimulStartLite(cm) -@@ -2647,9 +2647,8 @@ class RemoteBaremetal(CTSTest): - self.failed = 0 - self.fail_string = "" - self.remote_node_added = 0 -- self.remote_node = "remote1" - self.remote_rsc_added = 0 -- self.remote_rsc = "remote1-rsc" -+ self.remote_rsc = "remote-rsc" - self.cib_cmd = """cibadmin -C -o %s -X '%s' """ - - def del_rsc(self, node, rsc): -@@ -2679,10 +2678,11 @@ class RemoteBaremetal(CTSTest): - - def add_primitive_rsc(self, node): - rsc_xml = """ -- -+ - -- -+ - -+ - """ % (self.remote_rsc) - self.add_rsc(node, rsc_xml) - if self.failed == 0: -@@ -2691,21 +2691,38 @@ class RemoteBaremetal(CTSTest): - def add_connection_rsc(self, node): - rsc_xml = """ - -- -- -- -+ -+ -+ - - -- -- -+ -+ - -- - """ % (self.remote_node, node) - self.add_rsc(node, rsc_xml) - if self.failed == 0: - self.remote_node_added = 1 - -- def step1_start_metal(self, node): -+ def stop_pcmk_remote(self, node): -+ # disable pcmk remote -+ for i in range(10): -+ rc = self.rsh(node, "service pacemaker_remote stop") -+ if rc != 0: -+ time.sleep(6) -+ else: -+ break -+ -+ def start_pcmk_remote(self, node): -+ for i in range(10): -+ rc = self.rsh(node, "service pacemaker_remote start") -+ if rc != 0: -+ time.sleep(6) -+ else: -+ self.pcmk_started = 1 -+ break -+ -+ def start_metal(self, node): - pcmk_started = 0 - - # make sure the resource doesn't already exist for some reason -@@ -2717,13 +2734,7 @@ class RemoteBaremetal(CTSTest): - self.fail_string = "Failed to shutdown cluster node %s" % (node) - return - -- for i in range(10): -- rc = self.rsh(node, "service pacemaker_remote start") -- if rc != 0: -- time.sleep(6) -- else: -- self.pcmk_started = 1 -- break -+ self.start_pcmk_remote(node) - - if self.pcmk_started == 0: - self.failed = 1 -@@ -2735,6 +2746,7 @@ class RemoteBaremetal(CTSTest): - watch = self.create_watch(pats, 120) - watch.setwatch() - pats.append(self.templates["Pat:RscOpOK"] % (self.remote_node, "start")) -+ pats.append(self.templates["Pat:DC_IDLE"]) - - self.add_connection_rsc(node) - -@@ -2745,7 +2757,112 @@ class RemoteBaremetal(CTSTest): - self.fail_string = "Unmatched patterns: %s" % (repr(watch.unmatched)) - self.failed = 1 - -- def step2_add_rsc(self, node): -+ def migrate_connection(self, node): -+ if self.failed == 1: -+ return -+ -+ pats = [ ] -+ pats.append(self.templates["Pat:RscOpOK"] % (self.remote_node, "migrate_to")) -+ pats.append(self.templates["Pat:RscOpOK"] % (self.remote_node, "migrate_from")) -+ pats.append(self.templates["Pat:DC_IDLE"]) -+ watch = self.create_watch(pats, 120) -+ watch.setwatch() -+ -+ (rc, lines) = self.rsh(node, "crm_resource -M -r %s" % (self.remote_node), None) -+ if rc != 0: -+ self.fail_string = "failed to move remote node connection resource" -+ self.logger.log(self.fail_string) -+ self.failed = 1 -+ return -+ -+ self.set_timer("remoteMetalMigrate") -+ watch.lookforall() -+ self.log_timer("remoteMetalMigrate") -+ -+ if watch.unmatched: -+ self.fail_string = "Unmatched patterns: %s" % (repr(watch.unmatched)) -+ self.logger.log(self.fail_string) -+ self.failed = 1 -+ return -+ -+ def fail_rsc(self, node): -+ if self.failed == 1: -+ return -+ -+ watchpats = [ ] -+ watchpats.append(self.templates["Pat:RscRemoteOpOK"] % (self.remote_rsc, "stop", self.remote_node)) -+ watchpats.append(self.templates["Pat:RscRemoteOpOK"] % (self.remote_rsc, "start", self.remote_node)) -+ watchpats.append(self.templates["Pat:DC_IDLE"]) -+ -+ watch = self.create_watch(watchpats, 120) -+ watch.setwatch() -+ -+ self.debug("causing dummy rsc to fail.") -+ -+ rc = self.rsh(node, "rm -f /var/run/resource-agents/Dummy*") -+ -+ self.set_timer("remoteRscFail") -+ watch.lookforall() -+ self.log_timer("remoteRscFail") -+ if watch.unmatched: -+ self.fail_string = "Unmatched patterns during rsc fail: %s" % (repr(watch.unmatched)) -+ self.logger.log(self.fail_string) -+ self.failed = 1 -+ -+ def fail_connection(self, node): -+ if self.failed == 1: -+ return -+ -+ watchpats = [ ] -+ watchpats.append(self.templates["Pat:FenceOpOK"] % self.remote_node) -+ watchpats.append(self.templates["Pat:NodeFenced"] % self.remote_node) -+ -+ watch = self.create_watch(watchpats, 120) -+ watch.setwatch() -+ -+ # force stop the pcmk remote daemon. this will result in fencing -+ self.debug("Force stopped active remote node") -+ self.stop_pcmk_remote(node) -+ -+ self.debug("Waiting for remote node to be fenced.") -+ self.set_timer("remoteMetalFence") -+ watch.lookforall() -+ self.log_timer("remoteMetalFence") -+ if watch.unmatched: -+ self.fail_string = "Unmatched patterns: %s" % (repr(watch.unmatched)) -+ self.logger.log(self.fail_string) -+ self.failed = 1 -+ return -+ -+ self.debug("Waiting for the remote node to come back up") -+ self.CM.ns.WaitForNodeToComeUp(node, 120); -+ -+ pats = [ ] -+ watch = self.create_watch(pats, 120) -+ watch.setwatch() -+ pats.append(self.templates["Pat:RscOpOK"] % (self.remote_node, "start")) -+ if self.remote_rsc_added == 1: -+ pats.append(self.templates["Pat:RscOpOK"] % (self.remote_rsc, "monitor")) -+ -+ # start the remote node again watch it integrate back into cluster. -+ self.start_pcmk_remote(node) -+ if self.pcmk_started == 0: -+ self.failed = 1 -+ self.fail_string = "Failed to start pacemaker_remote on node %s" % (node) -+ self.logger.log(self.fail_string) -+ return -+ -+ self.debug("Waiting for remote node to rejoin cluster after being fenced.") -+ self.set_timer("remoteMetalRestart") -+ watch.lookforall() -+ self.log_timer("remoteMetalRestart") -+ if watch.unmatched: -+ self.fail_string = "Unmatched patterns: %s" % (repr(watch.unmatched)) -+ self.failed = 1 -+ self.logger.log(self.fail_string) -+ return -+ -+ def add_dummy_rsc(self, node): - if self.failed == 1: - return - -@@ -2753,33 +2870,19 @@ class RemoteBaremetal(CTSTest): - pats = [ ] - watch = self.create_watch(pats, 120) - watch.setwatch() -- pats.append("process_lrm_event:.*Operation %s_start_0.*node=%s, .*confirmed.*true" % (self.remote_rsc, self.remote_node)) -+ pats.append(self.templates["Pat:RscRemoteOpOK"] % (self.remote_rsc, "start", self.remote_node)) -+ pats.append(self.templates["Pat:DC_IDLE"]) - - # Add a resource that must live on remote-node - self.add_primitive_rsc(node) -- # this crm_resource command actually occurs on the remote node -- # which verifies that the ipc proxy works -- time.sleep(1) - -- (rc, lines) = self.rsh(node, "crm_resource -W -r remote1-rsc --quiet", None) -+ # force that rsc to prefer the remote node. -+ (rc, line) = self.CM.rsh(node, "crm_resource -M -r %s -N %s -f" % (self.remote_rsc, self.remote_node), None) - if rc != 0: -- self.fail_string = "Failed to get location of resource remote1-rsc" -+ self.fail_string = "Failed to place remote resource on remote node." - self.failed = 1 - return - -- find = 0 -- for line in lines: -- if self.remote_node in line.split(): -- find = 1 -- break -- -- if find == 0: -- rc = self.rsh(node, "crm_resource -M -r remote1-rsc -N %s" % (self.remote_node)) -- if rc != 0: -- self.fail_string = "Failed to place primitive on remote-node" -- self.failed = 1 -- return -- - self.set_timer("remoteMetalRsc") - watch.lookforall() - self.log_timer("remoteMetalRsc") -@@ -2787,7 +2890,7 @@ class RemoteBaremetal(CTSTest): - self.fail_string = "Unmatched patterns: %s" % (repr(watch.unmatched)) - self.failed = 1 - -- def step3_test_attributes(self, node): -+ def test_attributes(self, node): - if self.failed == 1: - return - -@@ -2827,9 +2930,10 @@ class RemoteBaremetal(CTSTest): - - self.set_timer("remoteMetalCleanup") - if self.remote_rsc_added == 1: -- self.rsh(node, "crm_resource -U -r remote1-rsc -N %s" % (self.remote_node)) -+ self.rsh(node, "crm_resource -U -r %s -N %s" % (self.remote_rsc, self.remote_node)) - self.del_rsc(node, self.remote_rsc) - if self.remote_node_added == 1: -+ self.rsh(node, "crm_resource -U -r %s" % (self.remote_node)) - self.del_rsc(node, self.remote_node) - watch.lookforall() - self.log_timer("remoteMetalCleanup") -@@ -2838,15 +2942,11 @@ class RemoteBaremetal(CTSTest): - self.fail_string = "Unmatched patterns: %s" % (repr(watch.unmatched)) - self.failed = 1 - -- # disable pcmk remote -- for i in range(10): -- rc = self.rsh(node, "service pacemaker_remote stop") -- if rc != 0: -- time.sleep(6) -- else: -- break -+ self.stop_pcmk_remote(node) - -- def setup_env(self): -+ def setup_env(self, node): -+ -+ self.remote_node = "remote_%s" % (node) - sync_key = 0 - - # we are assuming if all nodes have a key, that it is -@@ -2887,10 +2987,10 @@ class RemoteBaremetal(CTSTest): - if not ret: - return self.failure("Setup failed, start all nodes failed.") - -- self.setup_env() -- self.step1_start_metal(node) -- self.step2_add_rsc(node) -- self.step3_test_attributes(node) -+ self.setup_env(node) -+ self.start_metal(node) -+ self.add_dummy_rsc(node) -+ self.test_attributes(node) - self.cleanup_metal(node) - - self.debug("Waiting for the cluster to recover") -@@ -2902,11 +3002,201 @@ class RemoteBaremetal(CTSTest): - - def errorstoignore(self): - '''Return list of errors which should be ignored''' -- return [ """is running on remote1 which isn't allowed""", -+ return [ """is running on remote.*which isn't allowed""", - """Connection terminated""", - """Failed to send remote""", - ] - --AllTestClasses.append(RemoteBaremetal) -+# Remote driver is called by other tests. -+ -+################################################################### -+class RemoteBasic(CTSTest): -+################################################################### -+ def __init__(self, cm): -+ CTSTest.__init__(self,cm) -+ self.name = "RemoteBasic" -+ self.start = StartTest(cm) -+ self.startall = SimulStartLite(cm) -+ self.driver = RemoteDriver(cm) -+ self.is_docker_unsafe = 1 -+ -+ def __call__(self, node): -+ '''Perform the 'RemoteBaremetal' test. ''' -+ self.incr("calls") -+ -+ ret = self.startall(None) -+ if not ret: -+ return self.failure("Setup failed, start all nodes failed.") -+ -+ self.driver.setup_env(node) -+ self.driver.start_metal(node) -+ self.driver.add_dummy_rsc(node) -+ self.driver.test_attributes(node) -+ self.driver.cleanup_metal(node) -+ -+ self.debug("Waiting for the cluster to recover") -+ self.CM.cluster_stable() -+ if self.driver.failed == 1: -+ return self.failure(self.driver.fail_string) -+ -+ return self.success() -+ -+ def is_applicable(self): -+ return self.driver.is_applicable() -+ -+ def errorstoignore(self): -+ return self.driver.errorstoignore() -+ -+AllTestClasses.append(RemoteBasic) -+ -+################################################################### -+class RemoteStonithd(CTSTest): -+################################################################### -+ def __init__(self, cm): -+ CTSTest.__init__(self,cm) -+ self.name = "RemoteStonithd" -+ self.start = StartTest(cm) -+ self.startall = SimulStartLite(cm) -+ self.driver = RemoteDriver(cm) -+ self.is_docker_unsafe = 1 -+ -+ def __call__(self, node): -+ '''Perform the 'RemoteStonithd' test. ''' -+ self.incr("calls") -+ -+ ret = self.startall(None) -+ if not ret: -+ return self.failure("Setup failed, start all nodes failed.") -+ -+ self.driver.setup_env(node) -+ self.driver.start_metal(node) -+ self.driver.add_dummy_rsc(node) -+ -+ self.driver.fail_connection(node) -+ self.driver.cleanup_metal(node) -+ -+ self.debug("Waiting for the cluster to recover") -+ self.CM.cluster_stable() -+ if self.driver.failed == 1: -+ return self.failure(self.driver.fail_string) -+ -+ return self.success() -+ -+ def is_applicable(self): -+ if not self.driver.is_applicable(): -+ return False -+ -+ if self.Env.has_key("DoFencing"): -+ return self.Env["DoFencing"] -+ -+ return True -+ -+ def errorstoignore(self): -+ ignore_pats = [ -+ """Unexpected disconnect on remote-node""", -+ """error: process_lrm_event: Operation remote_.*_monitor""", -+ """LogActions: Recover remote_""", -+ """Calculated Transition .* /var/lib/pacemaker/pengine/pe-error""", -+ """error: native_create_actions: Resource .*ocf::.* is active on 2 nodes attempting recovery""", -+ ] -+ -+ ignore_pats.extend(self.driver.errorstoignore()) -+ return ignore_pats -+ -+AllTestClasses.append(RemoteStonithd) -+ -+################################################################### -+class RemoteMigrate(CTSTest): -+################################################################### -+ def __init__(self, cm): -+ CTSTest.__init__(self,cm) -+ self.name = "RemoteMigrate" -+ self.start = StartTest(cm) -+ self.startall = SimulStartLite(cm) -+ self.driver = RemoteDriver(cm) -+ self.is_docker_unsafe = 1 -+ -+ def __call__(self, node): -+ '''Perform the 'RemoteMigrate' test. ''' -+ self.incr("calls") -+ -+ ret = self.startall(None) -+ if not ret: -+ return self.failure("Setup failed, start all nodes failed.") -+ -+ self.driver.setup_env(node) -+ self.driver.start_metal(node) -+ self.driver.add_dummy_rsc(node) -+ self.driver.migrate_connection(node) -+ self.driver.cleanup_metal(node) -+ -+ self.debug("Waiting for the cluster to recover") -+ self.CM.cluster_stable() -+ if self.driver.failed == 1: -+ return self.failure(self.driver.fail_string) -+ -+ return self.success() -+ -+ def is_applicable(self): -+ return self.driver.is_applicable() -+ -+ def errorstoignore(self): -+ return self.driver.errorstoignore() -+ -+AllTestClasses.append(RemoteMigrate) -+ -+ -+################################################################### -+class RemoteRscFailure(CTSTest): -+################################################################### -+ def __init__(self, cm): -+ -+ # fail a rsc on a remote node, verify recovery. -+ CTSTest.__init__(self,cm) -+ self.name = "RemoteRscFailure" -+ self.start = StartTest(cm) -+ self.startall = SimulStartLite(cm) -+ self.driver = RemoteDriver(cm) -+ self.is_docker_unsafe = 1 -+ -+ def __call__(self, node): -+ '''Perform the 'RemoteRscFailure' test. ''' -+ self.incr("calls") -+ -+ ret = self.startall(None) -+ if not ret: -+ return self.failure("Setup failed, start all nodes failed.") -+ -+ self.driver.setup_env(node) -+ self.driver.start_metal(node) -+ self.driver.add_dummy_rsc(node) -+ -+ # This is an important step. We are migrating the connection -+ # before failing the resource. This verifies that the migration -+ # has properly maintained control over the remote-node. -+ self.driver.migrate_connection(node) -+ -+ self.driver.fail_rsc(node) -+ self.driver.cleanup_metal(node) -+ -+ self.debug("Waiting for the cluster to recover") -+ self.CM.cluster_stable() -+ if self.driver.failed == 1: -+ return self.failure(self.driver.fail_string) -+ -+ return self.success() -+ -+ def is_applicable(self): -+ return self.driver.is_applicable() -+ -+ def errorstoignore(self): -+ ignore_pats = [ -+ """LogActions: Recover remote-rsc""", -+ ] -+ -+ ignore_pats.extend(self.driver.errorstoignore()) -+ return ignore_pats -+ -+AllTestClasses.append(RemoteRscFailure) - - # vim:ts=4:sw=4:et: -diff --git a/cts/patterns.py b/cts/patterns.py -index 8d34e1c..e734f40 100644 ---- a/cts/patterns.py -+++ b/cts/patterns.py -@@ -56,6 +56,9 @@ class BasePatterns: - "Pat:Fencing_ok" : "stonith.*remote_op_done:.*Operation .* of %s by .*: OK", - - "Pat:RscOpOK" : "process_lrm_event:.*Operation %s_%s.*ok.*confirmed", -+ "Pat:RscRemoteOpOK" : "process_lrm_event:.*Operation %s_%s.*ok.*node=%s, .*confirmed.*true", -+ "Pat:NodeFenced" : "tengine_stonith_notify:.*Peer %s was terminated .*: OK", -+ "Pat:FenceOpOK" : "Operation .* for host '%s' with device .* returned: 0", - } - - def get_component(self, key): -diff --git a/cts/watcher.py b/cts/watcher.py -index 5e6ee43..41e4100 100644 ---- a/cts/watcher.py -+++ b/cts/watcher.py -@@ -31,7 +31,8 @@ from cts.remote import * - from cts.logging import * - - has_log_watcher = {} --log_watcher_bin = CTSvars.CRM_DAEMON_DIR + "/cts_log_watcher.py" -+log_watcher_file = "cts_log_watcher.py" -+log_watcher_bin = CTSvars.CRM_DAEMON_DIR + "/" + log_watcher_file - log_watcher = """ - import sys, os, fcntl - -@@ -164,14 +165,16 @@ class FileObj(SearchObj): - global log_watcher - global log_watcher_bin - -- self.debug("Installing %s on %s" % (log_watcher_bin, host)) -+ self.debug("Installing %s on %s" % (log_watcher_file, host)) - -- os.system("cat << END >> %s\n%s\nEND" %(log_watcher_bin, log_watcher)) -- os.system("chmod 755 %s" %(log_watcher_bin)) -+ os.system("cat << END >> %s\n%s\nEND" %(log_watcher_file, log_watcher)) -+ os.system("chmod 755 %s" %(log_watcher_file)) - -- self.rsh.cp(log_watcher_bin, "root@%s:%s" % (host, log_watcher_bin)) -+ self.rsh.cp(log_watcher_file, "root@%s:%s" % (host, log_watcher_bin)) - has_log_watcher[host] = 1 - -+ os.system("rm -f %s" %(log_watcher_file)) -+ - self.harvest() - - def async_complete(self, pid, returncode, outLines, errLines): -diff --git a/doc/Makefile.am b/doc/Makefile.am -index 8798365..9194f1d 100644 ---- a/doc/Makefile.am -+++ b/doc/Makefile.am -@@ -29,6 +29,7 @@ publican_docs = - generated_docs = - generated_mans = - -+ASCIIDOC_CLI_TYPE := pcs - DOCBOOK_FORMATS := html-desktop - DOCBOOK_LANGS := en-US - DOTs = $(wildcard */en-US/images/*.dot) -@@ -154,17 +155,15 @@ pdf: - make DOCBOOK_FORMATS="pdf" ASCIIDOC_CLI_TYPE=$(ASCIIDOC_CLI_TYPE) all-local - - # Make sure www-(pcs|crmsh) happen in serial --www: -- make www-pcs -- make www-crmsh -- make $(generated_docs) $(ascii) -+www: clean-local $(generated_docs) $(ascii) -+ make www-cli - rsync -rtz --progress $(generated_docs) $(ascii) $(asciiman) root@www.clusterlabs.org:/var/www/html/doc/ - - www-crmsh: - make ASCIIDOC_CLI_TYPE=crmsh clean-local www-cli - - www-pcs: -- make ASCIIDOC_CLI_TYPE=pcs clean-local www-cli -+ make ASCIIDOC_CLI_TYPE=pcs www-cli - - www-cli: - for book in $(docbook); do \ -diff --git a/doc/Pacemaker_Explained/en-US/Ch-Options.txt b/doc/Pacemaker_Explained/en-US/Ch-Options.txt -index cf1478f..3a6ee0b 100644 ---- a/doc/Pacemaker_Explained/en-US/Ch-Options.txt -+++ b/doc/Pacemaker_Explained/en-US/Ch-Options.txt -@@ -89,22 +89,22 @@ cluster cannot start resources or fence other nodes. See - +no-quorum-policy+ below. - - | dc-version | --indexterm:[dc-version,Cluster Peroperty] --indexterm:[Cluster,Peroperty,dc-version] -+indexterm:[dc-version,Cluster Property] -+indexterm:[Cluster,Property,dc-version] - Version of Pacemaker on the cluster's DC. - - Often includes the hash which identifies the exact Git changeset it - was built from. Used for diagnostic purposes. - - | cluster-infrastructure | --indexterm:[cluster-infrastructure,Cluster Peroperty] --indexterm:[Cluster,Peroperty,cluster-infrastructure] -+indexterm:[cluster-infrastructure,Cluster Property] -+indexterm:[Cluster,Property,cluster-infrastructure] - The messaging stack on which Pacemaker is currently running. - Used for informational and diagnostic purposes. - - | expected-quorum-votes | --indexterm:[expected-quorum-votes,Cluster Peroperty] --indexterm:[Cluster,Peroperty,expected-quorum-votes] -+indexterm:[expected-quorum-votes,Cluster Property] -+indexterm:[Cluster,Property,expected-quorum-votes] - The number of nodes expected to be in the cluster - - Used to calculate quorum in Corosync 1.x (not CMAN) based clusters. -diff --git a/extra/resources/ping b/extra/resources/ping -index b9a69b8..e7b9973 100755 ---- a/extra/resources/ping -+++ b/extra/resources/ping -@@ -77,7 +77,7 @@ The name of the attributes to set. This is the name to be used in the constrain - The number by which to multiply the number of connected ping nodes by - - Value multiplier -- -+ - - - -@@ -93,7 +93,7 @@ The list of ping nodes to count. - Number of ping attempts, per host, before declaring it dead - - no. of ping attempts -- -+ - - - -@@ -121,6 +121,15 @@ Default never fails. - - - -+ -+ -+Use fping rather than ping, if found. If set to 0, fping -+will not be used even if present. -+ -+Use fping if available -+ -+ -+ - - - Enables to use default attrd_updater verbose logging on every call. -@@ -154,7 +163,7 @@ ping_conditional_log() { - - ping_usage() { - cat <$f_out 2>$f_err; rc=$? - active=`grep alive $f_out|wc -l` - -@@ -274,7 +283,7 @@ ping_check() { - - ping_update() { - -- if have_binary fping; then -+ if ocf_is_true "$OCF_RESKEY_use_fping" && have_binary fping; then - fping_check - active=$? - else -@@ -306,6 +315,7 @@ ping_update() { - : ${OCF_RESKEY_multiplier:="1"} - : ${OCF_RESKEY_debug:="false"} - : ${OCF_RESKEY_failure_score:="0"} -+: ${OCF_RESKEY_use_fping:="1"} - - : ${OCF_RESKEY_CRM_meta_timeout:="20000"} - : ${OCF_RESKEY_CRM_meta_globally_unique:="true"} -diff --git a/extra/resources/remote b/extra/resources/remote -index 9f141a2..d79c4c3 100644 ---- a/extra/resources/remote -+++ b/extra/resources/remote -@@ -58,12 +58,12 @@ meta_data() { - tcp port to connect to. - - tcp port -- -+ - - - -- -- -+ -+ - - - -diff --git a/fencing/main.c b/fencing/main.c -index b03659e..fe6560d 100644 ---- a/fencing/main.c -+++ b/fencing/main.c -@@ -1002,15 +1002,22 @@ update_cib_cache_cb(const char *event, xmlNode * msg) - stonith_enabled_s = crm_element_value(stonith_enabled_xml, XML_NVPAIR_ATTR_VALUE); - } - -- if(daemon_option("watchdog")) { -- stonith_watchdog_xml = get_xpath_object("//nvpair[@name='stonith-watchdog-timeout']", local_cib, LOG_TRACE); -- } -+ if(daemon_option_enabled(crm_system_name, "watchdog")) { -+ const char *value = getenv("SBD_WATCHDOG_TIMEOUT"); - -- if (stonith_watchdog_xml) { -- const char *value = crm_element_value(stonith_watchdog_xml, XML_NVPAIR_ATTR_VALUE); -- stonith_watchdog_timeout_ms = crm_get_msec(value); -- } else { -- stonith_watchdog_timeout_ms = 0; -+ if(value == NULL) { -+ stonith_watchdog_xml = get_xpath_object("//nvpair[@name='stonith-watchdog-timeout']", local_cib, LOG_TRACE); -+ if (stonith_watchdog_xml) { -+ value = crm_element_value(stonith_watchdog_xml, XML_NVPAIR_ATTR_VALUE); -+ } -+ } -+ -+ if(value) { -+ stonith_watchdog_timeout_ms = crm_get_msec(value); -+ -+ } else { -+ stonith_watchdog_timeout_ms = 0; -+ } - } - - if (stonith_enabled_s && crm_is_true(stonith_enabled_s) == FALSE) { -@@ -1354,11 +1361,12 @@ main(int argc, char **argv) - - topology = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, free_topology_entry); - -- if(daemon_option("watchdog")) { -+ if(daemon_option_enabled(crm_system_name, "watchdog")) { - xmlNode *xml; - stonith_key_value_t *params = NULL; - -- stonith_key_value_add(params, STONITH_ATTR_HOSTLIST, stonith_our_uname); -+ params = stonith_key_value_add(params, STONITH_ATTR_HOSTLIST, stonith_our_uname); -+ - xml = create_device_registration_xml("watchdog", "internal", STONITH_WATCHDOG_AGENT, params, NULL); - stonith_device_register(xml, NULL, FALSE); - -diff --git a/fencing/remote.c b/fencing/remote.c -index 3f4f5ca..63c0274 100644 ---- a/fencing/remote.c -+++ b/fencing/remote.c -@@ -277,11 +277,9 @@ remote_op_done(remote_fencing_op_t * op, xmlNode * data, int rc, int dup) - } - - if (!op->delegate && data) { -- xmlNode *ndata = get_xpath_object("//@" F_STONITH_DELEGATE, data, LOG_WARNING); -+ xmlNode *ndata = get_xpath_object("//@" F_STONITH_DELEGATE, data, LOG_TRACE); - if(ndata) { - op->delegate = crm_element_value_copy(ndata, F_STONITH_DELEGATE); -- } else { -- op->delegate = crm_element_value_copy(data, F_ORIG); - } - } - -@@ -1055,9 +1053,10 @@ call_remote_stonith(remote_fencing_op_t * op, st_query_result_t * peer) - - } else { - timeout_one = TIMEOUT_MULTIPLY_FACTOR * get_peer_timeout(peer, op->base_timeout); -- crm_info("Requesting that %s perform op %s %s for %s (%ds)", -- peer->host, op->action, op->target, op->client_name, timeout_one); -+ crm_info("Requesting that %s perform op %s %s for %s (%ds, %ds)", -+ peer->host, op->action, op->target, op->client_name, timeout_one, stonith_watchdog_timeout_ms); - crm_xml_add(remote_op, F_STONITH_MODE, "smart"); -+ - } - - op->state = st_exec; -@@ -1065,7 +1064,17 @@ call_remote_stonith(remote_fencing_op_t * op, st_query_result_t * peer) - g_source_remove(op->op_timer_one); - } - -- if(device && stonith_watchdog_timeout_ms && safe_str_eq(device, "watchdog")) { -+ if(stonith_watchdog_timeout_ms > 0 && device && safe_str_eq(device, "watchdog")) { -+ crm_notice("Waiting %ds for %s to self-terminate for %s.%.8s (%p)", -+ stonith_watchdog_timeout_ms/1000, op->target, op->client_name, op->id, device); -+ op->op_timer_one = g_timeout_add(stonith_watchdog_timeout_ms, remote_op_watchdog_done, op); -+ -+ /* TODO: We should probably look into peer->device_list to verify watchdog is going to be in use */ -+ } else if(stonith_watchdog_timeout_ms > 0 -+ && safe_str_eq(peer->host, op->target) -+ && safe_str_neq(op->action, "on")) { -+ crm_notice("Waiting %ds for %s to self-terminate for %s.%.8s (%p)", -+ stonith_watchdog_timeout_ms/1000, op->target, op->client_name, op->id, device); - op->op_timer_one = g_timeout_add(stonith_watchdog_timeout_ms, remote_op_watchdog_done, op); - - } else { -@@ -1094,6 +1103,14 @@ call_remote_stonith(remote_fencing_op_t * op, st_query_result_t * peer) - /* if the operation never left the query state, - * but we have all the expected replies, then no devices - * are available to execute the fencing operation. */ -+ if(stonith_watchdog_timeout_ms && (device == NULL || safe_str_eq(device, "watchdog"))) { -+ crm_notice("Waiting %ds for %s to self-terminate for %s.%.8s (%p)", -+ stonith_watchdog_timeout_ms/1000, op->target, op->client_name, op->id, device); -+ -+ op->op_timer_one = g_timeout_add(stonith_watchdog_timeout_ms, remote_op_watchdog_done, op); -+ return; -+ } -+ - if (op->state == st_query) { - crm_info("None of the %d peers have devices capable of terminating %s for %s (%d)", - op->replies, op->target, op->client_name, op->state); -diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h -index 1ff425c..d3c2643 100644 ---- a/include/crm/msg_xml.h -+++ b/include/crm/msg_xml.h -@@ -86,6 +86,7 @@ - - # define XML_ATTR_QUORUM_PANIC "no-quorum-panic" - # define XML_ATTR_HAVE_QUORUM "have-quorum" -+# define XML_ATTR_HAVE_WATCHDOG "have-watchdog" - # define XML_ATTR_EXPECTED_VOTES "expected-quorum-votes" - # define XML_ATTR_GENERATION "epoch" - # define XML_ATTR_GENERATION_ADMIN "admin_epoch" -@@ -298,6 +299,8 @@ - # define XML_CONS_TAG_RSC_SET "resource_set" - # define XML_CONS_ATTR_SYMMETRICAL "symmetrical" - -+# define XML_LOCATION_ATTR_DISCOVERY "resource-discovery" -+ - # define XML_COLOC_ATTR_SOURCE "rsc" - # define XML_COLOC_ATTR_SOURCE_ROLE "rsc-role" - # define XML_COLOC_ATTR_TARGET "with-rsc" -@@ -321,6 +324,7 @@ - # define XML_NVPAIR_ATTR_VALUE "value" - - # define XML_NODE_ATTR_STATE "state" -+# define XML_NODE_ATTR_RSC_DISCOVERY "resource-discovery-enabled" - - # define XML_CONFIG_ATTR_DC_DEADTIME "dc-deadtime" - # define XML_CONFIG_ATTR_ELECTION_FAIL "election-timeout" -diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h -index d0ba856..f08a910 100644 ---- a/include/crm/pengine/status.h -+++ b/include/crm/pengine/status.h -@@ -136,6 +136,8 @@ struct node_shared_s { - gboolean shutdown; - gboolean expected_up; - gboolean is_dc; -+ gboolean rsc_discovery_enabled; -+ - int num_resources; - GListPtr running_rsc; /* resource_t* */ - GListPtr allocated_rsc; /* resource_t* */ -@@ -156,6 +158,7 @@ struct node_shared_s { - struct node_s { - int weight; - gboolean fixed; -+ int rsc_discover_mode; - int count; - struct node_shared_s *details; - }; -@@ -252,6 +255,7 @@ struct resource_s { - int migration_threshold; - - gboolean is_remote_node; -+ gboolean exclusive_discover; - - unsigned long long flags; - -diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c -index 022a8ab..15b354b 100644 ---- a/lib/cib/cib_utils.c -+++ b/lib/cib/cib_utils.c -@@ -665,7 +665,7 @@ cib_native_callback(cib_t * cib, xmlNode * msg, int call_id, int rc) - crm_trace("Invoking global callback for call %d", call_id); - cib->op_callback(msg, call_id, rc, output); - } -- crm_trace("OP callback activated."); -+ crm_trace("OP callback activated for %d", call_id); - } - - void -diff --git a/lib/common/mainloop.c b/lib/common/mainloop.c -index ac395ec..f2295ff 100644 ---- a/lib/common/mainloop.c -+++ b/lib/common/mainloop.c -@@ -799,7 +799,7 @@ mainloop_add_fd(const char *name, int priority, int fd, void *userdata, - { - mainloop_io_t *client = NULL; - -- if (fd > 0) { -+ if (fd >= 0) { - client = calloc(1, sizeof(mainloop_io_t)); - client->name = strdup(name); - client->userdata = userdata; -diff --git a/lib/common/utils.c b/lib/common/utils.c -index dc54e6d..6b8b12c 100644 ---- a/lib/common/utils.c -+++ b/lib/common/utils.c -@@ -2008,6 +2008,7 @@ attrd_update_delegate(crm_ipc_t * ipc, char command, const char *host, const cha - case 'u': - crm_xml_add(update, F_ATTRD_TASK, "update"); - crm_xml_add(update, F_ATTRD_REGEX, name); -+ break; - case 'D': - case 'U': - case 'v': -diff --git a/lib/common/watchdog.c b/lib/common/watchdog.c -index 7d70f91..3c616cd 100644 ---- a/lib/common/watchdog.c -+++ b/lib/common/watchdog.c -@@ -211,10 +211,10 @@ pcmk_panic_local(void) - - if(ppid > 1) { - /* child daemon */ -- crm_exit(pcmk_err_panic); -+ exit(pcmk_err_panic); - } else { - /* pacemakerd or orphan child */ -- crm_exit(DAEMON_RESPAWN_STOP); -+ exit(DAEMON_RESPAWN_STOP); - } - } - -@@ -222,6 +222,7 @@ static void - pcmk_panic_sbd(void) - { - union sigval signal_value; -+ pid_t ppid = getppid(); - - do_crm_log_always(LOG_EMERG, "Signaling sbd(%d) to panic", sbd_pid); - -@@ -232,7 +233,13 @@ pcmk_panic_sbd(void) - pcmk_panic_local(); - } - -- crm_exit(DAEMON_RESPAWN_STOP); -+ if(ppid > 1) { -+ /* child daemon */ -+ exit(pcmk_err_panic); -+ } else { -+ /* pacemakerd or orphan child */ -+ exit(DAEMON_RESPAWN_STOP); -+ } - } - - void -@@ -275,17 +282,27 @@ pcmk_locate_sbd(void) - } - - /* Look for the pid file */ -+ pidfile = g_strdup_printf("%s/sbd.pid", HA_STATE_DIR); - - /* Read the pid file */ - if(pidfile) { - int rc = crm_pidfile_inuse(pidfile, 1); - if(rc < pcmk_ok && rc != -ENOENT) { - sbd_pid = crm_read_pidfile(pidfile); -+ crm_trace("SBD detected at pid=%d (file)"); - } - } - -- /* Fall back to /proc for systems that support it */ -- sbd_pid = pcmk_locate_proc_entry("sbd"); -+ if(sbd_pid < 0) { -+ /* Fall back to /proc for systems that support it */ -+ sbd_pid = pcmk_locate_proc_entry("sbd"); -+ crm_trace("SBD detected at pid=%d (proc)"); -+ } -+ -+ if(sbd_pid < 0) { -+ sbd_pid = 0; -+ } - -+ free(pidfile); - return sbd_pid; - } -diff --git a/lib/common/xml.c b/lib/common/xml.c -index 06de44c..58d0a00 100644 ---- a/lib/common/xml.c -+++ b/lib/common/xml.c -@@ -386,6 +386,7 @@ static int __xml_build_schema_list(void) - xslt = get_schema_path(NULL, transform); - if(stat(xslt, &s) != 0) { - crm_err("Transform %s not found", xslt); -+ free(xslt); - __xml_schema_add(2, version, NULL, NULL, NULL, -1); - break; - } else { -@@ -1950,9 +1951,11 @@ bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]) - return -EINVAL; - } - -- for(lpc = 0; lpc < DIMOF(vfields); lpc++) { -- crm_element_value_int(tmp, vfields[lpc], &(del[lpc])); -- crm_trace("Got %d for del[%s]", del[lpc], vfields[lpc]); -+ if (tmp) { -+ for(lpc = 0; lpc < DIMOF(vfields); lpc++) { -+ crm_element_value_int(tmp, vfields[lpc], &(del[lpc])); -+ crm_trace("Got %d for del[%s]", del[lpc], vfields[lpc]); -+ } - } - - switch(format) { -@@ -1973,9 +1976,11 @@ bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]) - return -EINVAL; - } - -- for(lpc = 0; lpc < DIMOF(vfields); lpc++) { -- crm_element_value_int(tmp, vfields[lpc], &(add[lpc])); -- crm_trace("Got %d for add[%s]", add[lpc], vfields[lpc]); -+ if (tmp) { -+ for(lpc = 0; lpc < DIMOF(vfields); lpc++) { -+ crm_element_value_int(tmp, vfields[lpc], &(add[lpc])); -+ crm_trace("Got %d for add[%s]", add[lpc], vfields[lpc]); -+ } - } - - return pcmk_ok; -diff --git a/lib/pengine/common.c b/lib/pengine/common.c -index e98e1d3..e5e4ea7 100644 ---- a/lib/pengine/common.c -+++ b/lib/pengine/common.c -@@ -106,6 +106,8 @@ pe_cluster_option pe_opts[] = { - "Action to send to STONITH device", NULL }, - { "stonith-timeout", NULL, "time", NULL, "60s", &check_timer, - "How long to wait for the STONITH action to complete", NULL }, -+ { XML_ATTR_HAVE_WATCHDOG, NULL, "boolean", NULL, "false", &check_boolean, -+ "Enable watchdog integration", "Set automatically by the cluster if SBD is detected. User configured values are ignored." }, - { "startup-fencing", "startup_fencing", "boolean", NULL, "true", &check_boolean, - "STONITH unseen nodes", "Advanced Use Only! Not using the default is very unsafe!" }, - -diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c -index 7127c12..a19bdff 100644 ---- a/lib/pengine/unpack.c -+++ b/lib/pengine/unpack.c -@@ -140,6 +140,12 @@ unpack_config(xmlNode * config, pe_working_set_t * data_set) - crm_info("Startup probes: disabled (dangerous)"); - } - -+ value = pe_pref(data_set->config_hash, XML_ATTR_HAVE_WATCHDOG); -+ if (value && crm_is_true(value)) { -+ crm_notice("Relying on watchdog integration for fencing"); -+ set_bit(data_set->flags, pe_flag_have_stonith_resource); -+ } -+ - value = pe_pref(data_set->config_hash, "stonith-timeout"); - data_set->stonith_timeout = crm_get_msec(value); - crm_debug("STONITH timeout: %d", data_set->stonith_timeout); -@@ -294,6 +300,7 @@ create_node(const char *id, const char *uname, const char *type, const char *sco - new_node->details->uname = uname; - new_node->details->online = FALSE; - new_node->details->shutdown = FALSE; -+ new_node->details->rsc_discovery_enabled = TRUE; - new_node->details->running_rsc = NULL; - new_node->details->type = node_ping; - -@@ -308,6 +315,13 @@ create_node(const char *id, const char *uname, const char *type, const char *sco - new_node->details->attrs = g_hash_table_new_full(crm_str_hash, g_str_equal, - g_hash_destroy_str, - g_hash_destroy_str); -+ -+ if (is_remote_node(new_node)) { -+ g_hash_table_insert(new_node->details->attrs, strdup("#kind"), strdup("remote")); -+ } else { -+ g_hash_table_insert(new_node->details->attrs, strdup("#kind"), strdup("cluster")); -+ } -+ - new_node->details->utilization = - g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, - g_hash_destroy_str); -@@ -657,7 +671,10 @@ link_rsc2remotenode(pe_working_set_t *data_set, resource_t *new_rsc) - * as cluster nodes. */ - if (new_rsc->container == NULL) { - handle_startup_fencing(data_set, remote_node); -- return; -+ } else { -+ /* At this point we know if the remote node is a container or baremetal -+ * remote node, update the #kind attribute if a container is involved */ -+ g_hash_table_replace(remote_node->details->attrs, strdup("#kind"), strdup("container")); - } - } - -@@ -723,10 +740,12 @@ unpack_resources(xmlNode * xml_resources, pe_working_set_t * data_set) - } - - data_set->resources = g_list_sort(data_set->resources, sort_rsc_priority); -+ if (is_set(data_set->flags, pe_flag_quick_location)) { -+ /* Ignore */ -+ -+ } else if (is_set(data_set->flags, pe_flag_stonith_enabled) -+ && is_set(data_set->flags, pe_flag_have_stonith_resource) == FALSE) { - -- if (is_not_set(data_set->flags, pe_flag_quick_location) -- && is_set(data_set->flags, pe_flag_stonith_enabled) -- && is_set(data_set->flags, pe_flag_have_stonith_resource) == FALSE) { - crm_config_err("Resource start-up disabled since no STONITH resources have been defined"); - crm_config_err("Either configure some or disable STONITH with the stonith-enabled option"); - crm_config_err("NOTE: Clusters with shared data need STONITH to ensure data integrity"); -@@ -988,6 +1007,7 @@ unpack_status(xmlNode * status, pe_working_set_t * data_set) - - if (crm_str_eq((const char *)state->name, XML_CIB_TAG_STATE, TRUE)) { - xmlNode *attrs = NULL; -+ const char *resource_discovery_enabled = NULL; - - id = crm_element_value(state, XML_ATTR_ID); - uname = crm_element_value(state, XML_ATTR_UNAME); -@@ -1027,6 +1047,12 @@ unpack_status(xmlNode * status, pe_working_set_t * data_set) - this_node->details->maintenance = TRUE; - } - -+ resource_discovery_enabled = g_hash_table_lookup(this_node->details->attrs, XML_NODE_ATTR_RSC_DISCOVERY); -+ if (resource_discovery_enabled && !crm_is_true(resource_discovery_enabled)) { -+ crm_warn("ignoring %s attribute on node %s, disabling resource discovery is not allowed on cluster nodes", -+ XML_NODE_ATTR_RSC_DISCOVERY, this_node->details->uname); -+ } -+ - crm_trace("determining node state"); - determine_online_status(state, this_node, data_set); - -@@ -1102,6 +1128,7 @@ unpack_remote_status(xmlNode * status, pe_working_set_t * data_set) - - /* process attributes */ - for (state = __xml_first_child(status); state != NULL; state = __xml_next(state)) { -+ const char *resource_discovery_enabled = NULL; - xmlNode *attrs = NULL; - if (crm_str_eq((const char *)state->name, XML_CIB_TAG_STATE, TRUE) == FALSE) { - continue; -@@ -1125,6 +1152,26 @@ unpack_remote_status(xmlNode * status, pe_working_set_t * data_set) - crm_info("Node %s is in standby-mode", this_node->details->uname); - this_node->details->standby = TRUE; - } -+ -+ if (crm_is_true(g_hash_table_lookup(this_node->details->attrs, "maintenance"))) { -+ crm_info("Node %s is in maintenance-mode", this_node->details->uname); -+ this_node->details->maintenance = TRUE; -+ } -+ -+ resource_discovery_enabled = g_hash_table_lookup(this_node->details->attrs, XML_NODE_ATTR_RSC_DISCOVERY); -+ if (resource_discovery_enabled && !crm_is_true(resource_discovery_enabled)) { -+ if (is_baremetal_remote_node(this_node) && is_not_set(data_set->flags, pe_flag_stonith_enabled)) { -+ crm_warn("ignoring %s attribute on baremetal remote node %s, disabling resource discovery requires stonith to be enabled.", -+ XML_NODE_ATTR_RSC_DISCOVERY, this_node->details->uname); -+ } else { -+ /* if we're here, this is either a baremetal node and fencing is enabled, -+ * or this is a container node which we don't care if fencing is enabled -+ * or not on. container nodes are 'fenced' by recovering the container resource -+ * regardless of whether fencing is enabled. */ -+ crm_info("Node %s has resource discovery disabled", this_node->details->uname); -+ this_node->details->rsc_discovery_enabled = FALSE; -+ } -+ } - } - - /* process node rsc status */ -@@ -1858,7 +1905,7 @@ process_rsc_state(resource_t * rsc, node_t * node, - * reconnect to the remote-node in this transition or not. */ - if (is_set(rsc->flags, pe_rsc_failed) && rsc->is_remote_node) { - node_t *tmpnode = pe_find_node(data_set->nodes, rsc->id); -- if (tmpnode->details->unclean) { -+ if (tmpnode && tmpnode->details->unclean) { - tmpnode->details->unseen = FALSE; - } - } -@@ -3050,8 +3097,7 @@ add_node_attrs(xmlNode * xml_obj, node_t * node, gboolean overwrite, pe_working_ - - g_hash_table_insert(node->details->attrs, - strdup("#uname"), strdup(node->details->uname)); -- g_hash_table_insert(node->details->attrs, -- strdup("#kind"), strdup(node->details->remote_rsc?"container":"cluster")); -+ - g_hash_table_insert(node->details->attrs, strdup("#" XML_ATTR_ID), strdup(node->details->id)); - if (safe_str_eq(node->details->id, data_set->dc_uuid)) { - data_set->dc_node = node; -diff --git a/lib/services/dbus.c b/lib/services/dbus.c -index 587589c..f4632f2 100644 ---- a/lib/services/dbus.c -+++ b/lib/services/dbus.c -@@ -355,6 +355,11 @@ pcmk_dbus_get_property( - DBusMessage *reply = pcmk_dbus_send_recv(msg, connection, NULL); - - output = pcmk_dbus_lookup_result(reply, query_data); -+ free(query_data->target); -+ free(query_data->object); -+ free(query_data->name); -+ free(query_data); -+ - if(reply) { - dbus_message_unref(reply); - } -diff --git a/lib/services/services.c b/lib/services/services.c -index 8590b56..753e257 100644 ---- a/lib/services/services.c -+++ b/lib/services/services.c -@@ -313,6 +313,7 @@ services_action_free(svc_action_t * op) - - if (op->opaque->repeat_timer) { - g_source_remove(op->opaque->repeat_timer); -+ op->opaque->repeat_timer = 0; - } - if (op->opaque->stderr_gsource) { - mainloop_del_fd(op->opaque->stderr_gsource); -@@ -425,6 +426,7 @@ services_action_kick(const char *name, const char *action, int interval /* ms */ - } else { - if (op->opaque->repeat_timer) { - g_source_remove(op->opaque->repeat_timer); -+ op->opaque->repeat_timer = 0; - } - recurring_action_timer(op); - return TRUE; -@@ -459,6 +461,7 @@ handle_duplicate_recurring(svc_action_t * op, void (*action_callback) (svc_actio - if (dup->pid != 0) { - if (op->opaque->repeat_timer) { - g_source_remove(op->opaque->repeat_timer); -+ op->opaque->repeat_timer = 0; - } - recurring_action_timer(dup); - } -diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c -index 961ff18..2279e4e 100644 ---- a/lib/services/services_linux.c -+++ b/lib/services/services_linux.c -@@ -227,6 +227,7 @@ recurring_action_timer(gpointer data) - op->stdout_data = NULL; - free(op->stderr_data); - op->stderr_data = NULL; -+ op->opaque->repeat_timer = 0; - - services_action_async(op, NULL); - return FALSE; -diff --git a/lib/services/systemd.c b/lib/services/systemd.c -index c967430..9a7b078 100644 ---- a/lib/services/systemd.c -+++ b/lib/services/systemd.c -@@ -303,10 +303,14 @@ systemd_unit_listall(void) - gboolean - systemd_unit_exists(const char *name) - { -+ char *unit = NULL; -+ - /* Note: Makes a blocking dbus calls - * Used by resources_find_service_class() when resource class=service - */ -- if(systemd_unit_by_name(name, NULL)) { -+ unit = systemd_unit_by_name(name, NULL); -+ if(unit) { -+ free(unit); - return TRUE; - } - return FALSE; -@@ -542,9 +546,15 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - - reply = pcmk_dbus_send_recv(msg, systemd_proxy, &error); - systemd_exec_result(reply, op); -+ - if(reply) { - dbus_message_unref(reply); - } -+ if(msg) { -+ dbus_message_unref(msg); -+ } -+ -+ return FALSE; - } - - if(msg) { -@@ -563,6 +573,8 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) - gboolean - systemd_unit_exec(svc_action_t * op) - { -+ char *unit = NULL; -+ - CRM_ASSERT(op); - CRM_ASSERT(systemd_init()); - op->rc = PCMK_OCF_UNKNOWN_ERROR; -@@ -580,7 +592,9 @@ systemd_unit_exec(svc_action_t * op) - return TRUE; - } - -- systemd_unit_by_name(op->agent, op); -+ unit = systemd_unit_by_name(op->agent, op); -+ free(unit); -+ - if (op->synchronous == FALSE) { - return TRUE; - } -diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c -index 7075b9f..d3ede18 100644 ---- a/lrmd/lrmd.c -+++ b/lrmd/lrmd.c -@@ -837,7 +837,9 @@ action_complete(svc_action_t * action) - } - - cmd_reset(cmd); -- rsc->active = NULL; -+ if(rsc) { -+ rsc->active = NULL; -+ } - schedule_lrmd_cmd(rsc, cmd); - return; - -diff --git a/mcp/pacemaker.c b/mcp/pacemaker.c -index ba3c88f..c7852c3 100644 ---- a/mcp/pacemaker.c -+++ b/mcp/pacemaker.c -@@ -1038,6 +1038,10 @@ main(int argc, char **argv) - crm_exit(ENOPROTOOPT); - } - -+ if(pcmk_locate_sbd() > 0) { -+ setenv("PCMK_watchdog", "true", 1); -+ } -+ - find_and_track_existing_processes(); - - cluster.destroy = mcp_cpg_destroy; -diff --git a/mcp/pacemaker.service.in b/mcp/pacemaker.service.in -index b9f3336..7871167 100644 ---- a/mcp/pacemaker.service.in -+++ b/mcp/pacemaker.service.in -@@ -18,6 +18,7 @@ KillMode=process - NotifyAccess=main - SysVStartPriority=99 - EnvironmentFile=-@sysconfdir@/sysconfig/pacemaker -+EnvironmentFile=-@sysconfdir@/sysconfig/sbd - SuccessExitStatus=100 - - ExecStart=@sbindir@/pacemakerd -f -diff --git a/pengine/allocate.c b/pengine/allocate.c -index 8d02d9b..e708e26 100644 ---- a/pengine/allocate.c -+++ b/pengine/allocate.c -@@ -755,7 +755,7 @@ apply_system_health(pe_working_set_t * data_set) - for (; gIter2 != NULL; gIter2 = gIter2->next) { - resource_t *rsc = (resource_t *) gIter2->data; - -- rsc2node_new(health_strategy, rsc, system_health, node, data_set); -+ rsc2node_new(health_strategy, rsc, system_health, NULL, node, data_set); - } - } - -@@ -861,6 +861,10 @@ probe_resources(pe_working_set_t * data_set) - /* TODO enable container node probes once ordered probing is implemented. */ - continue; - -+ } else if (node->details->rsc_discovery_enabled == FALSE) { -+ /* resource discovery is disabled for this node */ -+ continue; -+ - } else if (probe_complete == NULL) { - probe_complete = get_pseudo_op(CRM_OP_PROBED, data_set); - if (is_set(data_set->flags, pe_flag_have_remote_nodes)) { -diff --git a/pengine/constraints.c b/pengine/constraints.c -index 1aa848e..88e382b 100644 ---- a/pengine/constraints.c -+++ b/pengine/constraints.c -@@ -658,6 +658,7 @@ unpack_rsc_location(xmlNode * xml_obj, resource_t * rsc_lh, const char * role, - const char *id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE); - const char *id = crm_element_value(xml_obj, XML_ATTR_ID); - const char *node = crm_element_value(xml_obj, XML_CIB_TAG_NODE); -+ const char *discovery = crm_element_value(xml_obj, XML_LOCATION_ATTR_DISCOVERY); - - if (rsc_lh == NULL) { - /* only a warn as BSC adds the constraint then the resource */ -@@ -676,7 +677,7 @@ unpack_rsc_location(xmlNode * xml_obj, resource_t * rsc_lh, const char * role, - if (!match) { - return FALSE; - } -- location = rsc2node_new(id, rsc_lh, score_i, match, data_set); -+ location = rsc2node_new(id, rsc_lh, score_i, discovery, match, data_set); - - } else { - xmlNode *rule_xml = NULL; -@@ -720,6 +721,7 @@ unpack_rsc_location(xmlNode * xml_obj, resource_t * rsc_lh, const char * role, - } - } - } -+ - return TRUE; - } - -@@ -958,7 +960,7 @@ generate_location_rule(resource_t * rsc, xmlNode * rule_xml, pe_working_set_t * - do_and = FALSE; - } - -- location_rule = rsc2node_new(rule_id, rsc, 0, NULL, data_set); -+ location_rule = rsc2node_new(rule_id, rsc, 0, NULL, NULL, data_set); - - if (location_rule == NULL) { - return NULL; -diff --git a/pengine/native.c b/pengine/native.c -index 5db8c60..0020344 100644 ---- a/pengine/native.c -+++ b/pengine/native.c -@@ -2097,9 +2097,14 @@ native_rsc_location(resource_t * rsc, rsc_to_node_t * constraint) - other_node->weight = merge_weights(other_node->weight, node->weight); - - } else { -- node_t *new_node = node_copy(node); -+ other_node = node_copy(node); - -- g_hash_table_insert(rsc->allowed_nodes, (gpointer) new_node->details->id, new_node); -+ g_hash_table_insert(rsc->allowed_nodes, (gpointer) other_node->details->id, other_node); -+ } -+ -+ if (other_node->rsc_discover_mode < constraint->discover_mode) { -+ /* exclusive > never > always... always is default */ -+ other_node->rsc_discover_mode = constraint->discover_mode; - } - } - -@@ -2704,6 +2709,7 @@ native_create_probe(resource_t * rsc, node_t * node, action_t * complete, - char *key = NULL; - action_t *probe = NULL; - node_t *running = NULL; -+ node_t *allowed = NULL; - resource_t *top = uber_parent(rsc); - - static const char *rc_master = NULL; -@@ -2780,6 +2786,23 @@ native_create_probe(resource_t * rsc, node_t * node, action_t * complete, - return FALSE; - } - -+ allowed = g_hash_table_lookup(rsc->allowed_nodes, node->details->id); -+ if (rsc->exclusive_discover || top->exclusive_discover) { -+ if (allowed == NULL) { -+ /* exclusive discover is enabled and this node is not in the allowed list. */ -+ return FALSE; -+ } else if (allowed->rsc_discover_mode != discover_exclusive) { -+ /* exclusive discover is enabled and this node is not marked -+ * as a node this resource should be discovered on */ -+ return FALSE; -+ } -+ } -+ if (allowed && allowed->rsc_discover_mode == discover_never) { -+ /* this resource is marked as not needing to be discovered on this node */ -+ return FALSE; -+ } -+ -+ - key = generate_op_key(rsc->id, RSC_STATUS, 0); - probe = custom_action(rsc, key, RSC_STATUS, node, FALSE, TRUE, data_set); - update_action_flags(probe, pe_action_optional | pe_action_clear); -diff --git a/pengine/pengine.h b/pengine/pengine.h -index 653fadf..87fa150 100644 ---- a/pengine/pengine.h -+++ b/pengine/pengine.h -@@ -75,11 +75,18 @@ struct rsc_ticket_s { - int role_lh; - }; - -+enum rsc_discover_e { -+ discover_always = 0, -+ discover_never, -+ discover_exclusive, -+}; -+ - struct rsc_to_node_s { - const char *id; - resource_t *rsc_lh; - - enum rsc_role_e role_filter; -+ enum rsc_discover_e discover_mode; - GListPtr node_list_rh; /* node_t* */ - }; - -diff --git a/pengine/regression.sh b/pengine/regression.sh -index bdc7d3a..a9a5605 100755 ---- a/pengine/regression.sh -+++ b/pengine/regression.sh -@@ -768,5 +768,10 @@ do_test remote-disable "Disable a baremetal remote-node" - do_test remote-orphaned "Properly shutdown orphaned connection resource" - do_test remote-recover "Recover connection resource after cluster-node fails." - do_test remote-stale-node-entry "Make sure we properly handle leftover remote-node entries in the node section" -+ -+echo "" -+do_test resource-discovery "Exercises resource-discovery location constraint option." -+do_test rsc-discovery-per-node "Disable resource discovery per node" -+ - echo "" - test_results -diff --git a/pengine/test10/remote-disable.dot b/pengine/test10/remote-disable.dot -index 2e21fef..fbcea60 100644 ---- a/pengine/test10/remote-disable.dot -+++ b/pengine/test10/remote-disable.dot -@@ -1,8 +1,4 @@ - digraph "g" { --"FAKE2_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] --"FAKE2_start_0 18builder" -> "FAKE2_monitor_60000 18builder" [ style = bold] --"FAKE2_start_0 18builder" [ style=bold color="green" fontcolor="black"] --"FAKE2_stop_0 remote1" -> "FAKE2_start_0 18builder" [ style = bold] - "FAKE2_stop_0 remote1" -> "all_stopped" [ style = bold] - "FAKE2_stop_0 remote1" -> "remote1_stop_0 18builder" [ style = bold] - "FAKE2_stop_0 remote1" [ style=bold color="green" fontcolor="black"] -diff --git a/pengine/test10/remote-disable.exp b/pengine/test10/remote-disable.exp -index 3273bb2..99c1c55 100644 ---- a/pengine/test10/remote-disable.exp -+++ b/pengine/test10/remote-disable.exp -@@ -14,32 +14,6 @@ - - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - - - -@@ -47,7 +21,7 @@ - - - -- -+ - - - -diff --git a/pengine/test10/remote-disable.scores b/pengine/test10/remote-disable.scores -index 4efd7d8..d66861f 100644 ---- a/pengine/test10/remote-disable.scores -+++ b/pengine/test10/remote-disable.scores -@@ -3,9 +3,9 @@ native_color: FAKE1 allocation score on 18builder: 0 - native_color: FAKE1 allocation score on 18node1: 0 - native_color: FAKE1 allocation score on 18node2: 0 - native_color: FAKE1 allocation score on remote1: 0 --native_color: FAKE2 allocation score on 18builder: 0 --native_color: FAKE2 allocation score on 18node1: 0 --native_color: FAKE2 allocation score on 18node2: 0 -+native_color: FAKE2 allocation score on 18builder: -INFINITY -+native_color: FAKE2 allocation score on 18node1: -INFINITY -+native_color: FAKE2 allocation score on 18node2: -INFINITY - native_color: FAKE2 allocation score on remote1: 0 - native_color: FAKE3 allocation score on 18builder: 0 - native_color: FAKE3 allocation score on 18node1: 0 -diff --git a/pengine/test10/remote-disable.summary b/pengine/test10/remote-disable.summary -index 57b06fe..0627647 100644 ---- a/pengine/test10/remote-disable.summary -+++ b/pengine/test10/remote-disable.summary -@@ -12,14 +12,12 @@ RemoteOnline: [ remote1 ] - - Transition Summary: - * Stop remote1 (18builder) -- * Move FAKE2 (Started remote1 -> 18builder) -+ * Stop FAKE2 (remote1) - - Executing cluster transition: - * Resource action: FAKE2 stop on remote1 - * Resource action: remote1 stop on 18builder -- * Resource action: FAKE2 start on 18builder - * Pseudo action: all_stopped -- * Resource action: FAKE2 monitor=60000 on 18builder - - Revised cluster status: - Online: [ 18builder 18node1 18node2 ] -@@ -28,7 +26,7 @@ RemoteOFFLINE: [ remote1 ] - shooter (stonith:fence_xvm): Started 18node1 - remote1 (ocf::pacemaker:remote): Stopped - FAKE1 (ocf::heartbeat:Dummy): Started 18node2 -- FAKE2 (ocf::heartbeat:Dummy): Started 18builder -+ FAKE2 (ocf::heartbeat:Dummy): Stopped - FAKE3 (ocf::heartbeat:Dummy): Started 18builder - FAKE4 (ocf::heartbeat:Dummy): Started 18node1 - -diff --git a/pengine/test10/remote-disable.xml b/pengine/test10/remote-disable.xml -index eae0055..1637801 100644 ---- a/pengine/test10/remote-disable.xml -+++ b/pengine/test10/remote-disable.xml -@@ -52,7 +52,13 @@ - - - -- -+ -+ -+ -+ -+ -+ -+ - - - -diff --git a/pengine/test10/resource-discovery.dot b/pengine/test10/resource-discovery.dot -new file mode 100644 -index 0000000..efb2434 ---- /dev/null -+++ b/pengine/test10/resource-discovery.dot -@@ -0,0 +1,185 @@ -+ digraph "g" { -+"FAKE1_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKE1_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE1_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE1_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE1_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE1_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE1_start_0 18node2" -> "FAKE1_monitor_60000 18node2" [ style = bold] -+"FAKE1_start_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_start_0 18node3" -> "FAKE2_monitor_60000 18node3" [ style = bold] -+"FAKE2_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_stop_0 18node2" -> "FAKE2_start_0 18node3" [ style = bold] -+"FAKE2_stop_0 18node2" -> "all_stopped" [ style = bold] -+"FAKE2_stop_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE3_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE3_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE3_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE3_start_0 18node3" -> "FAKE3_monitor_60000 18node3" [ style = bold] -+"FAKE3_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE3_stop_0 18builder" -> "FAKE3_start_0 18node3" [ style = bold] -+"FAKE3_stop_0 18builder" -> "all_stopped" [ style = bold] -+"FAKE3_stop_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE4_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE4_start_0 18node4" -> "FAKE4_monitor_60000 18node4" [ style = bold] -+"FAKE4_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE4_stop_0 18node1" -> "FAKE4_start_0 18node4" [ style = bold] -+"FAKE4_stop_0 18node1" -> "all_stopped" [ style = bold] -+"FAKE4_stop_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKE5_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE5_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE5_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE5_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE5_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 remote1" -> "probe_complete remote1" [ style = bold] -+"FAKE5_monitor_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE5_start_0 remote1" -> "FAKE5_monitor_60000 remote1" [ style = bold] -+"FAKE5_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:0_start_0 18builder" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:1_start_0 18node1" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:2_start_0 18node2" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:3_start_0 18node4" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:5_start_0 18node3" [ style = bold] -+"FAKECLONE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE1:0_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:0_start_0 18builder" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:0_start_0 18builder" -> "FAKECLONE1:0_monitor_60000 18builder" [ style = bold] -+"FAKECLONE1:0_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_start_0 18node1" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:1_start_0 18node1" -> "FAKECLONE1:1_monitor_60000 18node1" [ style = bold] -+"FAKECLONE1:1_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:2_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:2_start_0 18node2" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:2_start_0 18node2" -> "FAKECLONE1:2_monitor_60000 18node2" [ style = bold] -+"FAKECLONE1:2_start_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:3_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:3_start_0 18node4" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:3_start_0 18node4" -> "FAKECLONE1:3_monitor_60000 18node4" [ style = bold] -+"FAKECLONE1:3_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:4_monitor_0 remote1" -> "probe_complete remote1" [ style = bold] -+"FAKECLONE1:4_monitor_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:4_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:4_start_0 remote1" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:4_start_0 remote1" -> "FAKECLONE1:4_monitor_60000 remote1" [ style = bold] -+"FAKECLONE1:4_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:5_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:5_start_0 18node3" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:5_start_0 18node3" -> "FAKECLONE1:5_monitor_60000 18node3" [ style = bold] -+"FAKECLONE1:5_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:0_start_0 18builder" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:1_start_0 18node1" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:2_start_0 18node2" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:3_start_0 18node4" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:5_start_0 18node3" [ style = bold] -+"FAKECLONE2-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE2:0_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKECLONE2:0_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_start_0 18builder" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:0_start_0 18builder" -> "FAKECLONE2:0_monitor_60000 18builder" [ style = bold] -+"FAKECLONE2:0_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:1_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKECLONE2:1_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:1_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:1_start_0 18node1" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:1_start_0 18node1" -> "FAKECLONE2:1_monitor_60000 18node1" [ style = bold] -+"FAKECLONE2:1_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:2_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:2_start_0 18node2" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:2_start_0 18node2" -> "FAKECLONE2:2_monitor_60000 18node2" [ style = bold] -+"FAKECLONE2:2_start_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:3_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKECLONE2:3_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:3_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:3_start_0 18node4" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:3_start_0 18node4" -> "FAKECLONE2:3_monitor_60000 18node4" [ style = bold] -+"FAKECLONE2:3_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:4_monitor_0 remote1" -> "probe_complete remote1" [ style = bold] -+"FAKECLONE2:4_monitor_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:4_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:4_start_0 remote1" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:4_start_0 remote1" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] -+"FAKECLONE2:4_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:5_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKECLONE2:5_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:5_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:5_start_0 18node3" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:5_start_0 18node3" -> "FAKECLONE2:5_monitor_60000 18node3" [ style = bold] -+"FAKECLONE2:5_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"probe_complete 18builder" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18builder" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node1" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node1" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node2" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node2" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node3" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node3" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node4" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node4" [ style=bold color="green" fontcolor="black"] -+"probe_complete remote1" -> "probe_complete" [ style = bold] -+"probe_complete remote1" [ style=bold color="green" fontcolor="black"] -+"probe_complete" -> "FAKE1_start_0 18node2" [ style = bold] -+"probe_complete" -> "FAKE2_stop_0 18node2" [ style = bold] -+"probe_complete" -> "FAKE3_start_0 18node3" [ style = bold] -+"probe_complete" -> "FAKE3_stop_0 18builder" [ style = bold] -+"probe_complete" -> "FAKE4_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKE4_stop_0 18node1" [ style = bold] -+"probe_complete" -> "FAKE5_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:0_start_0 18builder" [ style = bold] -+"probe_complete" -> "FAKECLONE1:1_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:2_start_0 18node2" [ style = bold] -+"probe_complete" -> "FAKECLONE1:3_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:5_start_0 18node3" [ style = bold] -+"probe_complete" -> "FAKECLONE2:0_start_0 18builder" [ style = bold] -+"probe_complete" -> "FAKECLONE2:1_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKECLONE2:2_start_0 18node2" [ style = bold] -+"probe_complete" -> "FAKECLONE2:3_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKECLONE2:5_start_0 18node3" [ style = bold] -+"probe_complete" [ style=bold color="green" fontcolor="orange"] -+"probe_nodes_complete" -> "remote1_start_0 18builder" [ style = bold] -+"probe_nodes_complete" [ style=bold color="green" fontcolor="orange"] -+"remote1_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"remote1_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"remote1_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"remote1_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"remote1_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"remote1_start_0 18builder" -> "FAKE5_monitor_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKE5_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKE5_start_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE1:4_monitor_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE1:4_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE2:4_monitor_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "remote1_monitor_60000 18builder" [ style = bold] -+"remote1_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"shooter_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"shooter_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/resource-discovery.exp b/pengine/test10/resource-discovery.exp -new file mode 100644 -index 0000000..2770f4e ---- /dev/null -+++ b/pengine/test10/resource-discovery.exp -@@ -0,0 +1,1041 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/resource-discovery.scores b/pengine/test10/resource-discovery.scores -new file mode 100644 -index 0000000..e1fa78e ---- /dev/null -+++ b/pengine/test10/resource-discovery.scores -@@ -0,0 +1,199 @@ -+Allocation scores: -+clone_color: FAKECLONE1-clone allocation score on 18builder: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node1: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node2: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node3: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node4: 0 -+clone_color: FAKECLONE1-clone allocation score on remote1: 0 -+clone_color: FAKECLONE1:0 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:0 allocation score on remote1: 0 -+clone_color: FAKECLONE1:1 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:1 allocation score on remote1: 0 -+clone_color: FAKECLONE1:2 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:2 allocation score on remote1: 0 -+clone_color: FAKECLONE1:3 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:3 allocation score on remote1: 0 -+clone_color: FAKECLONE1:4 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:4 allocation score on remote1: 0 -+clone_color: FAKECLONE1:5 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:5 allocation score on remote1: 0 -+clone_color: FAKECLONE2-clone allocation score on 18builder: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node1: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node2: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node3: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node4: 0 -+clone_color: FAKECLONE2-clone allocation score on remote1: 0 -+clone_color: FAKECLONE2:0 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:0 allocation score on remote1: 0 -+clone_color: FAKECLONE2:1 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:1 allocation score on remote1: 0 -+clone_color: FAKECLONE2:2 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:2 allocation score on remote1: 0 -+clone_color: FAKECLONE2:3 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:3 allocation score on remote1: 0 -+clone_color: FAKECLONE2:4 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:4 allocation score on remote1: 0 -+clone_color: FAKECLONE2:5 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:5 allocation score on remote1: 0 -+native_color: FAKE1 allocation score on 18builder: 0 -+native_color: FAKE1 allocation score on 18node1: 0 -+native_color: FAKE1 allocation score on 18node2: 0 -+native_color: FAKE1 allocation score on 18node3: 0 -+native_color: FAKE1 allocation score on 18node4: 0 -+native_color: FAKE1 allocation score on remote1: -INFINITY -+native_color: FAKE2 allocation score on 18builder: 0 -+native_color: FAKE2 allocation score on 18node1: 0 -+native_color: FAKE2 allocation score on 18node2: -INFINITY -+native_color: FAKE2 allocation score on 18node3: 0 -+native_color: FAKE2 allocation score on 18node4: 0 -+native_color: FAKE2 allocation score on remote1: 0 -+native_color: FAKE3 allocation score on 18builder: 0 -+native_color: FAKE3 allocation score on 18node1: 0 -+native_color: FAKE3 allocation score on 18node2: 0 -+native_color: FAKE3 allocation score on 18node3: INFINITY -+native_color: FAKE3 allocation score on 18node4: 0 -+native_color: FAKE3 allocation score on remote1: 0 -+native_color: FAKE4 allocation score on 18builder: 0 -+native_color: FAKE4 allocation score on 18node1: 0 -+native_color: FAKE4 allocation score on 18node2: 0 -+native_color: FAKE4 allocation score on 18node3: 0 -+native_color: FAKE4 allocation score on 18node4: 0 -+native_color: FAKE4 allocation score on remote1: 0 -+native_color: FAKE5 allocation score on 18builder: 0 -+native_color: FAKE5 allocation score on 18node1: 0 -+native_color: FAKE5 allocation score on 18node2: 0 -+native_color: FAKE5 allocation score on 18node3: 0 -+native_color: FAKE5 allocation score on 18node4: 0 -+native_color: FAKE5 allocation score on remote1: 0 -+native_color: FAKECLONE1:0 allocation score on 18builder: 0 -+native_color: FAKECLONE1:0 allocation score on 18node1: 0 -+native_color: FAKECLONE1:0 allocation score on 18node2: 0 -+native_color: FAKECLONE1:0 allocation score on 18node3: 0 -+native_color: FAKECLONE1:0 allocation score on 18node4: 0 -+native_color: FAKECLONE1:0 allocation score on remote1: 0 -+native_color: FAKECLONE1:1 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:1 allocation score on 18node1: 0 -+native_color: FAKECLONE1:1 allocation score on 18node2: 0 -+native_color: FAKECLONE1:1 allocation score on 18node3: 0 -+native_color: FAKECLONE1:1 allocation score on 18node4: 0 -+native_color: FAKECLONE1:1 allocation score on remote1: 0 -+native_color: FAKECLONE1:2 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node2: 0 -+native_color: FAKECLONE1:2 allocation score on 18node3: 0 -+native_color: FAKECLONE1:2 allocation score on 18node4: 0 -+native_color: FAKECLONE1:2 allocation score on remote1: 0 -+native_color: FAKECLONE1:3 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node3: 0 -+native_color: FAKECLONE1:3 allocation score on 18node4: 0 -+native_color: FAKECLONE1:3 allocation score on remote1: 0 -+native_color: FAKECLONE1:4 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:4 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:4 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:4 allocation score on 18node3: 0 -+native_color: FAKECLONE1:4 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE1:4 allocation score on remote1: 0 -+native_color: FAKECLONE1:5 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE1:5 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:5 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:5 allocation score on 18node3: 0 -+native_color: FAKECLONE1:5 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE1:5 allocation score on remote1: -INFINITY -+native_color: FAKECLONE2:0 allocation score on 18builder: 0 -+native_color: FAKECLONE2:0 allocation score on 18node1: 0 -+native_color: FAKECLONE2:0 allocation score on 18node2: 0 -+native_color: FAKECLONE2:0 allocation score on 18node3: 0 -+native_color: FAKECLONE2:0 allocation score on 18node4: 0 -+native_color: FAKECLONE2:0 allocation score on remote1: 0 -+native_color: FAKECLONE2:1 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE2:1 allocation score on 18node1: 0 -+native_color: FAKECLONE2:1 allocation score on 18node2: 0 -+native_color: FAKECLONE2:1 allocation score on 18node3: 0 -+native_color: FAKECLONE2:1 allocation score on 18node4: 0 -+native_color: FAKECLONE2:1 allocation score on remote1: 0 -+native_color: FAKECLONE2:2 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE2:2 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:2 allocation score on 18node2: 0 -+native_color: FAKECLONE2:2 allocation score on 18node3: 0 -+native_color: FAKECLONE2:2 allocation score on 18node4: 0 -+native_color: FAKECLONE2:2 allocation score on remote1: 0 -+native_color: FAKECLONE2:3 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE2:3 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:3 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:3 allocation score on 18node3: 0 -+native_color: FAKECLONE2:3 allocation score on 18node4: 0 -+native_color: FAKECLONE2:3 allocation score on remote1: 0 -+native_color: FAKECLONE2:4 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE2:4 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:4 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:4 allocation score on 18node3: 0 -+native_color: FAKECLONE2:4 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE2:4 allocation score on remote1: 0 -+native_color: FAKECLONE2:5 allocation score on 18builder: -INFINITY -+native_color: FAKECLONE2:5 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:5 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:5 allocation score on 18node3: 0 -+native_color: FAKECLONE2:5 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE2:5 allocation score on remote1: -INFINITY -+native_color: remote1 allocation score on 18builder: 0 -+native_color: remote1 allocation score on 18node1: 0 -+native_color: remote1 allocation score on 18node2: 0 -+native_color: remote1 allocation score on 18node3: 0 -+native_color: remote1 allocation score on 18node4: 0 -+native_color: remote1 allocation score on remote1: -INFINITY -+native_color: shooter allocation score on 18builder: 0 -+native_color: shooter allocation score on 18node1: 0 -+native_color: shooter allocation score on 18node2: 0 -+native_color: shooter allocation score on 18node3: 0 -+native_color: shooter allocation score on 18node4: 0 -+native_color: shooter allocation score on remote1: -INFINITY -diff --git a/pengine/test10/resource-discovery.summary b/pengine/test10/resource-discovery.summary -new file mode 100644 -index 0000000..af0e5b3 ---- /dev/null -+++ b/pengine/test10/resource-discovery.summary -@@ -0,0 +1,124 @@ -+ -+Current cluster status: -+Online: [ 18builder 18node1 18node2 18node3 18node4 ] -+RemoteOFFLINE: [ remote1 ] -+ -+ shooter (stonith:fence_xvm): Started 18node1 -+ remote1 (ocf::pacemaker:remote): Stopped -+ FAKE1 (ocf::heartbeat:Dummy): Stopped -+ FAKE2 (ocf::heartbeat:Dummy): Started 18node2 -+ FAKE3 (ocf::heartbeat:Dummy): Started 18builder -+ FAKE4 (ocf::heartbeat:Dummy): Started 18node1 -+ FAKE5 (ocf::heartbeat:Dummy): Stopped -+ Clone Set: FAKECLONE1-clone [FAKECLONE1] -+ Stopped: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Clone Set: FAKECLONE2-clone [FAKECLONE2] -+ Stopped: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ -+Transition Summary: -+ * Start remote1 (18builder) -+ * Start FAKE1 (18node2) -+ * Move FAKE2 (Started 18node2 -> 18node3) -+ * Move FAKE3 (Started 18builder -> 18node3) -+ * Move FAKE4 (Started 18node1 -> 18node4) -+ * Start FAKE5 (remote1) -+ * Start FAKECLONE1:0 (18builder) -+ * Start FAKECLONE1:1 (18node1) -+ * Start FAKECLONE1:2 (18node2) -+ * Start FAKECLONE1:3 (18node4) -+ * Start FAKECLONE1:4 (remote1) -+ * Start FAKECLONE1:5 (18node3) -+ * Start FAKECLONE2:0 (18builder) -+ * Start FAKECLONE2:1 (18node1) -+ * Start FAKECLONE2:2 (18node2) -+ * Start FAKECLONE2:3 (18node4) -+ * Start FAKECLONE2:4 (remote1) -+ * Start FAKECLONE2:5 (18node3) -+ -+Executing cluster transition: -+ * Resource action: shooter monitor on 18node4 -+ * Resource action: shooter monitor on 18node3 -+ * Resource action: remote1 monitor on 18node4 -+ * Resource action: remote1 monitor on 18node3 -+ * Resource action: FAKE1 monitor on 18node4 -+ * Resource action: FAKE1 monitor on 18node3 -+ * Resource action: FAKE1 monitor on 18node2 -+ * Resource action: FAKE1 monitor on 18node1 -+ * Resource action: FAKE1 monitor on 18builder -+ * Resource action: FAKE3 monitor on 18node3 -+ * Resource action: FAKE4 monitor on 18node4 -+ * Resource action: FAKE5 monitor on 18node4 -+ * Resource action: FAKE5 monitor on 18node3 -+ * Resource action: FAKE5 monitor on 18node2 -+ * Resource action: FAKE5 monitor on 18node1 -+ * Resource action: FAKE5 monitor on 18builder -+ * Pseudo action: FAKECLONE1-clone_start_0 -+ * Resource action: FAKECLONE2:0 monitor on 18builder -+ * Resource action: FAKECLONE2:1 monitor on 18node1 -+ * Resource action: FAKECLONE2:3 monitor on 18node4 -+ * Resource action: FAKECLONE2:5 monitor on 18node3 -+ * Pseudo action: FAKECLONE2-clone_start_0 -+ * Pseudo action: probe_nodes_complete -+ * Resource action: remote1 start on 18builder -+ * Resource action: FAKE5 monitor on remote1 -+ * Resource action: FAKECLONE1:4 monitor on remote1 -+ * Resource action: FAKECLONE2:4 monitor on remote1 -+ * Pseudo action: probe_complete -+ * Resource action: remote1 monitor=60000 on 18builder -+ * Resource action: FAKE1 start on 18node2 -+ * Resource action: FAKE2 stop on 18node2 -+ * Resource action: FAKE3 stop on 18builder -+ * Resource action: FAKE4 stop on 18node1 -+ * Resource action: FAKE5 start on remote1 -+ * Resource action: FAKECLONE1:0 start on 18builder -+ * Resource action: FAKECLONE1:1 start on 18node1 -+ * Resource action: FAKECLONE1:2 start on 18node2 -+ * Resource action: FAKECLONE1:3 start on 18node4 -+ * Resource action: FAKECLONE1:4 start on remote1 -+ * Resource action: FAKECLONE1:5 start on 18node3 -+ * Pseudo action: FAKECLONE1-clone_running_0 -+ * Resource action: FAKECLONE2:0 start on 18builder -+ * Resource action: FAKECLONE2:1 start on 18node1 -+ * Resource action: FAKECLONE2:2 start on 18node2 -+ * Resource action: FAKECLONE2:3 start on 18node4 -+ * Resource action: FAKECLONE2:4 start on remote1 -+ * Resource action: FAKECLONE2:5 start on 18node3 -+ * Pseudo action: FAKECLONE2-clone_running_0 -+ * Pseudo action: all_stopped -+ * Resource action: FAKE1 monitor=60000 on 18node2 -+ * Resource action: FAKE2 start on 18node3 -+ * Resource action: FAKE3 start on 18node3 -+ * Resource action: FAKE4 start on 18node4 -+ * Resource action: FAKE5 monitor=60000 on remote1 -+ * Resource action: FAKECLONE1:0 monitor=60000 on 18builder -+ * Resource action: FAKECLONE1:1 monitor=60000 on 18node1 -+ * Resource action: FAKECLONE1:2 monitor=60000 on 18node2 -+ * Resource action: FAKECLONE1:3 monitor=60000 on 18node4 -+ * Resource action: FAKECLONE1:4 monitor=60000 on remote1 -+ * Resource action: FAKECLONE1:5 monitor=60000 on 18node3 -+ * Resource action: FAKECLONE2:0 monitor=60000 on 18builder -+ * Resource action: FAKECLONE2:1 monitor=60000 on 18node1 -+ * Resource action: FAKECLONE2:2 monitor=60000 on 18node2 -+ * Resource action: FAKECLONE2:3 monitor=60000 on 18node4 -+ * Resource action: FAKECLONE2:4 monitor=60000 on remote1 -+ * Resource action: FAKECLONE2:5 monitor=60000 on 18node3 -+ * Resource action: FAKE2 monitor=60000 on 18node3 -+ * Resource action: FAKE3 monitor=60000 on 18node3 -+ * Resource action: FAKE4 monitor=60000 on 18node4 -+ -+Revised cluster status: -+Online: [ 18builder 18node1 18node2 18node3 18node4 ] -+RemoteOnline: [ remote1 ] -+ -+ shooter (stonith:fence_xvm): Started 18node1 -+ remote1 (ocf::pacemaker:remote): Started 18builder -+ FAKE1 (ocf::heartbeat:Dummy): Started 18node2 -+ FAKE2 (ocf::heartbeat:Dummy): Started 18node3 -+ FAKE3 (ocf::heartbeat:Dummy): Started 18node3 -+ FAKE4 (ocf::heartbeat:Dummy): Started 18node4 -+ FAKE5 (ocf::heartbeat:Dummy): Started remote1 -+ Clone Set: FAKECLONE1-clone [FAKECLONE1] -+ Started: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Clone Set: FAKECLONE2-clone [FAKECLONE2] -+ Started: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ -diff --git a/pengine/test10/resource-discovery.xml b/pengine/test10/resource-discovery.xml -new file mode 100644 -index 0000000..5836804 ---- /dev/null -+++ b/pengine/test10/resource-discovery.xml -@@ -0,0 +1,185 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/rsc-discovery-per-node.dot b/pengine/test10/rsc-discovery-per-node.dot -new file mode 100644 -index 0000000..8f5889a ---- /dev/null -+++ b/pengine/test10/rsc-discovery-per-node.dot -@@ -0,0 +1,195 @@ -+ digraph "g" { -+"FAKE1_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKE1_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE1_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE1_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE1_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE1_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE1_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE1_start_0 18node2" -> "FAKE1_monitor_60000 18node2" [ style = bold] -+"FAKE1_start_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE2_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE2_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE2_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_start_0 18node3" -> "FAKE2_monitor_60000 18node3" [ style = bold] -+"FAKE2_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE2_stop_0 18node2" -> "FAKE2_start_0 18node3" [ style = bold] -+"FAKE2_stop_0 18node2" -> "all_stopped" [ style = bold] -+"FAKE2_stop_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE3_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE3_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE3_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE3_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE3_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE3_start_0 18node4" -> "FAKE3_monitor_60000 18node4" [ style = bold] -+"FAKE3_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE3_stop_0 18builder" -> "FAKE3_start_0 18node4" [ style = bold] -+"FAKE3_stop_0 18builder" -> "all_stopped" [ style = bold] -+"FAKE3_stop_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE4_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE4_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE4_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE4_start_0 remote1" -> "FAKE4_monitor_60000 remote1" [ style = bold] -+"FAKE4_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKE4_stop_0 18node1" -> "FAKE4_start_0 remote1" [ style = bold] -+"FAKE4_stop_0 18node1" -> "all_stopped" [ style = bold] -+"FAKE4_stop_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKE5_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKE5_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKE5_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKE5_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKE5_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKE5_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKE5_start_0 18builder" -> "FAKE5_monitor_60000 18builder" [ style = bold] -+"FAKE5_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:0_start_0 18node1" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:1_start_0 18node2" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:2_start_0 18node3" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:3_start_0 18node4" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] -+"FAKECLONE1-clone_start_0" -> "FAKECLONE1:5_start_0 18builder" [ style = bold] -+"FAKECLONE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE1:0_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKECLONE1:0_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:0_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:0_start_0 18node1" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:0_start_0 18node1" -> "FAKECLONE1:0_monitor_60000 18node1" [ style = bold] -+"FAKECLONE1:0_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKECLONE1:1_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:1_start_0 18node2" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:1_start_0 18node2" -> "FAKECLONE1:1_monitor_60000 18node2" [ style = bold] -+"FAKECLONE1:1_start_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:2_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKECLONE1:2_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:2_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:2_start_0 18node3" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:2_start_0 18node3" -> "FAKECLONE1:2_monitor_60000 18node3" [ style = bold] -+"FAKECLONE1:2_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:3_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKECLONE1:3_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:3_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:3_start_0 18node4" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:3_start_0 18node4" -> "FAKECLONE1:3_monitor_60000 18node4" [ style = bold] -+"FAKECLONE1:3_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:4_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:4_start_0 remote1" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:4_start_0 remote1" -> "FAKECLONE1:4_monitor_60000 remote1" [ style = bold] -+"FAKECLONE1:4_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:5_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKECLONE1:5_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:5_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE1:5_start_0 18builder" -> "FAKECLONE1-clone_running_0" [ style = bold] -+"FAKECLONE1:5_start_0 18builder" -> "FAKECLONE1:5_monitor_60000 18builder" [ style = bold] -+"FAKECLONE1:5_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2-clone_running_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:0_start_0 18node1" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:1_start_0 18node2" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:2_start_0 18node3" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:3_start_0 18node4" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"FAKECLONE2-clone_start_0" -> "FAKECLONE2:5_start_0 18builder" [ style = bold] -+"FAKECLONE2-clone_start_0" [ style=bold color="green" fontcolor="orange"] -+"FAKECLONE2:0_monitor_0 18node1" -> "probe_complete 18node1" [ style = bold] -+"FAKECLONE2:0_monitor_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_monitor_60000 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:0_start_0 18node1" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:0_start_0 18node1" -> "FAKECLONE2:0_monitor_60000 18node1" [ style = bold] -+"FAKECLONE2:0_start_0 18node1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:1_monitor_0 18node2" -> "probe_complete 18node2" [ style = bold] -+"FAKECLONE2:1_monitor_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:1_monitor_60000 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:1_start_0 18node2" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:1_start_0 18node2" -> "FAKECLONE2:1_monitor_60000 18node2" [ style = bold] -+"FAKECLONE2:1_start_0 18node2" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:2_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"FAKECLONE2:2_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:2_monitor_60000 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:2_start_0 18node3" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:2_start_0 18node3" -> "FAKECLONE2:2_monitor_60000 18node3" [ style = bold] -+"FAKECLONE2:2_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:3_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"FAKECLONE2:3_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:3_monitor_60000 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:3_start_0 18node4" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:3_start_0 18node4" -> "FAKECLONE2:3_monitor_60000 18node4" [ style = bold] -+"FAKECLONE2:3_start_0 18node4" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:4_monitor_60000 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:4_start_0 remote1" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:4_start_0 remote1" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] -+"FAKECLONE2:4_start_0 remote1" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:5_monitor_0 18builder" -> "probe_complete 18builder" [ style = bold] -+"FAKECLONE2:5_monitor_0 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:5_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"FAKECLONE2:5_start_0 18builder" -> "FAKECLONE2-clone_running_0" [ style = bold] -+"FAKECLONE2:5_start_0 18builder" -> "FAKECLONE2:5_monitor_60000 18builder" [ style = bold] -+"FAKECLONE2:5_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] -+"probe_complete 18builder" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18builder" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node1" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node1" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node2" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node2" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node3" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node3" [ style=bold color="green" fontcolor="black"] -+"probe_complete 18node4" -> "probe_nodes_complete" [ style = bold] -+"probe_complete 18node4" [ style=bold color="green" fontcolor="black"] -+"probe_complete" -> "FAKE1_start_0 18node2" [ style = bold] -+"probe_complete" -> "FAKE2_start_0 18node3" [ style = bold] -+"probe_complete" -> "FAKE2_stop_0 18node2" [ style = bold] -+"probe_complete" -> "FAKE3_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKE3_stop_0 18builder" [ style = bold] -+"probe_complete" -> "FAKE4_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKE4_stop_0 18node1" [ style = bold] -+"probe_complete" -> "FAKE5_start_0 18builder" [ style = bold] -+"probe_complete" -> "FAKECLONE1:0_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:1_start_0 18node2" [ style = bold] -+"probe_complete" -> "FAKECLONE1:2_start_0 18node3" [ style = bold] -+"probe_complete" -> "FAKECLONE1:3_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKECLONE1:5_start_0 18builder" [ style = bold] -+"probe_complete" -> "FAKECLONE2:0_start_0 18node1" [ style = bold] -+"probe_complete" -> "FAKECLONE2:1_start_0 18node2" [ style = bold] -+"probe_complete" -> "FAKECLONE2:2_start_0 18node3" [ style = bold] -+"probe_complete" -> "FAKECLONE2:3_start_0 18node4" [ style = bold] -+"probe_complete" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"probe_complete" -> "FAKECLONE2:5_start_0 18builder" [ style = bold] -+"probe_complete" [ style=bold color="green" fontcolor="orange"] -+"probe_nodes_complete" -> "remote1_start_0 18builder" [ style = bold] -+"probe_nodes_complete" [ style=bold color="green" fontcolor="orange"] -+"remote1_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"remote1_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"remote1_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"remote1_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+"remote1_monitor_60000 18builder" [ style=bold color="green" fontcolor="black"] -+"remote1_start_0 18builder" -> "FAKE4_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKE4_start_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE1:4_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE1:4_start_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE2:4_monitor_60000 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "FAKECLONE2:4_start_0 remote1" [ style = bold] -+"remote1_start_0 18builder" -> "remote1_monitor_60000 18builder" [ style = bold] -+"remote1_start_0 18builder" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_0 18node3" -> "probe_complete 18node3" [ style = bold] -+"shooter_monitor_0 18node3" [ style=bold color="green" fontcolor="black"] -+"shooter_monitor_0 18node4" -> "probe_complete 18node4" [ style = bold] -+"shooter_monitor_0 18node4" [ style=bold color="green" fontcolor="black"] -+} -diff --git a/pengine/test10/rsc-discovery-per-node.exp b/pengine/test10/rsc-discovery-per-node.exp -new file mode 100644 -index 0000000..8de04cd ---- /dev/null -+++ b/pengine/test10/rsc-discovery-per-node.exp -@@ -0,0 +1,1103 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/rsc-discovery-per-node.scores b/pengine/test10/rsc-discovery-per-node.scores -new file mode 100644 -index 0000000..a0ad11f ---- /dev/null -+++ b/pengine/test10/rsc-discovery-per-node.scores -@@ -0,0 +1,199 @@ -+Allocation scores: -+clone_color: FAKECLONE1-clone allocation score on 18builder: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node1: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node2: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node3: 0 -+clone_color: FAKECLONE1-clone allocation score on 18node4: 0 -+clone_color: FAKECLONE1-clone allocation score on remote1: 0 -+clone_color: FAKECLONE1:0 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:0 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:0 allocation score on remote1: 0 -+clone_color: FAKECLONE1:1 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:1 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:1 allocation score on remote1: 0 -+clone_color: FAKECLONE1:2 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:2 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:2 allocation score on remote1: 0 -+clone_color: FAKECLONE1:3 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:3 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:3 allocation score on remote1: 0 -+clone_color: FAKECLONE1:4 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:4 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:4 allocation score on remote1: 0 -+clone_color: FAKECLONE1:5 allocation score on 18builder: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node1: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node2: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node3: 0 -+clone_color: FAKECLONE1:5 allocation score on 18node4: 0 -+clone_color: FAKECLONE1:5 allocation score on remote1: 0 -+clone_color: FAKECLONE2-clone allocation score on 18builder: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node1: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node2: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node3: 0 -+clone_color: FAKECLONE2-clone allocation score on 18node4: 0 -+clone_color: FAKECLONE2-clone allocation score on remote1: 0 -+clone_color: FAKECLONE2:0 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:0 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:0 allocation score on remote1: 0 -+clone_color: FAKECLONE2:1 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:1 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:1 allocation score on remote1: 0 -+clone_color: FAKECLONE2:2 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:2 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:2 allocation score on remote1: 0 -+clone_color: FAKECLONE2:3 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:3 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:3 allocation score on remote1: 0 -+clone_color: FAKECLONE2:4 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:4 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:4 allocation score on remote1: 0 -+clone_color: FAKECLONE2:5 allocation score on 18builder: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node1: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node2: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node3: 0 -+clone_color: FAKECLONE2:5 allocation score on 18node4: 0 -+clone_color: FAKECLONE2:5 allocation score on remote1: 0 -+native_color: FAKE1 allocation score on 18builder: 0 -+native_color: FAKE1 allocation score on 18node1: 0 -+native_color: FAKE1 allocation score on 18node2: 0 -+native_color: FAKE1 allocation score on 18node3: 0 -+native_color: FAKE1 allocation score on 18node4: 0 -+native_color: FAKE1 allocation score on remote1: 0 -+native_color: FAKE2 allocation score on 18builder: 0 -+native_color: FAKE2 allocation score on 18node1: 0 -+native_color: FAKE2 allocation score on 18node2: 0 -+native_color: FAKE2 allocation score on 18node3: 0 -+native_color: FAKE2 allocation score on 18node4: 0 -+native_color: FAKE2 allocation score on remote1: 0 -+native_color: FAKE3 allocation score on 18builder: 0 -+native_color: FAKE3 allocation score on 18node1: 0 -+native_color: FAKE3 allocation score on 18node2: 0 -+native_color: FAKE3 allocation score on 18node3: 0 -+native_color: FAKE3 allocation score on 18node4: 0 -+native_color: FAKE3 allocation score on remote1: 0 -+native_color: FAKE4 allocation score on 18builder: 0 -+native_color: FAKE4 allocation score on 18node1: 0 -+native_color: FAKE4 allocation score on 18node2: 0 -+native_color: FAKE4 allocation score on 18node3: 0 -+native_color: FAKE4 allocation score on 18node4: 0 -+native_color: FAKE4 allocation score on remote1: 0 -+native_color: FAKE5 allocation score on 18builder: 0 -+native_color: FAKE5 allocation score on 18node1: 0 -+native_color: FAKE5 allocation score on 18node2: 0 -+native_color: FAKE5 allocation score on 18node3: 0 -+native_color: FAKE5 allocation score on 18node4: 0 -+native_color: FAKE5 allocation score on remote1: 0 -+native_color: FAKECLONE1:0 allocation score on 18builder: 0 -+native_color: FAKECLONE1:0 allocation score on 18node1: 0 -+native_color: FAKECLONE1:0 allocation score on 18node2: 0 -+native_color: FAKECLONE1:0 allocation score on 18node3: 0 -+native_color: FAKECLONE1:0 allocation score on 18node4: 0 -+native_color: FAKECLONE1:0 allocation score on remote1: 0 -+native_color: FAKECLONE1:1 allocation score on 18builder: 0 -+native_color: FAKECLONE1:1 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:1 allocation score on 18node2: 0 -+native_color: FAKECLONE1:1 allocation score on 18node3: 0 -+native_color: FAKECLONE1:1 allocation score on 18node4: 0 -+native_color: FAKECLONE1:1 allocation score on remote1: 0 -+native_color: FAKECLONE1:2 allocation score on 18builder: 0 -+native_color: FAKECLONE1:2 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:2 allocation score on 18node3: 0 -+native_color: FAKECLONE1:2 allocation score on 18node4: 0 -+native_color: FAKECLONE1:2 allocation score on remote1: 0 -+native_color: FAKECLONE1:3 allocation score on 18builder: 0 -+native_color: FAKECLONE1:3 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:3 allocation score on 18node4: 0 -+native_color: FAKECLONE1:3 allocation score on remote1: 0 -+native_color: FAKECLONE1:4 allocation score on 18builder: 0 -+native_color: FAKECLONE1:4 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:4 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:4 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:4 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE1:4 allocation score on remote1: 0 -+native_color: FAKECLONE1:5 allocation score on 18builder: 0 -+native_color: FAKECLONE1:5 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE1:5 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE1:5 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE1:5 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE1:5 allocation score on remote1: -INFINITY -+native_color: FAKECLONE2:0 allocation score on 18builder: 0 -+native_color: FAKECLONE2:0 allocation score on 18node1: 0 -+native_color: FAKECLONE2:0 allocation score on 18node2: 0 -+native_color: FAKECLONE2:0 allocation score on 18node3: 0 -+native_color: FAKECLONE2:0 allocation score on 18node4: 0 -+native_color: FAKECLONE2:0 allocation score on remote1: 0 -+native_color: FAKECLONE2:1 allocation score on 18builder: 0 -+native_color: FAKECLONE2:1 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:1 allocation score on 18node2: 0 -+native_color: FAKECLONE2:1 allocation score on 18node3: 0 -+native_color: FAKECLONE2:1 allocation score on 18node4: 0 -+native_color: FAKECLONE2:1 allocation score on remote1: 0 -+native_color: FAKECLONE2:2 allocation score on 18builder: 0 -+native_color: FAKECLONE2:2 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:2 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:2 allocation score on 18node3: 0 -+native_color: FAKECLONE2:2 allocation score on 18node4: 0 -+native_color: FAKECLONE2:2 allocation score on remote1: 0 -+native_color: FAKECLONE2:3 allocation score on 18builder: 0 -+native_color: FAKECLONE2:3 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:3 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:3 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE2:3 allocation score on 18node4: 0 -+native_color: FAKECLONE2:3 allocation score on remote1: 0 -+native_color: FAKECLONE2:4 allocation score on 18builder: 0 -+native_color: FAKECLONE2:4 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:4 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:4 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE2:4 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE2:4 allocation score on remote1: 0 -+native_color: FAKECLONE2:5 allocation score on 18builder: 0 -+native_color: FAKECLONE2:5 allocation score on 18node1: -INFINITY -+native_color: FAKECLONE2:5 allocation score on 18node2: -INFINITY -+native_color: FAKECLONE2:5 allocation score on 18node3: -INFINITY -+native_color: FAKECLONE2:5 allocation score on 18node4: -INFINITY -+native_color: FAKECLONE2:5 allocation score on remote1: -INFINITY -+native_color: remote1 allocation score on 18builder: 0 -+native_color: remote1 allocation score on 18node1: 0 -+native_color: remote1 allocation score on 18node2: 0 -+native_color: remote1 allocation score on 18node3: 0 -+native_color: remote1 allocation score on 18node4: 0 -+native_color: remote1 allocation score on remote1: -INFINITY -+native_color: shooter allocation score on 18builder: 0 -+native_color: shooter allocation score on 18node1: 0 -+native_color: shooter allocation score on 18node2: 0 -+native_color: shooter allocation score on 18node3: 0 -+native_color: shooter allocation score on 18node4: 0 -+native_color: shooter allocation score on remote1: -INFINITY -diff --git a/pengine/test10/rsc-discovery-per-node.summary b/pengine/test10/rsc-discovery-per-node.summary -new file mode 100644 -index 0000000..69d5ee3 ---- /dev/null -+++ b/pengine/test10/rsc-discovery-per-node.summary -@@ -0,0 +1,131 @@ -+ -+Current cluster status: -+Online: [ 18builder 18node1 18node2 18node3 18node4 ] -+RemoteOFFLINE: [ remote1 ] -+ -+ shooter (stonith:fence_xvm): Started 18node1 -+ remote1 (ocf::pacemaker:remote): Stopped -+ FAKE1 (ocf::heartbeat:Dummy): Stopped -+ FAKE2 (ocf::heartbeat:Dummy): Started 18node2 -+ FAKE3 (ocf::heartbeat:Dummy): Started 18builder -+ FAKE4 (ocf::heartbeat:Dummy): Started 18node1 -+ FAKE5 (ocf::heartbeat:Dummy): Stopped -+ Clone Set: FAKECLONE1-clone [FAKECLONE1] -+ Stopped: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Clone Set: FAKECLONE2-clone [FAKECLONE2] -+ Stopped: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ -+Transition Summary: -+ * Start remote1 (18builder) -+ * Start FAKE1 (18node2) -+ * Move FAKE2 (Started 18node2 -> 18node3) -+ * Move FAKE3 (Started 18builder -> 18node4) -+ * Move FAKE4 (Started 18node1 -> remote1) -+ * Start FAKE5 (18builder) -+ * Start FAKECLONE1:0 (18node1) -+ * Start FAKECLONE1:1 (18node2) -+ * Start FAKECLONE1:2 (18node3) -+ * Start FAKECLONE1:3 (18node4) -+ * Start FAKECLONE1:4 (remote1) -+ * Start FAKECLONE1:5 (18builder) -+ * Start FAKECLONE2:0 (18node1) -+ * Start FAKECLONE2:1 (18node2) -+ * Start FAKECLONE2:2 (18node3) -+ * Start FAKECLONE2:3 (18node4) -+ * Start FAKECLONE2:4 (remote1) -+ * Start FAKECLONE2:5 (18builder) -+ -+Executing cluster transition: -+ * Resource action: shooter monitor on 18node4 -+ * Resource action: shooter monitor on 18node3 -+ * Resource action: remote1 monitor on 18node4 -+ * Resource action: remote1 monitor on 18node3 -+ * Resource action: FAKE1 monitor on 18node4 -+ * Resource action: FAKE1 monitor on 18node3 -+ * Resource action: FAKE1 monitor on 18node2 -+ * Resource action: FAKE1 monitor on 18node1 -+ * Resource action: FAKE1 monitor on 18builder -+ * Resource action: FAKE2 monitor on 18node4 -+ * Resource action: FAKE2 monitor on 18node3 -+ * Resource action: FAKE3 monitor on 18node4 -+ * Resource action: FAKE3 monitor on 18node3 -+ * Resource action: FAKE4 monitor on 18node4 -+ * Resource action: FAKE4 monitor on 18node3 -+ * Resource action: FAKE5 monitor on 18node4 -+ * Resource action: FAKE5 monitor on 18node3 -+ * Resource action: FAKE5 monitor on 18node2 -+ * Resource action: FAKE5 monitor on 18node1 -+ * Resource action: FAKE5 monitor on 18builder -+ * Resource action: FAKECLONE1:0 monitor on 18node1 -+ * Resource action: FAKECLONE1:1 monitor on 18node2 -+ * Resource action: FAKECLONE1:2 monitor on 18node3 -+ * Resource action: FAKECLONE1:3 monitor on 18node4 -+ * Resource action: FAKECLONE1:5 monitor on 18builder -+ * Pseudo action: FAKECLONE1-clone_start_0 -+ * Resource action: FAKECLONE2:0 monitor on 18node1 -+ * Resource action: FAKECLONE2:1 monitor on 18node2 -+ * Resource action: FAKECLONE2:2 monitor on 18node3 -+ * Resource action: FAKECLONE2:3 monitor on 18node4 -+ * Resource action: FAKECLONE2:5 monitor on 18builder -+ * Pseudo action: FAKECLONE2-clone_start_0 -+ * Pseudo action: probe_nodes_complete -+ * Pseudo action: probe_complete -+ * Resource action: remote1 start on 18builder -+ * Resource action: FAKE1 start on 18node2 -+ * Resource action: FAKE2 stop on 18node2 -+ * Resource action: FAKE3 stop on 18builder -+ * Resource action: FAKE4 stop on 18node1 -+ * Resource action: FAKE5 start on 18builder -+ * Resource action: FAKECLONE1:0 start on 18node1 -+ * Resource action: FAKECLONE1:1 start on 18node2 -+ * Resource action: FAKECLONE1:2 start on 18node3 -+ * Resource action: FAKECLONE1:3 start on 18node4 -+ * Resource action: FAKECLONE1:4 start on remote1 -+ * Resource action: FAKECLONE1:5 start on 18builder -+ * Pseudo action: FAKECLONE1-clone_running_0 -+ * Resource action: FAKECLONE2:0 start on 18node1 -+ * Resource action: FAKECLONE2:1 start on 18node2 -+ * Resource action: FAKECLONE2:2 start on 18node3 -+ * Resource action: FAKECLONE2:3 start on 18node4 -+ * Resource action: FAKECLONE2:4 start on remote1 -+ * Resource action: FAKECLONE2:5 start on 18builder -+ * Pseudo action: FAKECLONE2-clone_running_0 -+ * Pseudo action: all_stopped -+ * Resource action: remote1 monitor=60000 on 18builder -+ * Resource action: FAKE1 monitor=60000 on 18node2 -+ * Resource action: FAKE2 start on 18node3 -+ * Resource action: FAKE3 start on 18node4 -+ * Resource action: FAKE4 start on remote1 -+ * Resource action: FAKE5 monitor=60000 on 18builder -+ * Resource action: FAKECLONE1:0 monitor=60000 on 18node1 -+ * Resource action: FAKECLONE1:1 monitor=60000 on 18node2 -+ * Resource action: FAKECLONE1:2 monitor=60000 on 18node3 -+ * Resource action: FAKECLONE1:3 monitor=60000 on 18node4 -+ * Resource action: FAKECLONE1:4 monitor=60000 on remote1 -+ * Resource action: FAKECLONE1:5 monitor=60000 on 18builder -+ * Resource action: FAKECLONE2:0 monitor=60000 on 18node1 -+ * Resource action: FAKECLONE2:1 monitor=60000 on 18node2 -+ * Resource action: FAKECLONE2:2 monitor=60000 on 18node3 -+ * Resource action: FAKECLONE2:3 monitor=60000 on 18node4 -+ * Resource action: FAKECLONE2:4 monitor=60000 on remote1 -+ * Resource action: FAKECLONE2:5 monitor=60000 on 18builder -+ * Resource action: FAKE2 monitor=60000 on 18node3 -+ * Resource action: FAKE3 monitor=60000 on 18node4 -+ * Resource action: FAKE4 monitor=60000 on remote1 -+ -+Revised cluster status: -+Online: [ 18builder 18node1 18node2 18node3 18node4 ] -+RemoteOnline: [ remote1 ] -+ -+ shooter (stonith:fence_xvm): Started 18node1 -+ remote1 (ocf::pacemaker:remote): Started 18builder -+ FAKE1 (ocf::heartbeat:Dummy): Started 18node2 -+ FAKE2 (ocf::heartbeat:Dummy): Started 18node3 -+ FAKE3 (ocf::heartbeat:Dummy): Started 18node4 -+ FAKE4 (ocf::heartbeat:Dummy): Started remote1 -+ FAKE5 (ocf::heartbeat:Dummy): Started 18builder -+ Clone Set: FAKECLONE1-clone [FAKECLONE1] -+ Started: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ Clone Set: FAKECLONE2-clone [FAKECLONE2] -+ Started: [ 18builder 18node1 18node2 18node3 18node4 remote1 ] -+ -diff --git a/pengine/test10/rsc-discovery-per-node.xml b/pengine/test10/rsc-discovery-per-node.xml -new file mode 100644 -index 0000000..c111de8 ---- /dev/null -+++ b/pengine/test10/rsc-discovery-per-node.xml -@@ -0,0 +1,182 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/pengine/test10/whitebox-start.dot b/pengine/test10/whitebox-start.dot -index bec57b0..659ea97 100644 ---- a/pengine/test10/whitebox-start.dot -+++ b/pengine/test10/whitebox-start.dot -@@ -1,4 +1,16 @@ - digraph "g" { -+"A_monitor_10000 lxc1" [ style=bold color="green" fontcolor="black"] -+"A_start_0 lxc1" -> "A_monitor_10000 lxc1" [ style = bold] -+"A_start_0 lxc1" [ style=bold color="green" fontcolor="black"] -+"A_stop_0 18node1" -> "A_start_0 lxc1" [ style = bold] -+"A_stop_0 18node1" -> "all_stopped" [ style = bold] -+"A_stop_0 18node1" [ style=bold color="green" fontcolor="black"] -+"B_monitor_10000 18node3" [ style=bold color="green" fontcolor="black"] -+"B_start_0 18node3" -> "B_monitor_10000 18node3" [ style = bold] -+"B_start_0 18node3" [ style=bold color="green" fontcolor="black"] -+"B_stop_0 lxc2" -> "B_start_0 18node3" [ style = bold] -+"B_stop_0 lxc2" -> "all_stopped" [ style = bold] -+"B_stop_0 lxc2" [ style=bold color="green" fontcolor="black"] - "M-clone_running_0" [ style=bold color="green" fontcolor="orange"] - "M-clone_start_0" -> "M-clone_running_0" [ style = bold] - "M-clone_start_0" -> "M_start_0 lxc1" [ style = bold] -@@ -7,9 +19,12 @@ digraph "g" { - "M_start_0 lxc1" -> "M-clone_running_0" [ style = bold] - "M_start_0 lxc1" -> "M_monitor_10000 lxc1" [ style = bold] - "M_start_0 lxc1" [ style=bold color="green" fontcolor="black"] -+"all_stopped" [ style=bold color="green" fontcolor="orange"] - "container1_start_0 18node1" -> "lxc1_start_0 18node1" [ style = bold] - "container1_start_0 18node1" [ style=bold color="green" fontcolor="black"] - "lxc1_monitor_30000 18node1" [ style=bold color="green" fontcolor="black"] -+"lxc1_start_0 18node1" -> "A_monitor_10000 lxc1" [ style = bold] -+"lxc1_start_0 18node1" -> "A_start_0 lxc1" [ style = bold] - "lxc1_start_0 18node1" -> "M_monitor_10000 lxc1" [ style = bold] - "lxc1_start_0 18node1" -> "M_start_0 lxc1" [ style = bold] - "lxc1_start_0 18node1" -> "lxc1_monitor_30000 18node1" [ style = bold] -diff --git a/pengine/test10/whitebox-start.exp b/pengine/test10/whitebox-start.exp -index 0ee104c..68ede8e 100644 ---- a/pengine/test10/whitebox-start.exp -+++ b/pengine/test10/whitebox-start.exp -@@ -20,7 +20,7 @@ - - - -- -+ - - - -@@ -36,7 +36,7 @@ - - - -- -+ - - - -@@ -65,20 +65,96 @@ - - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - - - - -- -+ - - - -- -+ - -- -+ - - - -@@ -89,5 +165,19 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - -- -diff --git a/pengine/test10/whitebox-start.scores b/pengine/test10/whitebox-start.scores -index 1a00b28..1f0f273 100644 ---- a/pengine/test10/whitebox-start.scores -+++ b/pengine/test10/whitebox-start.scores -@@ -32,11 +32,11 @@ clone_color: M:4 allocation score on lxc2: 0 - native_color: A allocation score on 18node1: 100 - native_color: A allocation score on 18node2: 0 - native_color: A allocation score on 18node3: 0 --native_color: A allocation score on lxc1: 0 --native_color: A allocation score on lxc2: 0 --native_color: B allocation score on 18node1: 0 --native_color: B allocation score on 18node2: 0 --native_color: B allocation score on 18node3: 0 -+native_color: A allocation score on lxc1: INFINITY -+native_color: A allocation score on lxc2: INFINITY -+native_color: B allocation score on 18node1: INFINITY -+native_color: B allocation score on 18node2: INFINITY -+native_color: B allocation score on 18node3: INFINITY - native_color: B allocation score on lxc1: 0 - native_color: B allocation score on lxc2: 100 - native_color: C allocation score on 18node1: 0 -diff --git a/pengine/test10/whitebox-start.summary b/pengine/test10/whitebox-start.summary -index 2801abe..6819ebc 100644 ---- a/pengine/test10/whitebox-start.summary -+++ b/pengine/test10/whitebox-start.summary -@@ -17,16 +17,25 @@ Containers: [ lxc2:container2 ] - Transition Summary: - * Start container1 (18node1) - * Start M:4 (lxc1) -+ * Move A (Started 18node1 -> lxc1) -+ * Move B (Started lxc2 -> 18node3) - * Start lxc1 (18node1) - - Executing cluster transition: - * Resource action: container1 start on 18node1 - * Pseudo action: M-clone_start_0 -+ * Resource action: A stop on 18node1 -+ * Resource action: B stop on lxc2 - * Resource action: lxc1 start on 18node1 -+ * Pseudo action: all_stopped - * Resource action: M start on lxc1 - * Pseudo action: M-clone_running_0 -+ * Resource action: A start on lxc1 -+ * Resource action: B start on 18node3 - * Resource action: lxc1 monitor=30000 on 18node1 - * Resource action: M monitor=10000 on lxc1 -+ * Resource action: A monitor=10000 on lxc1 -+ * Resource action: B monitor=10000 on 18node3 - - Revised cluster status: - Online: [ 18node1 18node2 18node3 ] -@@ -37,8 +46,8 @@ Containers: [ lxc1:container1 lxc2:container2 ] - shoot1 (stonith:fence_xvm): Started 18node3 - Clone Set: M-clone [M] - Started: [ 18node1 18node2 18node3 lxc1 lxc2 ] -- A (ocf::pacemaker:Dummy): Started 18node1 -- B (ocf::pacemaker:Dummy): Started lxc2 -+ A (ocf::pacemaker:Dummy): Started lxc1 -+ B (ocf::pacemaker:Dummy): Started 18node3 - C (ocf::pacemaker:Dummy): Started lxc2 - D (ocf::pacemaker:Dummy): Started 18node1 - -diff --git a/pengine/test10/whitebox-start.xml b/pengine/test10/whitebox-start.xml -index 2dad074..67fcbaf 100644 ---- a/pengine/test10/whitebox-start.xml -+++ b/pengine/test10/whitebox-start.xml -@@ -78,7 +78,18 @@ - - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -diff --git a/pengine/utils.c b/pengine/utils.c -index 7dfaf95..9782cb6 100644 ---- a/pengine/utils.c -+++ b/pengine/utils.c -@@ -60,7 +60,8 @@ pe_free_rsc_to_node(GListPtr constraints) - - rsc_to_node_t * - rsc2node_new(const char *id, resource_t * rsc, -- int node_weight, node_t * foo_node, pe_working_set_t * data_set) -+ int node_weight, const char *discover_mode, -+ node_t * foo_node, pe_working_set_t * data_set) - { - rsc_to_node_t *new_con = NULL; - -@@ -79,6 +80,18 @@ rsc2node_new(const char *id, resource_t * rsc, - new_con->node_list_rh = NULL; - new_con->role_filter = RSC_ROLE_UNKNOWN; - -+ -+ if (discover_mode == NULL || safe_str_eq(discover_mode, "always")) { -+ new_con->discover_mode = discover_always; -+ } else if (safe_str_eq(discover_mode, "never")) { -+ new_con->discover_mode = discover_never; -+ } else if (safe_str_eq(discover_mode, "exclusive")) { -+ new_con->discover_mode = discover_exclusive; -+ rsc->exclusive_discover = TRUE; -+ } else { -+ pe_err("Invalid %s value %s in location constraint", XML_LOCATION_ATTR_DISCOVERY, discover_mode); -+ } -+ - if (foo_node != NULL) { - node_t *copy = node_copy(foo_node); - -diff --git a/pengine/utils.h b/pengine/utils.h -index 1939d40..5142e68 100644 ---- a/pengine/utils.h -+++ b/pengine/utils.h -@@ -23,7 +23,8 @@ extern rsc_colocation_t *invert_constraint(rsc_colocation_t * constraint); - - extern rsc_to_node_t *copy_constraint(rsc_to_node_t * constraint); - --extern rsc_to_node_t *rsc2node_new(const char *id, resource_t * rsc, int weight, node_t * node, -+extern rsc_to_node_t *rsc2node_new(const char *id, resource_t * rsc, int weight, -+ const char *discovery_mode, node_t * node, - pe_working_set_t * data_set); - - extern void pe_free_rsc_to_node(GListPtr constraints); -diff --git a/tools/crm_resource.c b/tools/crm_resource.c -index 56583e0..ff5effd 100644 ---- a/tools/crm_resource.c -+++ b/tools/crm_resource.c -@@ -94,6 +94,10 @@ resource_ipc_connection_destroy(gpointer user_data) - static void - start_mainloop(void) - { -+ if (crmd_replies_needed == 0) { -+ return; -+ } -+ - mainloop = g_main_new(FALSE); - fprintf(stderr, "Waiting for %d replies from the CRMd", crmd_replies_needed); - crm_debug("Waiting for %d replies from the CRMd", crmd_replies_needed); -@@ -789,6 +793,7 @@ delete_lrm_rsc(cib_t *cib_conn, crm_ipc_t * crmd_channel, const char *host_uname - resource_t * rsc, pe_working_set_t * data_set) - { - int rc = pcmk_ok; -+ node_t *node = NULL; - - if (rsc == NULL) { - return -ENXIO; -@@ -807,7 +812,7 @@ delete_lrm_rsc(cib_t *cib_conn, crm_ipc_t * crmd_channel, const char *host_uname - GListPtr lpc = NULL; - - for (lpc = data_set->nodes; lpc != NULL; lpc = lpc->next) { -- node_t *node = (node_t *) lpc->data; -+ node = (node_t *) lpc->data; - - if (node->details->online) { - delete_lrm_rsc(cib_conn, crmd_channel, node->details->uname, rsc, data_set); -@@ -817,15 +822,20 @@ delete_lrm_rsc(cib_t *cib_conn, crm_ipc_t * crmd_channel, const char *host_uname - return pcmk_ok; - } - -- printf("Cleaning up %s on %s\n", rsc->id, host_uname); -- rc = send_lrm_rsc_op(crmd_channel, CRM_OP_LRM_DELETE, host_uname, rsc->id, TRUE, data_set); -+ node = pe_find_node(data_set->nodes, host_uname); -+ -+ if (node && node->details->rsc_discovery_enabled) { -+ printf("Cleaning up %s on %s\n", rsc->id, host_uname); -+ rc = send_lrm_rsc_op(crmd_channel, CRM_OP_LRM_DELETE, host_uname, rsc->id, TRUE, data_set); -+ } else { -+ printf("Resource discovery disabled on %s. Unable to delete lrm state.\n", host_uname); -+ } - - if (rc == pcmk_ok) { - char *attr_name = NULL; - const char *id = rsc->id; -- node_t *node = pe_find_node(data_set->nodes, host_uname); - -- if(node && node->details->remote_rsc == NULL) { -+ if(node && node->details->remote_rsc == NULL && node->details->rsc_discovery_enabled) { - crmd_replies_needed++; - } - if (rsc->clone_name) { -@@ -1970,6 +1980,7 @@ main(int argc, char **argv) - node_t *current = NULL; - node_t *dest = pe_find_node(data_set.nodes, host_uname); - resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); -+ gboolean cur_is_dest = FALSE; - - rc = -EINVAL; - -@@ -2032,11 +2043,16 @@ main(int argc, char **argv) - - } else if(scope_master && rsc->fns->state(rsc, TRUE) != RSC_ROLE_MASTER) { - crm_trace("%s is already active on %s but not in correct state", rsc_id, dest->details->uname); -- - } else if (safe_str_eq(current->details->uname, dest->details->uname)) { -- CMD_ERR("Error performing operation: %s is already %s on %s\n", -- rsc_id, scope_master?"promoted":"active", dest->details->uname); -- goto bail; -+ cur_is_dest = TRUE; -+ if (do_force) { -+ crm_info("%s is already %s on %s, reinforcing placement with location constraint.\n", -+ rsc_id, scope_master?"promoted":"active", dest->details->uname); -+ } else { -+ CMD_ERR("Error performing operation: %s is already %s on %s\n", -+ rsc_id, scope_master?"promoted":"active", dest->details->uname); -+ goto bail; -+ } - } - - /* Clear any previous constraints for 'dest' */ -@@ -2048,7 +2064,10 @@ main(int argc, char **argv) - crm_trace("%s%s now prefers node %s%s", - rsc->id, scope_master?" (master)":"", dest->details->uname, do_force?"(forced)":""); - -- if(do_force) { -+ /* only ban the previous location if current location != destination location. -+ * it is possible to use -M to enforce a location without regard of where the -+ * resource is currently located */ -+ if(do_force && (cur_is_dest == FALSE)) { - /* Ban the original location if possible */ - if(current) { - ban_resource(rsc_id, current->details->uname, NULL, cib_conn); -diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c -index 07f0871..7c0dcc7 100644 ---- a/tools/crm_simulate.c -+++ b/tools/crm_simulate.c -@@ -964,7 +964,7 @@ set_ticket_state_attr(const char *ticket_id, const char *attr_name, - - static void - modify_configuration(pe_working_set_t * data_set, -- const char *quorum, GListPtr node_up, GListPtr node_down, GListPtr node_fail, -+ const char *quorum, const char *watchdog, GListPtr node_up, GListPtr node_down, GListPtr node_fail, - GListPtr op_inject, GListPtr ticket_grant, GListPtr ticket_revoke, - GListPtr ticket_standby, GListPtr ticket_activate) - { -@@ -988,6 +988,16 @@ modify_configuration(pe_working_set_t * data_set, - CRM_ASSERT(rc == pcmk_ok); - } - -+ if (watchdog) { -+ quiet_log(" + Setting watchdog: %s\n", watchdog); -+ -+ rc = update_attr_delegate(global_cib, cib_sync_call | cib_scope_local, -+ XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, -+ XML_ATTR_HAVE_WATCHDOG, watchdog, FALSE, NULL, NULL); -+ -+ CRM_ASSERT(rc == pcmk_ok); -+ } -+ - for (gIter = node_up; gIter != NULL; gIter = gIter->next) { - char *node = (char *)gIter->data; - -@@ -1245,6 +1255,7 @@ static struct crm_option long_options[] = { - {"-spacer-", 0, 0, '-', "\t\tThe transition will normally stop at the failed action. Save the result with --save-output and re-run with --xml-file"}, - {"set-datetime", 1, 0, 't', "Set date/time"}, - {"quorum", 1, 0, 'q', "\tSpecify a value for quorum"}, -+ {"watchdog", 1, 0, 'w', "\tAssume a watchdog device is active"}, - {"ticket-grant", 1, 0, 'g', "Grant a ticket"}, - {"ticket-revoke", 1, 0, 'r', "Revoke a ticket"}, - {"ticket-standby", 1, 0, 'b', "Make a ticket standby"}, -@@ -1359,6 +1370,7 @@ main(int argc, char **argv) - - const char *xml_file = "-"; - const char *quorum = NULL; -+ const char *watchdog = NULL; - const char *test_dir = NULL; - const char *dot_file = NULL; - const char *graph_file = NULL; -@@ -1445,6 +1457,10 @@ main(int argc, char **argv) - simulate = TRUE; - op_fail = g_list_append(op_fail, optarg); - break; -+ case 'w': -+ modified++; -+ watchdog = optarg; -+ break; - case 'q': - modified++; - quorum = optarg; -@@ -1555,7 +1571,7 @@ main(int argc, char **argv) - - if (modified) { - quiet_log("Performing requested modifications\n"); -- modify_configuration(&data_set, quorum, node_up, node_down, node_fail, op_inject, -+ modify_configuration(&data_set, quorum, watchdog, node_up, node_down, node_fail, op_inject, - ticket_grant, ticket_revoke, ticket_standby, ticket_activate); - - rc = global_cib->cmds->query(global_cib, NULL, &input, cib_sync_call); -diff --git a/tools/regression.acls.exp b/tools/regression.acls.exp -index 2abdf97..2cea125 100644 ---- a/tools/regression.acls.exp -+++ b/tools/regression.acls.exp -@@ -1,4 +1,4 @@ --Created new pacemaker-1.3 configuration -+Created new pacemaker configuration - Setting up shadow instance - A new shadow instance was created. To begin using it paste the following into your shell: - CIB_shadow=tools-regression ; export CIB_shadow -diff --git a/tools/regression.sh b/tools/regression.sh -index 285dcba..0c4896c 100755 ---- a/tools/regression.sh -+++ b/tools/regression.sh -@@ -578,6 +578,7 @@ for t in $tests; do - -e 's/ last-run=\"[0-9]*\"//' \ - -e 's/crm_feature_set="[^"]*" //'\ - -e 's/validate-with="[^"]*" //'\ -+ -e 's/Created new pacemaker-.* configuration/Created new pacemaker configuration/'\ - -e 's/.*__xml_acl_check/__xml_acl_check/g'\ - -e 's/.*__xml_acl_post_process/__xml_acl_post_process/g'\ - -e 's/.*error: unpack_resources:/error: unpack_resources:/g'\ -diff --git a/tools/regression.tools.exp b/tools/regression.tools.exp -index 5b12c84..287caf9 100644 ---- a/tools/regression.tools.exp -+++ b/tools/regression.tools.exp -@@ -1,4 +1,4 @@ --Created new pacemaker-2.1 configuration -+Created new pacemaker configuration - Setting up shadow instance - A new shadow instance was created. To begin using it paste the following into your shell: - CIB_shadow=tools-regression ; export CIB_shadow -diff --git a/xml/Makefile.am b/xml/Makefile.am -index 4c21e55..e3a3d04 100644 ---- a/xml/Makefile.am -+++ b/xml/Makefile.am -@@ -26,8 +26,8 @@ xslt_SCRIPTS = upgrade06.xsl upgrade-*.xsl - RNGdir = $(dtddir) - - # See Readme.md for details on updating schema files --RNG_max = $(firstword $(shell ls -1 *.rng | sed -e 's/.*-//' -e 's/.rng//' | sort -unr)) --RNG_last = $(shell ls -1 *.rng | sed -e 's/.*-//' -e 's/.rng//' | sort -unr | head -n 2 | tail -n 1) -+RNG_max ?= $(firstword $(shell ls -1 *.rng | sed -e 's/.*-//' -e 's/.rng//' | sort -unr)) -+RNG_last ?= $(shell ls -1 *.rng | sed -e 's/.*-//' -e 's/.rng//' | sort -unr | head -n 2 | tail -n 1) - RNG_versions = $(shell ls -1 *.rng | sed -e 's/.*-//' -e 's/.rng//' | sort -un) - RNG_generated = pacemaker.rng $(foreach base,$(RNG_versions),pacemaker-$(base).rng) versions.rng - -diff --git a/xml/constraints-2.2.rng b/xml/constraints-2.2.rng -new file mode 100644 -index 0000000..216bf9c ---- /dev/null -+++ b/xml/constraints-2.2.rng -@@ -0,0 +1,249 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ group -+ listed -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ stop -+ demote -+ fence -+ freeze -+ -+ -+ -+ -+ -+ -+ -+ -+ always -+ never -+ exclusive -+ -+ -+ -+ -+ -+ start -+ promote -+ demote -+ stop -+ -+ -+ -+ -+ -+ Stopped -+ Started -+ Master -+ Slave -+ -+ -+ -+ -+ -+ Optional -+ Mandatory -+ Serialize -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/xml/constraints-next.rng b/xml/constraints-next.rng -index 051603d..0defe8f 100644 ---- a/xml/constraints-next.rng -+++ b/xml/constraints-next.rng -@@ -49,6 +49,11 @@ - - - -+ -+ -+ -+ -+ - - - -@@ -65,6 +70,14 @@ - - - -+ -+ -+ group -+ listed -+ -+ -+ -+ - - - -@@ -206,6 +219,14 @@ - - - -+ -+ -+ always -+ never -+ exclusive -+ -+ -+ - - - start diff --git a/SOURCES/pacemaker-rollup-7-1-3d781d3.patch b/SOURCES/pacemaker-rollup-7-1-3d781d3.patch new file mode 100644 index 0000000..30afd6d --- /dev/null +++ b/SOURCES/pacemaker-rollup-7-1-3d781d3.patch @@ -0,0 +1,7989 @@ +diff --git a/cib/io.c b/cib/io.c +index e2873a8..4e2b24a 100644 +--- a/cib/io.c ++++ b/cib/io.c +@@ -254,9 +254,7 @@ readCibXmlFile(const char *dir, const char *file, gboolean discard_status) + if (cib_writes_enabled && use_valgrind) { + if (crm_is_true(use_valgrind) || strstr(use_valgrind, "cib")) { + cib_writes_enabled = FALSE; +- crm_err("*********************************************************"); + crm_err("*** Disabling disk writes to avoid confusing Valgrind ***"); +- crm_err("*********************************************************"); + } + } + +diff --git a/crmd/crmd_lrm.h b/crmd/crmd_lrm.h +index 81a53c5..78432df 100644 +--- a/crmd/crmd_lrm.h ++++ b/crmd/crmd_lrm.h +@@ -37,6 +37,8 @@ typedef struct resource_history_s { + GHashTable *stop_params; + } rsc_history_t; + ++void history_free(gpointer data); ++ + /* TDOD - Replace this with lrmd_event_data_t */ + struct recurring_op_s { + int call_id; +diff --git a/crmd/lrm.c b/crmd/lrm.c +index 062f769..418e7cf 100644 +--- a/crmd/lrm.c ++++ b/crmd/lrm.c +@@ -103,6 +103,80 @@ copy_meta_keys(gpointer key, gpointer value, gpointer user_data) + } + } + ++/* ++ * \internal ++ * \brief Remove a recurring operation from a resource's history ++ * ++ * \param[in,out] history Resource history to modify ++ * \param[in] op Operation to remove ++ * ++ * \return TRUE if the operation was found and removed, FALSE otherwise ++ */ ++static gboolean ++history_remove_recurring_op(rsc_history_t *history, const lrmd_event_data_t *op) ++{ ++ GList *iter; ++ ++ for (iter = history->recurring_op_list; iter != NULL; iter = iter->next) { ++ lrmd_event_data_t *existing = iter->data; ++ ++ if ((op->interval == existing->interval) ++ && crm_str_eq(op->rsc_id, existing->rsc_id, TRUE) ++ && safe_str_eq(op->op_type, existing->op_type)) { ++ ++ history->recurring_op_list = g_list_delete_link(history->recurring_op_list, iter); ++ lrmd_free_event(existing); ++ return TRUE; ++ } ++ } ++ return FALSE; ++} ++ ++/* ++ * \internal ++ * \brief Free all recurring operations in resource history ++ * ++ * \param[in,out] history Resource history to modify ++ */ ++static void ++history_free_recurring_ops(rsc_history_t *history) ++{ ++ GList *iter; ++ ++ for (iter = history->recurring_op_list; iter != NULL; iter = iter->next) { ++ lrmd_free_event(iter->data); ++ } ++ g_list_free(history->recurring_op_list); ++ history->recurring_op_list = NULL; ++} ++ ++/* ++ * \internal ++ * \brief Free resource history ++ * ++ * \param[in,out] history Resource history to free ++ */ ++void ++history_free(gpointer data) ++{ ++ rsc_history_t *history = (rsc_history_t*)data; ++ ++ if (history->stop_params) { ++ g_hash_table_destroy(history->stop_params); ++ } ++ ++ /* Don't need to free history->rsc.id because it's set to history->id */ ++ free(history->rsc.type); ++ free(history->rsc.class); ++ free(history->rsc.provider); ++ ++ lrmd_free_event(history->failed); ++ lrmd_free_event(history->last); ++ free(history->id); ++ history_free_recurring_ops(history); ++ free(history); ++} ++ + static void + update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op) + { +@@ -145,25 +219,10 @@ update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_ + target_rc = rsc_op_expected_rc(op); + if (op->op_status == PCMK_LRM_OP_CANCELLED) { + if (op->interval > 0) { +- GList *gIter, *gIterNext; +- + crm_trace("Removing cancelled recurring op: %s_%s_%d", op->rsc_id, op->op_type, + op->interval); +- +- for (gIter = entry->recurring_op_list; gIter != NULL; gIter = gIterNext) { +- lrmd_event_data_t *existing = gIter->data; +- +- gIterNext = gIter->next; +- +- if (crm_str_eq(op->rsc_id, existing->rsc_id, TRUE) +- && safe_str_eq(op->op_type, existing->op_type) +- && op->interval == existing->interval) { +- lrmd_free_event(existing); +- entry->recurring_op_list = g_list_delete_link(entry->recurring_op_list, gIter); +- } +- } ++ history_remove_recurring_op(entry, op); + return; +- + } else { + crm_trace("Skipping %s_%s_%d rc=%d, status=%d", op->rsc_id, op->op_type, op->interval, + op->rc, op->op_status); +@@ -201,32 +260,17 @@ update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_ + } + + if (op->interval > 0) { +- GListPtr iter = NULL; +- +- for(iter = entry->recurring_op_list; iter; iter = iter->next) { +- lrmd_event_data_t *o = iter->data; +- +- /* op->rsc_id is implied */ +- if(op->interval == o->interval && strcmp(op->op_type, o->op_type) == 0) { +- crm_trace("Removing existing recurring op entry: %s_%s_%d", op->rsc_id, op->op_type, op->interval); +- entry->recurring_op_list = g_list_remove(entry->recurring_op_list, o); +- break; +- } +- } ++ /* Ensure there are no duplicates */ ++ history_remove_recurring_op(entry, op); + + crm_trace("Adding recurring op: %s_%s_%d", op->rsc_id, op->op_type, op->interval); + entry->recurring_op_list = g_list_prepend(entry->recurring_op_list, lrmd_copy_event(op)); + + } else if (entry->recurring_op_list && safe_str_eq(op->op_type, RSC_STATUS) == FALSE) { +- GList *gIter = entry->recurring_op_list; +- + crm_trace("Dropping %d recurring ops because of: %s_%s_%d", +- g_list_length(gIter), op->rsc_id, op->op_type, op->interval); +- for (; gIter != NULL; gIter = gIter->next) { +- lrmd_free_event(gIter->data); +- } +- g_list_free(entry->recurring_op_list); +- entry->recurring_op_list = NULL; ++ g_list_length(entry->recurring_op_list), op->rsc_id, ++ op->op_type, op->interval); ++ history_free_recurring_ops(entry); + } + } + +diff --git a/crmd/lrm_state.c b/crmd/lrm_state.c +index 374c806..162ad03 100644 +--- a/crmd/lrm_state.c ++++ b/crmd/lrm_state.c +@@ -32,24 +32,6 @@ int lrmd_internal_proxy_send(lrmd_t * lrmd, xmlNode *msg); + void lrmd_internal_set_proxy_callback(lrmd_t * lrmd, void *userdata, void (*callback)(lrmd_t *lrmd, void *userdata, xmlNode *msg)); + + static void +-history_cache_destroy(gpointer data) +-{ +- rsc_history_t *entry = data; +- +- if (entry->stop_params) { +- g_hash_table_destroy(entry->stop_params); +- } +- +- free(entry->rsc.type); +- free(entry->rsc.class); +- free(entry->rsc.provider); +- +- lrmd_free_event(entry->failed); +- lrmd_free_event(entry->last); +- free(entry->id); +- free(entry); +-} +-static void + free_rsc_info(gpointer value) + { + lrmd_rsc_info_t *rsc_info = value; +@@ -155,7 +137,7 @@ lrm_state_create(const char *node_name) + g_str_equal, g_hash_destroy_str, free_recurring_op); + + state->resource_history = g_hash_table_new_full(crm_str_hash, +- g_str_equal, NULL, history_cache_destroy); ++ g_str_equal, NULL, history_free); + + g_hash_table_insert(lrm_state_table, (char *)state->node_name, state); + return state; +diff --git a/cts/CM_ais.py b/cts/CM_ais.py +index 44f91cd..a34f9b1 100644 +--- a/cts/CM_ais.py ++++ b/cts/CM_ais.py +@@ -49,42 +49,46 @@ class crm_ais(crm_lha): + def NodeUUID(self, node): + return node + +- def ais_components(self): ++ def ais_components(self, extra={}): + + complist = [] + if not len(self.fullcomplist.keys()): + for c in ["cib", "lrmd", "crmd", "attrd" ]: +- self.fullcomplist[c] = Process( +- self, c, +- pats = self.templates.get_component(self.name, c), +- badnews_ignore = self.templates.get_component(self.name, "%s-ignore"%c), +- common_ignore = self.templates.get_component(self.name, "common-ignore")) +- +- self.fullcomplist["pengine"] = Process( +- self, "pengine", +- dc_pats = self.templates.get_component(self.name, "pengine"), +- badnews_ignore = self.templates.get_component(self.name, "pengine-ignore"), +- common_ignore = self.templates.get_component(self.name, "common-ignore")) +- +- self.fullcomplist["stonith-ng"] = Process( +- self, "stonith-ng", process="stonithd", +- pats = self.templates.get_component(self.name, "stonith"), +- badnews_ignore = self.templates.get_component(self.name, "stonith-ignore"), +- common_ignore = self.templates.get_component(self.name, "common-ignore")) +- ++ self.fullcomplist[c] = Process( ++ self, c, ++ pats = self.templates.get_component(self.name, c), ++ badnews_ignore = self.templates.get_component(self.name, "%s-ignore" % c), ++ common_ignore = self.templates.get_component(self.name, "common-ignore")) ++ ++ # pengine uses dc_pats instead of pats ++ self.fullcomplist["pengine"] = Process( ++ self, "pengine", ++ dc_pats = self.templates.get_component(self.name, "pengine"), ++ badnews_ignore = self.templates.get_component(self.name, "pengine-ignore"), ++ common_ignore = self.templates.get_component(self.name, "common-ignore")) ++ ++ # stonith-ng's process name is different from its component name ++ self.fullcomplist["stonith-ng"] = Process( ++ self, "stonith-ng", process="stonithd", ++ pats = self.templates.get_component(self.name, "stonith"), ++ badnews_ignore = self.templates.get_component(self.name, "stonith-ignore"), ++ common_ignore = self.templates.get_component(self.name, "common-ignore")) ++ ++ # add (or replace) any extra components passed in ++ self.fullcomplist.update(extra) ++ ++ # Processes running under valgrind can't be shot with "killall -9 processname", ++ # so don't include them in the returned list + vgrind = self.Env["valgrind-procs"].split() + for key in self.fullcomplist.keys(): + if self.Env["valgrind-tests"]: +- if key in vgrind: +- # Processes running under valgrind can't be shot with "killall -9 processname" ++ if key in vgrind: + self.log("Filtering %s from the component list as it is being profiled by valgrind" % key) + continue + if key == "stonith-ng" and not self.Env["DoFencing"]: + continue +- + complist.append(self.fullcomplist[key]) + +- #self.complist = [ fullcomplist["pengine"] ] + return complist + + +@@ -100,17 +104,14 @@ class crm_cs_v0(crm_ais): + crm_ais.__init__(self, Environment, randseed=randseed, name=name) + + def Components(self): +- self.ais_components() +- c = "corosync" +- +- self.fullcomplist[c] = Process( +- self, c, +- pats = self.templates.get_component(self.name, c), +- badnews_ignore = self.templates.get_component(self.name, "%s-ignore"%c), ++ extra = {} ++ extra["corosync"] = Process( ++ self, "corosync", ++ pats = self.templates.get_component(self.name, "corosync"), ++ badnews_ignore = self.templates.get_component(self.name, "corosync-ignore"), + common_ignore = self.templates.get_component(self.name, "common-ignore") + ) +- +- return self.ais_components() ++ return self.ais_components(extra=extra) + + + class crm_cs_v1(crm_cs_v0): +diff --git a/cts/environment.py b/cts/environment.py +index a3399c3..61d4211 100644 +--- a/cts/environment.py ++++ b/cts/environment.py +@@ -59,7 +59,7 @@ class Environment: + self["stonith-params"] = "hostlist=all,livedangerously=yes" + self["loop-minutes"] = 60 + self["valgrind-prefix"] = None +- self["valgrind-procs"] = "cib crmd attrd pengine stonith-ng" ++ self["valgrind-procs"] = "attrd cib crmd lrmd pengine stonith-ng" + self["valgrind-opts"] = """--leak-check=full --show-reachable=yes --trace-children=no --num-callers=25 --gen-suppressions=all --suppressions="""+CTSvars.CTS_home+"""/cts.supp""" + + self["experimental-tests"] = 0 +@@ -578,6 +578,10 @@ class Environment: + elif args[i] == "--valgrind-tests": + self["valgrind-tests"] = 1 + ++ elif args[i] == "--valgrind-procs": ++ self["valgrind-procs"] = args[i+1] ++ skipthis = 1 ++ + elif args[i] == "--no-loop-tests": + self["loop-tests"] = 0 + +diff --git a/cts/patterns.py b/cts/patterns.py +index 1bc05a6..493b690 100644 +--- a/cts/patterns.py ++++ b/cts/patterns.py +@@ -7,7 +7,9 @@ class BasePatterns: + def __init__(self, name): + self.name = name + patternvariants[name] = self +- self.ignore = [] ++ self.ignore = [ ++ "avoid confusing Valgrind", ++ ] + self.BadNews = [] + self.components = {} + self.commands = { +@@ -140,7 +142,7 @@ class crm_lha(BasePatterns): + r"Parameters to .* changed", + ] + +- self.ignore = [ ++ self.ignore = self.ignore + [ + r"(ERROR|error):.*\s+assert\s+at\s+crm_glib_handler:" + "(ERROR|error): Message hist queue is filling up", + "stonithd.*CRIT: external_hostlist:.*'vmware gethosts' returned an empty hostlist", +@@ -177,7 +179,7 @@ class crm_cs_v0(BasePatterns): + "Pat:PacemakerUp" : "%s\W.*pacemakerd.*Starting Pacemaker", + }) + +- self.ignore = [ ++ self.ignore = self.ignore + [ + r"crm_mon:", + r"crmadmin:", + r"update_trace_data", +diff --git a/extra/ansible/docker/group_vars/all b/extra/ansible/docker/group_vars/all +new file mode 100644 +index 0000000..935e88a +--- /dev/null ++++ b/extra/ansible/docker/group_vars/all +@@ -0,0 +1,5 @@ ++max: 4 ++prefix: ansible-pcmk ++base_image: centos:centos7 ++subnet: 172.17.200 ++pacemaker_authkey: this_is_very_insecure +\ No newline at end of file +diff --git a/extra/ansible/docker/hosts b/extra/ansible/docker/hosts +new file mode 100644 +index 0000000..5b0fb71 +--- /dev/null ++++ b/extra/ansible/docker/hosts +@@ -0,0 +1,7 @@ ++[controllers] ++oss-uk-1.clusterlabs.org ++ ++[containers] ++ansible-1 ++ansible-2 ++ansible-3 +diff --git a/extra/ansible/docker/roles/docker-host/files/docker-enter b/extra/ansible/docker/roles/docker-host/files/docker-enter +new file mode 100644 +index 0000000..04c4822 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/docker-enter +@@ -0,0 +1,29 @@ ++#! /bin/sh -e ++ ++case "$1" in ++ -h|--help) ++ echo "Usage: docker-enter CONTAINER [COMMAND]" ++ exit 0 ++ ;; ++esac ++ ++if [ $(id -ru) -ne 0 ]; then ++ echo "You have to be root." ++ exit 1 ++fi ++ ++if [ $# -eq 0 ]; then ++ echo "Usage: docker-enter CONTAINER [COMMAND]" ++ exit 1 ++fi ++ ++container=$1; shift ++PID=$(docker inspect --format {{.State.Pid}} "$container") ++ ++if [ $# -ne 0 ]; then ++ nsenter --target $PID --mount --uts --ipc --net --pid -- $* ++ exit $? ++fi ++ ++nsenter --target $PID --mount --uts --ipc --net --pid ++exit 0 +diff --git a/extra/ansible/docker/roles/docker-host/files/fence_docker_cts b/extra/ansible/docker/roles/docker-host/files/fence_docker_cts +new file mode 100644 +index 0000000..6d6f025 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/fence_docker_cts +@@ -0,0 +1,202 @@ ++#!/bin/bash ++# ++# Copyright (c) 2014 David Vossel ++# All Rights Reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it would be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++# ++# Further, this software is distributed without any warranty that it is ++# free of the rightful claim of any third person regarding infringement ++# or the like. Any license provided herein, whether implied or ++# otherwise, applies only to this software file. Patent licenses, if ++# any, provided herein do not apply to combinations of this program with ++# other software, or any other product whatsoever. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write the Free Software Foundation, ++# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++# ++####################################################################### ++ ++port="" ++action="list" # Default fence action ++ ++function usage() ++{ ++cat < ++ ++ ++ fence_docker_cts fences docker containers for testing purposes. ++ ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ The name/id of docker container to control/check ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++EOF ++ exit 0; ++} ++ ++function docker_log() { ++ if ! [ "$action" = "list" ]; then ++ printf "$*\n" 1>&2 ++ fi ++} ++ ++# stdin option processing ++if [ -z $1 ]; then ++ # If there are no command line args, look for options from stdin ++ while read line; do ++ for word in $(echo "$line"); do ++ case $word in ++ option=*|action=*) action=`echo $word | sed s/.*=//`;; ++ port=*) port=`echo $word | sed s/.*=//`;; ++ node=*) port=`echo $word | sed s/.*=//`;; ++ nodename=*) port=`echo $word | sed s/.*=//`;; ++ --);; ++ *) docker_log "Invalid command: $word";; ++ esac ++ done ++ done ++fi ++ ++# Command line option processing ++while true ; do ++ if [ -z "$1" ]; then ++ break; ++ fi ++ case "$1" in ++ -o|--action|--option) action=$2; shift; shift;; ++ -n|--port) port=$2; shift; shift;; ++ -V|--version) echo "1.0.0"; exit 0;; ++ --help|-h) ++ usage; ++ exit 0;; ++ --) shift ; break ;; ++ *) docker_log "Unknown option: $1. See --help for details."; exit 1;; ++ esac ++done ++ ++action=`echo $action | tr 'A-Z' 'a-z'` ++case $action in ++ hostlist|list) action=list;; ++ stat|status) action=status;; ++ restart|reboot|reset) action=reboot;; ++ poweron|on) action=start;; ++ poweroff|off) action=stop;; ++esac ++ ++function fence_done() ++{ ++ if [ $1 -eq 0 ]; then ++ docker_log "Operation $action (port=$port) passed" ++ else ++ docker_log "Operation $action (port=$port) failed: $1" ++ fi ++ if [ -z "$returnfile" ]; then ++ rm -f $returnfile ++ fi ++ if [ -z "$helperscript" ]; then ++ rm -f $helperscript ++ fi ++ exit $1 ++} ++ ++case $action in ++ metadata) metadata;; ++esac ++ ++returnfile=$(mktemp /tmp/fence_docker_cts_returnfileXXXX) ++returnstring="" ++helper_script=$(mktemp /tmp/fence_docker_cts_helperXXXX) ++ ++exec_action() ++{ ++ echo "#!/bin/bash" > $helper_script ++ echo "sleep 10000" >> $helper_script ++ chmod 755 $helper_script ++ src="$(uname -n)" ++ ++ $helper_script "$src" "$action" "$returnfile" "$port" > /dev/null 2>&1 & ++ pid=$! ++ docker_log "waiting on pid $pid" ++ wait $pid > /dev/null 2>&1 ++ returnstring=$(cat $returnfile) ++ ++ if [ -z "$returnstring" ]; then ++ docker_log "fencing daemon did not respond" ++ fence_done 1 ++ fi ++ ++ if [ "$returnstring" == "fail" ]; then ++ docker_log "fencing daemon failed to execute action [$action on port $port]" ++ fence_done 1 ++ fi ++ ++ return 0 ++} ++ ++exec_action ++case $action in ++ list) ++ cat $returnfile ++ fence_done 0 ++ ;; ++ ++ status) ++ # 0 if container is on ++ # 1 if container can not be contacted or unknown ++ # 2 if container is off ++ if [ "$returnstring" = "true" ]; then ++ fence_done 0 ++ else ++ fence_done 2 ++ fi ++ ;; ++ monitor|stop|start|reboot) : ;; ++ *) docker_log "Unknown action: $action"; fence_done 1;; ++esac ++ ++fence_done $? +diff --git a/extra/ansible/docker/roles/docker-host/files/launch.sh b/extra/ansible/docker/roles/docker-host/files/launch.sh +new file mode 100644 +index 0000000..66bebf4 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/launch.sh +@@ -0,0 +1,4 @@ ++#!/bin/bash ++while true; do ++ sleep 1 ++done +diff --git a/extra/ansible/docker/roles/docker-host/files/pcmk_remote_start b/extra/ansible/docker/roles/docker-host/files/pcmk_remote_start +new file mode 100644 +index 0000000..1bf0320 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/pcmk_remote_start +@@ -0,0 +1,18 @@ ++#!/bin/bash ++/usr/sbin/ip_start ++pid=$(pidof pacemaker_remoted) ++if [ "$?" -ne 0 ]; then ++ mkdir -p /var/run ++ ++ export PCMK_debugfile=$pcmklogs ++ (pacemaker_remoted &) & > /dev/null 2>&1 ++ sleep 5 ++ ++ pid=$(pidof pacemaker_remoted) ++ if [ "$?" -ne 0 ]; then ++ echo "startup of pacemaker failed" ++ exit 1 ++ fi ++ echo "$pid" > /var/run/pacemaker_remoted.pid ++fi ++exit 0 +diff --git a/extra/ansible/docker/roles/docker-host/files/pcmk_remote_stop b/extra/ansible/docker/roles/docker-host/files/pcmk_remote_stop +new file mode 100644 +index 0000000..074cd59 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/pcmk_remote_stop +@@ -0,0 +1,36 @@ ++#!/bin/bash ++status() ++{ ++ pid=$(pidof $1 2>/dev/null) ++ rtrn=$? ++ if [ $rtrn -ne 0 ]; then ++ echo "$1 is stopped" ++ else ++ echo "$1 (pid $pid) is running..." ++ fi ++ return $rtrn ++} ++stop() ++{ ++ desc="Pacemaker Remote" ++ prog=$1 ++ shutdown_prog=$prog ++ ++ if status $shutdown_prog > /dev/null 2>&1; then ++ kill -TERM $(pidof $prog) > /dev/null 2>&1 ++ ++ while status $prog > /dev/null 2>&1; do ++ sleep 1 ++ echo -n "." ++ done ++ else ++ echo -n "$desc is already stopped" ++ fi ++ ++ rm -f /var/lock/subsystem/pacemaker ++ rm -f /var/run/${prog}.pid ++ killall -q -9 'crmd stonithd attrd cib lrmd pacemakerd pacemaker_remoted' ++} ++ ++stop "pacemaker_remoted" ++exit 0 +diff --git a/extra/ansible/docker/roles/docker-host/files/pcmk_start b/extra/ansible/docker/roles/docker-host/files/pcmk_start +new file mode 100644 +index 0000000..d8b2ba8 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/pcmk_start +@@ -0,0 +1,23 @@ ++#!/bin/bash ++ ++/usr/sbin/ip_start ++sed -i 's@to_syslog:.*yes@to_logfile: yes\nlogfile: /var/log/pacemaker.log@g' /etc/corosync/corosync.conf ++ ++/usr/share/corosync/corosync start > /dev/null 2>&1 ++ ++pid=$(pidof pacemakerd) ++if [ "$?" -ne 0 ]; then ++ mkdir -p /var/run ++ ++ export PCMK_debugfile=$pcmklogs ++ (pacemakerd &) & > /dev/null 2>&1 ++ sleep 5 ++ ++ pid=$(pidof pacemakerd) ++ if [ "$?" -ne 0 ]; then ++ echo "startup of pacemaker failed" ++ exit 1 ++ fi ++ echo "$pid" > /var/run/pacemakerd.pid ++fi ++exit 0 +diff --git a/extra/ansible/docker/roles/docker-host/files/pcmk_stop b/extra/ansible/docker/roles/docker-host/files/pcmk_stop +new file mode 100644 +index 0000000..a8f395a +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/files/pcmk_stop +@@ -0,0 +1,45 @@ ++#!/bin/bash ++status() ++{ ++ pid=$(pidof $1 2>/dev/null) ++ rtrn=$? ++ if [ $rtrn -ne 0 ]; then ++ echo "$1 is stopped" ++ else ++ echo "$1 (pid $pid) is running..." ++ fi ++ return $rtrn ++} ++stop() ++{ ++ desc="Pacemaker Cluster Manager" ++ prog=$1 ++ shutdown_prog=$prog ++ ++ if ! status $prog > /dev/null 2>&1; then ++ shutdown_prog="crmd" ++ fi ++ ++ cname=$(crm_node --name) ++ crm_attribute -N $cname -n standby -v true -l reboot ++ ++ if status $shutdown_prog > /dev/null 2>&1; then ++ kill -TERM $(pidof $prog) > /dev/null 2>&1 ++ ++ while status $prog > /dev/null 2>&1; do ++ sleep 1 ++ echo -n "." ++ done ++ else ++ echo -n "$desc is already stopped" ++ fi ++ ++ rm -f /var/lock/subsystem/pacemaker ++ rm -f /var/run/${prog}.pid ++ killall -q -9 'crmd stonithd attrd cib lrmd pacemakerd pacemaker_remoted' ++} ++ ++stop "pacemakerd" ++/usr/share/corosync/corosync stop > /dev/null 2>&1 ++killall -q -9 'corosync' ++exit 0 +diff --git a/extra/ansible/docker/roles/docker-host/tasks/main.yml b/extra/ansible/docker/roles/docker-host/tasks/main.yml +new file mode 100644 +index 0000000..ce69adf +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/tasks/main.yml +@@ -0,0 +1,77 @@ ++--- ++#local_action: command /usr/bin/take_out_of_pool {{ inventory_hostname }} ++- name: Update docker ++ yum: pkg=docker state=latest ++- name: Start docker ++ service: name=docker state=started enabled=yes ++- name: Install helper ++ copy: src=docker-enter dest=/usr/sbin/ mode=0755 ++- name: Download image ++ shell: docker pull {{ base_image }} ++- name: Cleanup kill ++ shell: docker kill $(docker ps -a | grep {{ prefix }} | awk '{print $1}') || echo "Nothing to kill" ++- name: Cleanup remove ++ shell: docker rm $(docker ps -a | grep {{ prefix }} | awk '{print $1}') || echo "Nothing to remove" ++- name: Cleanup docker skeleton ++ file: path={{ prefix }} state=absent ++- name: Create docker skeleton ++ file: path={{ prefix }}/{{ item }} state=directory recurse=yes ++ with_items: ++ - rpms ++ - repos ++ - bin_files ++ - launch_scripts ++- name: Create IP helper ++ template: src=ip_start.j2 dest={{ prefix }}/bin_files/ip_start mode=0755 ++- name: Copy helper scripts ++ copy: src={{ item }} dest={{ prefix }}/bin_files/{{ item }} mode=0755 ++ with_items: ++ - pcmk_stop ++ - pcmk_start ++ - pcmk_remote_stop ++ - pcmk_remote_start ++ - fence_docker_cts ++- name: Copy launch script ++ copy: src=launch.sh dest={{ prefix }}/launch_scripts/launch.sh mode=0755 ++- name: Copy authorized keys ++ shell: cp /root/.ssh/authorized_keys {{ prefix }} ++- name: Create docker file ++ template: src=Dockerfile.j2 dest={{ prefix }}/Dockerfile ++- name: Making image ++ shell: docker build -t {{ prefix }} {{ prefix }} ++- name: Launch images ++ shell: docker run -d -i -t -P -h {{ prefix }}-{{ item }} --name={{ prefix }}-{{ item }} -p 2200{{ item }}:22 $(docker images | grep {{ prefix }}.*latest | awk '{print $3}') /bin/bash ++ with_sequence: count={{ max }} ++- name: Calculate IPs ++ shell: for n in $(seq {{ max }} ); do echo {{ subnet }}.${n}; done | tr '\n' ' ' ++ register: node_ips ++- name: Start the IP ++ shell: docker-enter {{ prefix }}-{{ item }} ip_start ++ with_sequence: count={{ max }} ++- name: Configure cluster ++ shell: docker-enter {{ prefix }}-{{ item }} pcs cluster setup --local --name {{ prefix }} {{ node_ips.stdout }} ++ with_sequence: count={{ max }} ++- name: Start the cluster ++ shell: docker-enter {{ prefix }}-{{ item }} pcmk_start ++ with_sequence: count={{ max }} ++- name: Set cluster options ++ shell: docker-enter {{ prefix }}-1 pcs property set stonith-enabled=false ++- name: Configure VIP ++ shell: docker-enter {{ prefix }}-1 pcs resource create ClusterIP ocf:heartbeat:IPaddr2 ip={{ subnet }}.100 cidr_netmask=32 op monitor interval=30s ++- name: Configure ++ shell: docker-enter {{ prefix }}-1 pcs resource defaults resource-stickiness=100 ++- name: Configure ++ shell: docker-enter {{ prefix }}-1 pcs resource create WebSite apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://localhost/server-status" op monitor interval=1min ++- name: Configure ++ shell: docker-enter {{ prefix }}-1 pcs constraint colocation add WebSite with ClusterIP INFINITY ++- name: Configure ++ shell: docker-enter {{ prefix }}-1 pcs constraint order ClusterIP then WebSite ++- name: Configure ++ shell: docker-enter {{ prefix }}-1 pcs constraint location WebSite prefers {{ prefix }}-1=50 ++# TODO: Enable fencing ++# TODO: Make this a full LAMP stack similar to https://github.com/ansible/ansible-examples/tree/master/lamp_simple ++# TODO: Create a Pacemaker module? ++ ++# run_once: true ++# delegate_to: web01.example.org ++ +diff --git a/extra/ansible/docker/roles/docker-host/templates/Dockerfile.j2 b/extra/ansible/docker/roles/docker-host/templates/Dockerfile.j2 +new file mode 100644 +index 0000000..1d57175 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/templates/Dockerfile.j2 +@@ -0,0 +1,16 @@ ++FROM {{ base_image }} ++ADD /repos /etc/yum.repos.d/ ++#ADD /rpms /root/ ++#RUN yum install -y /root/*.rpm ++ADD /launch_scripts /root/ ++ADD /bin_files /usr/sbin/ ++ ++RUN mkdir -p /root/.ssh; chmod 700 /root/.ssh ++ADD authorized_keys /root/.ssh/ ++ ++RUN yum install -y openssh-server net-tools pacemaker pacemaker-cts resource-agents pcs corosync which fence-agents-common sysvinit-tools ++RUN mkdir -p /etc/pacemaker/ ++RUN echo {{ pacemaker_authkey }} > /etc/pacemaker/authkey ++RUN /usr/sbin/sshd ++ ++ENTRYPOINT ["/root/launch.sh"] +diff --git a/extra/ansible/docker/roles/docker-host/templates/ip_start.j2 b/extra/ansible/docker/roles/docker-host/templates/ip_start.j2 +new file mode 100755 +index 0000000..edbd392 +--- /dev/null ++++ b/extra/ansible/docker/roles/docker-host/templates/ip_start.j2 +@@ -0,0 +1,3 @@ ++offset=$(hostname | sed s/.*-//) ++export OCF_ROOT=/usr/lib/ocf/ OCF_RESKEY_ip={{ subnet }}.${offset} OCF_RESKEY_cidr_netmask=32 ++/usr/lib/ocf/resource.d/heartbeat/IPaddr2 start +diff --git a/extra/ansible/docker/site.yml b/extra/ansible/docker/site.yml +new file mode 100644 +index 0000000..0cc65e4 +--- /dev/null ++++ b/extra/ansible/docker/site.yml +@@ -0,0 +1,12 @@ ++--- ++# See /etc/ansible/hosts or -i hosts ++- hosts: controllers ++ remote_user: root ++ roles: ++ - docker-host ++ ++#- hosts: containers ++# gather_facts: no ++# remote_user: root ++# roles: ++# - docker-container +diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h +index 42f9003..15f1b3c 100644 +--- a/include/crm/msg_xml.h ++++ b/include/crm/msg_xml.h +@@ -194,6 +194,7 @@ + # define XML_RSC_ATTR_INTERLEAVE "interleave" + # define XML_RSC_ATTR_INCARNATION "clone" + # define XML_RSC_ATTR_INCARNATION_MAX "clone-max" ++# define XML_RSC_ATTR_INCARNATION_MIN "clone-min" + # define XML_RSC_ATTR_INCARNATION_NODEMAX "clone-node-max" + # define XML_RSC_ATTR_MASTER_MAX "master-max" + # define XML_RSC_ATTR_MASTER_NODEMAX "master-node-max" +diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h +index 4214959..b95b1e5 100644 +--- a/include/crm/pengine/status.h ++++ b/include/crm/pengine/status.h +@@ -256,7 +256,6 @@ struct resource_s { + int stickiness; + int sort_index; + int failure_timeout; +- int remote_reconnect_interval; + int effective_priority; + int migration_threshold; + +@@ -295,6 +294,7 @@ struct resource_s { + + const char *isolation_wrapper; + gboolean exclusive_discover; ++ int remote_reconnect_interval; + }; + + struct pe_action_s { +@@ -324,6 +324,26 @@ struct pe_action_s { + GHashTable *meta; + GHashTable *extra; + ++ /* ++ * These two varables are associated with the constraint logic ++ * that involves first having one or more actions runnable before ++ * then allowing this action to execute. ++ * ++ * These varables are used with features such as 'clone-min' which ++ * requires at minimum X number of cloned instances to be running ++ * before an order dependency can run. Another option that uses ++ * this is 'require-all=false' in ordering constrants. This option ++ * says "only required one instance of a resource to start before ++ * allowing dependencies to start" basicall require-all=false is ++ * the same as clone-min=1. ++ */ ++ ++ /* current number of known runnable actions in the before list. */ ++ int runnable_before; ++ /* the number of "before" runnable actions required for this action ++ * to be considered runnable */ ++ int required_runnable_before; ++ + GListPtr actions_before; /* action_warpper_t* */ + GListPtr actions_after; /* action_warpper_t* */ + }; +diff --git a/lib/cib/Makefile.am b/lib/cib/Makefile.am +index e84f4f7..1e50511 100644 +--- a/lib/cib/Makefile.am ++++ b/lib/cib/Makefile.am +@@ -28,7 +28,7 @@ noinst_HEADERS = + libcib_la_SOURCES = cib_ops.c cib_utils.c cib_client.c cib_native.c cib_attrs.c + libcib_la_SOURCES += cib_file.c cib_remote.c + +-libcib_la_LDFLAGS = -version-info 4:1:0 -L$(top_builddir)/lib/pengine/.libs ++libcib_la_LDFLAGS = -version-info 4:2:0 -L$(top_builddir)/lib/pengine/.libs + libcib_la_LIBADD = $(CRYPTOLIB) $(top_builddir)/lib/pengine/libpe_rules.la $(top_builddir)/lib/common/libcrmcommon.la + libcib_la_CFLAGS = -I$(top_srcdir) + +diff --git a/lib/cluster/Makefile.am b/lib/cluster/Makefile.am +index 29413ba..29daeb2 100644 +--- a/lib/cluster/Makefile.am ++++ b/lib/cluster/Makefile.am +@@ -28,7 +28,7 @@ header_HEADERS = + lib_LTLIBRARIES = libcrmcluster.la + + libcrmcluster_la_SOURCES = election.c cluster.c membership.c +-libcrmcluster_la_LDFLAGS = -version-info 4:2:0 $(CLUSTERLIBS) ++libcrmcluster_la_LDFLAGS = -version-info 5:0:1 $(CLUSTERLIBS) + libcrmcluster_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la $(top_builddir)/lib/fencing/libstonithd.la + libcrmcluster_la_DEPENDENCIES = $(top_builddir)/lib/common/libcrmcommon.la $(top_builddir)/lib/fencing/libstonithd.la + +diff --git a/lib/common/Makefile.am b/lib/common/Makefile.am +index a593f40..f5c0766 100644 +--- a/lib/common/Makefile.am ++++ b/lib/common/Makefile.am +@@ -37,7 +37,7 @@ if BUILD_CIBSECRETS + libcrmcommon_la_SOURCES += cib_secrets.c + endif + +-libcrmcommon_la_LDFLAGS = -version-info 7:0:4 ++libcrmcommon_la_LDFLAGS = -version-info 8:0:5 + libcrmcommon_la_LIBADD = @LIBADD_DL@ $(GNUTLSLIBS) + libcrmcommon_la_SOURCES += $(top_builddir)/lib/gnu/md5.c + +diff --git a/lib/fencing/Makefile.am b/lib/fencing/Makefile.am +index 2bdcfeb..fbe02e4 100644 +--- a/lib/fencing/Makefile.am ++++ b/lib/fencing/Makefile.am +@@ -25,7 +25,7 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + lib_LTLIBRARIES = libstonithd.la + + libstonithd_la_SOURCES = st_client.c +-libstonithd_la_LDFLAGS = -version-info 3:2:1 ++libstonithd_la_LDFLAGS = -version-info 3:3:1 + libstonithd_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la + + AM_CFLAGS = $(AM_CPPFLAGS) +diff --git a/lib/lrmd/Makefile.am b/lib/lrmd/Makefile.am +index f961ae1..820654c 100644 +--- a/lib/lrmd/Makefile.am ++++ b/lib/lrmd/Makefile.am +@@ -25,7 +25,7 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + lib_LTLIBRARIES = liblrmd.la + + liblrmd_la_SOURCES = lrmd_client.c proxy_common.c +-liblrmd_la_LDFLAGS = -version-info 3:0:2 ++liblrmd_la_LDFLAGS = -version-info 3:1:2 + liblrmd_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la \ + $(top_builddir)/lib/services/libcrmservice.la \ + $(top_builddir)/lib/fencing/libstonithd.la +diff --git a/lib/pengine/Makefile.am b/lib/pengine/Makefile.am +index 78da075..60d1770 100644 +--- a/lib/pengine/Makefile.am ++++ b/lib/pengine/Makefile.am +@@ -26,11 +26,11 @@ lib_LTLIBRARIES = libpe_rules.la libpe_status.la + ## SOURCES + noinst_HEADERS = unpack.h variant.h + +-libpe_rules_la_LDFLAGS = -version-info 2:4:0 ++libpe_rules_la_LDFLAGS = -version-info 2:5:0 + libpe_rules_la_SOURCES = rules.c common.c + libpe_rules_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la + +-libpe_status_la_LDFLAGS = -version-info 8:0:4 ++libpe_status_la_LDFLAGS = -version-info 9:0:5 + libpe_status_la_SOURCES = status.c unpack.c utils.c complex.c native.c group.c clone.c rules.c common.c + libpe_status_la_LIBADD = @CURSESLIBS@ $(top_builddir)/lib/common/libcrmcommon.la + +diff --git a/lib/services/dbus.c b/lib/services/dbus.c +index 6341fc5..e2efecb 100644 +--- a/lib/services/dbus.c ++++ b/lib/services/dbus.c +@@ -64,11 +64,14 @@ pcmk_dbus_find_error(const char *method, DBusPendingCall* pending, DBusMessage * + } else { + DBusMessageIter args; + int dtype = dbus_message_get_type(reply); ++ char *sig; + + switch(dtype) { + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + dbus_message_iter_init(reply, &args); +- crm_trace("Call to %s returned '%s'", method, dbus_message_iter_get_signature(&args)); ++ sig = dbus_message_iter_get_signature(&args); ++ crm_trace("Call to %s returned '%s'", method, sig); ++ dbus_free(sig); + break; + case DBUS_MESSAGE_TYPE_INVALID: + error.message = "Invalid reply"; +@@ -217,11 +220,14 @@ bool pcmk_dbus_type_check(DBusMessage *msg, DBusMessageIter *field, int expected + + if(dtype != expected) { + DBusMessageIter args; ++ char *sig; + + dbus_message_iter_init(msg, &args); ++ sig = dbus_message_iter_get_signature(&args); + do_crm_log_alias(LOG_ERR, __FILE__, function, line, +- "Unexepcted DBus type, expected %c in '%s' instead of %c", +- expected, dbus_message_iter_get_signature(&args), dtype); ++ "Unexpected DBus type, expected %c in '%s' instead of %c", ++ expected, sig, dtype); ++ dbus_free(sig); + return FALSE; + } + +diff --git a/lib/services/services.c b/lib/services/services.c +index 08bff88..7e2b9f7 100644 +--- a/lib/services/services.c ++++ b/lib/services/services.c +@@ -348,6 +348,34 @@ services_action_create_generic(const char *exec, const char *args[]) + return op; + } + ++#if SUPPORT_DBUS ++/* ++ * \internal ++ * \brief Update operation's pending DBus call, unreferencing old one if needed ++ * ++ * \param[in,out] op Operation to modify ++ * \param[in] pending Pending call to set ++ */ ++void ++services_set_op_pending(svc_action_t *op, DBusPendingCall *pending) ++{ ++ if (op->opaque->pending && (op->opaque->pending != pending)) { ++ if (pending) { ++ crm_info("Lost pending DBus call (%p)", op->opaque->pending); ++ } else { ++ crm_trace("Done with pending DBus call (%p)", op->opaque->pending); ++ } ++ dbus_pending_call_unref(op->opaque->pending); ++ } ++ op->opaque->pending = pending; ++ if (pending) { ++ crm_trace("Updated pending DBus call (%p)", pending); ++ } else { ++ crm_trace("Cleared pending DBus call"); ++ } ++} ++#endif ++ + void + services_action_cleanup(svc_action_t * op) + { +diff --git a/lib/services/services_private.h b/lib/services/services_private.h +index 183afb5..a98cd91 100644 +--- a/lib/services/services_private.h ++++ b/lib/services/services_private.h +@@ -63,4 +63,8 @@ void handle_blocked_ops(void); + + gboolean is_op_blocked(const char *rsc); + ++#if SUPPORT_DBUS ++void services_set_op_pending(svc_action_t *op, DBusPendingCall *pending); ++#endif ++ + #endif /* __MH_SERVICES_PRIVATE_H__ */ +diff --git a/lib/services/systemd.c b/lib/services/systemd.c +index 749d61c..e1e1bc9 100644 +--- a/lib/services/systemd.c ++++ b/lib/services/systemd.c +@@ -461,7 +461,12 @@ systemd_async_dispatch(DBusPendingCall *pending, void *user_data) + + if(op) { + crm_trace("Got result: %p for %p for %s, %s", reply, pending, op->rsc, op->action); +- op->opaque->pending = NULL; ++ if (pending == op->opaque->pending) { ++ op->opaque->pending = NULL; ++ } else { ++ crm_info("Received unexpected reply for pending DBus call (%p vs %p)", ++ op->opaque->pending, pending); ++ } + systemd_exec_result(reply, op); + + } else { +@@ -499,10 +504,7 @@ systemd_unit_check(const char *name, const char *state, void *userdata) + } + + if (op->synchronous == FALSE) { +- if (op->opaque->pending) { +- dbus_pending_call_unref(op->opaque->pending); +- } +- op->opaque->pending = NULL; ++ services_set_op_pending(op, NULL); + operation_finalize(op); + } + } +@@ -535,7 +537,7 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) + return op->rc == PCMK_OCF_OK; + } else if (pending) { + dbus_pending_call_ref(pending); +- op->opaque->pending = pending; ++ services_set_op_pending(op, pending); + return TRUE; + } + +@@ -617,8 +619,7 @@ systemd_unit_exec_with_unit(svc_action_t * op, const char *unit) + + dbus_message_unref(msg); + if(pending) { +- dbus_pending_call_ref(pending); +- op->opaque->pending = pending; ++ services_set_op_pending(op, pending); + return TRUE; + } + return FALSE; +diff --git a/lib/transition/Makefile.am b/lib/transition/Makefile.am +index 8ce7775..04d18fe 100644 +--- a/lib/transition/Makefile.am ++++ b/lib/transition/Makefile.am +@@ -27,7 +27,7 @@ lib_LTLIBRARIES = libtransitioner.la + noinst_HEADERS = + libtransitioner_la_SOURCES = unpack.c graph.c utils.c + +-libtransitioner_la_LDFLAGS = -version-info 2:3:0 ++libtransitioner_la_LDFLAGS = -version-info 2:4:0 + libtransitioner_la_CFLAGS = -I$(top_builddir) + libtransitioner_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la + +diff --git a/pengine/Makefile.am b/pengine/Makefile.am +index 31532cf..0e12a1f 100644 +--- a/pengine/Makefile.am ++++ b/pengine/Makefile.am +@@ -61,7 +61,7 @@ endif + noinst_HEADERS = allocate.h utils.h pengine.h + #utils.h pengine.h + +-libpengine_la_LDFLAGS = -version-info 8:0:4 ++libpengine_la_LDFLAGS = -version-info 9:0:5 + # -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version + libpengine_la_SOURCES = pengine.c allocate.c utils.c constraints.c + libpengine_la_SOURCES += native.c group.c clone.c master.c graph.c utilization.c +diff --git a/pengine/allocate.c b/pengine/allocate.c +index 68cafd4..ec5a18d 100644 +--- a/pengine/allocate.c ++++ b/pengine/allocate.c +@@ -1962,7 +1962,6 @@ expand_node_list(GListPtr list) + if(node_list) { + existing_len = strlen(node_list); + } +- + crm_trace("Adding %s (%dc) at offset %d", node->details->uname, len - 2, existing_len); + node_list = realloc_safe(node_list, len + existing_len); + sprintf(node_list + existing_len, "%s%s", existing_len == 0 ? "":" ", node->details->uname); +diff --git a/pengine/allocate.h b/pengine/allocate.h +index f6602c6..73f750e 100644 +--- a/pengine/allocate.h ++++ b/pengine/allocate.h +@@ -171,5 +171,6 @@ extern enum pe_graph_flags clone_update_actions(action_t * first, action_t * the + enum pe_action_flags filter, enum pe_ordering type); + + gboolean update_action_flags(action_t * action, enum pe_action_flags flags); ++gboolean update_action(action_t * action); + + #endif +diff --git a/pengine/clone.c b/pengine/clone.c +index 3840a0a..ebf53ed 100644 +--- a/pengine/clone.c ++++ b/pengine/clone.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #define VARIANT_CLONE 1 + #include +@@ -1338,6 +1339,8 @@ clone_update_actions(action_t * first, action_t * then, node_t * node, enum pe_a + changed |= native_update_actions(first, then, node, flags, filter, type); + + for (; gIter != NULL; gIter = gIter->next) { ++ enum pe_graph_flags child_changed = pe_graph_none; ++ GListPtr lpc = NULL; + resource_t *child = (resource_t *) gIter->data; + action_t *child_action = find_first_action(child->actions, NULL, then->task, node); + +@@ -1345,9 +1348,17 @@ clone_update_actions(action_t * first, action_t * then, node_t * node, enum pe_a + enum pe_action_flags child_flags = child->cmds->action_flags(child_action, node); + + if (is_set(child_flags, pe_action_runnable)) { +- changed |= ++ ++ child_changed |= + child->cmds->update_actions(first, child_action, node, flags, filter, type); + } ++ changed |= child_changed; ++ if (child_changed & pe_graph_updated_then) { ++ for (lpc = child_action->actions_after; lpc != NULL; lpc = lpc->next) { ++ action_wrapper_t *other = (action_wrapper_t *) lpc->data; ++ update_action(other->action); ++ } ++ } + } + } + } +diff --git a/pengine/constraints.c b/pengine/constraints.c +index 1f44811..7527aa6 100644 +--- a/pengine/constraints.c ++++ b/pengine/constraints.c +@@ -256,7 +256,7 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) + resource_t *rsc_then = NULL; + resource_t *rsc_first = NULL; + gboolean invert_bool = TRUE; +- gboolean require_all = TRUE; ++ int min_required_before = 0; + enum pe_order_kind kind = pe_order_kind_mandatory; + enum pe_ordering cons_weight = pe_order_optional; + +@@ -351,7 +351,15 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) + && crm_is_true(require_all_s) == FALSE + && rsc_first->variant >= pe_clone) { + +- require_all = FALSE; ++ /* require-all=false means only one instance of the clone is required */ ++ min_required_before = 1; ++ } else if (rsc_first->variant >= pe_clone) { ++ const char *min_clones_s = g_hash_table_lookup(rsc_first->meta, XML_RSC_ATTR_INCARNATION_MIN); ++ if (min_clones_s) { ++ /* if clone min is set, we require at a minimum X number of instances ++ * to be runnable before allowing dependencies to be runnable. */ ++ min_required_before = crm_parse_int(min_clones_s, "0"); ++ } + } + + cons_weight = pe_order_optional; +@@ -368,22 +376,31 @@ unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set) + cons_weight |= get_flags(id, kind, action_first, action_then, FALSE); + } + +- if (require_all == FALSE) { ++ /* If there is a minimum number of instances that must be runnable before ++ * the 'then' action is runnable, we use a pseudo action as an intermediate step ++ * start min number of clones -> pseudo action is runnable -> dependency runnable. */ ++ if (min_required_before) { + GListPtr rIter = NULL; + char *task = crm_concat(CRM_OP_RELAXED_CLONE, id, ':'); + action_t *unordered_action = get_pseudo_op(task, data_set); + free(task); + ++ /* require the pseudo action to have "min_required_before" number of ++ * actions to be considered runnable before allowing the pseudo action ++ * to be runnable. */ ++ unordered_action->required_runnable_before = min_required_before; + update_action_flags(unordered_action, pe_action_requires_any); + + for (rIter = rsc_first->children; id && rIter; rIter = rIter->next) { + resource_t *child = rIter->data; +- ++ /* order each clone instance before the pseudo action */ + custom_action_order(child, generate_op_key(child->id, action_first, 0), NULL, + NULL, NULL, unordered_action, + pe_order_one_or_more | pe_order_implies_then_printed, data_set); + } + ++ /* order the "then" dependency to occur after the pseudo action only if ++ * the pseudo action is runnable */ + order_id = custom_action_order(NULL, NULL, unordered_action, + rsc_then, generate_op_key(rsc_then->id, action_then, 0), NULL, + cons_weight | pe_order_runnable_left, data_set); +diff --git a/pengine/graph.c b/pengine/graph.c +index 9cfede6..3d832f0 100644 +--- a/pengine/graph.c ++++ b/pengine/graph.c +@@ -29,7 +29,6 @@ + #include + #include + +-gboolean update_action(action_t * action); + void update_colo_start_chain(action_t * action); + gboolean rsc_update_action(action_t * first, action_t * then, enum pe_ordering type); + +@@ -261,8 +260,16 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac + pe_action_runnable, pe_order_one_or_more); + + } else if (is_set(flags, pe_action_runnable)) { +- if (update_action_flags(then, pe_action_runnable)) { +- changed |= pe_graph_updated_then; ++ /* alright. a "first" action is considered runnable, incremente ++ * the 'runnable_before' counter */ ++ then->runnable_before++; ++ ++ /* if the runnable before count for then exceeds the required number ++ * of "before" runnable actions... mark then as runnable */ ++ if (then->runnable_before >= then->required_runnable_before) { ++ if (update_action_flags(then, pe_action_runnable)) { ++ changed |= pe_graph_updated_then; ++ } + } + } + if (changed) { +@@ -456,6 +463,18 @@ update_action(action_t * then) + pe_action_pseudo) ? "pseudo" : then->node ? then->node->details->uname : ""); + + if (is_set(then->flags, pe_action_requires_any)) { ++ /* initialize current known runnable before actions to 0 ++ * from here as graph_update_action is called for each of ++ * then's before actions, this number will increment as ++ * runnable 'first' actions are encountered */ ++ then->runnable_before = 0; ++ ++ /* for backwards compatibility with previous options that use ++ * the 'requires_any' flag, initalize required to 1 if it is ++ * not set. */ ++ if (then->required_runnable_before == 0) { ++ then->required_runnable_before = 1; ++ } + clear_bit(then->flags, pe_action_runnable); + /* We are relying on the pe_order_one_or_more clause of + * graph_update_action(), called as part of the: +diff --git a/pengine/native.c b/pengine/native.c +index b93f8da..7d5f602 100644 +--- a/pengine/native.c ++++ b/pengine/native.c +@@ -2817,8 +2817,7 @@ native_create_probe(resource_t * rsc, node_t * node, action_t * complete, + } + + static void +-native_start_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_stonith, +- pe_working_set_t * data_set) ++native_start_constraints(resource_t * rsc, action_t * stonith_op, pe_working_set_t * data_set) + { + node_t *target = stonith_op ? stonith_op->node : NULL; + +@@ -2893,14 +2892,24 @@ find_fence_target_node_actions(GListPtr search_list, const char *key, node_t *fe + } + + static void +-native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_stonith, +- pe_working_set_t * data_set) ++native_stop_constraints(resource_t * rsc, action_t * stonith_op, pe_working_set_t * data_set) + { + char *key = NULL; + GListPtr gIter = NULL; + GListPtr action_list = NULL; ++ ++ action_t *start = NULL; + resource_t *top = uber_parent(rsc); + ++ key = start_key(rsc); ++ action_list = find_actions(rsc->actions, key, NULL); ++ if(action_list) { ++ start = action_list->data; ++ } ++ ++ g_list_free(action_list); ++ free(key); ++ + key = stop_key(rsc); + action_list = find_fence_target_node_actions(rsc->actions, key, stonith_op->node, data_set); + free(key); +@@ -2932,7 +2941,7 @@ native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_sto + update_action_flags(action, pe_action_runnable); + update_action_flags(action, pe_action_implied_by_stonith); + +- { ++ if(start == NULL || start->needs > rsc_req_quorum) { + enum pe_ordering flags = pe_order_optional; + action_t *parent_stop = find_first_action(top->actions, NULL, RSC_STOP, NULL); + +@@ -3032,7 +3041,8 @@ native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_sto + crm_trace("here - 1"); + update_action_flags(action, pe_action_pseudo); + update_action_flags(action, pe_action_runnable); +- if (is_stonith == FALSE) { ++ ++ if (start == NULL || start->needs > rsc_req_quorum) { + order_actions(stonith_op, action, pe_order_preserve|pe_order_optional); + } + } +@@ -3044,8 +3054,6 @@ native_stop_constraints(resource_t * rsc, action_t * stonith_op, gboolean is_sto + void + rsc_stonith_ordering(resource_t * rsc, action_t * stonith_op, pe_working_set_t * data_set) + { +- gboolean is_stonith = FALSE; +- + if (rsc->children) { + GListPtr gIter = NULL; + +@@ -3063,11 +3071,11 @@ rsc_stonith_ordering(resource_t * rsc, action_t * stonith_op, pe_working_set_t * + } + + /* Start constraints */ +- native_start_constraints(rsc, stonith_op, is_stonith, data_set); ++ native_start_constraints(rsc, stonith_op, data_set); + + /* Stop constraints */ + if (stonith_op) { +- native_stop_constraints(rsc, stonith_op, is_stonith, data_set); ++ native_stop_constraints(rsc, stonith_op, data_set); + } + } + +diff --git a/pengine/regression.sh b/pengine/regression.sh +index d184798..7f73f92 100755 +--- a/pengine/regression.sh ++++ b/pengine/regression.sh +@@ -31,6 +31,20 @@ info Performing the following tests from $io_dir + create_mode="false" + + echo "" ++do_test cloned_start_one "order first clone then clone... first clone_min=2" ++do_test cloned_start_two "order first clone then clone... first clone_min=2" ++do_test cloned_stop_one "order first clone then clone... first clone_min=2" ++do_test cloned_stop_two "order first clone then clone... first clone_min=2" ++do_test clone_min_interleave_start_one "order first clone then clone... first clone_min=2 and then has interleave=true" ++do_test clone_min_interleave_start_two "order first clone then clone... first clone_min=2 and then has interleave=true" ++do_test clone_min_interleave_stop_one "order first clone then clone... first clone_min=2 and then has interleave=true" ++do_test clone_min_interleave_stop_two "order first clone then clone... first clone_min=2 and then has interleave=true" ++do_test clone_min_start_one "order first clone then primitive... first clone_min=2" ++do_test clone_min_start_two "order first clone then primitive... first clone_min=2" ++do_test clone_min_stop_all "order first clone then primitive... first clone_min=2" ++do_test clone_min_stop_one "order first clone then primitive... first clone_min=2" ++do_test clone_min_stop_two "order first clone then primitive... first clone_min=2" ++ + do_test simple1 "Offline " + do_test simple2 "Start " + do_test simple3 "Start 2 " +diff --git a/pengine/test10/bug-5186-partial-migrate.dot b/pengine/test10/bug-5186-partial-migrate.dot +index 033d41d..65f5616 100644 +--- a/pengine/test10/bug-5186-partial-migrate.dot ++++ b/pengine/test10/bug-5186-partial-migrate.dot +@@ -66,13 +66,10 @@ + "stonith 'reboot' bl460g1n7" -> "clnDiskd1_stop_0" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "clnDiskd2_stop_0" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "clnPing_stop_0" [ style = bold] +-"stonith 'reboot' bl460g1n7" -> "grpStonith8_stop_0" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "prmDiskd1_stop_0 bl460g1n7" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "prmDiskd2_stop_0 bl460g1n7" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "prmDummy_stop_0 bl460g1n7" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "prmPing_stop_0 bl460g1n7" [ style = bold] +-"stonith 'reboot' bl460g1n7" -> "prmStonith8-1_stop_0 bl460g1n7" [ style = bold] +-"stonith 'reboot' bl460g1n7" -> "prmStonith8-2_stop_0 bl460g1n7" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "prmVM2_stop_0 bl460g1n7" [ style = bold] + "stonith 'reboot' bl460g1n7" -> "stonith_complete" [ style = bold] + "stonith 'reboot' bl460g1n7" [ style=bold color="green" fontcolor="black"] +diff --git a/pengine/test10/bug-5186-partial-migrate.exp b/pengine/test10/bug-5186-partial-migrate.exp +index 216d962..bc058ea 100644 +--- a/pengine/test10/bug-5186-partial-migrate.exp ++++ b/pengine/test10/bug-5186-partial-migrate.exp +@@ -104,11 +104,7 @@ + + + +- +- +- +- +- ++ + + + +@@ -182,9 +178,6 @@ + + + +- +- +- + + + +@@ -229,9 +222,6 @@ + + + +- +- +- + + + +diff --git a/pengine/test10/bug-5186-partial-migrate.summary b/pengine/test10/bug-5186-partial-migrate.summary +index f848c97..5e62a23 100644 +--- a/pengine/test10/bug-5186-partial-migrate.summary ++++ b/pengine/test10/bug-5186-partial-migrate.summary +@@ -35,18 +35,22 @@ Transition Summary: + + Executing cluster transition: + * Resource action: prmVM2 stop on bl460g1n6 ++ * Pseudo action: grpStonith8_stop_0 ++ * Pseudo action: prmStonith8-2_stop_0 + * Fencing bl460g1n7 (reboot) + * Pseudo action: stonith_complete + * Pseudo action: prmDummy_stop_0 + * Pseudo action: prmVM2_stop_0 +- * Pseudo action: grpStonith8_stop_0 +- * Pseudo action: prmStonith8-2_stop_0 ++ * Pseudo action: prmStonith8-1_stop_0 + * Pseudo action: clnDiskd1_stop_0 + * Pseudo action: clnDiskd2_stop_0 + * Pseudo action: clnPing_stop_0 + * Resource action: prmDummy start on bl460g1n6 + * Resource action: prmVM2 start on bl460g1n8 +- * Pseudo action: prmStonith8-1_stop_0 ++ * Pseudo action: grpStonith8_stopped_0 ++ * Pseudo action: grpStonith8_start_0 ++ * Resource action: prmStonith8-1 start on bl460g1n6 ++ * Resource action: prmStonith8-2 start on bl460g1n6 + * Pseudo action: prmDiskd1_stop_0 + * Pseudo action: clnDiskd1_stopped_0 + * Pseudo action: prmDiskd2_stop_0 +@@ -55,10 +59,6 @@ Executing cluster transition: + * Pseudo action: clnPing_stopped_0 + * Pseudo action: all_stopped + * Resource action: prmVM2 monitor=10000 on bl460g1n8 +- * Pseudo action: grpStonith8_stopped_0 +- * Pseudo action: grpStonith8_start_0 +- * Resource action: prmStonith8-1 start on bl460g1n6 +- * Resource action: prmStonith8-2 start on bl460g1n6 + * Pseudo action: grpStonith8_running_0 + * Resource action: prmStonith8-1 monitor=10000 on bl460g1n6 + * Resource action: prmStonith8-2 monitor=3600000 on bl460g1n6 +diff --git a/pengine/test10/bug-lf-2551.dot b/pengine/test10/bug-lf-2551.dot +index ed80e15..18bca44 100644 +--- a/pengine/test10/bug-lf-2551.dot ++++ b/pengine/test10/bug-lf-2551.dot +@@ -56,7 +56,6 @@ digraph "g" { + "stonith 'reboot' hex-9" -> "cmirrord:3_stop_0 hex-9" [ style = bold] + "stonith 'reboot' hex-9" -> "dlm:3_stop_0 hex-9" [ style = bold] + "stonith 'reboot' hex-9" -> "dummy1_stop_0 hex-9" [ style = bold] +-"stonith 'reboot' hex-9" -> "fencing-sbd_stop_0 hex-9" [ style = bold] + "stonith 'reboot' hex-9" -> "o2cb:3_stop_0 hex-9" [ style = bold] + "stonith 'reboot' hex-9" -> "ocfs2-1:3_stop_0 hex-9" [ style = bold] + "stonith 'reboot' hex-9" -> "stonith_complete" [ style = bold] +diff --git a/pengine/test10/bug-lf-2551.exp b/pengine/test10/bug-lf-2551.exp +index 0af9010..d6266e1 100644 +--- a/pengine/test10/bug-lf-2551.exp ++++ b/pengine/test10/bug-lf-2551.exp +@@ -18,11 +18,7 @@ + + + +- +- +- +- +- ++ + + + +diff --git a/pengine/test10/bug-lf-2551.summary b/pengine/test10/bug-lf-2551.summary +index f8d861c..158eb73 100644 +--- a/pengine/test10/bug-lf-2551.summary ++++ b/pengine/test10/bug-lf-2551.summary +@@ -107,6 +107,7 @@ Transition Summary: + * Stop vm-61 (hex-9) + + Executing cluster transition: ++ * Pseudo action: fencing-sbd_stop_0 + * Resource action: dummy1 monitor=300000 on hex-8 + * Resource action: dummy1 monitor=300000 on hex-7 + * Fencing hex-9 (reboot) +@@ -114,7 +115,7 @@ Executing cluster transition: + * Pseudo action: load_stopped_hex-8 + * Pseudo action: load_stopped_hex-7 + * Pseudo action: load_stopped_hex-0 +- * Pseudo action: fencing-sbd_stop_0 ++ * Resource action: fencing-sbd start on hex-0 + * Pseudo action: dummy1_stop_0 + * Pseudo action: vm-03_stop_0 + * Pseudo action: vm-06_stop_0 +@@ -133,7 +134,6 @@ Executing cluster transition: + * Pseudo action: vm-57_stop_0 + * Pseudo action: vm-61_stop_0 + * Pseudo action: load_stopped_hex-9 +- * Resource action: fencing-sbd start on hex-0 + * Resource action: dummy1 start on hex-0 + * Pseudo action: base-clone_stop_0 + * Resource action: dummy1 monitor=30000 on hex-0 +diff --git a/pengine/test10/clone_min_interleave_start_one.dot b/pengine/test10/clone_min_interleave_start_one.dot +new file mode 100644 +index 0000000..15ac9be +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_one.dot +@@ -0,0 +1,50 @@ ++ digraph "g" { ++"FAKE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_start_0" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1-clone_start_0" -> "FAKE1_start_0 c7auto1" [ style = bold] ++"FAKE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE1_start_0 c7auto1" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1_start_0 c7auto1" -> "FAKE1_monitor_10000 c7auto1" [ style = bold] ++"FAKE1_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE2-clone_running_0" -> "FAKE3-clone_start_0" [ style = dashed] ++"FAKE2-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE2-clone_start_0" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2-clone_start_0" -> "FAKE2:1_start_0 c7auto3" [ style = dashed] ++"FAKE2-clone_start_0" -> "FAKE2:2_start_0 c7auto1" [ style = dashed] ++"FAKE2-clone_start_0" -> "FAKE2_start_0 c7auto2" [ style = dashed] ++"FAKE2-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE2:1_monitor_10000 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE2:1_start_0 c7auto3" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2:1_start_0 c7auto3" -> "FAKE2:1_monitor_10000 c7auto3" [ style = dashed] ++"FAKE2:1_start_0 c7auto3" -> "FAKE3:1_start_0 c7auto3" [ style = dashed] ++"FAKE2:1_start_0 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE2:2_monitor_10000 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE2:2_start_0 c7auto1" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2:2_start_0 c7auto1" -> "FAKE2:2_monitor_10000 c7auto1" [ style = dashed] ++"FAKE2:2_start_0 c7auto1" -> "FAKE3:2_start_0 c7auto1" [ style = dashed] ++"FAKE2:2_start_0 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_monitor_10000 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_start_0 c7auto2" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2_start_0 c7auto2" -> "FAKE2_monitor_10000 c7auto2" [ style = dashed] ++"FAKE2_start_0 c7auto2" -> "FAKE3_start_0 c7auto2" [ style = dashed] ++"FAKE2_start_0 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE3-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE3-clone_start_0" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3-clone_start_0" -> "FAKE3:1_start_0 c7auto3" [ style = dashed] ++"FAKE3-clone_start_0" -> "FAKE3:2_start_0 c7auto1" [ style = dashed] ++"FAKE3-clone_start_0" -> "FAKE3_start_0 c7auto2" [ style = dashed] ++"FAKE3-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE3:1_monitor_10000 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE3:1_start_0 c7auto3" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3:1_start_0 c7auto3" -> "FAKE3:1_monitor_10000 c7auto3" [ style = dashed] ++"FAKE3:1_start_0 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE3:2_monitor_10000 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE3:2_start_0 c7auto1" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3:2_start_0 c7auto1" -> "FAKE3:2_monitor_10000 c7auto1" [ style = dashed] ++"FAKE3:2_start_0 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_monitor_10000 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_start_0 c7auto2" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3_start_0 c7auto2" -> "FAKE3_monitor_10000 c7auto2" [ style = dashed] ++"FAKE3_start_0 c7auto2" [ style=dashed color="red" fontcolor="black"] ++} +diff --git a/pengine/test10/clone_min_interleave_start_one.exp b/pengine/test10/clone_min_interleave_start_one.exp +new file mode 100644 +index 0000000..b6e0c5d +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_one.exp +@@ -0,0 +1,51 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_start_one.scores b/pengine/test10/clone_min_interleave_start_one.scores +new file mode 100644 +index 0000000..03de018 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_one.scores +@@ -0,0 +1,67 @@ ++Allocation scores: ++clone_color: FAKE1-clone allocation score on c7auto1: 0 ++clone_color: FAKE1-clone allocation score on c7auto2: -INFINITY ++clone_color: FAKE1-clone allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:0 allocation score on c7auto1: 0 ++clone_color: FAKE1:0 allocation score on c7auto2: -INFINITY ++clone_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:1 allocation score on c7auto1: 0 ++clone_color: FAKE1:1 allocation score on c7auto2: -INFINITY ++clone_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:2 allocation score on c7auto1: 0 ++clone_color: FAKE1:2 allocation score on c7auto2: -INFINITY ++clone_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++clone_color: FAKE2-clone allocation score on c7auto1: 0 ++clone_color: FAKE2-clone allocation score on c7auto2: 0 ++clone_color: FAKE2-clone allocation score on c7auto3: 0 ++clone_color: FAKE2:0 allocation score on c7auto1: 0 ++clone_color: FAKE2:0 allocation score on c7auto2: 0 ++clone_color: FAKE2:0 allocation score on c7auto3: 0 ++clone_color: FAKE2:1 allocation score on c7auto1: 0 ++clone_color: FAKE2:1 allocation score on c7auto2: 0 ++clone_color: FAKE2:1 allocation score on c7auto3: 0 ++clone_color: FAKE2:2 allocation score on c7auto1: 0 ++clone_color: FAKE2:2 allocation score on c7auto2: 0 ++clone_color: FAKE2:2 allocation score on c7auto3: 0 ++clone_color: FAKE3-clone allocation score on c7auto1: 0 ++clone_color: FAKE3-clone allocation score on c7auto2: 0 ++clone_color: FAKE3-clone allocation score on c7auto3: 0 ++clone_color: FAKE3:0 allocation score on c7auto1: 0 ++clone_color: FAKE3:0 allocation score on c7auto2: 0 ++clone_color: FAKE3:0 allocation score on c7auto3: 0 ++clone_color: FAKE3:1 allocation score on c7auto1: 0 ++clone_color: FAKE3:1 allocation score on c7auto2: 0 ++clone_color: FAKE3:1 allocation score on c7auto3: 0 ++clone_color: FAKE3:2 allocation score on c7auto1: 0 ++clone_color: FAKE3:2 allocation score on c7auto2: 0 ++clone_color: FAKE3:2 allocation score on c7auto3: 0 ++native_color: FAKE1:0 allocation score on c7auto1: 0 ++native_color: FAKE1:0 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto1: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto1: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:0 allocation score on c7auto1: 0 ++native_color: FAKE2:0 allocation score on c7auto2: 0 ++native_color: FAKE2:0 allocation score on c7auto3: 0 ++native_color: FAKE2:1 allocation score on c7auto1: 0 ++native_color: FAKE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE2:1 allocation score on c7auto3: 0 ++native_color: FAKE2:2 allocation score on c7auto1: 0 ++native_color: FAKE2:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE3:0 allocation score on c7auto1: 0 ++native_color: FAKE3:0 allocation score on c7auto2: 0 ++native_color: FAKE3:0 allocation score on c7auto3: 0 ++native_color: FAKE3:1 allocation score on c7auto1: 0 ++native_color: FAKE3:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE3:1 allocation score on c7auto3: 0 ++native_color: FAKE3:2 allocation score on c7auto1: 0 ++native_color: FAKE3:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE3:2 allocation score on c7auto3: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 +diff --git a/pengine/test10/clone_min_interleave_start_one.summary b/pengine/test10/clone_min_interleave_start_one.summary +new file mode 100644 +index 0000000..b15f68a +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_one.summary +@@ -0,0 +1,39 @@ ++ ++Current cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ ++Transition Summary: ++ * Start FAKE1:0 (c7auto1) ++ * Start FAKE2:0 (c7auto2 - blocked) ++ * Start FAKE2:1 (c7auto3 - blocked) ++ * Start FAKE2:2 (c7auto1 - blocked) ++ * Start FAKE3:0 (c7auto2 - blocked) ++ * Start FAKE3:1 (c7auto3 - blocked) ++ * Start FAKE3:2 (c7auto1 - blocked) ++ ++Executing cluster transition: ++ * Pseudo action: FAKE1-clone_start_0 ++ * Resource action: FAKE1 start on c7auto1 ++ * Pseudo action: FAKE1-clone_running_0 ++ * Resource action: FAKE1 monitor=10000 on c7auto1 ++ ++Revised cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Started: [ c7auto1 ] ++ Stopped: [ c7auto2 c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ +diff --git a/pengine/test10/clone_min_interleave_start_one.xml b/pengine/test10/clone_min_interleave_start_one.xml +new file mode 100644 +index 0000000..fbe99de +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_one.xml +@@ -0,0 +1,155 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_start_two.dot b/pengine/test10/clone_min_interleave_start_two.dot +new file mode 100644 +index 0000000..f99ce32 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_two.dot +@@ -0,0 +1,59 @@ ++ digraph "g" { ++"FAKE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_start_0" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1-clone_start_0" -> "FAKE1:1_start_0 c7auto1" [ style = bold] ++"FAKE1-clone_start_0" -> "FAKE1_start_0 c7auto2" [ style = bold] ++"FAKE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1:1_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE1:1_start_0 c7auto1" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1:1_start_0 c7auto1" -> "FAKE1:1_monitor_10000 c7auto1" [ style = bold] ++"FAKE1:1_start_0 c7auto1" -> "clone-one-or-more:order-FAKE1-clone-FAKE2-clone-mandatory" [ style = bold] ++"FAKE1:1_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE1_monitor_10000 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE1_start_0 c7auto2" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1_start_0 c7auto2" -> "FAKE1_monitor_10000 c7auto2" [ style = bold] ++"FAKE1_start_0 c7auto2" -> "clone-one-or-more:order-FAKE1-clone-FAKE2-clone-mandatory" [ style = bold] ++"FAKE1_start_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE2-clone_running_0" -> "FAKE3-clone_start_0" [ style = bold] ++"FAKE2-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE2-clone_start_0" -> "FAKE2-clone_running_0" [ style = bold] ++"FAKE2-clone_start_0" -> "FAKE2:1_start_0 c7auto2" [ style = bold] ++"FAKE2-clone_start_0" -> "FAKE2:2_start_0 c7auto1" [ style = bold] ++"FAKE2-clone_start_0" -> "FAKE2_start_0 c7auto3" [ style = bold] ++"FAKE2-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE2:1_monitor_10000 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE2:1_start_0 c7auto2" -> "FAKE2-clone_running_0" [ style = bold] ++"FAKE2:1_start_0 c7auto2" -> "FAKE2:1_monitor_10000 c7auto2" [ style = bold] ++"FAKE2:1_start_0 c7auto2" -> "FAKE3:1_start_0 c7auto2" [ style = bold] ++"FAKE2:1_start_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE2:2_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE2:2_start_0 c7auto1" -> "FAKE2-clone_running_0" [ style = bold] ++"FAKE2:2_start_0 c7auto1" -> "FAKE2:2_monitor_10000 c7auto1" [ style = bold] ++"FAKE2:2_start_0 c7auto1" -> "FAKE3:2_start_0 c7auto1" [ style = bold] ++"FAKE2:2_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE2_monitor_10000 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE2_start_0 c7auto3" -> "FAKE2-clone_running_0" [ style = bold] ++"FAKE2_start_0 c7auto3" -> "FAKE2_monitor_10000 c7auto3" [ style = bold] ++"FAKE2_start_0 c7auto3" -> "FAKE3_start_0 c7auto3" [ style = bold] ++"FAKE2_start_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE3-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE3-clone_start_0" -> "FAKE3-clone_running_0" [ style = bold] ++"FAKE3-clone_start_0" -> "FAKE3:1_start_0 c7auto2" [ style = bold] ++"FAKE3-clone_start_0" -> "FAKE3:2_start_0 c7auto1" [ style = bold] ++"FAKE3-clone_start_0" -> "FAKE3_start_0 c7auto3" [ style = bold] ++"FAKE3-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE3:1_monitor_10000 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE3:1_start_0 c7auto2" -> "FAKE3-clone_running_0" [ style = bold] ++"FAKE3:1_start_0 c7auto2" -> "FAKE3:1_monitor_10000 c7auto2" [ style = bold] ++"FAKE3:1_start_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE3:2_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE3:2_start_0 c7auto1" -> "FAKE3-clone_running_0" [ style = bold] ++"FAKE3:2_start_0 c7auto1" -> "FAKE3:2_monitor_10000 c7auto1" [ style = bold] ++"FAKE3:2_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE3_monitor_10000 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE3_start_0 c7auto3" -> "FAKE3-clone_running_0" [ style = bold] ++"FAKE3_start_0 c7auto3" -> "FAKE3_monitor_10000 c7auto3" [ style = bold] ++"FAKE3_start_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"clone-one-or-more:order-FAKE1-clone-FAKE2-clone-mandatory" -> "FAKE2-clone_start_0" [ style = bold] ++"clone-one-or-more:order-FAKE1-clone-FAKE2-clone-mandatory" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/clone_min_interleave_start_two.exp b/pengine/test10/clone_min_interleave_start_two.exp +new file mode 100644 +index 0000000..9846072 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_two.exp +@@ -0,0 +1,326 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_start_two.scores b/pengine/test10/clone_min_interleave_start_two.scores +new file mode 100644 +index 0000000..d443c58 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_two.scores +@@ -0,0 +1,67 @@ ++Allocation scores: ++clone_color: FAKE1-clone allocation score on c7auto1: 0 ++clone_color: FAKE1-clone allocation score on c7auto2: 0 ++clone_color: FAKE1-clone allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:0 allocation score on c7auto1: 0 ++clone_color: FAKE1:0 allocation score on c7auto2: 0 ++clone_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:1 allocation score on c7auto1: 0 ++clone_color: FAKE1:1 allocation score on c7auto2: 0 ++clone_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:2 allocation score on c7auto1: 0 ++clone_color: FAKE1:2 allocation score on c7auto2: 0 ++clone_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++clone_color: FAKE2-clone allocation score on c7auto1: 0 ++clone_color: FAKE2-clone allocation score on c7auto2: 0 ++clone_color: FAKE2-clone allocation score on c7auto3: 0 ++clone_color: FAKE2:0 allocation score on c7auto1: 0 ++clone_color: FAKE2:0 allocation score on c7auto2: 0 ++clone_color: FAKE2:0 allocation score on c7auto3: 0 ++clone_color: FAKE2:1 allocation score on c7auto1: 0 ++clone_color: FAKE2:1 allocation score on c7auto2: 0 ++clone_color: FAKE2:1 allocation score on c7auto3: 0 ++clone_color: FAKE2:2 allocation score on c7auto1: 0 ++clone_color: FAKE2:2 allocation score on c7auto2: 0 ++clone_color: FAKE2:2 allocation score on c7auto3: 0 ++clone_color: FAKE3-clone allocation score on c7auto1: 0 ++clone_color: FAKE3-clone allocation score on c7auto2: 0 ++clone_color: FAKE3-clone allocation score on c7auto3: 0 ++clone_color: FAKE3:0 allocation score on c7auto1: 0 ++clone_color: FAKE3:0 allocation score on c7auto2: 0 ++clone_color: FAKE3:0 allocation score on c7auto3: 0 ++clone_color: FAKE3:1 allocation score on c7auto1: 0 ++clone_color: FAKE3:1 allocation score on c7auto2: 0 ++clone_color: FAKE3:1 allocation score on c7auto3: 0 ++clone_color: FAKE3:2 allocation score on c7auto1: 0 ++clone_color: FAKE3:2 allocation score on c7auto2: 0 ++clone_color: FAKE3:2 allocation score on c7auto3: 0 ++native_color: FAKE1:0 allocation score on c7auto1: 0 ++native_color: FAKE1:0 allocation score on c7auto2: 0 ++native_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto1: 0 ++native_color: FAKE1:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto1: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:0 allocation score on c7auto1: 0 ++native_color: FAKE2:0 allocation score on c7auto2: 0 ++native_color: FAKE2:0 allocation score on c7auto3: 0 ++native_color: FAKE2:1 allocation score on c7auto1: 0 ++native_color: FAKE2:1 allocation score on c7auto2: 0 ++native_color: FAKE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:2 allocation score on c7auto1: 0 ++native_color: FAKE2:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE3:0 allocation score on c7auto1: 0 ++native_color: FAKE3:0 allocation score on c7auto2: 0 ++native_color: FAKE3:0 allocation score on c7auto3: 0 ++native_color: FAKE3:1 allocation score on c7auto1: 0 ++native_color: FAKE3:1 allocation score on c7auto2: 0 ++native_color: FAKE3:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE3:2 allocation score on c7auto1: 0 ++native_color: FAKE3:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE3:2 allocation score on c7auto3: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 +diff --git a/pengine/test10/clone_min_interleave_start_two.summary b/pengine/test10/clone_min_interleave_start_two.summary +new file mode 100644 +index 0000000..9f928f2 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_two.summary +@@ -0,0 +1,59 @@ ++ ++Current cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ ++Transition Summary: ++ * Start FAKE1:0 (c7auto2) ++ * Start FAKE1:1 (c7auto1) ++ * Start FAKE2:0 (c7auto3) ++ * Start FAKE2:1 (c7auto2) ++ * Start FAKE2:2 (c7auto1) ++ * Start FAKE3:0 (c7auto3) ++ * Start FAKE3:1 (c7auto2) ++ * Start FAKE3:2 (c7auto1) ++ ++Executing cluster transition: ++ * Pseudo action: FAKE1-clone_start_0 ++ * Resource action: FAKE1 start on c7auto2 ++ * Resource action: FAKE1 start on c7auto1 ++ * Pseudo action: FAKE1-clone_running_0 ++ * Pseudo action: clone-one-or-more:order-FAKE1-clone-FAKE2-clone-mandatory ++ * Resource action: FAKE1 monitor=10000 on c7auto2 ++ * Resource action: FAKE1 monitor=10000 on c7auto1 ++ * Pseudo action: FAKE2-clone_start_0 ++ * Resource action: FAKE2 start on c7auto3 ++ * Resource action: FAKE2 start on c7auto2 ++ * Resource action: FAKE2 start on c7auto1 ++ * Pseudo action: FAKE2-clone_running_0 ++ * Pseudo action: FAKE3-clone_start_0 ++ * Resource action: FAKE2 monitor=10000 on c7auto3 ++ * Resource action: FAKE2 monitor=10000 on c7auto2 ++ * Resource action: FAKE2 monitor=10000 on c7auto1 ++ * Resource action: FAKE3 start on c7auto3 ++ * Resource action: FAKE3 start on c7auto2 ++ * Resource action: FAKE3 start on c7auto1 ++ * Pseudo action: FAKE3-clone_running_0 ++ * Resource action: FAKE3 monitor=10000 on c7auto3 ++ * Resource action: FAKE3 monitor=10000 on c7auto2 ++ * Resource action: FAKE3 monitor=10000 on c7auto1 ++ ++Revised cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Started: [ c7auto1 c7auto2 ] ++ Stopped: [ c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ +diff --git a/pengine/test10/clone_min_interleave_start_two.xml b/pengine/test10/clone_min_interleave_start_two.xml +new file mode 100644 +index 0000000..2507018 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_start_two.xml +@@ -0,0 +1,154 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_stop_one.dot b/pengine/test10/clone_min_interleave_stop_one.dot +new file mode 100644 +index 0000000..a66ceb6 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_one.dot +@@ -0,0 +1,18 @@ ++ digraph "g" { ++"FAKE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_start_0" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1-clone_start_0" -> "FAKE1_start_0 " [ style = dashed] ++"FAKE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_stop_0" -> "FAKE1-clone_stopped_0" [ style = bold] ++"FAKE1-clone_stop_0" -> "FAKE1_stop_0 c7auto3" [ style = bold] ++"FAKE1-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_stopped_0" -> "FAKE1-clone_start_0" [ style = bold] ++"FAKE1-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1_start_0 " -> "FAKE1-clone_running_0" [ style = dashed] ++"FAKE1_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKE1_stop_0 c7auto3" -> "FAKE1-clone_stopped_0" [ style = bold] ++"FAKE1_stop_0 c7auto3" -> "FAKE1_start_0 " [ style = dashed] ++"FAKE1_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKE1_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/clone_min_interleave_stop_one.exp b/pengine/test10/clone_min_interleave_stop_one.exp +new file mode 100644 +index 0000000..31a15da +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_one.exp +@@ -0,0 +1,74 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_stop_one.scores b/pengine/test10/clone_min_interleave_stop_one.scores +new file mode 100644 +index 0000000..1a98230 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_one.scores +@@ -0,0 +1,67 @@ ++Allocation scores: ++clone_color: FAKE1-clone allocation score on c7auto1: 0 ++clone_color: FAKE1-clone allocation score on c7auto2: 0 ++clone_color: FAKE1-clone allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:0 allocation score on c7auto1: 0 ++clone_color: FAKE1:0 allocation score on c7auto2: 0 ++clone_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:1 allocation score on c7auto1: 1 ++clone_color: FAKE1:1 allocation score on c7auto2: 0 ++clone_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:2 allocation score on c7auto1: 0 ++clone_color: FAKE1:2 allocation score on c7auto2: 1 ++clone_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++clone_color: FAKE2-clone allocation score on c7auto1: 0 ++clone_color: FAKE2-clone allocation score on c7auto2: 0 ++clone_color: FAKE2-clone allocation score on c7auto3: 0 ++clone_color: FAKE2:0 allocation score on c7auto1: 0 ++clone_color: FAKE2:0 allocation score on c7auto2: 0 ++clone_color: FAKE2:0 allocation score on c7auto3: 1 ++clone_color: FAKE2:1 allocation score on c7auto1: 1 ++clone_color: FAKE2:1 allocation score on c7auto2: 0 ++clone_color: FAKE2:1 allocation score on c7auto3: 0 ++clone_color: FAKE2:2 allocation score on c7auto1: 0 ++clone_color: FAKE2:2 allocation score on c7auto2: 1 ++clone_color: FAKE2:2 allocation score on c7auto3: 0 ++clone_color: FAKE3-clone allocation score on c7auto1: 0 ++clone_color: FAKE3-clone allocation score on c7auto2: 0 ++clone_color: FAKE3-clone allocation score on c7auto3: 0 ++clone_color: FAKE3:0 allocation score on c7auto1: 0 ++clone_color: FAKE3:0 allocation score on c7auto2: 0 ++clone_color: FAKE3:0 allocation score on c7auto3: 1 ++clone_color: FAKE3:1 allocation score on c7auto1: 1 ++clone_color: FAKE3:1 allocation score on c7auto2: 0 ++clone_color: FAKE3:1 allocation score on c7auto3: 0 ++clone_color: FAKE3:2 allocation score on c7auto1: 0 ++clone_color: FAKE3:2 allocation score on c7auto2: 1 ++clone_color: FAKE3:2 allocation score on c7auto3: 0 ++native_color: FAKE1:0 allocation score on c7auto1: -INFINITY ++native_color: FAKE1:0 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto1: 1 ++native_color: FAKE1:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto1: 0 ++native_color: FAKE1:2 allocation score on c7auto2: 1 ++native_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:0 allocation score on c7auto1: 0 ++native_color: FAKE2:0 allocation score on c7auto2: 0 ++native_color: FAKE2:0 allocation score on c7auto3: 1 ++native_color: FAKE2:1 allocation score on c7auto1: 1 ++native_color: FAKE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:2 allocation score on c7auto1: 0 ++native_color: FAKE2:2 allocation score on c7auto2: 1 ++native_color: FAKE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE3:0 allocation score on c7auto1: 0 ++native_color: FAKE3:0 allocation score on c7auto2: 0 ++native_color: FAKE3:0 allocation score on c7auto3: 1 ++native_color: FAKE3:1 allocation score on c7auto1: 1 ++native_color: FAKE3:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE3:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE3:2 allocation score on c7auto1: 0 ++native_color: FAKE3:2 allocation score on c7auto2: 1 ++native_color: FAKE3:2 allocation score on c7auto3: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 +diff --git a/pengine/test10/clone_min_interleave_stop_one.summary b/pengine/test10/clone_min_interleave_stop_one.summary +new file mode 100644 +index 0000000..9280b7e +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_one.summary +@@ -0,0 +1,35 @@ ++ ++Current cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ ++Transition Summary: ++ * Stop FAKE1:0 (c7auto3) ++ ++Executing cluster transition: ++ * Pseudo action: FAKE1-clone_stop_0 ++ * Resource action: FAKE1 stop on c7auto3 ++ * Pseudo action: FAKE1-clone_stopped_0 ++ * Pseudo action: FAKE1-clone_start_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: FAKE1-clone_running_0 ++ ++Revised cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Started: [ c7auto1 c7auto2 ] ++ Stopped: [ c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ +diff --git a/pengine/test10/clone_min_interleave_stop_one.xml b/pengine/test10/clone_min_interleave_stop_one.xml +new file mode 100644 +index 0000000..31db5f3 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_one.xml +@@ -0,0 +1,153 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_stop_two.dot b/pengine/test10/clone_min_interleave_stop_two.dot +new file mode 100644 +index 0000000..73f60dd +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_two.dot +@@ -0,0 +1,108 @@ ++ digraph "g" { ++"FAKE1-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_start_0" -> "FAKE1-clone_running_0" [ style = bold] ++"FAKE1-clone_start_0" -> "FAKE1_start_0 " [ style = dashed] ++"FAKE1-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_stop_0" -> "FAKE1-clone_stopped_0" [ style = bold] ++"FAKE1-clone_stop_0" -> "FAKE1_stop_0 c7auto2" [ style = bold] ++"FAKE1-clone_stop_0" -> "FAKE1_stop_0 c7auto3" [ style = bold] ++"FAKE1-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1-clone_stopped_0" -> "FAKE1-clone_start_0" [ style = bold] ++"FAKE1-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE1_start_0 " -> "FAKE1-clone_running_0" [ style = dashed] ++"FAKE1_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKE1_stop_0 c7auto2" -> "FAKE1-clone_stopped_0" [ style = bold] ++"FAKE1_stop_0 c7auto2" -> "FAKE1_start_0 " [ style = dashed] ++"FAKE1_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKE1_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE1_stop_0 c7auto3" -> "FAKE1-clone_stopped_0" [ style = bold] ++"FAKE1_stop_0 c7auto3" -> "FAKE1_start_0 " [ style = dashed] ++"FAKE1_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKE1_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE2-clone_running_0" -> "FAKE3-clone_start_0" [ style = dashed] ++"FAKE2-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE2-clone_start_0" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2-clone_start_0" -> "FAKE2_start_0 c7auto1" [ style = dashed] ++"FAKE2-clone_start_0" -> "FAKE2_start_0 c7auto2" [ style = dashed] ++"FAKE2-clone_start_0" -> "FAKE2_start_0 c7auto3" [ style = dashed] ++"FAKE2-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE2-clone_stop_0" -> "FAKE2-clone_stopped_0" [ style = bold] ++"FAKE2-clone_stop_0" -> "FAKE2_stop_0 c7auto1" [ style = bold] ++"FAKE2-clone_stop_0" -> "FAKE2_stop_0 c7auto2" [ style = bold] ++"FAKE2-clone_stop_0" -> "FAKE2_stop_0 c7auto3" [ style = bold] ++"FAKE2-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE2-clone_stopped_0" -> "FAKE1-clone_stop_0" [ style = bold] ++"FAKE2-clone_stopped_0" -> "FAKE2-clone_start_0" [ style = dashed] ++"FAKE2-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE2_monitor_10000 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_monitor_10000 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_monitor_10000 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_start_0 c7auto1" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2_start_0 c7auto1" -> "FAKE2_monitor_10000 c7auto1" [ style = dashed] ++"FAKE2_start_0 c7auto1" -> "FAKE3_start_0 c7auto1" [ style = dashed] ++"FAKE2_start_0 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_start_0 c7auto2" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2_start_0 c7auto2" -> "FAKE2_monitor_10000 c7auto2" [ style = dashed] ++"FAKE2_start_0 c7auto2" -> "FAKE3_start_0 c7auto2" [ style = dashed] ++"FAKE2_start_0 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_start_0 c7auto3" -> "FAKE2-clone_running_0" [ style = dashed] ++"FAKE2_start_0 c7auto3" -> "FAKE2_monitor_10000 c7auto3" [ style = dashed] ++"FAKE2_start_0 c7auto3" -> "FAKE3_start_0 c7auto3" [ style = dashed] ++"FAKE2_start_0 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE2_stop_0 c7auto1" -> "FAKE2-clone_stopped_0" [ style = bold] ++"FAKE2_stop_0 c7auto1" -> "FAKE2_start_0 c7auto1" [ style = dashed] ++"FAKE2_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"FAKE2_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE2_stop_0 c7auto2" -> "FAKE1_stop_0 c7auto2" [ style = bold] ++"FAKE2_stop_0 c7auto2" -> "FAKE2-clone_stopped_0" [ style = bold] ++"FAKE2_stop_0 c7auto2" -> "FAKE2_start_0 c7auto2" [ style = dashed] ++"FAKE2_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKE2_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE2_stop_0 c7auto3" -> "FAKE1_stop_0 c7auto3" [ style = bold] ++"FAKE2_stop_0 c7auto3" -> "FAKE2-clone_stopped_0" [ style = bold] ++"FAKE2_stop_0 c7auto3" -> "FAKE2_start_0 c7auto3" [ style = dashed] ++"FAKE2_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKE2_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE3-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE3-clone_start_0" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3-clone_start_0" -> "FAKE3_start_0 c7auto1" [ style = dashed] ++"FAKE3-clone_start_0" -> "FAKE3_start_0 c7auto2" [ style = dashed] ++"FAKE3-clone_start_0" -> "FAKE3_start_0 c7auto3" [ style = dashed] ++"FAKE3-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKE3-clone_stop_0" -> "FAKE3-clone_stopped_0" [ style = bold] ++"FAKE3-clone_stop_0" -> "FAKE3_stop_0 c7auto1" [ style = bold] ++"FAKE3-clone_stop_0" -> "FAKE3_stop_0 c7auto2" [ style = bold] ++"FAKE3-clone_stop_0" -> "FAKE3_stop_0 c7auto3" [ style = bold] ++"FAKE3-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE3-clone_stopped_0" -> "FAKE2-clone_stop_0" [ style = bold] ++"FAKE3-clone_stopped_0" -> "FAKE3-clone_start_0" [ style = dashed] ++"FAKE3-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKE3_monitor_10000 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_monitor_10000 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_monitor_10000 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_start_0 c7auto1" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3_start_0 c7auto1" -> "FAKE3_monitor_10000 c7auto1" [ style = dashed] ++"FAKE3_start_0 c7auto1" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_start_0 c7auto2" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3_start_0 c7auto2" -> "FAKE3_monitor_10000 c7auto2" [ style = dashed] ++"FAKE3_start_0 c7auto2" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_start_0 c7auto3" -> "FAKE3-clone_running_0" [ style = dashed] ++"FAKE3_start_0 c7auto3" -> "FAKE3_monitor_10000 c7auto3" [ style = dashed] ++"FAKE3_start_0 c7auto3" [ style=dashed color="red" fontcolor="black"] ++"FAKE3_stop_0 c7auto1" -> "FAKE2_stop_0 c7auto1" [ style = bold] ++"FAKE3_stop_0 c7auto1" -> "FAKE3-clone_stopped_0" [ style = bold] ++"FAKE3_stop_0 c7auto1" -> "FAKE3_start_0 c7auto1" [ style = dashed] ++"FAKE3_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"FAKE3_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKE3_stop_0 c7auto2" -> "FAKE2_stop_0 c7auto2" [ style = bold] ++"FAKE3_stop_0 c7auto2" -> "FAKE3-clone_stopped_0" [ style = bold] ++"FAKE3_stop_0 c7auto2" -> "FAKE3_start_0 c7auto2" [ style = dashed] ++"FAKE3_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKE3_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE3_stop_0 c7auto3" -> "FAKE2_stop_0 c7auto3" [ style = bold] ++"FAKE3_stop_0 c7auto3" -> "FAKE3-clone_stopped_0" [ style = bold] ++"FAKE3_stop_0 c7auto3" -> "FAKE3_start_0 c7auto3" [ style = dashed] ++"FAKE3_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKE3_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/clone_min_interleave_stop_two.exp b/pengine/test10/clone_min_interleave_stop_two.exp +new file mode 100644 +index 0000000..62fe1e6 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_two.exp +@@ -0,0 +1,270 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_interleave_stop_two.scores b/pengine/test10/clone_min_interleave_stop_two.scores +new file mode 100644 +index 0000000..ee7df92 +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_two.scores +@@ -0,0 +1,67 @@ ++Allocation scores: ++clone_color: FAKE1-clone allocation score on c7auto1: 0 ++clone_color: FAKE1-clone allocation score on c7auto2: -INFINITY ++clone_color: FAKE1-clone allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:0 allocation score on c7auto1: 0 ++clone_color: FAKE1:0 allocation score on c7auto2: -INFINITY ++clone_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:1 allocation score on c7auto1: 1 ++clone_color: FAKE1:1 allocation score on c7auto2: -INFINITY ++clone_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++clone_color: FAKE1:2 allocation score on c7auto1: 0 ++clone_color: FAKE1:2 allocation score on c7auto2: -INFINITY ++clone_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++clone_color: FAKE2-clone allocation score on c7auto1: 0 ++clone_color: FAKE2-clone allocation score on c7auto2: 0 ++clone_color: FAKE2-clone allocation score on c7auto3: 0 ++clone_color: FAKE2:0 allocation score on c7auto1: 0 ++clone_color: FAKE2:0 allocation score on c7auto2: 0 ++clone_color: FAKE2:0 allocation score on c7auto3: 1 ++clone_color: FAKE2:1 allocation score on c7auto1: 1 ++clone_color: FAKE2:1 allocation score on c7auto2: 0 ++clone_color: FAKE2:1 allocation score on c7auto3: 0 ++clone_color: FAKE2:2 allocation score on c7auto1: 0 ++clone_color: FAKE2:2 allocation score on c7auto2: 1 ++clone_color: FAKE2:2 allocation score on c7auto3: 0 ++clone_color: FAKE3-clone allocation score on c7auto1: 0 ++clone_color: FAKE3-clone allocation score on c7auto2: 0 ++clone_color: FAKE3-clone allocation score on c7auto3: 0 ++clone_color: FAKE3:0 allocation score on c7auto1: 0 ++clone_color: FAKE3:0 allocation score on c7auto2: 0 ++clone_color: FAKE3:0 allocation score on c7auto3: 1 ++clone_color: FAKE3:1 allocation score on c7auto1: 1 ++clone_color: FAKE3:1 allocation score on c7auto2: 0 ++clone_color: FAKE3:1 allocation score on c7auto3: 0 ++clone_color: FAKE3:2 allocation score on c7auto1: 0 ++clone_color: FAKE3:2 allocation score on c7auto2: 1 ++clone_color: FAKE3:2 allocation score on c7auto3: 0 ++native_color: FAKE1:0 allocation score on c7auto1: -INFINITY ++native_color: FAKE1:0 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:0 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto1: 1 ++native_color: FAKE1:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto1: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto2: -INFINITY ++native_color: FAKE1:2 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:0 allocation score on c7auto1: 0 ++native_color: FAKE2:0 allocation score on c7auto2: -INFINITY ++native_color: FAKE2:0 allocation score on c7auto3: 1 ++native_color: FAKE2:1 allocation score on c7auto1: 1 ++native_color: FAKE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE2:2 allocation score on c7auto1: 0 ++native_color: FAKE2:2 allocation score on c7auto2: 1 ++native_color: FAKE2:2 allocation score on c7auto3: 0 ++native_color: FAKE3:0 allocation score on c7auto1: 0 ++native_color: FAKE3:0 allocation score on c7auto2: -INFINITY ++native_color: FAKE3:0 allocation score on c7auto3: 1 ++native_color: FAKE3:1 allocation score on c7auto1: 1 ++native_color: FAKE3:1 allocation score on c7auto2: -INFINITY ++native_color: FAKE3:1 allocation score on c7auto3: -INFINITY ++native_color: FAKE3:2 allocation score on c7auto1: 0 ++native_color: FAKE3:2 allocation score on c7auto2: 1 ++native_color: FAKE3:2 allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 +diff --git a/pengine/test10/clone_min_interleave_stop_two.summary b/pengine/test10/clone_min_interleave_stop_two.summary +new file mode 100644 +index 0000000..fb28e0d +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_two.summary +@@ -0,0 +1,53 @@ ++ ++Current cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ ++Transition Summary: ++ * Stop FAKE1:0 (c7auto3) ++ * Stop FAKE1:2 (c7auto2) ++ * Stop FAKE2:0 (Started c7auto3) ++ * Stop FAKE2:1 (Started c7auto1) ++ * Stop FAKE2:2 (Started c7auto2) ++ * Stop FAKE3:0 (Started c7auto3) ++ * Stop FAKE3:1 (Started c7auto1) ++ * Stop FAKE3:2 (Started c7auto2) ++ ++Executing cluster transition: ++ * Pseudo action: FAKE3-clone_stop_0 ++ * Resource action: FAKE3 stop on c7auto3 ++ * Resource action: FAKE3 stop on c7auto1 ++ * Resource action: FAKE3 stop on c7auto2 ++ * Pseudo action: FAKE3-clone_stopped_0 ++ * Pseudo action: FAKE2-clone_stop_0 ++ * Resource action: FAKE2 stop on c7auto3 ++ * Resource action: FAKE2 stop on c7auto1 ++ * Resource action: FAKE2 stop on c7auto2 ++ * Pseudo action: FAKE2-clone_stopped_0 ++ * Pseudo action: FAKE1-clone_stop_0 ++ * Resource action: FAKE1 stop on c7auto3 ++ * Resource action: FAKE1 stop on c7auto2 ++ * Pseudo action: FAKE1-clone_stopped_0 ++ * Pseudo action: FAKE1-clone_start_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: FAKE1-clone_running_0 ++ ++Revised cluster status: ++Online: [ c7auto1 c7auto2 c7auto3 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKE1-clone [FAKE1] ++ Started: [ c7auto1 ] ++ Stopped: [ c7auto2 c7auto3 ] ++ Clone Set: FAKE2-clone [FAKE2] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ Clone Set: FAKE3-clone [FAKE3] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ +diff --git a/pengine/test10/clone_min_interleave_stop_two.xml b/pengine/test10/clone_min_interleave_stop_two.xml +new file mode 100644 +index 0000000..32c2b3b +--- /dev/null ++++ b/pengine/test10/clone_min_interleave_stop_two.xml +@@ -0,0 +1,154 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_start_one.dot b/pengine/test10/clone_min_start_one.dot +new file mode 100644 +index 0000000..3940361 +--- /dev/null ++++ b/pengine/test10/clone_min_start_one.dot +@@ -0,0 +1,20 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 c7auto3" [ style = bold] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE_monitor_10000 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_start_0 c7auto3" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE_start_0 c7auto3" -> "FAKECLONE_monitor_10000 c7auto3" [ style = bold] ++"FAKECLONE_start_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE_monitor_10000 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKE_start_0 c7auto4" -> "FAKE_monitor_10000 c7auto4" [ style = dashed] ++"FAKE_start_0 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++"shooter_monitor_60000 c7auto3" [ style=bold color="green" fontcolor="black"] ++"shooter_start_0 c7auto3" -> "shooter_monitor_60000 c7auto3" [ style = bold] ++"shooter_start_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"shooter_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"shooter_stop_0 c7auto1" -> "shooter_start_0 c7auto3" [ style = bold] ++"shooter_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++} +diff --git a/pengine/test10/clone_min_start_one.exp b/pengine/test10/clone_min_start_one.exp +new file mode 100644 +index 0000000..a6868f6 +--- /dev/null ++++ b/pengine/test10/clone_min_start_one.exp +@@ -0,0 +1,98 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_start_one.scores b/pengine/test10/clone_min_start_one.scores +new file mode 100644 +index 0000000..668689e +--- /dev/null ++++ b/pengine/test10/clone_min_start_one.scores +@@ -0,0 +1,45 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:0 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKE allocation score on c7auto1: -INFINITY ++native_color: FAKE allocation score on c7auto2: -INFINITY ++native_color: FAKE allocation score on c7auto3: -INFINITY ++native_color: FAKE allocation score on c7auto4: 0 ++native_color: FAKECLONE:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: 0 ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/clone_min_start_one.summary b/pengine/test10/clone_min_start_one.summary +new file mode 100644 +index 0000000..ee33e01 +--- /dev/null ++++ b/pengine/test10/clone_min_start_one.summary +@@ -0,0 +1,37 @@ ++ ++Current cluster status: ++Node c7auto1 (1): standby ++Node c7auto2 (2): standby ++Online: [ c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Stopped ++ ++Transition Summary: ++ * Move shooter (Started c7auto1 -> c7auto3) ++ * Start FAKECLONE:0 (c7auto3) ++ * Start FAKE (c7auto4 - blocked) ++ ++Executing cluster transition: ++ * Resource action: shooter stop on c7auto1 ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: all_stopped ++ * Resource action: shooter start on c7auto3 ++ * Resource action: FAKECLONE start on c7auto3 ++ * Pseudo action: FAKECLONE-clone_running_0 ++ * Resource action: shooter monitor=60000 on c7auto3 ++ * Resource action: FAKECLONE monitor=10000 on c7auto3 ++ ++Revised cluster status: ++Node c7auto1 (1): standby ++Node c7auto2 (2): standby ++Online: [ c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto3 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto3 ] ++ Stopped: [ c7auto1 c7auto2 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Stopped ++ +diff --git a/pengine/test10/clone_min_start_one.xml b/pengine/test10/clone_min_start_one.xml +new file mode 100644 +index 0000000..dfb9379 +--- /dev/null ++++ b/pengine/test10/clone_min_start_one.xml +@@ -0,0 +1,155 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_start_two.dot b/pengine/test10/clone_min_start_two.dot +new file mode 100644 +index 0000000..3fe0062 +--- /dev/null ++++ b/pengine/test10/clone_min_start_two.dot +@@ -0,0 +1,22 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE:1_start_0 c7auto1" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 c7auto3" [ style = bold] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE:1_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE:1_start_0 c7auto1" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE:1_start_0 c7auto1" -> "FAKECLONE:1_monitor_10000 c7auto1" [ style = bold] ++"FAKECLONE:1_start_0 c7auto1" -> "clone-one-or-more:order-FAKECLONE-clone-FAKE-mandatory" [ style = bold] ++"FAKECLONE:1_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_monitor_10000 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_start_0 c7auto3" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE_start_0 c7auto3" -> "FAKECLONE_monitor_10000 c7auto3" [ style = bold] ++"FAKECLONE_start_0 c7auto3" -> "clone-one-or-more:order-FAKECLONE-clone-FAKE-mandatory" [ style = bold] ++"FAKECLONE_start_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE_monitor_10000 c7auto4" [ style=bold color="green" fontcolor="black"] ++"FAKE_start_0 c7auto4" -> "FAKE_monitor_10000 c7auto4" [ style = bold] ++"FAKE_start_0 c7auto4" [ style=bold color="green" fontcolor="black"] ++"clone-one-or-more:order-FAKECLONE-clone-FAKE-mandatory" -> "FAKE_start_0 c7auto4" [ style = bold] ++"clone-one-or-more:order-FAKECLONE-clone-FAKE-mandatory" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/clone_min_start_two.exp b/pengine/test10/clone_min_start_two.exp +new file mode 100644 +index 0000000..f7a053c +--- /dev/null ++++ b/pengine/test10/clone_min_start_two.exp +@@ -0,0 +1,121 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_start_two.scores b/pengine/test10/clone_min_start_two.scores +new file mode 100644 +index 0000000..b3bcac0 +--- /dev/null ++++ b/pengine/test10/clone_min_start_two.scores +@@ -0,0 +1,45 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:0 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKE allocation score on c7auto1: -INFINITY ++native_color: FAKE allocation score on c7auto2: -INFINITY ++native_color: FAKE allocation score on c7auto3: -INFINITY ++native_color: FAKE allocation score on c7auto4: 0 ++native_color: FAKECLONE:0 allocation score on c7auto1: 0 ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: 0 ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: 0 ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/clone_min_start_two.summary b/pengine/test10/clone_min_start_two.summary +new file mode 100644 +index 0000000..f0c649c +--- /dev/null ++++ b/pengine/test10/clone_min_start_two.summary +@@ -0,0 +1,36 @@ ++ ++Current cluster status: ++Node c7auto2 (2): standby ++Online: [ c7auto1 c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Stopped ++ ++Transition Summary: ++ * Start FAKECLONE:0 (c7auto3) ++ * Start FAKECLONE:1 (c7auto1) ++ * Start FAKE (c7auto4) ++ ++Executing cluster transition: ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Resource action: FAKECLONE start on c7auto3 ++ * Resource action: FAKECLONE start on c7auto1 ++ * Pseudo action: FAKECLONE-clone_running_0 ++ * Pseudo action: clone-one-or-more:order-FAKECLONE-clone-FAKE-mandatory ++ * Resource action: FAKECLONE monitor=10000 on c7auto3 ++ * Resource action: FAKECLONE monitor=10000 on c7auto1 ++ * Resource action: FAKE start on c7auto4 ++ * Resource action: FAKE monitor=10000 on c7auto4 ++ ++Revised cluster status: ++Node c7auto2 (2): standby ++Online: [ c7auto1 c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto3 ] ++ Stopped: [ c7auto2 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Started c7auto4 ++ +diff --git a/pengine/test10/clone_min_start_two.xml b/pengine/test10/clone_min_start_two.xml +new file mode 100644 +index 0000000..ae84425 +--- /dev/null ++++ b/pengine/test10/clone_min_start_two.xml +@@ -0,0 +1,153 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_stop_all.dot b/pengine/test10/clone_min_stop_all.dot +new file mode 100644 +index 0000000..254e889 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_all.dot +@@ -0,0 +1,41 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = dashed] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto1" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto2" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto3" [ style = bold] ++"FAKECLONE-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stopped_0" -> "FAKECLONE-clone_start_0" [ style = dashed] ++"FAKECLONE-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE_start_0 " -> "FAKECLONE-clone_running_0" [ style = dashed] ++"FAKECLONE_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto1" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto1" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto3" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto3" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKE_monitor_10000 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKE_start_0 c7auto4" -> "FAKE_monitor_10000 c7auto4" [ style = dashed] ++"FAKE_start_0 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKE_stop_0 c7auto4" -> "FAKECLONE-clone_stop_0" [ style = bold] ++"FAKE_stop_0 c7auto4" -> "FAKE_start_0 c7auto4" [ style = dashed] ++"FAKE_stop_0 c7auto4" -> "all_stopped" [ style = bold] ++"FAKE_stop_0 c7auto4" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++"shooter_monitor_60000 c7auto4" [ style=bold color="green" fontcolor="black"] ++"shooter_start_0 c7auto4" -> "shooter_monitor_60000 c7auto4" [ style = bold] ++"shooter_start_0 c7auto4" [ style=bold color="green" fontcolor="black"] ++"shooter_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"shooter_stop_0 c7auto1" -> "shooter_start_0 c7auto4" [ style = bold] ++"shooter_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++} +diff --git a/pengine/test10/clone_min_stop_all.exp b/pengine/test10/clone_min_stop_all.exp +new file mode 100644 +index 0000000..1b8c9ce +--- /dev/null ++++ b/pengine/test10/clone_min_stop_all.exp +@@ -0,0 +1,142 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_stop_all.scores b/pengine/test10/clone_min_stop_all.scores +new file mode 100644 +index 0000000..0bcbb1f +--- /dev/null ++++ b/pengine/test10/clone_min_stop_all.scores +@@ -0,0 +1,45 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:0 allocation score on c7auto1: 1 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 1 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 1 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKE allocation score on c7auto1: -INFINITY ++native_color: FAKE allocation score on c7auto2: -INFINITY ++native_color: FAKE allocation score on c7auto3: -INFINITY ++native_color: FAKE allocation score on c7auto4: 0 ++native_color: FAKECLONE:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/clone_min_stop_all.summary b/pengine/test10/clone_min_stop_all.summary +new file mode 100644 +index 0000000..eb2944f +--- /dev/null ++++ b/pengine/test10/clone_min_stop_all.summary +@@ -0,0 +1,43 @@ ++ ++Current cluster status: ++Node c7auto1 (1): standby ++Node c7auto2 (2): standby ++Node c7auto3 (3): standby ++Online: [ c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Stopped: [ c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Started c7auto4 ++ ++Transition Summary: ++ * Move shooter (Started c7auto1 -> c7auto4) ++ * Stop FAKECLONE:0 (c7auto1) ++ * Stop FAKECLONE:1 (c7auto2) ++ * Stop FAKECLONE:2 (c7auto3) ++ * Stop FAKE (Started c7auto4) ++ ++Executing cluster transition: ++ * Resource action: shooter stop on c7auto1 ++ * Resource action: FAKE stop on c7auto4 ++ * Resource action: shooter start on c7auto4 ++ * Pseudo action: FAKECLONE-clone_stop_0 ++ * Resource action: shooter monitor=60000 on c7auto4 ++ * Resource action: FAKECLONE stop on c7auto1 ++ * Resource action: FAKECLONE stop on c7auto2 ++ * Resource action: FAKECLONE stop on c7auto3 ++ * Pseudo action: FAKECLONE-clone_stopped_0 ++ * Pseudo action: all_stopped ++ ++Revised cluster status: ++Node c7auto1 (1): standby ++Node c7auto2 (2): standby ++Node c7auto3 (3): standby ++Online: [ c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto4 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Stopped ++ +diff --git a/pengine/test10/clone_min_stop_all.xml b/pengine/test10/clone_min_stop_all.xml +new file mode 100644 +index 0000000..70e8a96 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_all.xml +@@ -0,0 +1,158 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_stop_one.dot b/pengine/test10/clone_min_stop_one.dot +new file mode 100644 +index 0000000..19f84cc +--- /dev/null ++++ b/pengine/test10/clone_min_stop_one.dot +@@ -0,0 +1,18 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto2" [ style = bold] ++"FAKECLONE-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stopped_0" -> "FAKECLONE-clone_start_0" [ style = bold] ++"FAKECLONE-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE_start_0 " -> "FAKECLONE-clone_running_0" [ style = dashed] ++"FAKECLONE_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/clone_min_stop_one.exp b/pengine/test10/clone_min_stop_one.exp +new file mode 100644 +index 0000000..4e6edb8 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_one.exp +@@ -0,0 +1,74 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_stop_one.scores b/pengine/test10/clone_min_stop_one.scores +new file mode 100644 +index 0000000..1f28932 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_one.scores +@@ -0,0 +1,45 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:0 allocation score on c7auto1: 1 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 1 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 1 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKE allocation score on c7auto1: -INFINITY ++native_color: FAKE allocation score on c7auto2: -INFINITY ++native_color: FAKE allocation score on c7auto3: -INFINITY ++native_color: FAKE allocation score on c7auto4: 0 ++native_color: FAKECLONE:0 allocation score on c7auto1: 1 ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: 0 ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: 1 ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/clone_min_stop_one.summary b/pengine/test10/clone_min_stop_one.summary +new file mode 100644 +index 0000000..9206a0d +--- /dev/null ++++ b/pengine/test10/clone_min_stop_one.summary +@@ -0,0 +1,32 @@ ++ ++Current cluster status: ++Node c7auto2 (2): standby ++Online: [ c7auto1 c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Stopped: [ c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Started c7auto4 ++ ++Transition Summary: ++ * Stop FAKECLONE:1 (c7auto2) ++ ++Executing cluster transition: ++ * Pseudo action: FAKECLONE-clone_stop_0 ++ * Resource action: FAKECLONE stop on c7auto2 ++ * Pseudo action: FAKECLONE-clone_stopped_0 ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: FAKECLONE-clone_running_0 ++ ++Revised cluster status: ++Node c7auto2 (2): standby ++Online: [ c7auto1 c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto3 ] ++ Stopped: [ c7auto2 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Started c7auto4 ++ +diff --git a/pengine/test10/clone_min_stop_one.xml b/pengine/test10/clone_min_stop_one.xml +new file mode 100644 +index 0000000..eb05803 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_one.xml +@@ -0,0 +1,152 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_stop_two.dot b/pengine/test10/clone_min_stop_two.dot +new file mode 100644 +index 0000000..11640f4 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_two.dot +@@ -0,0 +1,36 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto1" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto2" [ style = bold] ++"FAKECLONE-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stopped_0" -> "FAKECLONE-clone_start_0" [ style = bold] ++"FAKECLONE-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE_start_0 " -> "FAKECLONE-clone_running_0" [ style = dashed] ++"FAKECLONE_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto1" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto1" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKE_monitor_10000 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKE_start_0 c7auto4" -> "FAKE_monitor_10000 c7auto4" [ style = dashed] ++"FAKE_start_0 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKE_stop_0 c7auto4" -> "FAKECLONE-clone_stop_0" [ style = bold] ++"FAKE_stop_0 c7auto4" -> "FAKE_start_0 c7auto4" [ style = dashed] ++"FAKE_stop_0 c7auto4" -> "all_stopped" [ style = bold] ++"FAKE_stop_0 c7auto4" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++"shooter_monitor_60000 c7auto3" [ style=bold color="green" fontcolor="black"] ++"shooter_start_0 c7auto3" -> "shooter_monitor_60000 c7auto3" [ style = bold] ++"shooter_start_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"shooter_stop_0 c7auto1" -> "all_stopped" [ style = bold] ++"shooter_stop_0 c7auto1" -> "shooter_start_0 c7auto3" [ style = bold] ++"shooter_stop_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++} +diff --git a/pengine/test10/clone_min_stop_two.exp b/pengine/test10/clone_min_stop_two.exp +new file mode 100644 +index 0000000..5697611 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_two.exp +@@ -0,0 +1,147 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/clone_min_stop_two.scores b/pengine/test10/clone_min_stop_two.scores +new file mode 100644 +index 0000000..ce43eb9 +--- /dev/null ++++ b/pengine/test10/clone_min_stop_two.scores +@@ -0,0 +1,45 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:0 allocation score on c7auto1: 1 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 1 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 1 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKE allocation score on c7auto1: -INFINITY ++native_color: FAKE allocation score on c7auto2: -INFINITY ++native_color: FAKE allocation score on c7auto3: -INFINITY ++native_color: FAKE allocation score on c7auto4: 0 ++native_color: FAKECLONE:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: 1 ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/clone_min_stop_two.summary b/pengine/test10/clone_min_stop_two.summary +new file mode 100644 +index 0000000..c009d7d +--- /dev/null ++++ b/pengine/test10/clone_min_stop_two.summary +@@ -0,0 +1,42 @@ ++ ++Current cluster status: ++Node c7auto1 (1): standby ++Node c7auto2 (2): standby ++Online: [ c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Stopped: [ c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Started c7auto4 ++ ++Transition Summary: ++ * Move shooter (Started c7auto1 -> c7auto3) ++ * Stop FAKECLONE:0 (c7auto1) ++ * Stop FAKECLONE:1 (c7auto2) ++ * Stop FAKE (Started c7auto4) ++ ++Executing cluster transition: ++ * Resource action: shooter stop on c7auto1 ++ * Resource action: FAKE stop on c7auto4 ++ * Resource action: shooter start on c7auto3 ++ * Pseudo action: FAKECLONE-clone_stop_0 ++ * Resource action: shooter monitor=60000 on c7auto3 ++ * Resource action: FAKECLONE stop on c7auto1 ++ * Resource action: FAKECLONE stop on c7auto2 ++ * Pseudo action: FAKECLONE-clone_stopped_0 ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: FAKECLONE-clone_running_0 ++ ++Revised cluster status: ++Node c7auto1 (1): standby ++Node c7auto2 (2): standby ++Online: [ c7auto3 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto3 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto3 ] ++ Stopped: [ c7auto1 c7auto2 c7auto4 ] ++ FAKE (ocf::heartbeat:Dummy): Stopped ++ +diff --git a/pengine/test10/clone_min_stop_two.xml b/pengine/test10/clone_min_stop_two.xml +new file mode 100644 +index 0000000..8d085ad +--- /dev/null ++++ b/pengine/test10/clone_min_stop_two.xml +@@ -0,0 +1,154 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_start_one.dot b/pengine/test10/cloned_start_one.dot +new file mode 100644 +index 0000000..b3c254c +--- /dev/null ++++ b/pengine/test10/cloned_start_one.dot +@@ -0,0 +1,32 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 c7auto1" [ style = bold] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKECLONE2-clone_start_0" -> "FAKECLONE2-clone_running_0" [ style = dashed] ++"FAKECLONE2-clone_start_0" -> "FAKECLONE2_start_0 c7auto4" [ style = dashed] ++"FAKECLONE2-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2_stop_0 c7auto3" [ style = bold] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2_stop_0 c7auto4" [ style = bold] ++"FAKECLONE2-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_stopped_0" -> "FAKECLONE2-clone_start_0" [ style = dashed] ++"FAKECLONE2-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2_monitor_10000 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE2_start_0 c7auto4" -> "FAKECLONE2-clone_running_0" [ style = dashed] ++"FAKECLONE2_start_0 c7auto4" -> "FAKECLONE2_monitor_10000 c7auto4" [ style = dashed] ++"FAKECLONE2_start_0 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE2_stop_0 c7auto3" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE2_stop_0 c7auto4" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2_stop_0 c7auto4" -> "FAKECLONE2_start_0 c7auto4" [ style = dashed] ++"FAKECLONE2_stop_0 c7auto4" -> "all_stopped" [ style = bold] ++"FAKECLONE2_stop_0 c7auto4" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_start_0 c7auto1" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE_start_0 c7auto1" -> "FAKECLONE_monitor_10000 c7auto1" [ style = bold] ++"FAKECLONE_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/cloned_start_one.exp b/pengine/test10/cloned_start_one.exp +new file mode 100644 +index 0000000..636ccd8 +--- /dev/null ++++ b/pengine/test10/cloned_start_one.exp +@@ -0,0 +1,118 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_start_one.scores b/pengine/test10/cloned_start_one.scores +new file mode 100644 +index 0000000..3dc6ab8 +--- /dev/null ++++ b/pengine/test10/cloned_start_one.scores +@@ -0,0 +1,77 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE2-clone allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto3: 1 ++clone_color: FAKECLONE2:0 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++clone_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:2 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto4: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++native_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto1: 0 ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/cloned_start_one.summary b/pengine/test10/cloned_start_one.summary +new file mode 100644 +index 0000000..20ac58f +--- /dev/null ++++ b/pengine/test10/cloned_start_one.summary +@@ -0,0 +1,41 @@ ++ ++Current cluster status: ++Node c7auto2 (2): standby ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Started: [ c7auto3 c7auto4 ] ++ Stopped: [ c7auto1 c7auto2 ] ++ ++Transition Summary: ++ * Start FAKECLONE:0 (c7auto1) ++ * Stop FAKECLONE2:0 (c7auto3) ++ * Stop FAKECLONE2:1 (Started c7auto4) ++ ++Executing cluster transition: ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: FAKECLONE2-clone_stop_0 ++ * Resource action: FAKECLONE start on c7auto1 ++ * Pseudo action: FAKECLONE-clone_running_0 ++ * Resource action: FAKECLONE2 stop on c7auto3 ++ * Resource action: FAKECLONE2 stop on c7auto4 ++ * Pseudo action: FAKECLONE2-clone_stopped_0 ++ * Pseudo action: all_stopped ++ * Resource action: FAKECLONE monitor=10000 on c7auto1 ++ ++Revised cluster status: ++Node c7auto2 (2): standby ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 ] ++ Stopped: [ c7auto2 c7auto3 c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ +diff --git a/pengine/test10/cloned_start_one.xml b/pengine/test10/cloned_start_one.xml +new file mode 100644 +index 0000000..6c2bfe1 +--- /dev/null ++++ b/pengine/test10/cloned_start_one.xml +@@ -0,0 +1,154 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_start_two.dot b/pengine/test10/cloned_start_two.dot +new file mode 100644 +index 0000000..348d435 +--- /dev/null ++++ b/pengine/test10/cloned_start_two.dot +@@ -0,0 +1,26 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE:1_start_0 c7auto1" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 c7auto2" [ style = bold] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2_stop_0 c7auto3" [ style = bold] ++"FAKECLONE2-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2_stop_0 c7auto3" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE:1_monitor_10000 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE:1_start_0 c7auto1" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE:1_start_0 c7auto1" -> "FAKECLONE:1_monitor_10000 c7auto1" [ style = bold] ++"FAKECLONE:1_start_0 c7auto1" -> "clone-one-or-more:order-FAKECLONE-clone-FAKECLONE2-clone-mandatory" [ style = bold] ++"FAKECLONE:1_start_0 c7auto1" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_monitor_10000 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_start_0 c7auto2" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE_start_0 c7auto2" -> "FAKECLONE_monitor_10000 c7auto2" [ style = bold] ++"FAKECLONE_start_0 c7auto2" -> "clone-one-or-more:order-FAKECLONE-clone-FAKECLONE2-clone-mandatory" [ style = bold] ++"FAKECLONE_start_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++"clone-one-or-more:order-FAKECLONE-clone-FAKECLONE2-clone-mandatory" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/cloned_start_two.exp b/pengine/test10/cloned_start_two.exp +new file mode 100644 +index 0000000..ee82324 +--- /dev/null ++++ b/pengine/test10/cloned_start_two.exp +@@ -0,0 +1,143 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_start_two.scores b/pengine/test10/cloned_start_two.scores +new file mode 100644 +index 0000000..dae3b5d +--- /dev/null ++++ b/pengine/test10/cloned_start_two.scores +@@ -0,0 +1,77 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE2-clone allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto3: 1 ++clone_color: FAKECLONE2:0 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++clone_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:2 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto4: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++native_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto1: 0 ++native_color: FAKECLONE:0 allocation score on c7auto2: 0 ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: 0 ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/cloned_start_two.summary b/pengine/test10/cloned_start_two.summary +new file mode 100644 +index 0000000..bea4609 +--- /dev/null ++++ b/pengine/test10/cloned_start_two.summary +@@ -0,0 +1,42 @@ ++ ++Current cluster status: ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto2 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Started: [ c7auto3 c7auto4 ] ++ Stopped: [ c7auto1 c7auto2 ] ++ ++Transition Summary: ++ * Start FAKECLONE:0 (c7auto2) ++ * Start FAKECLONE:1 (c7auto1) ++ * Stop FAKECLONE2:0 (c7auto3) ++ ++Executing cluster transition: ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: FAKECLONE2-clone_stop_0 ++ * Resource action: FAKECLONE start on c7auto2 ++ * Resource action: FAKECLONE start on c7auto1 ++ * Pseudo action: FAKECLONE-clone_running_0 ++ * Resource action: FAKECLONE2 stop on c7auto3 ++ * Pseudo action: FAKECLONE2-clone_stopped_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: clone-one-or-more:order-FAKECLONE-clone-FAKECLONE2-clone-mandatory ++ * Resource action: FAKECLONE monitor=10000 on c7auto2 ++ * Resource action: FAKECLONE monitor=10000 on c7auto1 ++ ++Revised cluster status: ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto2 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 ] ++ Stopped: [ c7auto3 c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Started: [ c7auto4 ] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ +diff --git a/pengine/test10/cloned_start_two.xml b/pengine/test10/cloned_start_two.xml +new file mode 100644 +index 0000000..be78317 +--- /dev/null ++++ b/pengine/test10/cloned_start_two.xml +@@ -0,0 +1,152 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_stop_one.dot b/pengine/test10/cloned_stop_one.dot +new file mode 100644 +index 0000000..d181135 +--- /dev/null ++++ b/pengine/test10/cloned_stop_one.dot +@@ -0,0 +1,26 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto3" [ style = bold] ++"FAKECLONE-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stopped_0" -> "FAKECLONE-clone_start_0" [ style = bold] ++"FAKECLONE-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2_stop_0 c7auto3" [ style = bold] ++"FAKECLONE2-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_stopped_0" -> "FAKECLONE-clone_stop_0" [ style = bold] ++"FAKECLONE2-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2_stop_0 c7auto3" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_start_0 " -> "FAKECLONE-clone_running_0" [ style = dashed] ++"FAKECLONE_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto3" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto3" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/cloned_stop_one.exp b/pengine/test10/cloned_stop_one.exp +new file mode 100644 +index 0000000..9613d6f +--- /dev/null ++++ b/pengine/test10/cloned_stop_one.exp +@@ -0,0 +1,117 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_stop_one.scores b/pengine/test10/cloned_stop_one.scores +new file mode 100644 +index 0000000..6d66638 +--- /dev/null ++++ b/pengine/test10/cloned_stop_one.scores +@@ -0,0 +1,77 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE2-clone allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto3: 1 ++clone_color: FAKECLONE2:0 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++clone_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:2 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto4: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto1: 1 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 1 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 1 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++native_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto1: 1 ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: 0 ++native_color: FAKECLONE:1 allocation score on c7auto2: 1 ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/cloned_stop_one.summary b/pengine/test10/cloned_stop_one.summary +new file mode 100644 +index 0000000..1a952a2 +--- /dev/null ++++ b/pengine/test10/cloned_stop_one.summary +@@ -0,0 +1,40 @@ ++ ++Current cluster status: ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto2 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Stopped: [ c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Started: [ c7auto3 c7auto4 ] ++ Stopped: [ c7auto1 c7auto2 ] ++ ++Transition Summary: ++ * Stop FAKECLONE:2 (c7auto3) ++ * Stop FAKECLONE2:0 (c7auto3) ++ ++Executing cluster transition: ++ * Pseudo action: FAKECLONE2-clone_stop_0 ++ * Resource action: FAKECLONE2 stop on c7auto3 ++ * Pseudo action: FAKECLONE2-clone_stopped_0 ++ * Pseudo action: FAKECLONE-clone_stop_0 ++ * Resource action: FAKECLONE stop on c7auto3 ++ * Pseudo action: FAKECLONE-clone_stopped_0 ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: FAKECLONE-clone_running_0 ++ ++Revised cluster status: ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto2 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 ] ++ Stopped: [ c7auto3 c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Started: [ c7auto4 ] ++ Stopped: [ c7auto1 c7auto2 c7auto3 ] ++ +diff --git a/pengine/test10/cloned_stop_one.xml b/pengine/test10/cloned_stop_one.xml +new file mode 100644 +index 0000000..2e2fdfd +--- /dev/null ++++ b/pengine/test10/cloned_stop_one.xml +@@ -0,0 +1,153 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_stop_two.dot b/pengine/test10/cloned_stop_two.dot +new file mode 100644 +index 0000000..2c7fd3d +--- /dev/null ++++ b/pengine/test10/cloned_stop_two.dot +@@ -0,0 +1,45 @@ ++ digraph "g" { ++"FAKECLONE-clone_running_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_start_0" -> "FAKECLONE-clone_running_0" [ style = bold] ++"FAKECLONE-clone_start_0" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE-clone_start_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto2" [ style = bold] ++"FAKECLONE-clone_stop_0" -> "FAKECLONE_stop_0 c7auto3" [ style = bold] ++"FAKECLONE-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE-clone_stopped_0" -> "FAKECLONE-clone_start_0" [ style = bold] ++"FAKECLONE-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_running_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKECLONE2-clone_start_0" -> "FAKECLONE2-clone_running_0" [ style = dashed] ++"FAKECLONE2-clone_start_0" -> "FAKECLONE2_start_0 c7auto4" [ style = dashed] ++"FAKECLONE2-clone_start_0" [ style=dashed color="red" fontcolor="orange"] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2_stop_0 c7auto3" [ style = bold] ++"FAKECLONE2-clone_stop_0" -> "FAKECLONE2_stop_0 c7auto4" [ style = bold] ++"FAKECLONE2-clone_stop_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2-clone_stopped_0" -> "FAKECLONE-clone_stop_0" [ style = bold] ++"FAKECLONE2-clone_stopped_0" -> "FAKECLONE2-clone_start_0" [ style = dashed] ++"FAKECLONE2-clone_stopped_0" [ style=bold color="green" fontcolor="orange"] ++"FAKECLONE2_monitor_10000 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE2_start_0 c7auto4" -> "FAKECLONE2-clone_running_0" [ style = dashed] ++"FAKECLONE2_start_0 c7auto4" -> "FAKECLONE2_monitor_10000 c7auto4" [ style = dashed] ++"FAKECLONE2_start_0 c7auto4" [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE2_stop_0 c7auto3" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE2_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE2_stop_0 c7auto4" -> "FAKECLONE2-clone_stopped_0" [ style = bold] ++"FAKECLONE2_stop_0 c7auto4" -> "FAKECLONE2_start_0 c7auto4" [ style = dashed] ++"FAKECLONE2_stop_0 c7auto4" -> "all_stopped" [ style = bold] ++"FAKECLONE2_stop_0 c7auto4" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_start_0 " -> "FAKECLONE-clone_running_0" [ style = dashed] ++"FAKECLONE_start_0 " [ style=dashed color="red" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto2" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto2" [ style=bold color="green" fontcolor="black"] ++"FAKECLONE_stop_0 c7auto3" -> "FAKECLONE-clone_stopped_0" [ style = bold] ++"FAKECLONE_stop_0 c7auto3" -> "FAKECLONE_start_0 " [ style = dashed] ++"FAKECLONE_stop_0 c7auto3" -> "all_stopped" [ style = bold] ++"FAKECLONE_stop_0 c7auto3" [ style=bold color="green" fontcolor="black"] ++"all_stopped" [ style=bold color="green" fontcolor="orange"] ++} +diff --git a/pengine/test10/cloned_stop_two.exp b/pengine/test10/cloned_stop_two.exp +new file mode 100644 +index 0000000..4aa0e58 +--- /dev/null ++++ b/pengine/test10/cloned_stop_two.exp +@@ -0,0 +1,155 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/cloned_stop_two.scores b/pengine/test10/cloned_stop_two.scores +new file mode 100644 +index 0000000..f6e9779 +--- /dev/null ++++ b/pengine/test10/cloned_stop_two.scores +@@ -0,0 +1,77 @@ ++Allocation scores: ++clone_color: FAKECLONE-clone allocation score on c7auto1: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto2: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE-clone allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2-clone allocation score on c7auto3: 0 ++clone_color: FAKECLONE2-clone allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:0 allocation score on c7auto3: 1 ++clone_color: FAKECLONE2:0 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++clone_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:2 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:2 allocation score on c7auto4: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++clone_color: FAKECLONE2:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE2:3 allocation score on c7auto4: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto1: 1 ++clone_color: FAKECLONE:0 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:1 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto2: 1 ++clone_color: FAKECLONE:1 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:2 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:2 allocation score on c7auto3: 1 ++clone_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++clone_color: FAKECLONE:3 allocation score on c7auto1: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto2: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto3: 0 ++clone_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:1 allocation score on c7auto4: 1 ++native_color: FAKECLONE2:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE2:3 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto1: 1 ++native_color: FAKECLONE:0 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:0 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:1 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:2 allocation score on c7auto4: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto1: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto2: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto3: -INFINITY ++native_color: FAKECLONE:3 allocation score on c7auto4: -INFINITY ++native_color: shooter allocation score on c7auto1: 0 ++native_color: shooter allocation score on c7auto2: 0 ++native_color: shooter allocation score on c7auto3: 0 ++native_color: shooter allocation score on c7auto4: 0 +diff --git a/pengine/test10/cloned_stop_two.summary b/pengine/test10/cloned_stop_two.summary +new file mode 100644 +index 0000000..531295f +--- /dev/null ++++ b/pengine/test10/cloned_stop_two.summary +@@ -0,0 +1,45 @@ ++ ++Current cluster status: ++Node c7auto2 (2): standby ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 c7auto2 c7auto3 ] ++ Stopped: [ c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Started: [ c7auto3 c7auto4 ] ++ Stopped: [ c7auto1 c7auto2 ] ++ ++Transition Summary: ++ * Stop FAKECLONE:1 (c7auto2) ++ * Stop FAKECLONE:2 (c7auto3) ++ * Stop FAKECLONE2:0 (c7auto3) ++ * Stop FAKECLONE2:1 (Started c7auto4) ++ ++Executing cluster transition: ++ * Pseudo action: FAKECLONE2-clone_stop_0 ++ * Resource action: FAKECLONE2 stop on c7auto3 ++ * Resource action: FAKECLONE2 stop on c7auto4 ++ * Pseudo action: FAKECLONE2-clone_stopped_0 ++ * Pseudo action: FAKECLONE-clone_stop_0 ++ * Resource action: FAKECLONE stop on c7auto2 ++ * Resource action: FAKECLONE stop on c7auto3 ++ * Pseudo action: FAKECLONE-clone_stopped_0 ++ * Pseudo action: FAKECLONE-clone_start_0 ++ * Pseudo action: all_stopped ++ * Pseudo action: FAKECLONE-clone_running_0 ++ ++Revised cluster status: ++Node c7auto2 (2): standby ++Node c7auto3 (3): standby ++Online: [ c7auto1 c7auto4 ] ++ ++ shooter (stonith:fence_phd_kvm): Started c7auto1 ++ Clone Set: FAKECLONE-clone [FAKECLONE] ++ Started: [ c7auto1 ] ++ Stopped: [ c7auto2 c7auto3 c7auto4 ] ++ Clone Set: FAKECLONE2-clone [FAKECLONE2] ++ Stopped: [ c7auto1 c7auto2 c7auto3 c7auto4 ] ++ +diff --git a/pengine/test10/cloned_stop_two.xml b/pengine/test10/cloned_stop_two.xml +new file mode 100644 +index 0000000..220dfc2 +--- /dev/null ++++ b/pengine/test10/cloned_stop_two.xml +@@ -0,0 +1,157 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/pengine/test10/stonith-1.dot b/pengine/test10/stonith-1.dot +index d64edcf..3814ac9 100644 +--- a/pengine/test10/stonith-1.dot ++++ b/pengine/test10/stonith-1.dot +@@ -88,8 +88,6 @@ digraph "g" { + "rsc_sles-3_stop_0 sles-3" -> "rsc_sles-3_start_0 sles-4" [ style = bold] + "rsc_sles-3_stop_0 sles-3" [ style=bold color="green" fontcolor="orange" ] + "rsc_sles-4_monitor_5000 sles-4" [ style=bold color="green" fontcolor="black" ] +-"stonith 'reboot' sles-3" -> "DoFencing_stop_0" [ style = bold] +-"stonith 'reboot' sles-3" -> "child_DoFencing:2_stop_0 sles-3" [ style = bold] + "stonith 'reboot' sles-3" -> "master_rsc_1_stop_0" [ style = bold] + "stonith 'reboot' sles-3" -> "migrator_stop_0 sles-3" [ style = bold] + "stonith 'reboot' sles-3" -> "ocf_msdummy:2_stop_0 sles-3" [ style = bold] +diff --git a/pengine/test10/stonith-1.exp b/pengine/test10/stonith-1.exp +index 4d58afa..40b22cb 100644 +--- a/pengine/test10/stonith-1.exp ++++ b/pengine/test10/stonith-1.exp +@@ -210,9 +210,6 @@ + + + +- +- +- + + + +@@ -236,11 +233,7 @@ + + + +- +- +- +- +- ++ + + + +diff --git a/pengine/test10/stonith-1.summary b/pengine/test10/stonith-1.summary +index ef904fe..e99bb5e 100644 +--- a/pengine/test10/stonith-1.summary ++++ b/pengine/test10/stonith-1.summary +@@ -45,20 +45,22 @@ Executing cluster transition: + * Resource action: lsb_dummy monitor=5000 on sles-2 + * Resource action: rsc_sles-2 monitor=5000 on sles-2 + * Resource action: rsc_sles-4 monitor=5000 on sles-4 ++ * Pseudo action: DoFencing_stop_0 + * Fencing sles-3 (reboot) + * Pseudo action: stonith_complete + * Resource action: r192.168.100.183 start on sles-1 + * Pseudo action: migrator_stop_0 + * Pseudo action: rsc_sles-3_stop_0 +- * Pseudo action: DoFencing_stop_0 ++ * Pseudo action: child_DoFencing:2_stop_0 ++ * Pseudo action: DoFencing_stopped_0 ++ * Pseudo action: DoFencing_start_0 + * Pseudo action: master_rsc_1_stop_0 + * Pseudo action: group-1_running_0 + * Resource action: r192.168.100.183 monitor=5000 on sles-1 + * Resource action: migrator start on sles-4 + * Resource action: rsc_sles-3 start on sles-4 +- * Pseudo action: child_DoFencing:2_stop_0 +- * Pseudo action: DoFencing_stopped_0 +- * Pseudo action: DoFencing_start_0 ++ * Resource action: child_DoFencing:2 start on sles-4 ++ * Pseudo action: DoFencing_running_0 + * Pseudo action: ocf_msdummy:2_stop_0 + * Pseudo action: ocf_msdummy:5_stop_0 + * Pseudo action: master_rsc_1_stopped_0 +@@ -66,8 +68,7 @@ Executing cluster transition: + * Pseudo action: all_stopped + * Resource action: migrator monitor=10000 on sles-4 + * Resource action: rsc_sles-3 monitor=5000 on sles-4 +- * Resource action: child_DoFencing:2 start on sles-4 +- * Pseudo action: DoFencing_running_0 ++ * Resource action: child_DoFencing:2 monitor=60000 on sles-4 + * Resource action: ocf_msdummy:0 start on sles-4 + * Resource action: ocf_msdummy:1 start on sles-1 + * Resource action: ocf_msdummy:2 start on sles-2 +@@ -75,7 +76,6 @@ Executing cluster transition: + * Resource action: ocf_msdummy:4 start on sles-1 + * Resource action: ocf_msdummy:5 start on sles-2 + * Pseudo action: master_rsc_1_running_0 +- * Resource action: child_DoFencing:2 monitor=60000 on sles-4 + * Resource action: ocf_msdummy:0 monitor=5000 on sles-4 + * Resource action: ocf_msdummy:1 monitor=5000 on sles-1 + * Resource action: ocf_msdummy:2 monitor=5000 on sles-2 +diff --git a/pengine/test10/ticket-master-21.dot b/pengine/test10/ticket-master-21.dot +index 60386a8..3f94948 100644 +--- a/pengine/test10/ticket-master-21.dot ++++ b/pengine/test10/ticket-master-21.dot +@@ -23,7 +23,6 @@ digraph "g" { + "stonith 'reboot' node1" -> "ms1_stop_0" [ style = bold] + "stonith 'reboot' node1" -> "rsc1:1_demote_0 node1" [ style = bold] + "stonith 'reboot' node1" -> "rsc1:1_stop_0 node1" [ style = bold] +-"stonith 'reboot' node1" -> "rsc_stonith_stop_0 node1" [ style = bold] + "stonith 'reboot' node1" -> "stonith_complete" [ style = bold] + "stonith 'reboot' node1" [ style=bold color="green" fontcolor="black"] + "stonith_complete" -> "all_stopped" [ style = bold] +diff --git a/pengine/test10/ticket-master-21.exp b/pengine/test10/ticket-master-21.exp +index cc8df2f..c32bac5 100644 +--- a/pengine/test10/ticket-master-21.exp ++++ b/pengine/test10/ticket-master-21.exp +@@ -18,11 +18,7 @@ + + + +- +- +- +- +- ++ + + + +diff --git a/pengine/test10/ticket-master-21.summary b/pengine/test10/ticket-master-21.summary +index 64a9cbe..b228696 100644 +--- a/pengine/test10/ticket-master-21.summary ++++ b/pengine/test10/ticket-master-21.summary +@@ -12,14 +12,14 @@ Transition Summary: + * Demote rsc1:0 (Master -> Stopped node1) + + Executing cluster transition: ++ * Pseudo action: rsc_stonith_stop_0 + * Pseudo action: ms1_demote_0 + * Fencing node1 (reboot) + * Pseudo action: stonith_complete +- * Pseudo action: rsc_stonith_stop_0 ++ * Resource action: rsc_stonith start on node2 + * Pseudo action: rsc1:1_demote_0 + * Pseudo action: ms1_demoted_0 + * Pseudo action: ms1_stop_0 +- * Resource action: rsc_stonith start on node2 + * Pseudo action: rsc1:1_stop_0 + * Pseudo action: ms1_stopped_0 + * Pseudo action: all_stopped +diff --git a/pengine/test10/ticket-master-9.dot b/pengine/test10/ticket-master-9.dot +index 3a29836..c648feb 100644 +--- a/pengine/test10/ticket-master-9.dot ++++ b/pengine/test10/ticket-master-9.dot +@@ -23,7 +23,6 @@ digraph "g" { + "stonith 'reboot' node1" -> "ms1_stop_0" [ style = bold] + "stonith 'reboot' node1" -> "rsc1:1_demote_0 node1" [ style = bold] + "stonith 'reboot' node1" -> "rsc1:1_stop_0 node1" [ style = bold] +-"stonith 'reboot' node1" -> "rsc_stonith_stop_0 node1" [ style = bold] + "stonith 'reboot' node1" -> "stonith_complete" [ style = bold] + "stonith 'reboot' node1" [ style=bold color="green" fontcolor="black"] + "stonith_complete" -> "all_stopped" [ style = bold] +diff --git a/pengine/test10/ticket-master-9.exp b/pengine/test10/ticket-master-9.exp +index cc8df2f..c32bac5 100644 +--- a/pengine/test10/ticket-master-9.exp ++++ b/pengine/test10/ticket-master-9.exp +@@ -18,11 +18,7 @@ + + + +- +- +- +- +- ++ + + + +diff --git a/pengine/test10/ticket-master-9.summary b/pengine/test10/ticket-master-9.summary +index 64a9cbe..b228696 100644 +--- a/pengine/test10/ticket-master-9.summary ++++ b/pengine/test10/ticket-master-9.summary +@@ -12,14 +12,14 @@ Transition Summary: + * Demote rsc1:0 (Master -> Stopped node1) + + Executing cluster transition: ++ * Pseudo action: rsc_stonith_stop_0 + * Pseudo action: ms1_demote_0 + * Fencing node1 (reboot) + * Pseudo action: stonith_complete +- * Pseudo action: rsc_stonith_stop_0 ++ * Resource action: rsc_stonith start on node2 + * Pseudo action: rsc1:1_demote_0 + * Pseudo action: ms1_demoted_0 + * Pseudo action: ms1_stop_0 +- * Resource action: rsc_stonith start on node2 + * Pseudo action: rsc1:1_stop_0 + * Pseudo action: ms1_stopped_0 + * Pseudo action: all_stopped +diff --git a/pengine/test10/whitebox-imply-stop-on-fence.dot b/pengine/test10/whitebox-imply-stop-on-fence.dot +index 66700b8..b3fd40b 100644 +--- a/pengine/test10/whitebox-imply-stop-on-fence.dot ++++ b/pengine/test10/whitebox-imply-stop-on-fence.dot +@@ -69,7 +69,6 @@ + "stonith 'reboot' kiff-01" -> "clvmd_stop_0 kiff-01" [ style = bold] + "stonith 'reboot' kiff-01" -> "dlm-clone_stop_0" [ style = bold] + "stonith 'reboot' kiff-01" -> "dlm_stop_0 kiff-01" [ style = bold] +-"stonith 'reboot' kiff-01" -> "fence-kiff-02_stop_0 kiff-01" [ style = bold] + "stonith 'reboot' kiff-01" -> "lxc-01_kiff-01_stop_0 kiff-01" [ style = bold] + "stonith 'reboot' kiff-01" -> "lxc-02_kiff-01_stop_0 kiff-01" [ style = bold] + "stonith 'reboot' kiff-01" -> "shared0-clone_stop_0" [ style = bold] +diff --git a/pengine/test10/whitebox-imply-stop-on-fence.exp b/pengine/test10/whitebox-imply-stop-on-fence.exp +index d13c25f..4a3e757 100644 +--- a/pengine/test10/whitebox-imply-stop-on-fence.exp ++++ b/pengine/test10/whitebox-imply-stop-on-fence.exp +@@ -31,11 +31,7 @@ + + + +- +- +- +- +- ++ + + + +diff --git a/pengine/test10/whitebox-imply-stop-on-fence.summary b/pengine/test10/whitebox-imply-stop-on-fence.summary +index 3bb1572..3ee9570 100644 +--- a/pengine/test10/whitebox-imply-stop-on-fence.summary ++++ b/pengine/test10/whitebox-imply-stop-on-fence.summary +@@ -36,16 +36,16 @@ Transition Summary: + * Move lxc-02_kiff-01 (Started kiff-01 -> kiff-02) + + Executing cluster transition: ++ * Pseudo action: fence-kiff-02_stop_0 + * Fencing kiff-01 (reboot) + * Pseudo action: stonith_complete +- * Pseudo action: fence-kiff-02_stop_0 ++ * Resource action: fence-kiff-02 start on kiff-02 + * Pseudo action: vm-fs_stop_0 + * Pseudo action: lxc-01_kiff-01_stop_0 + * Pseudo action: lxc-02_kiff-01_stop_0 +- * Resource action: fence-kiff-02 start on kiff-02 ++ * Resource action: fence-kiff-02 monitor=60000 on kiff-02 + * Pseudo action: R-lxc-01_kiff-01_stop_0 + * Pseudo action: R-lxc-02_kiff-01_stop_0 +- * Resource action: fence-kiff-02 monitor=60000 on kiff-02 + * Pseudo action: shared0-clone_stop_0 + * Resource action: R-lxc-01_kiff-01 start on kiff-02 + * Resource action: R-lxc-02_kiff-01 start on kiff-02 diff --git a/SOURCES/pacemaker-rollup-7-1-63f8e9a.patch b/SOURCES/pacemaker-rollup-7-1-63f8e9a.patch new file mode 100644 index 0000000..c79ea14 --- /dev/null +++ b/SOURCES/pacemaker-rollup-7-1-63f8e9a.patch @@ -0,0 +1,121831 @@ +diff --git a/.gitignore b/.gitignore +index ac0f761..5a12fca 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -12,6 +12,7 @@ Makefile.in + *.pc + *.pyc + *.bz2 ++*.tar.gz + *.rpm + *.la + *.lo +@@ -48,24 +49,41 @@ m4/ltoptions.m4 + m4/ltsugar.m4 + m4/ltversion.m4 + m4/lt~obsolete.m4 ++test-driver ++ylwrap + + # Configure targets ++Doxyfile ++coverage.sh + cts/CTSvars.py ++cts/HBDummy + cts/LSBDummy + cts/benchmark/clubench ++cts/lxc_autogen.sh ++extra/logrotate/pacemaker + include/config.h + include/config.h.in + include/crm_config.h ++lrmd/pacemaker_remote ++lrmd/pacemaker_remoted ++lrmd/pacemaker_remote.service + mcp/pacemaker ++mcp/pacemaker.combined.upstart + mcp/pacemaker.service ++mcp/pacemaker.upstart + pengine/regression.core.sh + publican.cfg + shell/modules/help.py + shell/modules/ra.py + shell/modules/ui.py + shell/modules/vars.py ++tools/cibsecret + tools/coverage.sh ++tools/crm_error ++tools/crm_mon.service ++tools/crm_mon.upstart + tools/crm_report ++tools/report.common + lrmd/regression.py + fencing/regression.py + +@@ -76,6 +94,7 @@ fencing/regression.py + *.8 + *.8.xml + *.8.html ++attrd/attrd + doc/*/en-US/images/*.png + doc/*/tmp/** + doc/*/publish +@@ -84,6 +103,7 @@ cib/cibmon + cib/cibpipe + crmd/atest + crmd/crmd ++doc/api/* + doc/Clusters_from_Scratch.txt + doc/Pacemaker_Explained.txt + doc/acls.html +@@ -93,6 +113,7 @@ fencing/stonith_admin + fencing/stonithd + fencing/stonithd.xml + lrmd/lrmd ++lrmd/lrmd_internal_ctl + lrmd/lrmd_test + mcp/pacemakerd + pengine/pengine +@@ -100,7 +121,6 @@ pengine/pengine.xml + pengine/ptest + shell/regression/testcases/confbasic-xml.filter + scratch +-tools/attrd + tools/attrd_updater + tools/cibadmin + tools/crm_attribute +@@ -117,14 +137,16 @@ tools/iso8601 + tools/crm_ticket + tools/report.collector.1 + xml/crm.dtd +-xml/pacemaker.rng +-extra/rgmanager/ccs2cib +-extra/rgmanager/ccs_flatten +-extra/rgmanager/disable_rgmanager ++xml/pacemaker*.rng ++xml/versions.rng ++doc/Clusters_from_Scratch.build + doc/Clusters_from_Scratch/en-US/Ap-*.xml + doc/Clusters_from_Scratch/en-US/Ch-*.xml ++doc/Pacemaker_Explained.build + doc/Pacemaker_Explained/en-US/Ch-*.xml + doc/Pacemaker_Explained/en-US/Ap-*.xml ++doc/Pacemaker_Remote.build ++doc/Pacemaker_Remote/en-US/Ch-*.xml + lib/gnu/libgnu.a + lib/gnu/stdalign.h + *.coverity +@@ -132,9 +154,8 @@ lib/gnu/stdalign.h + #Other + mock + HTML +-pacemaker.spec ++pacemaker*.spec + pengine/.regression.failed.diff +-ClusterLabs-pacemaker-*.tar.gz + coverity-* + + compat_reports +diff --git a/.travis.yml b/.travis.yml +index 8ca2c57..9634df7 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -29,13 +29,13 @@ env: + + # sudo add-apt-repository ppa:hotot-team + before_install: +- - sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ saucy main" ++ - sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ utopic main" + - sudo apt-get update -qq + + install: + - sudo apt-get install -qq automake autoconf chrpath libglib2.0-dev perl net-tools python libtool libxml2-dev bison flex uuid-dev libbz2-dev zlib1g-dev libltdl3-dev libgnutls-dev python-central python-dev libpam0g-dev libncurses5-dev libcorosync-dev libxslt1-dev libdbus-1-dev + - sudo apt-get install -qq cluster-glue-dev heartbeat-dev libheartbeat2-dev +- - sudo apt-get install -qq libqb-dev/saucy ++ - sudo apt-get install -qq libqb-dev + + before_script: + # Save and restore CC so that ./configure can pass +@@ -69,3 +69,4 @@ notifications: + branches: + only: + - master ++ - 1.1 +diff --git a/ChangeLog b/ChangeLog +index d70edbd..e445890 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,218 @@ + ++* Wed Jun 24 2015 Andrew Beekhof Pacemaker-1.1.13-1 ++- Update source tarball to revision: 2a1847e ++- Changesets: 750 ++- Diff: 156 files changed, 11323 insertions(+), 3725 deletions(-) ++ ++- Features added since Pacemaker-1.1.12 ++ + Allow fail-counts to be removed en-mass when the new attrd is in operation ++ + attrd supports private attributes (not written to CIB) ++ + crmd: Ensure a watchdog device is in use if stonith-watchdog-timeout is configured ++ + crmd: If configured, trigger the watchdog immediately if we loose quorum and no-quorum-policy=suicide ++ + crm_diff: Support generating a difference without versions details if --no-version/-u is supplied ++ + crm_resource: Implement an intelligent restart capability ++ + Fencing: Advertise the watchdog device for fencing operations ++ + Fencing: Allow the cluster to recover resources if the watchdog is in use ++ + fencing: cl#5134 - Support random fencing delay to avoid double fencing ++ + mcp: Allow orphan children to initiate node panic via SIGQUIT ++ + mcp: Turn on sbd integration if pacemakerd finds it running ++ + mcp: Two new error codes that result in machine reset or power off ++ + Officially support the resource-discovery attribute for location constraints ++ + PE: Allow natural ordering of colocation sets ++ + PE: Support non-actionable degraded mode for OCF ++ + pengine: cl#5207 - Display "UNCLEAN" for resources running on unclean offline nodes ++ + remote: pcmk remote client tool for use with container wrapper script ++ + Support machine panics for some kinds of errors (via sbd if available) ++ + tools: add crm_resource --wait option ++ + tools: attrd_updater supports --query and --all options ++ + tools: attrd_updater: Allow attributes to be set for other nodes ++ ++- Changes since Pacemaker-1.1.12 ++ + pengine: exclusive discovery implies rsc is only allowed on exclusive subset of nodes ++ + acl: Correctly implement the 'reference' acl directive ++ + acl: Do not delay evaluation of added nodes in some situations ++ + attrd: b22b1fe did uuid test too early ++ + attrd: Clean out the node cache when requested by the admin ++ + attrd: fixes double free in attrd legacy ++ + attrd: properly write attributes for peers once uuid is discovered ++ + attrd: refresh should force an immediate write-out of all attributes ++ + attrd: Simplify how node deletions happen ++ + Bug rhbz#1067544 - Tools: Correctly handle --ban, --move and --locate for master/slave groups ++ + Bug rhbz#1181824 - Ensure the DC can be reliably fenced ++ + cib: Ability to upgrade cib validation schema in legacy mode ++ + cib: Always generate digests for cib diffs in legacy mode ++ + cib: assignment where comparison intended ++ + cib: Avoid nodeid conflicts we don't care about ++ + cib: Correctly add "update-origin", "update-client" and "update-user" attributes for cib ++ + cib: Correctly set up signal handlers ++ + cib: Correctly track node state ++ + cib: Do not update on disk backups if we're just querying them ++ + cib: Enable cib legacy mode for plugin-based clusters ++ + cib: Ensure file-based backends treat '-o section' consistently with the native backend ++ + cib: Ensure upgrade operations from a non-DC get an acknowledgement ++ + cib: No need to enforce cib digests for v2 diffs in legacy mode ++ + cib: Revert d153b86 to instantly get cib synchronized in legacy mode ++ + cib: tls sock cleanup for remote cib connections ++ + cli: Ensure subsequent unknown long options are correctly detected ++ + cluster: Invoke crm_remove_conflicting_peer() only when the new node's uname is being assigned in the node cache ++ + common: Increment current and age for lib common as a result of APIs being added ++ + corosync: Bug cl#5232 - Somewhat gracefully handle nodes with invalid UUIDs ++ + corosync: Avoid unnecessary repeated CMAP API calls ++ + crmd/pengine: handle on-fail=ignore properly ++ + crmd: Add "on_node" attribute for *_last_failure_0 lrm resource operations ++ + crmd: All peers need to track node shutdown requests ++ + crmd: Cached copies of transient attributes cease to be valid once a node leaves the membership ++ + crmd: Correctly add the local option that validates against schema for pengine to calculate ++ + crmd: Disable debug logging that results in significant overhead ++ + crmd: do not remove connection resources during re-probe ++ + crmd: don't update fail count twice for same failure ++ + crmd: Ensure remote connection resources timeout properly during 'migrate_from' action ++ + crmd: Ensure throttle_mode() does something on Linux ++ + crmd: Fixes crash when remote connection migration fails ++ + crmd: gracefully handle remote node disconnects during op execution ++ + crmd: Handle remote connection failures while executing ops on remote connection ++ + crmd: include remote nodes when forcing cluster wide resource reprobe ++ + crmd: never stop recurring monitor ops for pcmk remote during incomplete migration ++ + crmd: Prevent the old version of DC from being fenced when it shuts down for rolling-upgrade ++ + crmd: Prevent use-of-NULL during reprobe ++ + crmd: properly update job limit for baremetal remote-nodes ++ + crmd: Remote-node throttle jobs count towards cluster-node hosting conneciton rsc ++ + crmd: Reset stonith failcount to recover transitioner when the node rejoins ++ + crmd: resolves memory leak in crmd. ++ + crmd: respect start-failure-is-fatal even for artifically injected events ++ + crmd: Wait for all pending operations to complete before poking the policy engine ++ + crmd: When container's host is fenced, cancel in-flight operations ++ + crm_attribute: Correctly update config options when -o crm_config is specified ++ + crm_failcount: Better error reporting when no resource is specified ++ + crm_mon: add exit reason to resource failure output ++ + crm_mon: Fill CRM_notify_node in traps with node's uname rather than node's id if possible ++ + crm_mon: Repair notification delivery when the v2 patch format is in use ++ + crm_node: Correctly remove nodes from the CIB by nodeid ++ + crm_report: More patterns for finding logs on non-DC nodes ++ + crm_resource: Allow resource restart operations to be node specific ++ + crm_resource: avoid deletion of lrm cache on node with resource discovery disabled. ++ + crm_resource: Calculate how long to wait for a restart based on the resource timeouts ++ + crm_resource: Clean up memory in --restart error paths ++ + crm_resource: Display the locations of all anonymous clone children when supplying the children's common ID ++ + crm_resource: Ensure --restart sets/clears meta attributes ++ + crm_resource: Ensure fail-counts are purged when we redetect the state of all resources ++ + crm_resource: Implement --timeout for resource restart operations ++ + crm_resource: Include group members when calculating the next timeout ++ + crm_resource: Memory leak in error paths ++ + crm_resource: Prevent use-after-free ++ + crm_resource: Repair regression test outputs ++ + crm_resource: Use-after-free when restarting a resource ++ + dbus: ref count leaks ++ + dbus: Ensure both the read and write queues get dispatched ++ + dbus: Fail gracefully if malloc fails ++ + dbus: handle dispatch queue when multiple replies need to be processed ++ + dbus: Notice when dbus connections get disabled ++ + dbus: Remove double-free introduced while trying to make coverity shut up ++ + ensure if B is colocated with A, B can never run without A ++ + fence_legacy: Avoid passing 'port' to cluster-glue agents ++ + fencing: Allow nodes to be purged from the member cache ++ + fencing: Correctly make args for fencing agents ++ + fencing: Correctly wait for self-fencing to occur when the watchdog is in use ++ + fencing: Ensure the hostlist parameter is set for watchdog agents ++ + fencing: Force 'stonith-ng' as the system name ++ + fencing: Gracefully handle invalid metadata from agents ++ + fencing: If configured, wait stonith-watchdog-timer seconds for self-fencing to complete ++ + fencing: Reject actions for devices that haven't been explicitly registered yet ++ + ipc: properly allocate server enforced buffer size on client ++ + ipc: use server enforced buffer during ipc client send ++ + lrmd, services: interpret LSB status codes properly ++ + lrmd: add back support for class heartbeat agents ++ + lrmd: cancel pending async connection during disconnect ++ + lrmd: enable ipc proxy for docker-wrapper privileged mode ++ + lrmd: fix rescheduling of systemd monitor op during start ++ + lrmd: Handle systemd reporting 'done' before a resource is actually stopped ++ + lrmd: Hint to child processes that using sd_notify is not required ++ + lrmd: Log with the correct personality ++ + lrmd: Prevent glib assert triggered by timers being removed from mainloop more than once ++ + lrmd: report original timeout when systemd operation completes ++ + lrmd: store failed operation exit reason in cib ++ + mainloop: resolves race condition mainloop poll involving modification of ipc connections ++ + make targetted reprobe for remote node work, crm_resource -C -N ++ + mcp: Allow a configurable delay when debugging shutdown issues ++ + mcp: Avoid requiring 'export' for SYS-V sysconfig options ++ + Membership: Detect and resolve nodes that change their ID ++ + pacemakerd: resolves memory leak of xml structure in pacemakerd ++ + pengine: ability to launch resources in isolated containers ++ + pengine: add #kind=remote for baremetal remote-nodes ++ + pengine: allow baremetal remote-nodes to recover without requiring fencing when cluster-node fails ++ + pengine: allow remote-nodes to be placed in maintenance mode ++ + pengine: Avoid trailing whitespaces when printing resource state ++ + pengine: cl#5130 - Choose nodes capable of running all the colocated utilization resources ++ + pengine: cl#5130 - Only check the capacities of the nodes that are allowed to run the resource ++ + pengine: Correctly compare feature set to determine how to unpack meta attributes ++ + pengine: disable migrations for resources with isolation containers ++ + pengine: disable reloading of resources within isolated container wrappers ++ + pengine: Do not aggregate children in a pending state into the started/stopped/etc lists ++ + pengine: Do not record duplicate copies of the failed actions ++ + pengine: Do not reschedule monitors that are no longer needed while resource definitions have changed ++ + pengine: Fence baremetal remote when recurring monitor op fails ++ + pengine: Fix colocation with unmanaged resources ++ + pengine: Fix the behaviors of multi-state resources with asymmetrical ordering ++ + pengine: fixes pengine crash with orphaned remote node connection resource ++ + pengine: fixes segfault caused by malformed log warning ++ + pengine: handle cloned isolated resources in a sane way ++ + pengine: handle isolated resource scenario, cloned group of isolated resources ++ + pengine: Handle ordering between stateful and migratable resources ++ + pengine: imply stop in container node resources when host node is fenced ++ + pengine: only fence baremetal remote when connection can fails or can not be recovered ++ + pengine: only kill process group on timeout when on-fail does not equal block. ++ + pengine: per-node control over resource discovery ++ + pengine: prefer migration target for remote node connections ++ + pengine: prevent disabling rsc discovery per node in certain situations ++ + pengine: Prevent use-after-free in sort_rsc_process_order() ++ + pengine: properly handle ordering during remote connection partial migration ++ + pengine: properly recover remote-nodes when cluster-node proxy goes offline ++ + pengine: remove unnecessary whitespace from notify environment variables ++ + pengine: require-all feature for ordered clones ++ + pengine: Resolve memory leaks ++ + pengine: resource discovery mode for location constraints ++ + pengine: restart master instances on instance attribute changes ++ + pengine: Turn off legacy unpacking of resource options into the meta hashtable ++ + pengine: Watchdog integration is sufficient for fencing ++ + Perform systemd reloads asynchronously ++ + ping: Correctly advertise multiplier default ++ + Prefer to inherit the watchdog timeout from SBD ++ + properly record stop args after reload ++ + provide fake meta data for ra class heartbeat ++ + remote: report timestamps for remote connection resource operations ++ + remote: Treat recv msg timeout as a disconnect ++ + service: Prevent potential use-of-NULL in metadata lookups ++ + solaris: Allow compilation when dirent.d_type is not available ++ + solaris: Correctly replace the linux swab functions ++ + solaris: Disable throttling since /proc doesn't exist ++ + stonith-ng: Correctly observe the watchdog completion timeout ++ + stonith-ng: Correctly track node state ++ + stonith-ng: Reset mainloop source IDs after removing them ++ + systemd: Correctly handle long running stop actions ++ + systemd: Ensure failed monitor operations always return ++ + systemd: Ensure we don't call dbus_message_unref() with NULL ++ + systemd: fix crash caused when canceling in-flight operation ++ + systemd: Kindly ask dbus NOT to kill the process if the dbus connection fails ++ + systemd: Perform actions asynchronously ++ + systemd: Perform monitor operations without blocking ++ + systemd: Tell systemd not to take DBus down from underneath us ++ + systemd: Trick systemd into not stopping our services before us during shutdown ++ + tools: Improve crm_mon output with certain option combinations ++ + upstart: Monitor actions always return 'ok' or 'not running' ++ + upstart: Perform more parts of monitor operations without blocking ++ + xml: add 'require-all' to xml schema for constraints ++ + xml: cl#5231 - Unset the deleted attributes in the resulting diffs ++ + xml: Clone the latest constraint schema in preparation for changes" ++ + xml: Correctly create v1 patchsets when deleting attributes ++ + xml: Do not change the ordering of properties when applying v1 cib diffs ++ + xml: Do not dump deleted attributes ++ + xml: Do not prune leaves from v1 cib diffs that are being created with digests ++ + xml: Ensure ACLs are reapplied before calculating what a replace operation changed ++ + xml: Fix upgrade-1.3.xsl to correctly transform ACL rules with "attribute" ++ + xml: Prevent assert errors in crm_element_value() on applying a patch without version information ++ + xml: Prevent potential use-of-NULL ++ ++ + * Tue Jul 22 2014 Andrew Beekhof Pacemaker-1.1.12-1 + - Update source tarball to revision: 93a037d + - Changesets: 795 +diff --git a/Doxyfile.in b/Doxyfile.in +index 81f21d6..68fc8ce 100644 +--- a/Doxyfile.in ++++ b/Doxyfile.in +@@ -1,109 +1,119 @@ +-# Doxyfile 1.7.4 ++# Doxyfile 1.8.5 + + # This file describes the settings to be used by the documentation system + # doxygen (www.doxygen.org) for a project. + # +-# All text after a hash (#) is considered a comment and will be ignored. ++# All text after a double hash (##) is considered a comment and is placed in ++# front of the TAG it is preceding. ++# ++# All text after a single hash (#) is considered a comment and will be ignored. + # The format is: +-# TAG = value [value, ...] +-# For lists items can also be appended using: +-# TAG += value [value, ...] +-# Values that contain spaces should be placed between quotes (" "). ++# TAG = value [value, ...] ++# For lists, items can also be appended using: ++# TAG += value [value, ...] ++# Values that contain spaces should be placed between quotes (\" \"). + + #--------------------------------------------------------------------------- + # Project related configuration options + #--------------------------------------------------------------------------- + + # This tag specifies the encoding used for all characters in the config file +-# that follow. The default is UTF-8 which is also the encoding used for all +-# text before the first occurrence of this tag. Doxygen uses libiconv (or the +-# iconv built into libc) for the transcoding. See +-# http://www.gnu.org/software/libiconv for the list of possible encodings. ++# that follow. The default is UTF-8 which is also the encoding used for all text ++# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv ++# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv ++# for the list of possible encodings. ++# The default value is: UTF-8. + + DOXYFILE_ENCODING = UTF-8 + +-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +-# by quotes) that should identify the project. ++# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by ++# double-quotes, unless you are using Doxywizard) that should identify the ++# project for which the documentation is generated. This name is used in the ++# title of most generated pages and in a few other places. ++# The default value is: My Project. + + PROJECT_NAME = @PACKAGE_NAME@ + +-# The PROJECT_NUMBER tag can be used to enter a project or revision number. +-# This could be handy for archiving the generated documentation or +-# if some version control system is used. ++# The PROJECT_NUMBER tag can be used to enter a project or revision number. This ++# could be handy for archiving the generated documentation or if some version ++# control system is used. + + PROJECT_NUMBER = @PACKAGE_VERSION@-@BUILD_VERSION@ + + # Using the PROJECT_BRIEF tag one can provide an optional one line description +-# for a project that appears at the top of each page and should give viewer +-# a quick idea about the purpose of the project. Keep the description short. ++# for a project that appears at the top of each page and should give viewer a ++# quick idea about the purpose of the project. Keep the description short. + + PROJECT_BRIEF = "Scalable High-Availability cluster resource manager" + +-# With the PROJECT_LOGO tag one can specify an logo or icon that is +-# included in the documentation. The maximum height of the logo should not +-# exceed 55 pixels and the maximum width should not exceed 200 pixels. +-# Doxygen will copy the logo to the output directory. ++# With the PROJECT_LOGO tag one can specify an logo or icon that is included in ++# the documentation. The maximum height of the logo should not exceed 55 pixels ++# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo ++# to the output directory. + + PROJECT_LOGO = doc/publican-clusterlabs/en-US/images/title_logo.png + +-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +-# base path where the generated documentation will be put. +-# If a relative path is entered, it will be relative to the location +-# where doxygen was started. If left blank the current directory will be used. ++# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path ++# into which the generated documentation will be written. If a relative path is ++# entered, it will be relative to the location where doxygen was started. If ++# left blank the current directory will be used. + + OUTPUT_DIRECTORY = doc/api/ + +-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +-# 4096 sub-directories (in 2 levels) under the output directory of each output +-# format and will distribute the generated files over these directories. +-# Enabling this option can be useful when feeding doxygen a huge amount of +-# source files, where putting all generated files in the same directory would +-# otherwise cause performance problems for the file system. ++# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- ++# directories (in 2 levels) under the output directory of each output format and ++# will distribute the generated files over these directories. Enabling this ++# option can be useful when feeding doxygen a huge amount of source files, where ++# putting all generated files in the same directory would otherwise causes ++# performance problems for the file system. ++# The default value is: NO. + + CREATE_SUBDIRS = NO + + # The OUTPUT_LANGUAGE tag is used to specify the language in which all + # documentation generated by doxygen is written. Doxygen will use this + # information to generate all constant output in the proper language. +-# The default language is English, other supported languages are: +-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. ++# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- ++# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, ++# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, ++# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, ++# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, ++# Turkish, Ukrainian and Vietnamese. ++# The default value is: English. + + OUTPUT_LANGUAGE = English + +-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +-# include brief member descriptions after the members that are listed in +-# the file and class documentation (similar to JavaDoc). +-# Set to NO to disable this. ++# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member ++# descriptions after the members that are listed in the file and class ++# documentation (similar to Javadoc). Set to NO to disable this. ++# The default value is: YES. + + BRIEF_MEMBER_DESC = YES + +-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +-# the brief description of a member or function before the detailed description. +-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the ++# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief ++# description of a member or function before the detailed description ++# ++# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the + # brief descriptions will be completely suppressed. ++# The default value is: YES. + + REPEAT_BRIEF = YES + +-# This tag implements a quasi-intelligent brief description abbreviator +-# that is used to form the text in various listings. Each string +-# in this list, if found as the leading text of the brief description, will be +-# stripped from the text and the result after processing the whole list, is +-# used as the annotated text. Otherwise, the brief description is used as-is. +-# If left blank, the following values are used ("$name" is automatically +-# replaced with the name of the entity): "The $name class" "The $name widget" +-# "The $name file" "is" "provides" "specifies" "contains" +-# "represents" "a" "an" "the" ++# This tag implements a quasi-intelligent brief description abbreviator that is ++# used to form the text in various listings. Each string in this list, if found ++# as the leading text of the brief description, will be stripped from the text ++# and the result, after processing the whole list, is used as the annotated ++# text. Otherwise, the brief description is used as-is. If left blank, the ++# following values are used ($name is automatically replaced with the name of ++# the entity):The $name class, The $name widget, The $name file, is, provides, ++# specifies, contains, represents, a, an and the. + + ABBREVIATE_BRIEF = + + # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +-# Doxygen will generate a detailed section even if there is only a brief ++# doxygen will generate a detailed section even if there is only a brief + # description. ++# The default value is: NO. + + ALWAYS_DETAILED_SEC = NO + +@@ -111,153 +121,204 @@ ALWAYS_DETAILED_SEC = NO + # inherited members of a class in the documentation of that class as if those + # members were ordinary class members. Constructors, destructors and assignment + # operators of the base classes will not be shown. ++# The default value is: NO. + + INLINE_INHERITED_MEMB = NO + +-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +-# path before files name in the file list and in the header files. If set +-# to NO the shortest path that makes the file name unique will be used. ++# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path ++# before files name in the file list and in the header files. If set to NO the ++# shortest path that makes the file name unique will be used ++# The default value is: YES. + + FULL_PATH_NAMES = YES + +-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +-# can be used to strip a user-defined part of the path. Stripping is +-# only done if one of the specified strings matches the left-hand part of +-# the path. The tag can be used to show relative paths in the file list. +-# If left blank the directory from which doxygen is run is used as the +-# path to strip. ++# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. ++# Stripping is only done if one of the specified strings matches the left-hand ++# part of the path. The tag can be used to show relative paths in the file list. ++# If left blank the directory from which doxygen is run is used as the path to ++# strip. ++# ++# Note that you can specify absolute paths here, but also relative paths, which ++# will be relative from the directory where doxygen is started. ++# This tag requires that the tag FULL_PATH_NAMES is set to YES. + + STRIP_FROM_PATH = + +-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +-# the path mentioned in the documentation of a class, which tells +-# the reader which header file to include in order to use a class. +-# If left blank only the name of the header file containing the class +-# definition is used. Otherwise one should specify the include paths that +-# are normally passed to the compiler using the -I flag. ++# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the ++# path mentioned in the documentation of a class, which tells the reader which ++# header file to include in order to use a class. If left blank only the name of ++# the header file containing the class definition is used. Otherwise one should ++# specify the list of include paths that are normally passed to the compiler ++# using the -I flag. + + STRIP_FROM_INC_PATH = + +-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +-# (but less readable) file names. This can be useful if your file system +-# doesn't support long names like on DOS, Mac, or CD-ROM. ++# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but ++# less readable) file names. This can be useful is your file systems doesn't ++# support long names like on DOS, Mac, or CD-ROM. ++# The default value is: NO. + + SHORT_NAMES = NO + +-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +-# will interpret the first line (until the first dot) of a JavaDoc-style +-# comment as the brief description. If set to NO, the JavaDoc +-# comments will behave just like regular Qt-style comments +-# (thus requiring an explicit @brief command for a brief description.) ++# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the ++# first line (until the first dot) of a Javadoc-style comment as the brief ++# description. If set to NO, the Javadoc-style will behave just like regular Qt- ++# style comments (thus requiring an explicit @brief command for a brief ++# description.) ++# The default value is: NO. + + JAVADOC_AUTOBRIEF = NO + +-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +-# interpret the first line (until the first dot) of a Qt-style +-# comment as the brief description. If set to NO, the comments +-# will behave just like regular Qt-style comments (thus requiring +-# an explicit \brief command for a brief description.) ++# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first ++# line (until the first dot) of a Qt-style comment as the brief description. If ++# set to NO, the Qt-style will behave just like regular Qt-style comments (thus ++# requiring an explicit \brief command for a brief description.) ++# The default value is: NO. + + QT_AUTOBRIEF = NO + +-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +-# treat a multi-line C++ special comment block (i.e. a block of //! or /// +-# comments) as a brief description. This used to be the default behaviour. +-# The new default is to treat a multi-line C++ comment block as a detailed +-# description. Set this tag to YES if you prefer the old behaviour instead. ++# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a ++# multi-line C++ special comment block (i.e. a block of //! or /// comments) as ++# a brief description. This used to be the default behavior. The new default is ++# to treat a multi-line C++ comment block as a detailed description. Set this ++# tag to YES if you prefer the old behavior instead. ++# ++# Note that setting this tag to YES also means that rational rose comments are ++# not recognized any more. ++# The default value is: NO. + + MULTILINE_CPP_IS_BRIEF = NO + +-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +-# member inherits the documentation from any documented member that it +-# re-implements. ++# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the ++# documentation from any documented member that it re-implements. ++# The default value is: YES. + + INHERIT_DOCS = YES + +-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +-# a new page for each member. If set to NO, the documentation of a member will +-# be part of the file/class/namespace that contains it. ++# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a ++# new page for each member. If set to NO, the documentation of a member will be ++# part of the file/class/namespace that contains it. ++# The default value is: NO. + + SEPARATE_MEMBER_PAGES = NO + +-# The TAB_SIZE tag can be used to set the number of spaces in a tab. +-# Doxygen uses this value to replace tabs by spaces in code fragments. ++# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen ++# uses this value to replace tabs by spaces in code fragments. ++# Minimum value: 1, maximum value: 16, default value: 4. + + TAB_SIZE = 4 + +-# This tag can be used to specify a number of aliases that acts +-# as commands in the documentation. An alias has the form "name=value". +-# For example adding "sideeffect=\par Side Effects:\n" will allow you to +-# put the command \sideeffect (or @sideeffect) in the documentation, which +-# will result in a user-defined paragraph with heading "Side Effects:". +-# You can put \n's in the value part of an alias to insert newlines. ++# This tag can be used to specify a number of aliases that act as commands in ++# the documentation. An alias has the form: ++# name=value ++# For example adding ++# "sideeffect=@par Side Effects:\n" ++# will allow you to put the command \sideeffect (or @sideeffect) in the ++# documentation, which will result in a user-defined paragraph with heading ++# "Side Effects:". You can put \n's in the value part of an alias to insert ++# newlines. + + ALIASES = + +-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +-# sources only. Doxygen will then generate output that is more tailored for C. +-# For instance, some of the names that are used will be different. The list +-# of all members will be omitted, etc. ++# This tag can be used to specify a number of word-keyword mappings (TCL only). ++# A mapping has the form "name=value". For example adding "class=itcl::class" ++# will allow you to use the command class in the itcl::class meaning. ++ ++TCL_SUBST = ++ ++# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources ++# only. Doxygen will then generate output that is more tailored for C. For ++# instance, some of the names that are used will be different. The list of all ++# members will be omitted, etc. ++# The default value is: NO. + + OPTIMIZE_OUTPUT_FOR_C = YES + +-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +-# sources only. Doxygen will then generate output that is more tailored for +-# Java. For instance, namespaces will be presented as packages, qualified +-# scopes will look different, etc. ++# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or ++# Python sources only. Doxygen will then generate output that is more tailored ++# for that language. For instance, namespaces will be presented as packages, ++# qualified scopes will look different, etc. ++# The default value is: NO. + + OPTIMIZE_OUTPUT_JAVA = NO + + # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +-# sources only. Doxygen will then generate output that is more tailored for +-# Fortran. ++# sources. Doxygen will then generate output that is tailored for Fortran. ++# The default value is: NO. + + OPTIMIZE_FOR_FORTRAN = NO + + # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +-# sources. Doxygen will then generate output that is tailored for +-# VHDL. ++# sources. Doxygen will then generate output that is tailored for VHDL. ++# The default value is: NO. + + OPTIMIZE_OUTPUT_VHDL = NO + + # Doxygen selects the parser to use depending on the extension of the files it +-# parses. With this tag you can assign which parser to use for a given extension. +-# Doxygen has a built-in mapping, but you can override or extend it using this +-# tag. The format is ext=language, where ext is a file extension, and language +-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make ++# parses. With this tag you can assign which parser to use for a given ++# extension. Doxygen has a built-in mapping, but you can override or extend it ++# using this tag. The format is ext=language, where ext is a file extension, and ++# language is one of the parsers supported by doxygen: IDL, Java, Javascript, ++# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make + # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. ++# (default is Fortran), use: inc=Fortran f=C. ++# ++# Note For files without extension you can use no_extension as a placeholder. ++# ++# Note that for custom extensions you also need to set FILE_PATTERNS otherwise ++# the files are not read by doxygen. + + EXTENSION_MAPPING = + ++# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments ++# according to the Markdown format, which allows for more readable ++# documentation. See http://daringfireball.net/projects/markdown/ for details. ++# The output of markdown processing is further processed by doxygen, so you can ++# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in ++# case of backward compatibilities issues. ++# The default value is: YES. ++ ++MARKDOWN_SUPPORT = YES ++ ++# When enabled doxygen tries to link words that correspond to documented ++# classes, or namespaces to their corresponding documentation. Such a link can ++# be prevented in individual cases by by putting a % sign in front of the word ++# or globally by setting AUTOLINK_SUPPORT to NO. ++# The default value is: YES. ++ ++AUTOLINK_SUPPORT = YES ++ + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +-# to include (a tag file for) the STL sources as input, then you should +-# set this tag to YES in order to let doxygen match functions declarations and +-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +-# func(std::string) {}). This also makes the inheritance and collaboration ++# to include (a tag file for) the STL sources as input, then you should set this ++# tag to YES in order to let doxygen match functions declarations and ++# definitions whose arguments contain STL classes (e.g. func(std::string); ++# versus func(std::string) {}). This also make the inheritance and collaboration + # diagrams that involve STL classes more complete and accurate. ++# The default value is: NO. + + BUILTIN_STL_SUPPORT = NO + + # If you use Microsoft's C++/CLI language, you should set this option to YES to + # enable parsing support. ++# The default value is: NO. + + CPP_CLI_SUPPORT = NO + +-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +-# Doxygen will parse them like normal C++ but will assume all classes use public +-# instead of private inheritance when no explicit protection keyword is present. ++# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: ++# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen ++# will parse them like normal C++ but will assume all classes use public instead ++# of private inheritance when no explicit protection keyword is present. ++# The default value is: NO. + + SIP_SUPPORT = NO + +-# For Microsoft's IDL there are propget and propput attributes to indicate getter +-# and setter methods for a property. Setting this option to YES (the default) +-# will make doxygen replace the get and set methods by a property in the +-# documentation. This will only work if the methods are indeed getting or +-# setting a simple type. If this is not the case, or you want to show the +-# methods anyway, you should set this option to NO. ++# For Microsoft's IDL there are propget and propput attributes to indicate ++# getter and setter methods for a property. Setting this option to YES will make ++# doxygen to replace the get and set methods by a property in the documentation. ++# This will only work if the methods are indeed getting or setting a simple ++# type. If this is not the case, or you want to show the methods anyway, you ++# should set this option to NO. ++# The default value is: YES. + + IDL_PROPERTY_SUPPORT = YES + +@@ -265,394 +326,464 @@ IDL_PROPERTY_SUPPORT = YES + # tag is set to YES, then doxygen will reuse the documentation of the first + # member in the group (if any) for the other members of the group. By default + # all members of a group must be documented explicitly. ++# The default value is: NO. + + DISTRIBUTE_GROUP_DOC = YES + +-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +-# the same type (for instance a group of public functions) to be put as a +-# subgroup of that type (e.g. under the Public Functions section). Set it to +-# NO to prevent subgrouping. Alternatively, this can be done per class using +-# the \nosubgrouping command. ++# Set the SUBGROUPING tag to YES to allow class member groups of the same type ++# (for instance a group of public functions) to be put as a subgroup of that ++# type (e.g. under the Public Functions section). Set it to NO to prevent ++# subgrouping. Alternatively, this can be done per class using the ++# \nosubgrouping command. ++# The default value is: YES. + + SUBGROUPING = YES + +-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +-# unions are shown inside the group in which they are included (e.g. using +-# @ingroup) instead of on a separate page (for HTML and Man pages) or +-# section (for LaTeX and RTF). ++# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions ++# are shown inside the group in which they are included (e.g. using \ingroup) ++# instead of on a separate page (for HTML and Man pages) or section (for LaTeX ++# and RTF). ++# ++# Note that this feature does not work in combination with ++# SEPARATE_MEMBER_PAGES. ++# The default value is: NO. + + INLINE_GROUPED_CLASSES = NO + +-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +-# is documented as struct, union, or enum with the name of the typedef. So ++# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions ++# with only public data fields or simple typedef fields will be shown inline in ++# the documentation of the scope in which they are defined (i.e. file, ++# namespace, or group documentation), provided this scope is documented. If set ++# to NO, structs, classes, and unions are shown on a separate page (for HTML and ++# Man pages) or section (for LaTeX and RTF). ++# The default value is: NO. ++ ++INLINE_SIMPLE_STRUCTS = NO ++ ++# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or ++# enum is documented as struct, union, or enum with the name of the typedef. So + # typedef struct TypeS {} TypeT, will appear in the documentation as a struct + # with name TypeT. When disabled the typedef will appear as a member of a file, +-# namespace, or class. And the struct will be named TypeS. This can typically +-# be useful for C code in case the coding convention dictates that all compound ++# namespace, or class. And the struct will be named TypeS. This can typically be ++# useful for C code in case the coding convention dictates that all compound + # types are typedef'ed and only the typedef is referenced, never the tag name. ++# The default value is: NO. + + TYPEDEF_HIDES_STRUCT = NO + +-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +-# determine which symbols to keep in memory and which to flush to disk. +-# When the cache is full, less often used symbols will be written to disk. +-# For small to medium size projects (<1000 input files) the default value is +-# probably good enough. For larger projects a too small cache size can cause +-# doxygen to be busy swapping symbols to and from disk most of the time +-# causing a significant performance penalty. +-# If the system has enough physical memory increasing the cache will improve the +-# performance by keeping more symbols in memory. Note that the value works on +-# a logarithmic scale so increasing the size by one will roughly double the +-# memory usage. The cache size is given by this formula: +-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +-# corresponding to a cache size of 2^16 = 65536 symbols +- +-SYMBOL_CACHE_SIZE = 0 ++# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This ++# cache is used to resolve symbols given their name and scope. Since this can be ++# an expensive process and often the same symbol appears multiple times in the ++# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small ++# doxygen will become slower. If the cache is too large, memory is wasted. The ++# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range ++# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 ++# symbols. At the end of a run doxygen will report the cache usage and suggest ++# the optimal cache size from a speed point of view. ++# Minimum value: 0, maximum value: 9, default value: 0. ++ ++LOOKUP_CACHE_SIZE = 0 + + #--------------------------------------------------------------------------- + # Build related configuration options + #--------------------------------------------------------------------------- + + # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +-# documentation are documented, even if no documentation was available. +-# Private class members and static file members will be hidden unless +-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES ++# documentation are documented, even if no documentation was available. Private ++# class members and static file members will be hidden unless the ++# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. ++# Note: This will also disable the warnings about undocumented members that are ++# normally produced when WARNINGS is set to YES. ++# The default value is: NO. + + EXTRACT_ALL = YES + +-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +-# will be included in the documentation. ++# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will ++# be included in the documentation. ++# The default value is: NO. + + EXTRACT_PRIVATE = NO + +-# If the EXTRACT_STATIC tag is set to YES all static members of a file +-# will be included in the documentation. ++# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal ++# scope will be included in the documentation. ++# The default value is: NO. ++ ++EXTRACT_PACKAGE = NO ++ ++# If the EXTRACT_STATIC tag is set to YES all static members of a file will be ++# included in the documentation. ++# The default value is: NO. + + EXTRACT_STATIC = NO + +-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +-# defined locally in source files will be included in the documentation. +-# If set to NO only classes defined in header files are included. ++# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined ++# locally in source files will be included in the documentation. If set to NO ++# only classes defined in header files are included. Does not have any effect ++# for Java sources. ++# The default value is: YES. + + EXTRACT_LOCAL_CLASSES = NO + +-# This flag is only useful for Objective-C code. When set to YES local +-# methods, which are defined in the implementation section but not in +-# the interface are included in the documentation. +-# If set to NO (the default) only methods in the interface are included. ++# This flag is only useful for Objective-C code. When set to YES local methods, ++# which are defined in the implementation section but not in the interface are ++# included in the documentation. If set to NO only methods in the interface are ++# included. ++# The default value is: NO. + + EXTRACT_LOCAL_METHODS = NO + + # If this flag is set to YES, the members of anonymous namespaces will be + # extracted and appear in the documentation as a namespace called +-# 'anonymous_namespace{file}', where file will be replaced with the base +-# name of the file that contains the anonymous namespace. By default +-# anonymous namespaces are hidden. ++# 'anonymous_namespace{file}', where file will be replaced with the base name of ++# the file that contains the anonymous namespace. By default anonymous namespace ++# are hidden. ++# The default value is: NO. + + EXTRACT_ANON_NSPACES = NO + +-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +-# undocumented members of documented classes, files or namespaces. +-# If set to NO (the default) these members will be included in the +-# various overviews, but no documentation section is generated. +-# This option has no effect if EXTRACT_ALL is enabled. ++# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all ++# undocumented members inside documented classes or files. If set to NO these ++# members will be included in the various overviews, but no documentation ++# section is generated. This option has no effect if EXTRACT_ALL is enabled. ++# The default value is: NO. + + HIDE_UNDOC_MEMBERS = NO + +-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +-# undocumented classes that are normally visible in the class hierarchy. +-# If set to NO (the default) these classes will be included in the various +-# overviews. This option has no effect if EXTRACT_ALL is enabled. ++# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all ++# undocumented classes that are normally visible in the class hierarchy. If set ++# to NO these classes will be included in the various overviews. This option has ++# no effect if EXTRACT_ALL is enabled. ++# The default value is: NO. + + HIDE_UNDOC_CLASSES = NO + +-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +-# friend (class|struct|union) declarations. +-# If set to NO (the default) these declarations will be included in the +-# documentation. ++# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend ++# (class|struct|union) declarations. If set to NO these declarations will be ++# included in the documentation. ++# The default value is: NO. + + HIDE_FRIEND_COMPOUNDS = NO + +-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +-# documentation blocks found inside the body of a function. +-# If set to NO (the default) these blocks will be appended to the +-# function's detailed documentation block. ++# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any ++# documentation blocks found inside the body of a function. If set to NO these ++# blocks will be appended to the function's detailed documentation block. ++# The default value is: NO. + + HIDE_IN_BODY_DOCS = NO + +-# The INTERNAL_DOCS tag determines if documentation +-# that is typed after a \internal command is included. If the tag is set +-# to NO (the default) then the documentation will be excluded. +-# Set it to YES to include the internal documentation. ++# The INTERNAL_DOCS tag determines if documentation that is typed after a ++# \internal command is included. If the tag is set to NO then the documentation ++# will be excluded. Set it to YES to include the internal documentation. ++# The default value is: NO. + + INTERNAL_DOCS = NO + +-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +-# file names in lower-case letters. If set to YES upper-case letters are also ++# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file ++# names in lower-case letters. If set to YES upper-case letters are also + # allowed. This is useful if you have classes or files whose names only differ + # in case and if your file system supports case sensitive file names. Windows + # and Mac users are advised to set this option to NO. ++# The default value is: system dependent. + + CASE_SENSE_NAMES = YES + +-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +-# will show members with their full class and namespace scopes in the +-# documentation. If set to YES the scope will be hidden. ++# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with ++# their full class and namespace scopes in the documentation. If set to YES the ++# scope will be hidden. ++# The default value is: NO. + + HIDE_SCOPE_NAMES = NO + +-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +-# will put a list of the files that are included by a file in the documentation +-# of that file. ++# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of ++# the files that are included by a file in the documentation of that file. ++# The default value is: YES. + + SHOW_INCLUDE_FILES = YES + +-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +-# will list include files with double quotes in the documentation +-# rather than with sharp brackets. ++# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include ++# files with double quotes in the documentation rather than with sharp brackets. ++# The default value is: NO. + + FORCE_LOCAL_INCLUDES = NO + +-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +-# is inserted in the documentation for inline members. ++# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the ++# documentation for inline members. ++# The default value is: YES. + + INLINE_INFO = YES + +-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +-# will sort the (detailed) documentation of file and class members +-# alphabetically by member name. If set to NO the members will appear in +-# declaration order. ++# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the ++# (detailed) documentation of file and class members alphabetically by member ++# name. If set to NO the members will appear in declaration order. ++# The default value is: YES. + + SORT_MEMBER_DOCS = YES + +-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +-# brief documentation of file, namespace and class members alphabetically +-# by member name. If set to NO (the default) the members will appear in +-# declaration order. ++# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief ++# descriptions of file, namespace and class members alphabetically by member ++# name. If set to NO the members will appear in declaration order. ++# The default value is: NO. + + SORT_BRIEF_DOCS = NO + +-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +-# will sort the (brief and detailed) documentation of class members so that +-# constructors and destructors are listed first. If set to NO (the default) +-# the constructors will appear in the respective orders defined by +-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. ++# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the ++# (brief and detailed) documentation of class members so that constructors and ++# destructors are listed first. If set to NO the constructors will appear in the ++# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. ++# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief ++# member documentation. ++# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting ++# detailed member documentation. ++# The default value is: NO. + + SORT_MEMBERS_CTORS_1ST = YES + +-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +-# hierarchy of group names into alphabetical order. If set to NO (the default) +-# the group names will appear in their defined order. ++# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy ++# of group names into alphabetical order. If set to NO the group names will ++# appear in their defined order. ++# The default value is: NO. + + SORT_GROUP_NAMES = NO + +-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +-# sorted by fully-qualified names, including namespaces. If set to +-# NO (the default), the class list will be sorted only by class name, +-# not including the namespace part. ++# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by ++# fully-qualified names, including namespaces. If set to NO, the class list will ++# be sorted only by class name, not including the namespace part. + # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +-# Note: This option applies only to the class list, not to the +-# alphabetical list. ++# Note: This option applies only to the class list, not to the alphabetical ++# list. ++# The default value is: NO. + + SORT_BY_SCOPE_NAME = NO + +-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +-# do proper type resolution of all parameters of a function it will reject a +-# match between the prototype and the implementation of a member function even +-# if there is only one candidate or it is obvious which candidate to choose +-# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +-# will still accept a match between prototype and implementation in such cases. ++# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper ++# type resolution of all parameters of a function it will reject a match between ++# the prototype and the implementation of a member function even if there is ++# only one candidate or it is obvious which candidate to choose by doing a ++# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still ++# accept a match between prototype and implementation in such cases. ++# The default value is: NO. + + STRICT_PROTO_MATCHING = NO + +-# The GENERATE_TODOLIST tag can be used to enable (YES) or +-# disable (NO) the todo list. This list is created by putting \todo +-# commands in the documentation. ++# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the ++# todo list. This list is created by putting \todo commands in the ++# documentation. ++# The default value is: YES. + + GENERATE_TODOLIST = YES + +-# The GENERATE_TESTLIST tag can be used to enable (YES) or +-# disable (NO) the test list. This list is created by putting \test +-# commands in the documentation. ++# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the ++# test list. This list is created by putting \test commands in the ++# documentation. ++# The default value is: YES. + + GENERATE_TESTLIST = YES + +-# The GENERATE_BUGLIST tag can be used to enable (YES) or +-# disable (NO) the bug list. This list is created by putting \bug +-# commands in the documentation. ++# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug ++# list. This list is created by putting \bug commands in the documentation. ++# The default value is: YES. + + GENERATE_BUGLIST = YES + +-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +-# disable (NO) the deprecated list. This list is created by putting +-# \deprecated commands in the documentation. ++# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) ++# the deprecated list. This list is created by putting \deprecated commands in ++# the documentation. ++# The default value is: YES. + + GENERATE_DEPRECATEDLIST= YES + +-# The ENABLED_SECTIONS tag can be used to enable conditional +-# documentation sections, marked by \if sectionname ... \endif. ++# The ENABLED_SECTIONS tag can be used to enable conditional documentation ++# sections, marked by \if ... \endif and \cond ++# ... \endcond blocks. + + ENABLED_SECTIONS = + +-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +-# the initial value of a variable or macro consists of for it to appear in +-# the documentation. If the initializer consists of more lines than specified +-# here it will be hidden. Use a value of 0 to hide initializers completely. +-# The appearance of the initializer of individual variables and macros in the +-# documentation can be controlled using \showinitializer or \hideinitializer +-# command in the documentation regardless of this setting. ++# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the ++# initial value of a variable or macro / define can have for it to appear in the ++# documentation. If the initializer consists of more lines than specified here ++# it will be hidden. Use a value of 0 to hide initializers completely. The ++# appearance of the value of individual variables and macros / defines can be ++# controlled using \showinitializer or \hideinitializer command in the ++# documentation regardless of this setting. ++# Minimum value: 0, maximum value: 10000, default value: 30. + + MAX_INITIALIZER_LINES = 30 + +-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +-# at the bottom of the documentation of classes and structs. If set to YES the +-# list will mention the files that were used to generate the documentation. ++# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at ++# the bottom of the documentation of classes and structs. If set to YES the list ++# will mention the files that were used to generate the documentation. ++# The default value is: YES. + + SHOW_USED_FILES = YES + +-# If the sources in your project are distributed over multiple directories +-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +-# in the documentation. The default is NO. +- +-SHOW_DIRECTORIES = NO +- +-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +-# This will remove the Files entry from the Quick Index and from the +-# Folder Tree View (if specified). The default is YES. ++# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This ++# will remove the Files entry from the Quick Index and from the Folder Tree View ++# (if specified). ++# The default value is: YES. + + SHOW_FILES = YES + +-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +-# Namespaces page. +-# This will remove the Namespaces entry from the Quick Index +-# and from the Folder Tree View (if specified). The default is YES. ++# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces ++# page. This will remove the Namespaces entry from the Quick Index and from the ++# Folder Tree View (if specified). ++# The default value is: YES. + + SHOW_NAMESPACES = YES + + # The FILE_VERSION_FILTER tag can be used to specify a program or script that + # doxygen should invoke to get the current version for each file (typically from + # the version control system). Doxygen will invoke the program by executing (via +-# popen()) the command , where is the value of +-# the FILE_VERSION_FILTER tag, and is the name of an input file +-# provided by doxygen. Whatever the program writes to standard output +-# is used as the file version. See the manual for examples. ++# popen()) the command command input-file, where command is the value of the ++# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided ++# by doxygen. Whatever the program writes to standard output is used as the file ++# version. For an example see the documentation. + + FILE_VERSION_FILTER = + + # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed + # by doxygen. The layout file controls the global structure of the generated +-# output files in an output format independent way. The create the layout file +-# that represents doxygen's defaults, run doxygen with the -l option. +-# You can optionally specify a file name after the option, if omitted +-# DoxygenLayout.xml will be used as the name of the layout file. ++# output files in an output format independent way. To create the layout file ++# that represents doxygen's defaults, run doxygen with the -l option. You can ++# optionally specify a file name after the option, if omitted DoxygenLayout.xml ++# will be used as the name of the layout file. ++# ++# Note that if you run doxygen from a directory containing a file called ++# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE ++# tag is left empty. + + LAYOUT_FILE = + ++# The CITE_BIB_FILES tag can be used to specify one or more bib files containing ++# the reference definitions. This must be a list of .bib files. The .bib ++# extension is automatically appended if omitted. This requires the bibtex tool ++# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. ++# For LaTeX the style of the bibliography can be controlled using ++# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the ++# search path. Do not use file names with spaces, bibtex cannot handle them. See ++# also \cite for info how to create references. ++ ++CITE_BIB_FILES = ++ + #--------------------------------------------------------------------------- +-# configuration options related to warning and progress messages ++# Configuration options related to warning and progress messages + #--------------------------------------------------------------------------- + +-# The QUIET tag can be used to turn on/off the messages that are generated +-# by doxygen. Possible values are YES and NO. If left blank NO is used. ++# The QUIET tag can be used to turn on/off the messages that are generated to ++# standard output by doxygen. If QUIET is set to YES this implies that the ++# messages are off. ++# The default value is: NO. + + QUIET = NO + + # The WARNINGS tag can be used to turn on/off the warning messages that are +-# generated by doxygen. Possible values are YES and NO. If left blank +-# NO is used. ++# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES ++# this implies that the warnings are on. ++# ++# Tip: Turn warnings on while writing the documentation. ++# The default value is: YES. + + WARNINGS = YES + +-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +-# automatically be disabled. ++# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate ++# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag ++# will automatically be disabled. ++# The default value is: YES. + + WARN_IF_UNDOCUMENTED = YES + +-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +-# potential errors in the documentation, such as not documenting some +-# parameters in a documented function, or documenting parameters that +-# don't exist or using markup commands wrongly. ++# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for ++# potential errors in the documentation, such as not documenting some parameters ++# in a documented function, or documenting parameters that don't exist or using ++# markup commands wrongly. ++# The default value is: YES. + + WARN_IF_DOC_ERROR = YES + +-# The WARN_NO_PARAMDOC option can be enabled to get warnings for +-# functions that are documented, but have no documentation for their parameters +-# or return value. If set to NO (the default) doxygen will only warn about +-# wrong or incomplete parameter documentation, but not about the absence of +-# documentation. ++# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that ++# are documented, but have no documentation for their parameters or return ++# value. If set to NO doxygen will only warn about wrong or incomplete parameter ++# documentation, but not about the absence of documentation. ++# The default value is: NO. + + WARN_NO_PARAMDOC = NO + +-# The WARN_FORMAT tag determines the format of the warning messages that +-# doxygen can produce. The string should contain the $file, $line, and $text +-# tags, which will be replaced by the file and line number from which the +-# warning originated and the warning text. Optionally the format may contain +-# $version, which will be replaced by the version of the file (if it could +-# be obtained via FILE_VERSION_FILTER) ++# The WARN_FORMAT tag determines the format of the warning messages that doxygen ++# can produce. The string should contain the $file, $line, and $text tags, which ++# will be replaced by the file and line number from which the warning originated ++# and the warning text. Optionally the format may contain $version, which will ++# be replaced by the version of the file (if it could be obtained via ++# FILE_VERSION_FILTER) ++# The default value is: $file:$line: $text. + + WARN_FORMAT = "$file:$line: $text" + +-# The WARN_LOGFILE tag can be used to specify a file to which warning +-# and error messages should be written. If left blank the output is written +-# to stderr. ++# The WARN_LOGFILE tag can be used to specify a file to which warning and error ++# messages should be written. If left blank the output is written to standard ++# error (stderr). + + WARN_LOGFILE = + + #--------------------------------------------------------------------------- +-# configuration options related to the input files ++# Configuration options related to the input files + #--------------------------------------------------------------------------- + +-# The INPUT tag can be used to specify the files and/or directories that contain +-# documented source files. You may enter file names like "myfile.cpp" or +-# directories like "/usr/src/myproject". Separate the files or directories +-# with spaces. ++# The INPUT tag is used to specify the files and/or directories that contain ++# documented source files. You may enter file names like myfile.cpp or ++# directories like /usr/src/myproject. Separate the files or directories with ++# spaces. ++# Note: If this tag is empty the current directory is searched. + +-INPUT = include/crm include/crm_config.h include/doxygen.h ++INPUT = include \ ++ lib + + # This tag can be used to specify the character encoding of the source files +-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +-# also the default input encoding. Doxygen uses libiconv (or the iconv built +-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +-# the list of possible encodings. ++# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses ++# libiconv (or the iconv built into libc) for the transcoding. See the libiconv ++# documentation (see: http://www.gnu.org/software/libiconv) for the list of ++# possible encodings. ++# The default value is: UTF-8. + + INPUT_ENCODING = UTF-8 + + # If the value of the INPUT tag contains directories, you can use the +-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +-# and *.h) to filter out the source-files in the directories. If left +-# blank the following patterns are tested: +-# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +-# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +-# *.f90 *.f *.for *.vhd *.vhdl ++# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and ++# *.h) to filter out the source-files in the directories. If left blank the ++# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, ++# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, ++# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, ++# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, ++# *.qsf, *.as and *.js. + + FILE_PATTERNS = + +-# The RECURSIVE tag can be used to turn specify whether or not subdirectories +-# should be searched for input files as well. Possible values are YES and NO. +-# If left blank NO is used. ++# The RECURSIVE tag can be used to specify whether or not subdirectories should ++# be searched for input files as well. ++# The default value is: NO. + + RECURSIVE = YES + +-# The EXCLUDE tag can be used to specify files and/or directories that should ++# The EXCLUDE tag can be used to specify files and/or directories that should be + # excluded from the INPUT source files. This way you can easily exclude a + # subdirectory from a directory tree whose root is specified with the INPUT tag. ++# ++# Note that relative paths are relative to the directory from which doxygen is ++# run. + + EXCLUDE = + +-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or ++# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or + # directories that are symbolic links (a Unix file system feature) are excluded + # from the input. ++# The default value is: NO. + + EXCLUDE_SYMLINKS = NO + + # If the value of the INPUT tag contains directories, you can use the + # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +-# certain files from those directories. Note that the wildcards are matched +-# against the file with absolute path, so to exclude all test directories +-# for example use the pattern */test/* ++# certain files from those directories. ++# ++# Note that the wildcards are matched against the file with absolute path, so to ++# exclude all test directories for example use the pattern */test/* + + EXCLUDE_PATTERNS = + +@@ -661,744 +792,1080 @@ EXCLUDE_PATTERNS = + # output. The symbol name can be a fully qualified name, a word, or if the + # wildcard * is used, a substring. Examples: ANamespace, AClass, + # AClass::ANamespace, ANamespace::*Test ++# ++# Note that the wildcards are matched against the file with absolute path, so to ++# exclude all test directories use the pattern */test/* + + EXCLUDE_SYMBOLS = + +-# The EXAMPLE_PATH tag can be used to specify one or more files or +-# directories that contain example code fragments that are included (see +-# the \include command). ++# The EXAMPLE_PATH tag can be used to specify one or more files or directories ++# that contain example code fragments that are included (see the \include ++# command). + + EXAMPLE_PATH = . + + # If the value of the EXAMPLE_PATH tag contains directories, you can use the +-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +-# and *.h) to filter out the source-files in the directories. If left +-# blank all files are included. ++# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and ++# *.h) to filter out the source-files in the directories. If left blank all ++# files are included. + + EXAMPLE_PATTERNS = + + # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +-# searched for input files to be used with the \include or \dontinclude +-# commands irrespective of the value of the RECURSIVE tag. +-# Possible values are YES and NO. If left blank NO is used. ++# searched for input files to be used with the \include or \dontinclude commands ++# irrespective of the value of the RECURSIVE tag. ++# The default value is: NO. + + EXAMPLE_RECURSIVE = YES + +-# The IMAGE_PATH tag can be used to specify one or more files or +-# directories that contain image that are included in the documentation (see +-# the \image command). ++# The IMAGE_PATH tag can be used to specify one or more files or directories ++# that contain images that are to be included in the documentation (see the ++# \image command). + + IMAGE_PATH = + + # The INPUT_FILTER tag can be used to specify a program that doxygen should + # invoke to filter for each input file. Doxygen will invoke the filter program +-# by executing (via popen()) the command , where +-# is the value of the INPUT_FILTER tag, and is the name of an +-# input file. Doxygen will then use the output that the filter program writes +-# to standard output. +-# If FILTER_PATTERNS is specified, this tag will be +-# ignored. ++# by executing (via popen()) the command: ++# ++# ++# ++# where is the value of the INPUT_FILTER tag, and is the ++# name of an input file. Doxygen will then use the output that the filter ++# program writes to standard output. If FILTER_PATTERNS is specified, this tag ++# will be ignored. ++# ++# Note that the filter must not add or remove lines; it is applied before the ++# code is scanned, but not when the output code is generated. If lines are added ++# or removed, the anchors will not be placed correctly. + + INPUT_FILTER = + + # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +-# basis. +-# Doxygen will compare the file name with each pattern and apply the +-# filter if there is a match. +-# The filters are a list of the form: +-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +-# info on how filters are used. If FILTER_PATTERNS is empty or if +-# non of the patterns match the file name, INPUT_FILTER is applied. ++# basis. Doxygen will compare the file name with each pattern and apply the ++# filter if there is a match. The filters are a list of the form: pattern=filter ++# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how ++# filters are used. If the FILTER_PATTERNS tag is empty or if none of the ++# patterns match the file name, INPUT_FILTER is applied. + + FILTER_PATTERNS = + + # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +-# INPUT_FILTER) will be used to filter the input files when producing source +-# files to browse (i.e. when SOURCE_BROWSER is set to YES). ++# INPUT_FILTER ) will also be used to filter the input files that are used for ++# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). ++# The default value is: NO. + + FILTER_SOURCE_FILES = NO + + # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +-# and it is also possible to disable source filtering for a specific pattern +-# using *.ext= (so without naming a filter). This option only has effect when +-# FILTER_SOURCE_FILES is enabled. ++# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and ++# it is also possible to disable source filtering for a specific pattern using ++# *.ext= (so without naming a filter). ++# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + + FILTER_SOURCE_PATTERNS = + ++# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that ++# is part of the input, its contents will be placed on the main page ++# (index.html). This can be useful if you have a project on for instance GitHub ++# and want to reuse the introduction page also for the doxygen output. ++ ++USE_MDFILE_AS_MAINPAGE = ++ + #--------------------------------------------------------------------------- +-# configuration options related to source browsing ++# Configuration options related to source browsing + #--------------------------------------------------------------------------- + +-# If the SOURCE_BROWSER tag is set to YES then a list of source files will +-# be generated. Documented entities will be cross-referenced with these sources. +-# Note: To get rid of all source code in the generated output, make sure also +-# VERBATIM_HEADERS is set to NO. ++# If the SOURCE_BROWSER tag is set to YES then a list of source files will be ++# generated. Documented entities will be cross-referenced with these sources. ++# ++# Note: To get rid of all source code in the generated output, make sure that ++# also VERBATIM_HEADERS is set to NO. ++# The default value is: NO. + + SOURCE_BROWSER = YES + +-# Setting the INLINE_SOURCES tag to YES will include the body +-# of functions and classes directly in the documentation. ++# Setting the INLINE_SOURCES tag to YES will include the body of functions, ++# classes and enums directly into the documentation. ++# The default value is: NO. + + INLINE_SOURCES = NO + +-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +-# doxygen to hide any special comment blocks from generated source code +-# fragments. Normal C and C++ comments will always remain visible. ++# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any ++# special comment blocks from generated source code fragments. Normal C, C++ and ++# Fortran comments will always remain visible. ++# The default value is: YES. + + STRIP_CODE_COMMENTS = YES + +-# If the REFERENCED_BY_RELATION tag is set to YES +-# then for each documented function all documented +-# functions referencing it will be listed. ++# If the REFERENCED_BY_RELATION tag is set to YES then for each documented ++# function all documented functions referencing it will be listed. ++# The default value is: NO. + + REFERENCED_BY_RELATION = NO + +-# If the REFERENCES_RELATION tag is set to YES +-# then for each documented function all documented entities +-# called/used by that function will be listed. ++# If the REFERENCES_RELATION tag is set to YES then for each documented function ++# all documented entities called/used by that function will be listed. ++# The default value is: NO. + + REFERENCES_RELATION = NO + +-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +-# link to the source code. +-# Otherwise they will link to the documentation. ++# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set ++# to YES, then the hyperlinks from functions in REFERENCES_RELATION and ++# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will ++# link to the documentation. ++# The default value is: YES. + + REFERENCES_LINK_SOURCE = YES + +-# If the USE_HTAGS tag is set to YES then the references to source code +-# will point to the HTML generated by the htags(1) tool instead of doxygen +-# built-in source browser. The htags tool is part of GNU's global source +-# tagging system (see http://www.gnu.org/software/global/global.html). You +-# will need version 4.8.6 or higher. ++# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the ++# source code will show a tooltip with additional information such as prototype, ++# brief description and links to the definition and documentation. Since this ++# will make the HTML file larger and loading of large files a bit slower, you ++# can opt to disable this feature. ++# The default value is: YES. ++# This tag requires that the tag SOURCE_BROWSER is set to YES. ++ ++SOURCE_TOOLTIPS = YES ++ ++# If the USE_HTAGS tag is set to YES then the references to source code will ++# point to the HTML generated by the htags(1) tool instead of doxygen built-in ++# source browser. The htags tool is part of GNU's global source tagging system ++# (see http://www.gnu.org/software/global/global.html). You will need version ++# 4.8.6 or higher. ++# ++# To use it do the following: ++# - Install the latest version of global ++# - Enable SOURCE_BROWSER and USE_HTAGS in the config file ++# - Make sure the INPUT points to the root of the source tree ++# - Run doxygen as normal ++# ++# Doxygen will invoke htags (and that will in turn invoke gtags), so these ++# tools must be available from the command line (i.e. in the search path). ++# ++# The result: instead of the source browser generated by doxygen, the links to ++# source code will now point to the output of htags. ++# The default value is: NO. ++# This tag requires that the tag SOURCE_BROWSER is set to YES. + + USE_HTAGS = NO + +-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +-# will generate a verbatim copy of the header file for each class for +-# which an include is specified. Set to NO to disable this. ++# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a ++# verbatim copy of the header file for each class for which an include is ++# specified. Set to NO to disable this. ++# See also: Section \class. ++# The default value is: YES. + + VERBATIM_HEADERS = YES + + #--------------------------------------------------------------------------- +-# configuration options related to the alphabetical class index ++# Configuration options related to the alphabetical class index + #--------------------------------------------------------------------------- + +-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +-# of all compounds will be generated. Enable this if the project +-# contains a lot of classes, structs, unions or interfaces. ++# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all ++# compounds will be generated. Enable this if the project contains a lot of ++# classes, structs, unions or interfaces. ++# The default value is: YES. + + ALPHABETICAL_INDEX = YES + +-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +-# in which this list will be split (can be a number in the range [1..20]) ++# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in ++# which the alphabetical index list will be split. ++# Minimum value: 1, maximum value: 20, default value: 5. ++# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + + COLS_IN_ALPHA_INDEX = 5 + +-# In case all classes in a project start with a common prefix, all +-# classes will be put under the same header in the alphabetical index. +-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +-# should be ignored while generating the index headers. ++# In case all classes in a project start with a common prefix, all classes will ++# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag ++# can be used to specify a prefix (or a list of prefixes) that should be ignored ++# while generating the index headers. ++# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + + IGNORE_PREFIX = + + #--------------------------------------------------------------------------- +-# configuration options related to the HTML output ++# Configuration options related to the HTML output + #--------------------------------------------------------------------------- + +-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +-# generate HTML output. ++# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output ++# The default value is: YES. + + GENERATE_HTML = YES + +-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +-# If a relative path is entered the value of OUTPUT_DIRECTORY will be +-# put in front of it. If left blank `html' will be used as the default path. ++# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a ++# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of ++# it. ++# The default directory is: html. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_OUTPUT = html + +-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +-# doxygen will generate files with .html extension. ++# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each ++# generated HTML page (for example: .htm, .php, .asp). ++# The default value is: .html. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_FILE_EXTENSION = .html + +-# The HTML_HEADER tag can be used to specify a personal HTML header for +-# each generated HTML page. If it is left blank doxygen will generate a +-# standard header. Note that when using a custom header you are responsible +-# for the proper inclusion of any scripts and style sheets that doxygen +-# needs, which is dependent on the configuration options used. +-# It is adviced to generate a default header using "doxygen -w html +-# header.html footer.html stylesheet.css YourConfigFile" and then modify +-# that header. Note that the header is subject to change so you typically +-# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! ++# The HTML_HEADER tag can be used to specify a user-defined HTML header file for ++# each generated HTML page. If the tag is left blank doxygen will generate a ++# standard header. ++# ++# To get valid HTML the header file that includes any scripts and style sheets ++# that doxygen needs, which is dependent on the configuration options used (e.g. ++# the setting GENERATE_TREEVIEW). It is highly recommended to start with a ++# default header using ++# doxygen -w html new_header.html new_footer.html new_stylesheet.css ++# YourConfigFile ++# and then modify the file new_header.html. See also section "Doxygen usage" ++# for information on how to generate the default header that doxygen normally ++# uses. ++# Note: The header is subject to change so you typically have to regenerate the ++# default header when upgrading to a newer version of doxygen. For a description ++# of the possible markers and block names see the documentation. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_HEADER = + +-# The HTML_FOOTER tag can be used to specify a personal HTML footer for +-# each generated HTML page. If it is left blank doxygen will generate a +-# standard footer. ++# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each ++# generated HTML page. If the tag is left blank doxygen will generate a standard ++# footer. See HTML_HEADER for more information on how to generate a default ++# footer and what special commands can be used inside the footer. See also ++# section "Doxygen usage" for information on how to generate the default footer ++# that doxygen normally uses. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_FOOTER = + +-# If the HTML_TIMESTAMP tag is set to YES then the generated HTML documentation will contain the timesstamp. ++# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style ++# sheet that is used by each HTML page. It can be used to fine-tune the look of ++# the HTML output. If left blank doxygen will generate a default style sheet. ++# See also section "Doxygen usage" for information on how to generate the style ++# sheet that doxygen normally uses. ++# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as ++# it is more robust and this tag (HTML_STYLESHEET) will in the future become ++# obsolete. ++# This tag requires that the tag GENERATE_HTML is set to YES. + +-HTML_TIMESTAMP = NO ++HTML_STYLESHEET = + +-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +-# style sheet that is used by each HTML page. It can be used to +-# fine-tune the look of the HTML output. If the tag is left blank doxygen +-# will generate a default style sheet. Note that doxygen will try to copy +-# the style sheet file to the HTML output directory, so don't put your own +-# stylesheet in the HTML output directory as well, or it will be erased! ++# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- ++# defined cascading style sheet that is included after the standard style sheets ++# created by doxygen. Using this option one can overrule certain style aspects. ++# This is preferred over using HTML_STYLESHEET since it does not replace the ++# standard style sheet and is therefor more robust against future updates. ++# Doxygen will copy the style sheet file to the output directory. For an example ++# see the documentation. ++# This tag requires that the tag GENERATE_HTML is set to YES. + +-HTML_STYLESHEET = ++HTML_EXTRA_STYLESHEET = + + # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or + # other source files which should be copied to the HTML output directory. Note + # that these files will be copied to the base HTML output directory. Use the +-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +-# files. In the HTML_STYLESHEET file, use the file name only. Also note that +-# the files will be copied as-is; there are no commands or markers available. ++# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these ++# files. In the HTML_STYLESHEET file, use the file name only. Also note that the ++# files will be copied as-is; there are no commands or markers available. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_EXTRA_FILES = + +-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +-# Doxygen will adjust the colors in the stylesheet and background images +-# according to this color. Hue is specified as an angle on a colorwheel, +-# see http://en.wikipedia.org/wiki/Hue for more information. +-# For instance the value 0 represents red, 60 is yellow, 120 is green, +-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +-# The allowed range is 0 to 359. ++# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen ++# will adjust the colors in the stylesheet and background images according to ++# this color. Hue is specified as an angle on a colorwheel, see ++# http://en.wikipedia.org/wiki/Hue for more information. For instance the value ++# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 ++# purple, and 360 is red again. ++# Minimum value: 0, maximum value: 359, default value: 220. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_COLORSTYLE_HUE = 220 + +-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +-# the colors in the HTML output. For a value of 0 the output will use +-# grayscales only. A value of 255 will produce the most vivid colors. ++# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors ++# in the HTML output. For a value of 0 the output will use grayscales only. A ++# value of 255 will produce the most vivid colors. ++# Minimum value: 0, maximum value: 255, default value: 100. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_COLORSTYLE_SAT = 100 + +-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +-# the luminance component of the colors in the HTML output. Values below +-# 100 gradually make the output lighter, whereas values above 100 make +-# the output darker. The value divided by 100 is the actual gamma applied, +-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +-# and 100 does not change the gamma. ++# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the ++# luminance component of the colors in the HTML output. Values below 100 ++# gradually make the output lighter, whereas values above 100 make the output ++# darker. The value divided by 100 is the actual gamma applied, so 80 represents ++# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not ++# change the gamma. ++# Minimum value: 40, maximum value: 240, default value: 80. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_COLORSTYLE_GAMMA = 80 + + # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +-# page will contain the date and time when the page was generated. Setting +-# this to NO can help when comparing the output of multiple runs. ++# page will contain the date and time when the page was generated. Setting this ++# to NO can help when comparing the output of multiple runs. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_TIMESTAMP = YES + +-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +-# files or namespaces will be aligned in HTML using tables. If set to +-# NO a bullet list will be used. +- +-HTML_ALIGN_MEMBERS = YES +- + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML + # documentation will contain sections that can be hidden and shown after the +-# page has loaded. For this to work a browser that supports +-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). ++# page has loaded. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + HTML_DYNAMIC_SECTIONS = NO + +-# If the GENERATE_DOCSET tag is set to YES, additional index files +-# will be generated that can be used as input for Apple's Xcode 3 +-# integrated development environment, introduced with OSX 10.5 (Leopard). +-# To create a documentation set, doxygen will generate a Makefile in the +-# HTML output directory. Running make will produce the docset in that +-# directory and running "make install" will install the docset in +-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +-# it at startup. +-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html ++# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries ++# shown in the various tree structured indices initially; the user can expand ++# and collapse entries dynamically later on. Doxygen will expand the tree to ++# such a level that at most the specified number of entries are visible (unless ++# a fully collapsed tree already exceeds this amount). So setting the number of ++# entries 1 will produce a full collapsed tree by default. 0 is a special value ++# representing an infinite number of entries and will result in a full expanded ++# tree by default. ++# Minimum value: 0, maximum value: 9999, default value: 100. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_INDEX_NUM_ENTRIES = 100 ++ ++# If the GENERATE_DOCSET tag is set to YES, additional index files will be ++# generated that can be used as input for Apple's Xcode 3 integrated development ++# environment (see: http://developer.apple.com/tools/xcode/), introduced with ++# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a ++# Makefile in the HTML output directory. Running make will produce the docset in ++# that directory and running make install will install the docset in ++# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at ++# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html + # for more information. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + GENERATE_DOCSET = NO + +-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +-# feed. A documentation feed provides an umbrella under which multiple +-# documentation sets from a single provider (such as a company or product suite) +-# can be grouped. ++# This tag determines the name of the docset feed. A documentation feed provides ++# an umbrella under which multiple documentation sets from a single provider ++# (such as a company or product suite) can be grouped. ++# The default value is: Doxygen generated docs. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. + + DOCSET_FEEDNAME = "Doxygen generated docs" + +-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +-# should uniquely identify the documentation set bundle. This should be a +-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +-# will append .docset to the name. ++# This tag specifies a string that should uniquely identify the documentation ++# set bundle. This should be a reverse domain-name style string, e.g. ++# com.mycompany.MyDocSet. Doxygen will append .docset to the name. ++# The default value is: org.doxygen.Project. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. + + DOCSET_BUNDLE_ID = org.doxygen.Pacemaker + +-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify ++# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify + # the documentation publisher. This should be a reverse domain-name style + # string, e.g. com.mycompany.MyDocSet.documentation. ++# The default value is: org.doxygen.Publisher. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. + + DOCSET_PUBLISHER_ID = org.doxygen.ClusterLabs + +-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. ++# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. ++# The default value is: Publisher. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. + + DOCSET_PUBLISHER_NAME = ClusterLabs + +-# If the GENERATE_HTMLHELP tag is set to YES, additional index files +-# will be generated that can be used as input for tools like the +-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +-# of the generated HTML documentation. ++# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three ++# additional HTML index files: index.hhp, index.hhc, and index.hhk. The ++# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop ++# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on ++# Windows. ++# ++# The HTML Help Workshop contains a compiler that can convert all HTML output ++# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML ++# files are now used as the Windows 98 help format, and will replace the old ++# Windows help format (.hlp) on all Windows platforms in the future. Compressed ++# HTML files also contain an index, a table of contents, and you can search for ++# words in the documentation. The HTML workshop also contains a viewer for ++# compressed HTML files. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + GENERATE_HTMLHELP = NO + +-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +-# be used to specify the file name of the resulting .chm file. You +-# can add a path in front of the file if the result should not be ++# The CHM_FILE tag can be used to specify the file name of the resulting .chm ++# file. You can add a path in front of the file if the result should not be + # written to the html output directory. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + + CHM_FILE = + +-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +-# be used to specify the location (absolute path including file name) of +-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +-# the HTML help compiler on the generated index.hhp. ++# The HHC_LOCATION tag can be used to specify the location (absolute path ++# including file name) of the HTML help compiler ( hhc.exe). If non-empty ++# doxygen will try to run the HTML help compiler on the generated index.hhp. ++# The file has to be specified with full path. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + + HHC_LOCATION = + +-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +-# controls if a separate .chi index file is generated (YES) or that +-# it should be included in the master .chm file (NO). ++# The GENERATE_CHI flag controls if a separate .chi index file is generated ( ++# YES) or that it should be included in the master .chm file ( NO). ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + + GENERATE_CHI = NO + +-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +-# is used to encode HtmlHelp index (hhk), content (hhc) and project file +-# content. ++# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) ++# and project file content. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + + CHM_INDEX_ENCODING = + +-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +-# controls whether a binary table of contents is generated (YES) or a +-# normal table of contents (NO) in the .chm file. ++# The BINARY_TOC flag controls whether a binary table of contents is generated ( ++# YES) or a normal table of contents ( NO) in the .chm file. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + + BINARY_TOC = NO + +-# The TOC_EXPAND flag can be set to YES to add extra items for group members +-# to the contents of the HTML help documentation and to the tree view. ++# The TOC_EXPAND flag can be set to YES to add extra items for group members to ++# the table of contents of the HTML help documentation and to the tree view. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + + TOC_EXPAND = NO + + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +-# that can be used as input for Qt's qhelpgenerator to generate a +-# Qt Compressed Help (.qch) of the generated HTML documentation. ++# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that ++# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help ++# (.qch) of the generated HTML documentation. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + GENERATE_QHP = NO + +-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +-# be used to specify the file name of the resulting .qch file. +-# The path specified is relative to the HTML output folder. ++# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify ++# the file name of the resulting .qch file. The path specified is relative to ++# the HTML output folder. ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QCH_FILE = + +-# The QHP_NAMESPACE tag specifies the namespace to use when generating +-# Qt Help Project output. For more information please see +-# http://doc.trolltech.com/qthelpproject.html#namespace ++# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help ++# Project output. For more information please see Qt Help Project / Namespace ++# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). ++# The default value is: org.doxygen.Project. ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QHP_NAMESPACE = org.doxygen.Project + +-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +-# Qt Help Project output. For more information please see +-# http://doc.trolltech.com/qthelpproject.html#virtual-folders ++# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt ++# Help Project output. For more information please see Qt Help Project / Virtual ++# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- ++# folders). ++# The default value is: doc. ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QHP_VIRTUAL_FOLDER = doc + +-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +-# add. For more information please see +-# http://doc.trolltech.com/qthelpproject.html#custom-filters ++# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom ++# filter to add. For more information please see Qt Help Project / Custom ++# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- ++# filters). ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QHP_CUST_FILTER_NAME = + +-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +-# custom filter to add. For more information please see +-# +-# Qt Help Project / Custom Filters. ++# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the ++# custom filter to add. For more information please see Qt Help Project / Custom ++# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- ++# filters). ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QHP_CUST_FILTER_ATTRS = + + # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +-# project's +-# filter section matches. +-# +-# Qt Help Project / Filter Attributes. ++# project's filter section matches. Qt Help Project / Filter Attributes (see: ++# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QHP_SECT_FILTER_ATTRS = + +-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +-# be used to specify the location of Qt's qhelpgenerator. +-# If non-empty doxygen will try to run qhelpgenerator on the generated +-# .qhp file. ++# The QHG_LOCATION tag can be used to specify the location of Qt's ++# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the ++# generated .qhp file. ++# This tag requires that the tag GENERATE_QHP is set to YES. + + QHG_LOCATION = + +-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +-# will be generated, which together with the HTML files, form an Eclipse help +-# plugin. To install this plugin and make it available under the help contents +-# menu in Eclipse, the contents of the directory containing the HTML and XML +-# files needs to be copied into the plugins directory of eclipse. The name of +-# the directory within the plugins directory should be the same as +-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +-# the help appears. ++# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be ++# generated, together with the HTML files, they form an Eclipse help plugin. To ++# install this plugin and make it available under the help contents menu in ++# Eclipse, the contents of the directory containing the HTML and XML files needs ++# to be copied into the plugins directory of eclipse. The name of the directory ++# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. ++# After copying Eclipse needs to be restarted before the help appears. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + GENERATE_ECLIPSEHELP = NO + +-# A unique identifier for the eclipse help plugin. When installing the plugin +-# the directory name containing the HTML and XML files should also have +-# this name. ++# A unique identifier for the Eclipse help plugin. When installing the plugin ++# the directory name containing the HTML and XML files should also have this ++# name. Each documentation set should have its own identifier. ++# The default value is: org.doxygen.Project. ++# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + + ECLIPSE_DOC_ID = org.doxygen.Project + +-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +-# top of each HTML page. The value NO (the default) enables the index and +-# the value YES disables it. ++# If you want full control over the layout of the generated HTML pages it might ++# be necessary to disable the index and replace it with your own. The ++# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top ++# of each HTML page. A value of NO enables the index and the value YES disables ++# it. Since the tabs in the index contain the same information as the navigation ++# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + DISABLE_INDEX = NO + +-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +-# (range [0,1..20]) that doxygen will group on one line in the generated HTML +-# documentation. Note that a value of 0 will completely suppress the enum +-# values from appearing in the overview section. +- +-ENUM_VALUES_PER_LINE = 4 +- + # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +-# structure should be generated to display hierarchical information. +-# If the tag value is set to YES, a side panel will be generated +-# containing a tree-like index structure (just like the one that +-# is generated for HTML Help). For this to work a browser that supports +-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +-# Windows users are probably better off using the HTML help feature. ++# structure should be generated to display hierarchical information. If the tag ++# value is set to YES, a side panel will be generated containing a tree-like ++# index structure (just like the one that is generated for HTML Help). For this ++# to work a browser that supports JavaScript, DHTML, CSS and frames is required ++# (i.e. any modern browser). Windows users are probably better off using the ++# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can ++# further fine-tune the look of the index. As an example, the default style ++# sheet generated by doxygen has an example that shows how to put an image at ++# the root of the tree instead of the PROJECT_NAME. Since the tree basically has ++# the same information as the tab index, you could consider setting ++# DISABLE_INDEX to YES when enabling this option. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + GENERATE_TREEVIEW = NO + +-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +-# and Class Hierarchy pages using a tree view instead of an ordered list. ++# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that ++# doxygen will group on one line in the generated HTML documentation. ++# ++# Note that a value of 0 will completely suppress the enum values from appearing ++# in the overview section. ++# Minimum value: 0, maximum value: 20, default value: 4. ++# This tag requires that the tag GENERATE_HTML is set to YES. + +-USE_INLINE_TREES = NO ++ENUM_VALUES_PER_LINE = 4 + +-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +-# used to set the initial width (in pixels) of the frame in which the tree +-# is shown. ++# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used ++# to set the initial width (in pixels) of the frame in which the tree is shown. ++# Minimum value: 0, maximum value: 1500, default value: 250. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + TREEVIEW_WIDTH = 250 + +-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +-# links to external symbols imported via tag files in a separate window. ++# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to ++# external symbols imported via tag files in a separate window. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + EXT_LINKS_IN_WINDOW = NO + +-# Use this tag to change the font size of Latex formulas included +-# as images in the HTML documentation. The default is 10. Note that +-# when you change the font size after a successful doxygen run you need +-# to manually remove any form_*.png images from the HTML output directory +-# to force them to be regenerated. ++# Use this tag to change the font size of LaTeX formulas included as images in ++# the HTML documentation. When you change the font size after a successful ++# doxygen run you need to manually remove any form_*.png images from the HTML ++# output directory to force them to be regenerated. ++# Minimum value: 8, maximum value: 50, default value: 10. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + FORMULA_FONTSIZE = 10 + + # Use the FORMULA_TRANPARENT tag to determine whether or not the images +-# generated for formulas are transparent PNGs. Transparent PNGs are +-# not supported properly for IE 6.0, but are supported on all modern browsers. +-# Note that when changing this option you need to delete any form_*.png files +-# in the HTML output before the changes have effect. ++# generated for formulas are transparent PNGs. Transparent PNGs are not ++# supported properly for IE 6.0, but are supported on all modern browsers. ++# ++# Note that when changing this option you need to delete any form_*.png files in ++# the HTML output directory before the changes have effect. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + FORMULA_TRANSPARENT = YES + +-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +-# (see http://www.mathjax.org) which uses client side Javascript for the +-# rendering instead of using prerendered bitmaps. Use this if you do not +-# have LaTeX installed or if you want to formulas look prettier in the HTML +-# output. When enabled you also need to install MathJax separately and +-# configure the path to it using the MATHJAX_RELPATH option. ++# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see ++# http://www.mathjax.org) which uses client side Javascript for the rendering ++# instead of using prerendered bitmaps. Use this if you do not have LaTeX ++# installed or if you want to formulas look prettier in the HTML output. When ++# enabled you may also need to install MathJax separately and configure the path ++# to it using the MATHJAX_RELPATH option. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. + + USE_MATHJAX = NO + +-# When MathJax is enabled you need to specify the location relative to the +-# HTML output directory using the MATHJAX_RELPATH option. The destination +-# directory should contain the MathJax.js script. For instance, if the mathjax +-# directory is located at the same level as the HTML output directory, then +-# MATHJAX_RELPATH should be ../mathjax. The default value points to the +-# mathjax.org site, so you can quickly see the result without installing +-# MathJax, but it is strongly recommended to install a local copy of MathJax +-# before deployment. ++# When MathJax is enabled you can set the default output format to be used for ++# the MathJax output. See the MathJax site (see: ++# http://docs.mathjax.org/en/latest/output.html) for more details. ++# Possible values are: HTML-CSS (which is slower, but has the best ++# compatibility), NativeMML (i.e. MathML) and SVG. ++# The default value is: HTML-CSS. ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_FORMAT = HTML-CSS ++ ++# When MathJax is enabled you need to specify the location relative to the HTML ++# output directory using the MATHJAX_RELPATH option. The destination directory ++# should contain the MathJax.js script. For instance, if the mathjax directory ++# is located at the same level as the HTML output directory, then ++# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax ++# Content Delivery Network so you can quickly see the result without installing ++# MathJax. However, it is strongly recommended to install a local copy of ++# MathJax from http://www.mathjax.org before deployment. ++# The default value is: http://cdn.mathjax.org/mathjax/latest. ++# This tag requires that the tag USE_MATHJAX is set to YES. + + MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +-# When the SEARCHENGINE tag is enabled doxygen will generate a search box +-# for the HTML output. The underlying search engine uses javascript +-# and DHTML and should work on any modern browser. Note that when using +-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +-# (GENERATE_DOCSET) there is already a search function so this one should +-# typically be disabled. For large projects the javascript based search engine +-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. ++# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax ++# extension names that should be enabled during MathJax rendering. For example ++# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_EXTENSIONS = ++ ++# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces ++# of code that will be used on startup of the MathJax code. See the MathJax site ++# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an ++# example see the documentation. ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_CODEFILE = ++ ++# When the SEARCHENGINE tag is enabled doxygen will generate a search box for ++# the HTML output. The underlying search engine uses javascript and DHTML and ++# should work on any modern browser. Note that when using HTML help ++# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) ++# there is already a search function so this one should typically be disabled. ++# For large projects the javascript based search engine can be slow, then ++# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to ++# search using the keyboard; to jump to the search box use + S ++# (what the is depends on the OS and browser, but it is typically ++# , / ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/doc/Pacemaker_Explained/en-US/Ap-Upgrade-Config.txt b/doc/Pacemaker_Explained/en-US/Ap-Upgrade-Config.txt +index db51b25..7f1eb06 100644 +--- a/doc/Pacemaker_Explained/en-US/Ap-Upgrade-Config.txt ++++ b/doc/Pacemaker_Explained/en-US/Ap-Upgrade-Config.txt +@@ -1,18 +1,14 @@ + [appendix] + +-== Upgrading the Configuration from 0.6 == ++== Upgrading the Configuration == ++ ++This process was originally written for the upgrade from 0.6.'x' to 1.'y', ++but the concepts should apply for any upgrade involving a change in ++the XML schema version. + +-=== Preparation === + indexterm:[Upgrading the Configuration] + indexterm:[Configuration,Upgrading] + +-indexterm:[Download,DTD] +-indexterm:[DTD,Download] +- +-Download the latest +-http://hg.clusterlabs.org/pacemaker/stable-1.0/file-raw/tip/xml/crm.dtd[DTD] +-and ensure your configuration validates. +- + === Perform the upgrade === + + ==== Upgrade the software ==== +@@ -23,11 +19,11 @@ Refer to the appendix: <> + + As XML is not the friendliest of languages, it is common for cluster + administrators to have scripted some of their activities. In such +-cases, it is likely that those scripts will not work with the new 1.0 ++cases, it is likely that those scripts will not work with the new XML + syntax. + + In order to support such environments, it is actually possible to +-continue using the old 0.6 syntax. ++continue using the old XML syntax. + + The downside is, however, that not all the new features will be + available and there is a performance impact since the cluster must do +@@ -36,26 +32,23 @@ while using the old syntax is possible, it is not advisable to + continue using it indefinitely. + + Even if you wish to continue using the old syntax, it is advisable to +-follow the upgrade procedure to ensure that the cluster is able to use +-your existing configuration (since it will perform much the same task +-internally). ++follow the upgrade procedure (except for the last step) to ensure that the ++cluster is able to use your existing configuration (since it will perform much ++the same task internally). + + . Create a shadow copy to work with + + +-[source,C] + ----- + # crm_shadow --create upgrade06 + ----- + . Verify the configuration is valid indexterm:[Configuration,Verify]indexterm:[Verify,Configuration] + + +-[source,C] + ----- + # crm_verify --live-check + ----- + . Fix any errors or warnings + . Perform the upgrade: + + +-[source,C] + ----- + # cibadmin --upgrade + ----- +@@ -66,29 +59,28 @@ internally). + The most common reason is ID values being repeated or invalid. Pacemaker 1.0 is much stricter regarding this type of validation. + ] + + +-If the result of the transformation is invalid, you may see a number of errors from the validation library. If these are not helpful, visit http://clusterlabs.org/wiki/Validation_FAQ and/or try the procedure described below under <> ++If the result of the transformation is invalid, you may see a number of errors ++from the validation library. If these are not helpful, visit the ++http://clusterlabs.org/wiki/Validation_FAQ[Validation FAQ wiki page] and/or try ++the procedure described below under <> + + + . Check the changes + + +-[source,C] + ----- + # crm_shadow --diff + ----- + + + If at this point there is anything about the upgrade that you wish to fine-tune (for example, to change some of the automatic IDs) now is the time to do so. Since the shadow configuration is not in use by the cluster, it is safe to edit the file manually: + + +-[source,C] + ----- + # crm_shadow --edit + ----- + + +-This will open the configuration in your favorite editor (whichever is specified by the standard +$EDITOR+ environment variable) ++This will open the configuration in your favorite editor (whichever is ++specified by the standard *$EDITOR* environment variable) + + +-. Preview how the cluster will react ++. Preview how the cluster will react: + + +-Test what the cluster will do when you upload the new configuration +-+ +-[source,C] + ------ + # crm_simulate --live-check --save-dotfile upgrade06.dot -S + # graphviz upgrade06.dot +@@ -99,38 +91,38 @@ happy with any that are scheduled. If the output contains actions you + do not expect (possibly due to changes to the score calculations), you + may need to make further manual changes. See + <> for further details on how to interpret +-the output of `crm_simulate` ++the output of `crm_simulate` and `graphviz`. + + + . Upload the changes + + +-[source,C] + ----- + # crm_shadow --commit upgrade06 --force + ----- +-If this step fails, something really strange has occurred. You should report a bug. +++ ++In the unlikely event this step fails, please report a bug. + + [[s-upgrade-config-manual]] + ==== Manually Upgrading the Configuration ==== + + indexterm:[Configuration,Upgrade manually] +-It is also possible to perform the configuration upgrade steps manually. To do this ++It is also possible to perform the configuration upgrade steps manually: + +-Locate the 'upgrade06.xsl' conversion script or download the latest +-version from +-https://github.com/ClusterLabs/pacemaker/tree/master/xml/upgrade06.xsl[Git] ++. Locate the +upgrade06.xsl+ conversion script provided with the source code ++ (the https://github.com/ClusterLabs/pacemaker/tree/master/xml/upgrade06.xsl[latest version] is available via ++ git). + + . Convert the XML blob: indexterm:[XML,Convert] + + +-[source,C] + ----- + # xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml + ----- + + +-. Locate the 'pacemaker.rng' script. ++. Locate the +pacemaker.rng+ script. + . Check the XML validity: indexterm:[Validate Configuration]indexterm:[Configuration,Validate XML] + + +-[source,C] ++---- + # xmllint --relaxng /path/to/pacemaker.rng config10.xml ++---- + + The advantage of this method is that it can be performed without the + cluster running and any validation errors should be more informative +diff --git a/doc/Pacemaker_Explained/en-US/Ap-Upgrade.txt b/doc/Pacemaker_Explained/en-US/Ap-Upgrade.txt +index dc14d71..66f5cc5 100644 +--- a/doc/Pacemaker_Explained/en-US/Ap-Upgrade.txt ++++ b/doc/Pacemaker_Explained/en-US/Ap-Upgrade.txt +@@ -1,18 +1,14 @@ + [appendix] + + [[ap-upgrade]] +-== Upgrading Cluster Software ++== Upgrading Cluster Software == + +-=== Version Compatibility === ++There will always be an upgrade path from any pacemaker 1._x_ ++release to any other 1._y_ release. + +-When releasing newer versions we take care to make sure we are +-backwards compatible with older versions. While you will always be +-able to upgrade from version x to x+1, in order to continue to produce +-high quality software it may occasionally be necessary to drop +-compatibility with older versions. +- +-There will always be an upgrade path from any series-2 release to any +-other series-2 release. ++Consult the documentation for your messaging layer ++(Heartbeat or Corosync) to see whether upgrading them to a ++newer version is also supported. + + There are three approaches to upgrading your cluster software: + +@@ -21,10 +17,10 @@ There are three approaches to upgrading your cluster software: + * Disconnect and Reattach + + Each method has advantages and disadvantages, some of which are listed +-in the table below, and you should chose the one most appropriate to ++in the table below, and you should choose the one most appropriate to + your needs. + +-.Summary of Upgrade Methodologies ++.Upgrade Methods + [width="95%",cols="6*",options="header",align="center"] + |========================================================= + +@@ -36,11 +32,7 @@ your needs. + |Allows change of cluster stack type + indexterm:[Cluster,Switching between Stacks] + indexterm:[Changing Cluster Stack] +-footnote:[ +-For example, switching from Heartbeat to Corosync. Consult the +-Heartbeat or Corosync documentation to see if upgrading them to a +-newer version is also supported. +-] ++footnote:[For example, switching from Heartbeat to Corosync.] + + |Shutdown + indexterm:[Upgrade,Shutdown] +@@ -73,53 +65,51 @@ indexterm:[Reattach Upgrade] + + === Complete Cluster Shutdown === + +-In this scenario one shuts down all cluster nodes and resources and +-upgrades all the nodes before restarting the cluster. ++In this scenario, one shuts down all cluster nodes and resources, ++then upgrades all the nodes before restarting the cluster. + +-==== Procedure ==== + . On each node: +-.. Shutdown the cluster stack (Heartbeat or Corosync) +-.. Upgrade the Pacemaker software. +- This may also include upgrading the cluster stack and/or the +- underlying operating system. ++.. Shutdown the cluster software (pacemaker and the messaging layer). ++.. Upgrade the Pacemaker software. This may also include upgrading the ++ messaging layer and/or the underlying operating system. + .. Check the configuration manually or with the `crm_verify` tool if available. + . On each node: +-.. Start the cluster stack. +- This can be either Corosync or Heartbeat and does not need to be +- the same as the previous cluster stack. ++.. Start the cluster software. ++ The messaging layer can be either Corosync or Heartbeat and does not need to ++ be the same one before the upgrade. + + === Rolling (node by node) === + +-In this scenario each node is removed from the cluster, upgraded and then brought back online until all nodes are running the newest version. +- +-[IMPORTANT] +-=========== +-This method is currently broken between Pacemaker 0.6.x and 1.0.x. ++In this scenario, each node is removed from the cluster, upgraded and then ++brought back online until all nodes are running the newest version. + +-Measures have been put into place to ensure rolling upgrades always +-work for versions after 1.0.0. Please try one of the other upgrade +-strategies. Detach/Reattach is a particularly good option for most +-people. +-=========== +- +-==== Procedure ==== ++Rolling upgrades should always be possible for pacemaker versions ++1.0.0 and later. + + On each node: +-. Shutdown the cluster stack (Heartbeat or Corosync) ++ ++. Put the node into standby mode, and wait for any active resources ++ to be moved cleanly to another node. ++. Shutdown the cluster software (pacemaker and the messaging layer) on the node. + . Upgrade the Pacemaker software. This may also include upgrading the +- cluster stack and/or the underlying operating system. +-.. On the first node, check the configuration manually or with the +- `crm_verify` tool if available. +-.. Start the cluster stack. +-+ +-This must be the same type of cluster stack (Corosync or Heartbeat) +-that the rest of the cluster is using. Upgrading Corosync/Heartbeat +-may also be possible, please consult the documentation for those +-projects to see if the two versions will be compatible. +-+ +-.. Repeat for each node in the cluster. ++ messaging layer and/or the underlying operating system. ++. If this is the first node to be upgraded, check the configuration manually ++ or with the `crm_verify` tool if available. ++. Start the messaging layer. ++ This must be the same messaging layer (Corosync or Heartbeat) ++ that the rest of the cluster is using. Upgrading the messaging layer ++ may also be possible; consult the documentation for those ++ projects to see whether the two versions will be compatible. + +-==== Version Compatibility ==== ++[NOTE] ++==== ++Rolling upgrades were not always possible with older heartbeat and ++pacemaker versions. The table below shows which versions were ++compatible during rolling upgrades. Rolling upgrades that cross compatibility ++boundaries must be performed in multiple steps (for example, ++upgrading heartbeat 2.0.6 to heartbeat 2.1.3, and then upgrading again ++to pacemaker 0.6.6). Rolling upgrades from pacemaker 0._x_ to 1._y_ are not ++possible. + + .Version Compatibility Table + [width="95%",cols="2*",options="header",align="center"] +@@ -147,70 +137,57 @@ projects to see if the two versions will be compatible. + |None. Use an alternate upgrade strategy. + + |========================================================= +- +-==== Crossing Compatibility Boundaries ==== +- +-Rolling upgrades that cross compatibility boundaries must be preformed +-in multiple steps. For example, to perform a rolling update from +-Heartbeat 2.0.1 to Pacemaker 0.6.6 one must: +- +-. Perform a rolling upgrade from Heartbeat 2.0.1 to Heartbeat 2.0.4 +-. Perform a rolling upgrade from Heartbeat 2.0.4 to Heartbeat 2.1.3 +-. Perform a rolling upgrade from Heartbeat 2.1.3 to Pacemaker 0.6.6 ++==== + + === Disconnect and Reattach === + +-A variant of a complete cluster shutdown, but the resources are left +-active and get re-detected when the cluster is restarted. +- +-==== Procedure ==== ++The reattach method is a variant of a complete cluster shutdown, where the ++resources are left active and get re-detected when the cluster is restarted. + +-. Tell the cluster to stop managing services. ++. Tell the cluster to stop managing services. This is required to allow the ++ services to remain active after the cluster shuts down. + + +-This is required to allow the services to remain active after the +-cluster shuts down. +-+ +-[source,C] ++---- + # crm_attribute -t crm_config -n is-managed-default -v false +-+ ++---- ++ + . For any resource that has a value for +is-managed+, make sure it is +-set to +false+ (so that the cluster will not stop it) ++set to +false+ so that the cluster will not stop it (replacing $rsc_id ++appropriately): + + +-[source,C] ++---- + # crm_resource -t primitive -r $rsc_id -p is-managed -v false +-+ ++---- ++ + . On each node: +-.. Shutdown the cluster stack (Heartbeat or Corosync) +-.. Upgrade the cluster stack program - This may also include upgrading +-the underlying operating system. ++.. Shutdown the cluster software (pacemaker and the messaging layer). ++.. Upgrade the Pacemaker software. This may also include upgrading the ++ messaging layer and/or the underlying operating system. + . Check the configuration manually or with the `crm_verify` tool if available. + . On each node: +-.. Start the cluster stack. +-+ +-This can be either Corosync or Heartbeat and does not need to be the +-same as the previous cluster stack. +-+ ++.. Start the cluster software. The messaging layer can be either Corosync or ++ Heartbeat and does not need to be the same one as before the upgrade. ++ + . Verify that the cluster re-detected all resources correctly. + . Allow the cluster to resume managing resources again: + + +-[source,C] ++---- + # crm_attribute -t crm_config -n is-managed-default -v true +-+ +-. For any resource that has a value for +is-managed+ reset it to ++---- ++ ++. For any resource that has a value for +is-managed+, reset it to + +true+ (so the cluster can recover the service if it fails) if + desired: + + +-[source,C] ++---- + # crm_resource -t primitive -r $rsc_id -p is-managed -v true ++---- + +- +-==== Notes ==== ++[NOTE] ++The oldest version of the CRM to support this upgrade type was in Heartbeat 2.0.4. + + [IMPORTANT] + =========== + Always check your existing configuration is still compatible with the + version you are installing before starting the cluster. + =========== +- +-[NOTE] +-The oldest version of the CRM to support this upgrade type was in Heartbeat 2.0.4 +diff --git a/doc/Pacemaker_Explained/en-US/Book_Info.xml b/doc/Pacemaker_Explained/en-US/Book_Info.xml +index 93f1783..56b9d9b 100644 +--- a/doc/Pacemaker_Explained/en-US/Book_Info.xml ++++ b/doc/Pacemaker_Explained/en-US/Book_Info.xml +@@ -6,24 +6,19 @@ + An A-Z guide to Pacemaker's Configuration Options + Pacemaker + 1.1 +- 1 ++ ++ 5 + 0 + + + The purpose of this document is to definitively explain the concepts used to configure Pacemaker. +- To achieve this, it will focus exclusively on the XML syntax used to configure the CIB. +- +- +- For those that are allergic to XML, there exist several unified shells +- and GUIs for Pacemaker. However these tools will not be covered at all +- in this document +- I hope, however, that the concepts explained here make the functionality of these tools more easily understood. +- , precisely because they hide the XML. +- +- +- Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. +- Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster. +- Try the Clusters from Scratch document instead. ++ To achieve this, it will focus exclusively on the XML syntax used to configure Pacemaker's ++ Cluster Information Base (CIB). + + + +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Advanced-Options.txt b/doc/Pacemaker_Explained/en-US/Ch-Advanced-Options.txt +index ab9a089..d1cf176 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Advanced-Options.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Advanced-Options.txt +@@ -12,64 +12,74 @@ variables and runs the same commands as when working on a cluster + node. + + .Environment Variables Used to Connect to Remote Instances of the CIB +-[width="95%",cols="1m,2<",options="header",align="center"] ++[width="95%",cols="1m,1,3<",options="header",align="center"] + |========================================================= + + |Environment Variable ++|Default + |Description + + |CIB_user ++|$USER + |The user to connect as. Needs to be part of the +hacluster+ group on +- the target host. Defaults to _$USER_. ++ the target host. + indexterm:[Environment Variable,CIB_user] + + |CIB_passwd ++| + |The user's password. Read from the command line if unset. + indexterm:[Environment Variable,CIB_passwd] + + |CIB_server +-|The host to contact. Defaults to _localhost_. ++|localhost ++|The host to contact + indexterm:[Environment Variable,CIB_server] + + |CIB_port ++| + |The port on which to contact the server; required. + indexterm:[Environment Variable,CIB_port] + + |CIB_encrypted +-|Encrypt network traffic; defaults to _true_. ++|TRUE ++|Whether to encrypt network traffic + indexterm:[Environment Variable,CIB_encrypted] + + |========================================================= + +-So, if +c001n01+ is an active cluster node and is listening on +1234+ +-for connections, and +someguy+ is a member of the +hacluster+ group, +-then the following would prompt for +someguy+'s password and return ++So, if *c001n01* is an active cluster node and is listening on port 1234 ++for connections, and *someuser* is a member of the *hacluster* group, ++then the following would prompt for *someuser*'s password and return + the cluster's current configuration: + +-[source,C] +-# export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy; ++---- ++# export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someuser; + # cibadmin -Q ++---- + + For security reasons, the cluster does not listen for remote + connections by default. If you wish to allow remote access, you need + to set the +remote-tls-port+ (encrypted) or +remote-clear-port+ +-(unencrypted) top-level options (ie., those kept in the cib tag, like ++(unencrypted) CIB properties (i.e., those kept in the +cib+ tag, like + +num_updates+ and +epoch+). + +-.Extra top-level CIB options for remote access +-[width="95%",cols="1m,2<",options="header",align="center"] ++.Extra top-level CIB properties for remote access ++[width="95%",cols="1m,1,3<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |remote-tls-port +-|Listen for encrypted remote connections on this port. Default: _none_ ++|_none_ ++|Listen for encrypted remote connections on this port. + indexterm:[remote-tls-port,Remote Connection Option] + indexterm:[Remote Connection,Option,remote-tls-port] + + |remote-clear-port +-|Listen for plaintext remote connections on this port. Default: _none_ ++|_none_ ++|Listen for plaintext remote connections on this port. + indexterm:[remote-clear-port,Remote Connection Option] + indexterm:[Remote Connection,Option,remote-clear-port] + +@@ -82,25 +92,25 @@ to set the +remote-tls-port+ (encrypted) or +remote-clear-port+ + By default, recurring actions are scheduled relative to when the + resource started. So if your resource was last started at 14:32 and + you have a backup set to be performed every 24 hours, then the backup +-will always run at in the middle of the business day - hardly ++will always run at in the middle of the business day -- hardly + desirable. + +-To specify a date/time that the operation should be relative to, set ++To specify a date and time that the operation should be relative to, set + the operation's +interval-origin+. The cluster uses this point to + calculate the correct +start-delay+ such that the operation will occur + at _origin + (interval * N)_. + +-So, if the operation's interval is 24h, it's interval-origin is set to +-+02:00+ and it is currently +14:32+, then the cluster would initiate ++So, if the operation's interval is 24h, its interval-origin is set to ++02:00 and it is currently 14:32, then the cluster would initiate + the operation with a start delay of 11 hours and 28 minutes. If the +-resource is moved to another node before 2am, then the operation is of +-course cancelled. ++resource is moved to another node before 2am, then the operation is ++cancelled. + +-The value specified for interval and +interval-origin+ can be any ++The value specified for +interval+ and +interval-origin+ can be any + date/time conforming to the + http://en.wikipedia.org/wiki/ISO_8601[ISO8601 standard]. By way of + example, to specify an operation that would run on the first Monday of +-2009 and every Monday after that you would add: ++2009 and every Monday after that, you would add: + + .Specifying a Base for Recurring Action Intervals + ===== +@@ -112,51 +122,58 @@ example, to specify an operation that would run on the first Monday of + indexterm:[Moving,Resources] + indexterm:[Resource,Moving] + +-=== Manual Intervention === ++=== Moving Resources Manually === + + There are primarily two occasions when you would want to move a +-resource from it's current location: when the whole node is under ++resource from its current location: when the whole node is under + maintenance, and when a single resource needs to be moved. + ++==== Standby Mode ==== ++ + Since everything eventually comes down to a score, you could create + constraints for every resource to prevent them from running on one +-node. While the configuration can seem convoluted at times, not even ++node. While pacemaker configuration can seem convoluted at times, not even + we would require this of administrators. + +-Instead one can set a special node attribute which tells the cluster ++Instead, one can set a special node attribute which tells the cluster + "don't let anything run here". There is even a helpful tool to help + query and set it, called `crm_standby`. To check the standby status +-of the current machine, simply run: ++of the current machine, run: + +-[source,C] +-# crm_standby --get-value ++---- ++# crm_standby -G ++---- + +-A value of +true+ indicates that the node is _NOT_ able to host any +-resources, while a value of +false+ says that it _CAN_. ++A value of +on+ indicates that the node is _not_ able to host any ++resources, while a value of +off+ says that it _can_. + + You can also check the status of other nodes in the cluster by +-specifying the `--node-uname` option: ++specifying the `--node` option: ++ ++---- ++# crm_standby -G --node sles-2 ++---- + +-[source,C] +-# crm_standby --get-value --node-uname sles-2 ++To change the current node's standby status, use `-v` instead of `-G`: + +-To change the current node's standby status, use `--attr-value` +-instead of `--get-value`. ++---- ++# crm_standby -v on ++---- + +-[source,C] +-# crm_standby --attr-value ++Again, you can change another host's value by supplying a hostname with `--node`. + +-Again, you can change another host's value by supplying a host name with `--node-uname`. ++==== Moving One Resource ==== + +-When only one resource is required to move, we do this by creating +-location constraints. However, once again we provide a user friendly ++When only one resource is required to move, we could do this by creating ++location constraints. However, once again we provide a user-friendly + shortcut as part of the `crm_resource` command, which creates and +-modifies the extra constraints for you. If +Email+ was running on ++modifies the extra constraints for you. If +Email+ were running on + +sles-1+ and you wanted it moved to a specific location, the command + would look something like: + +-[source,C] ++---- + # crm_resource -M -r Email -H sles-2 ++---- + + Behind the scenes, the tool will create the following location constraint: + +@@ -166,31 +183,35 @@ Behind the scenes, the tool will create the following location constraint: + It is important to note that subsequent invocations of `crm_resource + -M` are not cumulative. So, if you ran these commands + +-[source,C] ++---- + # crm_resource -M -r Email -H sles-2 + # crm_resource -M -r Email -H sles-3 ++---- + + then it is as if you had never performed the first command. + + To allow the resource to move back again, use: + +-[source,C] ++---- + # crm_resource -U -r Email ++---- + + Note the use of the word _allow_. The resource can move back to its + original location but, depending on +resource-stickiness+, it might + stay where it is. To be absolutely certain that it moves back to + +sles-1+, move it there before issuing the call to `crm_resource -U`: + +-[source,C] ++---- + # crm_resource -M -r Email -H sles-1 + # crm_resource -U -r Email ++---- + + Alternatively, if you only care that the resource should be moved from +-its current location, try ++its current location, try: + +-[source,C] +-# crm_resource -M -r Email` ++---- ++# crm_resource -B -r Email ++---- + + Which will instead create a negative constraint, like + +@@ -206,8 +227,8 @@ where every other cluster node is no longer available! + In some cases, such as when +resource-stickiness+ is set to + +INFINITY+, it is possible that you will end up with the problem + described in <>. The tool can detect +-some of these cases and deals with them by also creating both a +-positive and negative constraint. Eg. ++some of these cases and deals with them by creating both ++positive and negative constraints. E.g. + + +Email+ prefers +sles-1+ with a score of +-INFINITY+ + +@@ -218,34 +239,40 @@ which has the same long-term consequences as discussed earlier. + [[s-failure-migration]] + === Moving Resources Due to Failure === + ++Normally, if a running resource fails, pacemaker will try to start ++it again on the same node. However if a resource fails repeatedly, ++it is possible that there is an underlying problem on that node, and you ++might desire trying a different node in such a case. + +-New in 1.0 is the concept of a migration threshold. ++Pacemaker allows you to set your preference via the +migration-threshold+ ++resource option. + footnote:[ + The naming of this option was perhaps unfortunate as it is easily +-confused with true migration, the process of moving a resource from ++confused with live migration, the process of moving a resource from + one node to another without stopping it. Xen virtual guests are the + most common example of resources that can be migrated in this manner. + ] + +-Simply define +migration-threshold=N+ for a resource and it will +-migrate to a new node after N failures. There is no threshold defined ++Simply define +migration-threshold=pass:[N]+ for a resource and it will ++migrate to a new node after 'N' failures. There is no threshold defined + by default. To determine the resource's current failure status and +-limits, use `crm_mon --failcounts`. ++limits, run `crm_mon --failcounts`. + +-By default, once the threshold has been reached, this node will no ++By default, once the threshold has been reached, the troublesome node will no + longer be allowed to run the failed resource until the administrator + manually resets the resource's failcount using `crm_failcount` (after +-hopefully first fixing the failure's cause). However it is possible +-to expire them by setting the resource's +failure-timeout+ option. ++hopefully first fixing the failure's cause). Alternatively, it is possible ++to expire them by setting the +failure-timeout+ option for the resource. + +-So a setting of +migration-threshold=2+ and +failure-timeout=60s+ ++For example, a setting of +migration-threshold=2+ and +failure-timeout=60s+ + would cause the resource to move to a new node after 2 failures, and +-allow it to move back (depending on the stickiness and constraint +-scores) after one minute. ++allow it to move back (depending on stickiness and constraint scores) after one ++minute. + +-There are two exceptions to the migration threshold concept; they +-occur when a resource either fails to start or fails to stop. Start +-failures cause the failcount to be set to +INFINITY+ and thus always ++There are two exceptions to the migration threshold concept: ++when a resource either fails to start or fails to stop. ++ ++Start failures cause the failcount to be set to +INFINITY+ and thus always + cause the resource to move immediately. + + Stop failures are slightly different and crucial. If a resource fails +@@ -256,39 +283,37 @@ to start the resource elsewhere, but will try to stop it again after + the failure timeout. + + [IMPORTANT] +-Please read <> before enabling this option. ++Please read <> to understand how timeouts work ++before configuring a +failure-timeout+. + + === Moving Resources Due to Connectivity Changes === + +-Setting up the cluster to move resources when external connectivity is +-lost is a two-step process. +- +-==== Tell Pacemaker to monitor connectivity ==== ++You can configure the cluster to move resources when external connectivity is ++lost in two steps. + ++==== Tell Pacemaker to Monitor Connectivity ==== + +-To do this, you need to add a +ping+ resource to the cluster. The +-+ping+ resource uses the system utility of the same name to a test if ++First, add an *ocf:pacemaker:ping* resource to the cluster. The ++*ping* resource uses the system utility of the same name to a test whether + list of machines (specified by DNS hostname or IPv4/IPv6 address) are +-reachable and uses the results to maintain a node attribute normally +-called +pingd+. ++reachable and uses the results to maintain a node attribute called +pingd+ ++by default. + footnote:[ +-The attribute name is customizable; that allows multiple ping groups to be defined. ++The attribute name is customizable, in order to allow multiple ping groups to be defined. + ] + + [NOTE] +-Older versions of Heartbeat required users to add ping nodes to _ha.cf_ - this is no longer required. +- +-[IMPORTANT] + =========== +-Older versions of Pacemaker used a custom binary called 'pingd' for +-this functionality; this is now deprecated in favor of 'ping'. ++Older versions of Heartbeat required users to add ping nodes to +ha.cf+, but ++this is no longer required. + +-If your version of Pacemaker does not contain the ping agent, you can +-download the latest version from ++Older versions of Pacemaker used a different agent *ocf:pacemaker:pingd* which ++is now deprecated in favor of *ping*. If your version of Pacemaker does not ++contain the *ping* resource agent, download the latest version from + https://github.com/ClusterLabs/pacemaker/tree/master/extra/resources/ping + =========== + +-Normally the resource will run on all cluster nodes, which means that ++Normally, the ping resource should run on all cluster nodes, which means that + you'll need to create a clone. A template for this can be found below + along with a description of the most interesting parameters. + +@@ -347,24 +372,21 @@ how to deal with the connectivity status that +ocf:pacemaker:ping+ is + recording. + =========== + +-==== Tell Pacemaker how to interpret the connectivity data ==== ++==== Tell Pacemaker How to Interpret the Connectivity Data ==== + +-[NOTE] ++[IMPORTANT] + ====== +-Before reading the following, please make sure you have read and +-understood <> above. ++Before attempting the following, make sure you understand ++<>. + ====== + +-There are a number of ways to use the connectivity data provided by +-Heartbeat. The most common setup is for people to have a single ping +-node, to prevent the cluster from running a resource on any +-unconnected node. ++There are a number of ways to use the connectivity data. + +-//// +-TODO: is the idea that only nodes that can reach eg. the router should have active resources? +-//// ++The most common setup is for people to have a single ping ++target (e.g. the service network's default gateway), to prevent the cluster ++from running a resource on any unconnected node. + +-.Don't run on unconnected nodes ++.Don't run a resource on unconnected nodes + ===== + [source,XML] + ------- +@@ -376,23 +398,29 @@ TODO: is the idea that only nodes that can reach eg. the router should have acti + ------- + ===== + +-A more complex setup is to have a number of ping nodes configured. ++A more complex setup is to have a number of ping targets configured. + You can require the cluster to only run resources on nodes that can + connect to all (or a minimum subset) of them. + +-.Run only on nodes connected to three or more ping nodes; this assumes +multiplier+ is set to 1000: ++.Run only on nodes connected to three or more ping targets. + ===== + [source,XML] + ------- ++ ++... ++ ++... ++ ++... + + +- ++ + + + ------- + ===== + +-Instead you can tell the cluster only to _prefer_ nodes with the best ++Alternatively, you can tell the cluster only to _prefer_ nodes with the best + connectivity. Just be sure to set +multiplier+ to a value higher than + that of +resource-stickiness+ (and don't set either of them to + +INFINITY+). +@@ -411,11 +439,11 @@ that of +resource-stickiness+ (and don't set either of them to + + It is perhaps easier to think of this in terms of the simple + constraints that the cluster translates it into. For example, if +-+sles-1+ is connected to all 5 ping nodes but +sles-2+ is only +-connected to 2, then it would be as if you instead had the following ++*sles-1* is connected to all five ping nodes but *sles-2* is only ++connected to two, then it would be as if you instead had the following + constraints in your configuration: + +-.How the cluster translates the pingd constraint ++.How the cluster translates the above location constraint + ===== + [source,XML] + ------- +@@ -447,24 +475,29 @@ three (again assuming that +multiplier+ is set to 1000). + ------- + ===== + +-=== Resource Migration === ++=== Migrating Resources === ++ ++Normally, when the cluster needs to move a resource, it fully restarts ++the resource (i.e. stops the resource on the current node ++and starts it on the new node). + +-Some resources, such as Xen virtual guests, are able to move to +-another location without loss of state. We call this resource +-migration; this is different from the normal practice of stopping the +-resource on the first machine and starting it elsewhere. ++However, some types of resources, such as Xen virtual guests, are able to move to ++another location without loss of state (often referred to as live migration ++or hot migration). In pacemaker, this is called resource migration. ++Pacemaker can be configured to migrate a resource when moving it, ++rather than restarting it. + +-Not all resources are able to migrate, see the Migration Checklist ++Not all resources are able to migrate; see the Migration Checklist + below, and those that can, won't do so in all situations. +-Conceptually there are two requirements from which the other ++Conceptually, there are two requirements from which the other + prerequisites follow: + +-* the resource must be active and healthy at the old location ++* The resource must be active and healthy at the old location; and + * everything required for the resource to run must be available on +- both the old and new locations ++ both the old and new locations. + +-The cluster is able to accommodate both push and pull migration models +-by requiring the resource agent to support two new actions: ++The cluster is able to accommodate both 'push' and 'pull' migration models ++by requiring the resource agent to support two special actions: + +migrate_to+ (performed on the current location) and +migrate_from+ + (performed on the destination). + +@@ -477,30 +510,34 @@ Conversely for pull, the +migrate_to+ action is practically empty and + +migrate_from+ does most of the work, extracting the relevant resource + state from the old location and activating it. + +-There is no wrong or right way to implement migration for your +-service, as long as it works. +- +-==== Migration Checklist ==== ++There is no wrong or right way for a resource agent to implement migration, ++as long as it works. + ++.Migration Checklist + * The resource may not be a clone. + * The resource must use an OCF style agent. + * The resource must not be in a failed or degraded state. +-* The resource must not, directly or indirectly, depend on any +- primitive or group resources. +-* The resource must support two new actions: +migrate_to+ and +- +migrate_from+, and advertise them in its metadata. ++* The resource agent must support +migrate_to+ and ++ +migrate_from+ actions, and advertise them in its metadata. + * The resource must have the +allow-migrate+ meta-attribute set to + +true+ (which is not the default). + +-//// +-TODO: how can a KVM with DRBD migrate? +-//// ++If an otherwise migratable resource depends on another resource ++via an ordering constraint, there are special situations in which it will be ++restarted rather than migrated. ++ ++For example, if the resource depends on a clone, and at the time the resource ++needs to be moved, the clone has instances that are stopping and instances ++that are starting, then the resource will be restarted. ++The Policy Engine is not yet able to model this ++situation correctly and so takes the safer (if less optimal) path. ++ ++In pacemaker 1.1.11 and earlier, a migratable resource will be restarted ++when moving if it directly or indirectly depends on 'any' primitive or group ++resources. + +-If the resource depends on a clone, and at the time the resource needs +-to be move, the clone has instances that are stopping and instances +-that are starting, then the resource will be moved in the traditional +-manner. The Policy Engine is not yet able to model this situation +-correctly and so takes the safe (yet less optimal) path. ++Even in newer versions, if a migratable resource depends on a non-migratable ++resource, and both need to be moved, the migratable resource will be restarted. + + [[s-reusing-config-elements]] + == Reusing Rules, Options and Sets of Operations == +@@ -574,17 +611,17 @@ The same principle applies for +meta_attributes+ and + == Reloading Services After a Definition Change == + + The cluster automatically detects changes to the definition of +-services it manages. However, the normal response is to stop the ++services it manages. The normal response is to stop the + service (using the old definition) and start it again (with the new + definition). This works well, but some services are smarter and can + be told to use a new set of options without restarting. + +-To take advantage of this capability, your resource agent must: ++To take advantage of this capability, the resource agent must: + + . Accept the +reload+ operation and perform any required actions. +- _The steps required here depend completely on your application!_ ++ _The actions here depend completely on your application!_ + + +-.The DRBD Agent's Control logic for Supporting the +reload+ Operation ++.The DRBD agent's logic for supporting +reload+ + ===== + [source,Bash] + ------- +@@ -657,13 +694,13 @@ Any parameter with the +unique+ set to 0 is eligible to be used in this way. + + Once these requirements are satisfied, the cluster will automatically + know to reload the resource (instead of restarting) when a non-unique +-fields changes. ++field changes. + + [NOTE] + ====== +-The metadata is re-read when the resource is started. This may mean +-that the resource will be restarted the first time, even though you +-changed a parameter with +unique=0+ ++Metadata will not be re-read unless the resource needs to be started. This may ++mean that the resource will be restarted the first time, even though you ++changed a parameter with +unique=0+. + ====== + + [NOTE] +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Advanced-Resources.txt b/doc/Pacemaker_Explained/en-US/Ch-Advanced-Resources.txt +index 8262578..4060201 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Advanced-Resources.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Advanced-Resources.txt +@@ -8,21 +8,21 @@ indexterm:[Resources,Groups] + + One of the most common elements of a cluster is a set of resources + that need to be located together, start sequentially, and stop in the +-reverse order. To simplify this configuration we support the concept ++reverse order. To simplify this configuration, we support the concept + of groups. + +-.An example group ++.A group of two primitive resources + ====== + [source,XML] + ------- + + + +- ++ + + + +- ++ + ------- + ====== + +@@ -53,7 +53,7 @@ The group above is logically equivalent to writing: + + + +- ++ + + + +@@ -81,7 +81,7 @@ mount, an IP address, and an application that uses them. + |Description + + |id +-|Your name for the group ++|A unique name for the group + indexterm:[id,Group Resource Property] + indexterm:[Resource,Group Property,id] + +@@ -89,27 +89,27 @@ mount, an IP address, and an application that uses them. + + === Group Options === + +-Options inherited from <> resources: +-+priority, target-role, is-managed+ ++Groups inherit the +priority+, +target-role+, and +is-managed+ properties ++from primitive resources. See <> for information about ++those properties. + + === Group Instance Attributes === + +-Groups have no instance attributes, however any that are set here will +-be inherited by the group's children. ++Groups have no instance attributes. However, any that are set for the group ++object will be inherited by the group's children. + + === Group Contents === + +-Groups may only contain a collection of +-<> cluster resources. To refer to +-the child of a group resource, just use the child's id instead of the +-group's. ++Groups may only contain a collection of cluster resources (see ++<>). To refer to a child of a group resource, just use ++the child's +id+ instead of the group's. + + === Group Constraints === + +-Although it is possible to reference the group's children in +-constraints, it is usually preferable to use the group's name instead. ++Although it is possible to reference a group's children in ++constraints, it is usually preferable to reference the group itself. + +-.Example constraints involving groups ++.Some constraints involving groups + ====== + [source,XML] + ------- +@@ -136,32 +136,32 @@ current location with a score of 500. + indexterm:[Clone Resources] + indexterm:[Resources,Clones] + +-Clones were initially conceived as a convenient way to start N +-instances of an IP resource and have them distributed throughout the ++Clones were initially conceived as a convenient way to start multiple ++instances of an IP address resource and have them distributed throughout the + cluster for load balancing. They have turned out to quite useful for +-a number of purposes including integrating with Red Hat's DLM, the +-fencing subsystem, and OCFS2. ++a number of purposes including integrating with the Distributed Lock Manager ++(used by many cluster filesystems), the fencing subsystem, and OCFS2. + + You can clone any resource, provided the resource agent supports it. + + Three types of cloned resources exist: + + * Anonymous +-* Globally Unique ++* Globally unique + * Stateful + +-Anonymous clones are the simplest type. These resources behave ++'Anonymous' clones are the simplest. These behave + completely identically everywhere they are running. Because of this, +-there can only be one copy of an anonymous clone active per machine. ++there can be only one copy of an anonymous clone active per machine. + +-Globally unique clones are distinct entities. A copy of the clone ++'Globally unique' clones are distinct entities. A copy of the clone + running on one machine is not equivalent to another instance on +-another node. Nor would any two copies on the same node be ++another node, nor would any two copies on the same node be + equivalent. + +-Stateful clones are covered later in <>. ++'Stateful' clones are covered later in <>. + +-.An example clone ++.A clone of an LSB resource + ====== + [source,XML] + ------- +@@ -184,7 +184,7 @@ Stateful clones are covered later in <>. + |Description + + |id +-|Your name for the clone ++|A unique name for the clone + indexterm:[id,Clone Property] + indexterm:[Clone,Property,id] + +@@ -195,49 +195,54 @@ Stateful clones are covered later in <>. + Options inherited from <> resources: + +priority, target-role, is-managed+ + +-.Clone specific configuration options +-[width="95%",cols="3m,5<",options="header",align="center"] ++.Clone-specific configuration options ++[width="95%",cols="1m,1,3<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |clone-max +-|How many copies of the resource to start. Defaults to the number of +- nodes in the cluster. ++|number of nodes in cluster ++|How many copies of the resource to start + indexterm:[clone-max,Clone Option] + indexterm:[Clone,Option,clone-max] + + |clone-node-max +-|How many copies of the resource can be started on a single node; +- default _1_. ++|1 ++|How many copies of the resource can be started on a single node + indexterm:[clone-node-max,Clone Option] + indexterm:[Clone,Option,clone-node-max] + + |notify ++|true + |When stopping or starting a copy of the clone, tell all the other +- copies beforehand and when the action was successful. Allowed values: +- _false_, +true+ ++ copies beforehand and again when the action was successful. Allowed values: ++ +false+, +true+ + indexterm:[notify,Clone Option] + indexterm:[Clone,Option,notify] + + |globally-unique ++|false + |Does each copy of the clone perform a different function? Allowed +- values: _false_, +true+ ++ values: +false+, +true+ + indexterm:[globally-unique,Clone Option] + indexterm:[Clone,Option,globally-unique] + + |ordered ++|false + |Should the copies be started in series (instead of in +- parallel). Allowed values: _false_, +true+ ++ parallel)? Allowed values: +false+, +true+ + indexterm:[ordered,Clone Option] + indexterm:[Clone,Option,ordered] + + |interleave +-|Changes the behavior of ordering constraints (between clones/masters) +- so that instances can start/stop as soon as their peer instance has +- (rather than waiting for every instance of the other clone +- has). Allowed values: _false_, +true+ ++|false ++|If this clone depends on another clone via an ordering constraint, ++is it allowed to start after the local instance of the other clone ++starts, rather than wait for all instances of the other clone to start? ++Allowed values: +false+, +true+ + indexterm:[interleave,Clone Option] + indexterm:[Clone,Option,interleave] + +@@ -250,7 +255,7 @@ will be inherited by the clone's children. + + === Clone Contents === + +-Clones must contain exactly one group or one regular resource. ++Clones must contain exactly one primitive or group resource. + + [WARNING] + You should never reference the name of a clone's child. +@@ -261,26 +266,10 @@ If you think you need to do this, you probably need to re-evaluate your design. + In most cases, a clone will have a single copy on each active cluster + node. If this is not the case, you can indicate which nodes the + cluster should preferentially assign copies to with resource location +-constraints. These constraints are written no differently to those +-for regular resources except that the clone's id is used. +- +-Ordering constraints behave slightly differently for clones. In the +-example below, +apache-stats+ will wait until all copies of the clone +-that need to be started have done so before being started itself. +-Only if _no_ copies can be started +apache-stats+ will be prevented +-from being active. Additionally, the clone will wait for +-+apache-stats+ to be stopped before stopping the clone. ++constraints. These constraints are written no differently from those ++for primitive resources except that the clone's +id+ is used. + +-Colocation of a regular (or group) resource with a clone means that +-the resource can run on any machine with an active copy of the clone. +-The cluster will choose a copy based on where the clone is running and +-the resource's own location preferences. +- +-Colocation between clones is also possible. In such cases, the set of +-allowed locations for the clone is limited to nodes on which the clone +-is (or will be) active. Allocation is then performed as normally. +- +-.Example constraints involving clones ++.Some constraints involving clones + ====== + [source,XML] + ------- +@@ -292,6 +281,24 @@ is (or will be) active. Allocation is then performed as normally. + ------- + ====== + ++Ordering constraints behave slightly differently for clones. In the ++example above, +apache-stats+ will wait until all copies of +apache-clone+ ++that need to be started have done so before being started itself. ++Only if _no_ copies can be started will +apache-stats+ be prevented ++from being active. Additionally, the clone will wait for +++apache-stats+ to be stopped before stopping itself. ++ ++Colocation of a primitive or group resource with a clone means that ++the resource can run on any machine with an active copy of the clone. ++The cluster will choose a copy based on where the clone is running and ++the resource's own location preferences. ++ ++Colocation between clones is also possible. If one clone +A+ is colocated ++with another clone +B+, the set of allowed locations for +A+ is limited to ++nodes on which +B+ is (or will be) active. Placement is then performed ++normally. ++ ++[[s-clone-stickiness]] + === Clone Stickiness === + + indexterm:[resource-stickiness,Clones] +@@ -302,6 +309,16 @@ will use a value of 1. Being a small value, it causes minimal + disturbance to the score calculations of other resources but is enough + to prevent Pacemaker from needlessly moving copies around the cluster. + ++[NOTE] ++==== ++For globally unique clones, this may result in multiple instances of the ++clone staying on a single node, even after another eligible node becomes ++active (for example, after being put into standby mode then made active again). ++If you do not want this behavior, specify a +resource-stickiness+ of 0 ++for the clone temporarily and let the cluster adjust, then set it back ++to 1 if you want the default behavior to apply again. ++==== ++ + === Clone Resource Agent Requirements === + + Any resource can be used as an anonymous clone, as it requires no +@@ -310,27 +327,27 @@ do so depends on your resource and its resource agent. + + Globally unique clones do require some additional support in the + resource agent. In particular, it must only respond with +-+${OCF_SUCCESS}+ if the node has that exact instance active. All +++$\{OCF_SUCCESS}+ if the node has that exact instance active. All + other probes for instances of the clone should result in +-+${OCF_NOT_RUNNING}+. Unless of course they are failed, in which case +-they should return one of the other OCF error codes. +++$\{OCF_NOT_RUNNING}+ (or one of the other OCF error codes if ++they are failed). + +-Copies of a clone are identified by appending a colon and a numerical +-offset, eg. +apache:2+. ++Individual instances of a clone are identified by appending a colon and a ++numerical offset, e.g. +apache:2+. + + Resource agents can find out how many copies there are by examining + the +OCF_RESKEY_CRM_meta_clone_max+ environment variable and which + copy it is by examining +OCF_RESKEY_CRM_meta_clone+. + +-You should not make any assumptions (based on +-+OCF_RESKEY_CRM_meta_clone+) about which copies are active. In ++The resource agent must not make any assumptions (based on +++OCF_RESKEY_CRM_meta_clone+) about which numerical instances are active. In + particular, the list of active copies will not always be an unbroken + sequence, nor always start at 0. + + ==== Clone Notifications ==== + + Supporting notifications requires the +notify+ action to be +-implemented. Once supported, the notify action will be passed a ++implemented. If supported, the notify action will be passed a + number of extra variables which, when combined with additional + context, can be used to calculate the current state of the cluster and + what is about to happen to it. +@@ -397,13 +414,13 @@ what is about to happen to it. + The variables come in pairs, such as + +OCF_RESKEY_CRM_meta_notify_start_resource+ and + +OCF_RESKEY_CRM_meta_notify_start_uname+ and should be treated as an +-array of whitespace separated elements. ++array of whitespace-separated elements. + + Thus in order to indicate that +clone:0+ will be started on +sles-1+, + +clone:2+ will be started on +sles-3+, and +clone:3+ will be started + on +sles-2+, the cluster would set + +-.Example notification variables ++.Notification variables + ====== + [source,Bash] + ------- +@@ -453,12 +470,13 @@ OCF_RESKEY_CRM_meta_notify_start_uname="sles-1 sles-3 sles-2" + indexterm:[Multi-state Resources] + indexterm:[Resources,Multi-state] + +-Multi-state resources are a specialization of Clone resources; please +-ensure you understand the section on clones before continuing! They +-allow the instances to be in one of two operating modes; these are +-called +Master+ and +Slave+, but can mean whatever you wish them to +-mean. The only limitation is that when an instance is started, it +-must come up in the +Slave+ state. ++Multi-state resources are a specialization of clone resources; please ++ensure you understand <> before continuing! ++ ++Multi-state resources allow the instances to be in one of two operating modes ++(called 'roles'). The roles are called 'master' and 'slave', but can mean ++whatever you wish them to mean. The only limitation is that when an instance is ++started, it must come up in the slave role. + + === Multi-state Properties === + +@@ -485,22 +503,24 @@ Options inherited from <> resources: + +clone-max+, +clone-node-max+, +notify+, +globally-unique+, +ordered+, + +interleave+ + +-.Multi-state specific resource configuration options +-[width="95%",cols="3m,5<",options="header",align="center"] ++.Multi-state-specific resource configuration options ++[width="95%",cols="1m,1,3<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |master-max +-|How many copies of the resource can be promoted to +master+ status; +- default 1. ++|1 ++|How many copies of the resource can be promoted to the +master+ role + indexterm:[master-max,Multi-State Option] + indexterm:[Multi-State,Option,master-max] + + |master-node-max +-|How many copies of the resource can be promoted to +master+ status on +- a single node; default 1. ++|1 ++|How many copies of the resource can be promoted to the +master+ role on ++ a single node + indexterm:[master-node-max,Multi-State Option] + indexterm:[Multi-State,Option,master-node-max] + +@@ -509,11 +529,11 @@ Options inherited from <> resources: + === Multi-state Instance Attributes === + + Multi-state resources have no instance attributes; however, any that +-are set here will be inherited by master's children. ++are set here will be inherited by a master's children. + + === Multi-state Contents === + +-Masters must contain exactly one group or one regular resource. ++Masters must contain exactly one primitive or group resource. + + [WARNING] + You should never reference the name of a master's child. +@@ -521,21 +541,12 @@ If you think you need to do this, you probably need to re-evaluate your design. + + === Monitoring Multi-State Resources === + +-The normal type of monitor actions are not sufficient to monitor a +-multi-state resource in the +Master+ state. To detect failures of the +-+Master+ instance, you need to define an additional monitor action +-with +role="Master"+. ++The usual monitor actions are insufficient to monitor a multi-state resource, ++because pacemaker needs to verify not only that the resource is active, but ++also that its actual role matches its intended one. + +-[IMPORTANT] +-=========== +-It is crucial that _every_ monitor operation has a different interval! +- +-This is because Pacemaker currently differentiates between operations +-only by resource and interval; so if eg. a master/slave resource has +-the same monitor interval for both roles, Pacemaker would ignore the +-role when checking the status - which would cause unexpected return +-codes, and therefore unnecessary complications. +-=========== ++Define two monitoring actions: the usual one will cover the slave role, ++and an additional one with +role="master"+ will cover the master role. + + .Monitoring both states of a multi-state resource + ====== +@@ -552,14 +563,23 @@ codes, and therefore unnecessary complications. + ------- + ====== + ++[IMPORTANT] ++=========== ++It is crucial that _every_ monitor operation has a different interval! ++Pacemaker currently differentiates between operations ++only by resource and interval; so if (for example) a master/slave resource had ++the same monitor interval for both roles, Pacemaker would ignore the ++role when checking the status -- which would cause unexpected return ++codes, and therefore unnecessary complications. ++=========== + + === Multi-state Constraints === + +-In most cases, a multi-state resources will have a single copy on each ++In most cases, multi-state resources will have a single copy on each + active cluster node. If this is not the case, you can indicate which + nodes the cluster should preferentially assign copies to with resource +-location constraints. These constraints are written no differently to +-those for regular resources except that the master's id is used. ++location constraints. These constraints are written no differently from ++those for primitive resources except that the master's +id+ is used. + + When considering multi-state resources in constraints, for most + purposes it is sufficient to treat them as clones. The exception is +@@ -568,52 +588,50 @@ constraints) and +first-action+ and/or +then-action+ fields (for + ordering constraints) are used. + + .Additional constraint options relevant to multi-state resources +-[width="95%",cols="3m,5<",options="header",align="center"] ++[width="95%",cols="1m,1,3<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |rsc-role ++|started + |An additional attribute of colocation constraints that specifies the +- role that +rsc+ must be in. Allowed values: _Started_, +Master+, +- +Slave+. ++ role that +rsc+ must be in. Allowed values: +started+, +master+, ++ +slave+. + indexterm:[rsc-role,Ordering Constraints] + indexterm:[Constraints,Ordering,rsc-role] + + |with-rsc-role ++|started + |An additional attribute of colocation constraints that specifies the +- role that +with-rsc+ must be in. Allowed values: _Started_, +- +Master+, +Slave+. ++ role that +with-rsc+ must be in. Allowed values: +started+, ++ +master+, +slave+. + indexterm:[with-rsc-role,Ordering Constraints] + indexterm:[Constraints,Ordering,with-rsc-role] + + |first-action ++|start + |An additional attribute of ordering constraints that specifies the + action that the +first+ resource must complete before executing the +- specified action for the +then+ resource. Allowed values: _start_, ++ specified action for the +then+ resource. Allowed values: +start+, + +stop+, +promote+, +demote+. + indexterm:[first-action,Ordering Constraints] + indexterm:[Constraints,Ordering,first-action] + + |then-action ++|value of +first-action+ + |An additional attribute of ordering constraints that specifies the + action that the +then+ resource can only execute after the + +first-action+ on the +first+ resource has completed. Allowed +- values: +start+, +stop+, +promote+, +demote+. Defaults to the value +- (specified or implied) of +first-action+. ++ values: +start+, +stop+, +promote+, +demote+. + indexterm:[then-action,Ordering Constraints] + indexterm:[Constraints,Ordering,then-action] + + |========================================================= + +-In the example below, +myApp+ will wait until one of the database +-copies has been started and promoted to master before being started +-itself. Only if no copies can be promoted will +apache-stats+ be +-prevented from being active. Additionally, the database will wait for +-+myApp+ to be stopped before it is demoted. +- +-.Example constraints involving multi-state resources ++.Constraints involving multi-state resources + ====== + [source,XML] + ------- +@@ -630,54 +648,60 @@ prevented from being active. Additionally, the database will wait for + ------- + ====== + +-Colocation of a regular (or group) resource with a multi-state ++In the example above, +myApp+ will wait until one of the database ++copies has been started and promoted to master before being started ++itself on the same node. Only if no copies can be promoted will +myApp+ be ++prevented from being active. Additionally, the cluster will wait for +++myApp+ to be stopped before demoting the database. ++ ++Colocation of a primitive or group resource with a multi-state + resource means that it can run on any machine with an active copy of +-the multi-state resource that is in the specified state (+Master+ or +-+Slave+). In the example, the cluster will choose a location based on +-where database is running as a +Master+, and if there are multiple +-+Master+ instances it will also factor in +myApp+'s own location ++the multi-state resource that has the specified role (+master+ or +++slave+). In the example above, the cluster will choose a location based on ++where database is running as a +master+, and if there are multiple +++master+ instances it will also factor in +myApp+'s own location + preferences when deciding which location to choose. + + Colocation with regular clones and other multi-state resources is also + possible. In such cases, the set of allowed locations for the +rsc+ + clone is (after role filtering) limited to nodes on which the + +with-rsc+ multi-state resource is (or will be) in the specified role. +-Allocation is then performed as-per-normal. ++Placement is then performed as normal. + +-==== Using Multi-state Resources in Colocation/Ordering Sets ==== ++==== Using Multi-state Resources in Colocation Sets ==== + + .Additional colocation set options relevant to multi-state resources +-[width="95%",cols="3m,5<",options="header",align="center"] ++[width="95%",cols="1m,1,6<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |role +-|An additional attribute of colocation constraint sets that specifies the +- role that *all members of the set* must be in. Allowed values: _Started_, +Master+, +- +Slave+. ++|started ++|The role that 'all members' of the set must be in. Allowed values: +started+, +master+, ++ +slave+. + indexterm:[role,Ordering Constraints] + indexterm:[Constraints,Ordering,role] + + |========================================================= + + In the following example +B+'s master must be located on the same node as +A+'s master. +-Additionally resources +C+ and +D+ must be located on the same node as +B+'s master. ++Additionally resources +C+ and +D+ must be located on the same node as +A+'s ++and +B+'s masters. + +-.Colocate C and C with A and B's master instances ++.Colocate C and D with A's and B's master instances + ====== + [source,XML] + ------- + + +- ++ + + + +- +- +- ++ + + + +@@ -686,68 +710,68 @@ Additionally resources +C+ and +D+ must be located on the same node as +B+'s mas + ------- + ====== + ++==== Using Multi-state Resources in Ordering Sets ==== ++ + .Additional ordered set options relevant to multi-state resources +-[width="95%",cols="3m,5<",options="header",align="center"] ++[width="95%",cols="1m,1,3<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |action +-|An additional attribute of ordering constraint set that specifies the +- action that applies to *all members of the set*. Allowed +- values: +start+, +stop+, +promote+, +demote+. Defaults to the value +- (specified or implied) of +first-action+. ++|value of +first-action+ ++|An additional attribute of ordering constraint sets that specifies the ++ action that applies to 'all members' of the set. Allowed ++ values: +start+, +stop+, +promote+, +demote+. + indexterm:[action,Ordering Constraints] + indexterm:[Constraints,Ordering,action] + + |========================================================= + +-In the following example +B+ cannot be promoted until +A+'s has been promoted. +-Additionally resources +C+ and +D+ must wait until +A+ and +B+ have been promoted before they can start. +- +-.Start C and C after first promoting A and B ++.Start C and D after first promoting A and B + ====== + [source,XML] + ------- + +- +- ++ ++ + + + +- ++ + + + +- ++ + + ------- + ====== + ++In the above example, +B+ cannot be promoted to a master role until +A+ has ++been promoted. Additionally, resources +C+ and +D+ must wait until +A+ and +B+ ++have been promoted before they can start. ++ + + === Multi-state Stickiness === + + indexterm:[resource-stickiness,Multi-State] +-To achieve a stable allocation pattern, multi-state resources are +-slightly sticky by default. If no value for +resource-stickiness+ is +-provided, the multi-state resource will use a value of 1. Being a +-small value, it causes minimal disturbance to the score calculations +-of other resources but is enough to prevent Pacemaker from needlessly +-moving copies around the cluster. ++As with regular clones, multi-state resources are ++slightly sticky by default. See <> for details. + + === Which Resource Instance is Promoted === + +-During the start operation, most Resource Agent scripts should call ++During the start operation, most resource agents should call + the `crm_master` utility. This tool automatically detects both the + resource and host and should be used to set a preference for being + promoted. Based on this, +master-max+, and +master-node-max+, the + instance(s) with the highest preference will be promoted. + +-The other alternative is to create a location constraint that ++An alternative is to create a location constraint that + indicates which nodes are most preferred as masters. + +-.Manually specifying which node should be promoted ++.Explicitly preferring node1 to be promoted to master + ====== + [source,XML] + ------- +@@ -759,27 +783,29 @@ indicates which nodes are most preferred as masters. + ------- + ====== + +-=== Multi-state Resource Agent Requirements === ++=== Requirements for Multi-state Resource Agents === + + Since multi-state resources are an extension of cloned resources, all +-the requirements of Clones are also requirements of multi-state +-resources. Additionally, multi-state resources require two extra +-actions: +demote+ and +promote+; these actions are responsible for ++the requirements for resource agents that support clones are also requirements ++for resource agents that support multi-state resources. ++ ++Additionally, multi-state resources require two extra ++actions, +demote+ and +promote+, which are responsible for + changing the state of the resource. Like +start+ and +stop+, they +-should return +OCF_SUCCESS+ if they completed successfully or a ++should return +$\{OCF_SUCCESS}+ if they completed successfully or a + relevant error code if they did not. + + The states can mean whatever you wish, but when the resource is +-started, it must come up in the mode called +Slave+. From there the +-cluster will then decide which instances to promote to +Master+. ++started, it must come up in the mode called +slave+. From there the ++cluster will decide which instances to promote to +master+. + +-In addition to the Clone requirements for monitor actions, agents must ++In addition to the clone requirements for monitor actions, agents must + also _accurately_ report which state they are in. The cluster relies + on the agent to report its status (including role) accurately and does + not indicate to the agent what role it currently believes it to be in. + + .Role implications of OCF return codes +-[width="95%",cols="5,3<",options="header",align="center"] ++[width="95%",cols="1,1<",options="header",align="center"] + |========================================================= + + |Monitor Return Code +@@ -806,15 +832,15 @@ not indicate to the agent what role it currently believes it to be in. + + |========================================================= + +-=== Multi-state Notifications === ++==== Multi-state Notifications ==== + + Like clones, supporting notifications requires the +notify+ action to +-be implemented. Once supported the notify action will be passed a ++be implemented. If supported, the notify action will be passed a + number of extra variables which, when combined with additional + context, can be used to calculate the current state of the cluster and + what is about to happen to it. + +-.Environment variables supplied with Master notify actions footnote:[Emphasized variables are specific to +Master+ resources and all behave in the same manner as described for Clone resources.] ++.Environment variables supplied with multi-state notify actions footnote:[Emphasized variables are specific to +Master+ resources, and all behave in the same manner as described for Clone resources.] + [width="95%",cols="5,3<",options="header",align="center"] + |========================================================= + +@@ -913,7 +939,7 @@ what is about to happen to it. + + |========================================================= + +-=== Multi-state - Proper Interpretation of Notification Environment Variables === ++==== Proper Interpretation of Multi-state Notification Environment Variables ==== + + + .Pre-notification (demote): +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Basics.txt b/doc/Pacemaker_Explained/en-US/Ch-Basics.txt +index 6f73955..5134e69 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Basics.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Basics.txt +@@ -2,56 +2,67 @@ + + == Configuration Layout == + +-The cluster is written using XML notation and divided into two main +-sections: configuration and status. +- +-The status section contains the history of each resource on each node +-and based on this data, the cluster can construct the complete current +-state of the cluster. The authoritative source for the status section +-is the local resource manager (lrmd) process on each cluster node and +-the cluster will occasionally repopulate the entire section. For this +-reason it is never written to disk and administrators are advised +-against modifying it in any way. +- +-The configuration section contains the more traditional information +-like cluster options, lists of resources and indications of where they +-should be placed. The configuration section is the primary focus of +-this document. +- +-The configuration section itself is divided into four parts: +- +- * Configuration options (called +crm_config+) +- * Nodes +- * Resources +- * Resource relationships (called +constraints+) ++The cluster is defined by the Cluster Information Base (CIB), ++which uses XML notation. The simplest CIB, an empty one, looks like this: + + .An empty configuration + ====== + [source,XML] + ------- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ + ------- + ====== + ++The empty configuration above contains the major sections that make up a CIB: ++ ++* +cib+: The entire CIB is enclosed with a +cib+ tag. Certain fundamental settings ++ are defined as attributes of this tag. ++ ++ ** +configuration+: This section -- the primary focus of this document -- ++ contains traditional configuration information such as what resources the ++ cluster serves and the relationships among them. ++ ++ *** +crm_config+: cluster-wide configuration options ++ *** +nodes+: the machines that host the cluster ++ *** +resources+: the services run by the cluster ++ *** +constraints+: indications of how resources should be placed ++ ++ ** +status+: This section contains the history of each resource on each node. ++ Based on this data, the cluster can construct the complete current ++ state of the cluster. The authoritative source for this section ++ is the local resource manager (lrmd process) on each cluster node, and ++ the cluster will occasionally repopulate the entire section. For this ++ reason, it is never written to disk, and administrators are advised ++ against modifying it in any way. ++ ++In this document, configuration settings will be described as 'properties' or 'options' ++based on how they are defined in the CIB: ++ ++* Properties are XML attributes of an XML element. ++* Options are name-value pairs expressed as +nvpair+ child elements of an XML element. ++ ++Normally you will use command-line tools that abstract the XML, so the ++distinction will be unimportant; both properties and options are ++cluster settings you can tweak. ++ + == The Current State of the Cluster == + + Before one starts to configure a cluster, it is worth explaining how + to view the finished product. For this purpose we have created the +-`crm_mon` utility that will display the ++`crm_mon` utility, which will display the + current state of an active cluster. It can show the cluster status by + node or by resource and can be used in either single-shot or + dynamically-updating mode. There are also modes for displaying a list + of the operations performed (grouped by node and resource) as well as + information about failures. +- + + Using this tool, you can examine the state of the cluster for + irregularities and see how it responds when you cause or simulate +@@ -113,7 +124,7 @@ Details on all the available options can be obtained using the + ====== + + The DC (Designated Controller) node is where all the decisions are +-made and if the current DC fails a new one is elected from the ++made, and if the current DC fails a new one is elected from the + remaining cluster nodes. The choice of DC is of no significance to an + administrator beyond the fact that its logs will generally be more + interesting. +@@ -122,27 +133,30 @@ interesting. + + There are three basic rules for updating the cluster configuration: + +- * Rule 1 - Never edit the cib.xml file manually. Ever. I'm not making this up. ++ * Rule 1 - Never edit the +cib.xml+ file manually. Ever. I'm not making this up. + * Rule 2 - Read Rule 1 again. + * Rule 3 - The cluster will notice if you ignored rules 1 & 2 and refuse to use the configuration. + +-Now that it is clear how NOT to update the configuration, we can begin +-to explain how you should. ++Now that it is clear how 'not' to update the configuration, we can begin ++to explain how you 'should'. ++ ++=== Editing the CIB Using XML === + + The most powerful tool for modifying the configuration is the +-+cibadmin+ command which talks to a running cluster. With +cibadmin+, +-the user can query, add, remove, update or replace any part of the +-configuration; all changes take effect immediately, so there is no +-need to perform a reload-like operation. +- +++cibadmin+ command. With +cibadmin+, you can query, add, remove, update ++or replace any part of the configuration. All changes take effect immediately, ++so there is no need to perform a reload-like operation. + +-The simplest way of using cibadmin is to use it to save the current ++The simplest way of using `cibadmin` is to use it to save the current + configuration to a temporary file, edit that file with your favorite +-text or XML editor and then upload the revised configuration. ++text or XML editor, and then upload the revised configuration. footnote:[This ++process might appear to risk overwriting changes that happen after the initial ++cibadmin call, but pacemaker will reject any update that is "too old". If the ++CIB is updated in some other fashion after the initial cibadmin, the second ++cibadmin will be rejected because the version number will be too low.] + + .Safely using an editor to modify the cluster configuration + ====== +-[source,C] + -------- + # cibadmin --query > tmp.xml + # vi tmp.xml +@@ -152,16 +166,16 @@ text or XML editor and then upload the revised configuration. + + Some of the better XML editors can make use of a Relax NG schema to + help make sure any changes you make are valid. The schema describing +-the configuration can normally be found in +-'/usr/lib/heartbeat/pacemaker.rng' on most systems. +- ++the configuration can be found in +pacemaker.rng+, which may be ++deployed in a location such as +/usr/share/pacemaker+ or +++/usr/lib/heartbeat+ depending on your operating system and how you ++installed the software. + +-If you only wanted to modify the resources section, you could instead +-do ++If you want to modify just one section of the configuration, you can ++query and replace just that section to avoid modifying any others. + +-.Safely using an editor to modify a subsection of the cluster configuration ++.Safely using an editor to modify only the resources section + ====== +-[source,C] + -------- + # cibadmin --query --obj_type resources > tmp.xml + # vi tmp.xml +@@ -169,18 +183,15 @@ do + -------- + ====== + +-to avoid modifying any other part of the configuration. ++=== Quickly Deleting Part of the Configuration === + +-== Quickly Deleting Part of the Configuration == +- +-Identify the object you wish to delete. Eg. run ++Identify the object you wish to delete by XML tag and id. For example, ++you might search the CIB for all STONITH-related configuration: + +-.Searching for STONITH related configuration items ++.Searching for STONITH-related configuration items + ====== +-[source,C] ++---- + # cibadmin -Q | grep stonith +-[source,XML] +--------- + + + +@@ -191,34 +202,48 @@ Identify the object you wish to delete. Eg. run + + + +--------- ++---- + ====== + +-Next identify the resource's tag name and id (in this case we'll +-choose +primitive+ and +child_DoFencing+). Then simply execute: ++If you wanted to delete the +primitive+ tag with id +child_DoFencing+, ++you would run: + +-[source,C] ++---- + # cibadmin --delete --crm_xml '' ++---- + +-== Updating the Configuration Without Using XML == ++=== Updating the Configuration Without Using XML === + +-Some common tasks can also be performed with one of the higher level +-tools that avoid the need to read or edit XML. ++Most tasks can be performed with one of the other command-line ++tools provided with pacemaker, avoiding the need to read or edit XML. + +-To enable stonith for example, one could run: ++To enable STONITH for example, one could run: + +-[source,C] +-# crm_attribute --attr-name stonith-enabled --attr-value true ++---- ++# crm_attribute --name stonith-enabled --update 1 ++---- + +-Or, to see if +somenode+ is allowed to run resources, there is: ++Or, to check whether *somenode* is allowed to run resources, there is: + +-[source,C] +-# crm_standby --get-value --node-uname somenode ++---- ++# crm_standby --get-value --node somenode ++---- + +-Or, to find the current location of +my-test-rsc+, one can use: ++Or, to find the current location of *my-test-rsc*, one can use: + +-[source,C] ++---- + # crm_resource --locate --resource my-test-rsc ++---- ++ ++Examples of using these tools for specific cases will be given throughout this ++document where appropriate. ++ ++[NOTE] ++==== ++Old versions of pacemaker (1.0.3 and earlier) had different ++command-line tool syntax. If you are using an older version, ++check your installed manual pages for the proper syntax to use. ++==== + + [[s-config-sandboxes]] + == Making Configuration Changes in a Sandbox == +@@ -229,46 +254,46 @@ have created `crm_shadow` which creates a + "shadow" copy of the configuration and arranges for all the command + line tools to use it. + +-To begin, simply invoke `crm_shadow` and give +-it the name of a configuration to create footnote:[Shadow copies are +-identified with a name, making it possible to have more than one.] ; +-be sure to follow the simple on-screen instructions. ++To begin, simply invoke `crm_shadow --create` with ++the name of a configuration to create footnote:[Shadow copies are ++identified with a name, making it possible to have more than one.], ++and follow the simple on-screen instructions. + +-WARNING: Read the above carefully, failure to do so could result in you +-destroying the cluster's active configuration! ++[WARNING] ++==== ++Read this section and the on-screen instructions carefully; failure to do so could ++result in destroying the cluster's active configuration! ++==== + + + .Creating and displaying the active sandbox + ====== +-[source,Bash] +--------- +- # crm_shadow --create test +- Setting up shadow instance +- Type Ctrl-D to exit the crm_shadow shell +- shadow[test]: +- shadow[test] # crm_shadow --which +- test +--------- ++---- ++# crm_shadow --create test ++Setting up shadow instance ++Type Ctrl-D to exit the crm_shadow shell ++shadow[test]: ++shadow[test] # crm_shadow --which ++test ++---- + ====== + + From this point on, all cluster commands will automatically use the + shadow copy instead of talking to the cluster's active configuration. +-Once you have finished experimenting, you can either commit the +-changes, or discard them as shown below. Again, be sure to follow the +-on-screen instructions carefully. ++Once you have finished experimenting, you can either make the ++changes active via the `--commit` option, or discard them using the `--delete` ++option. Again, be sure to follow the on-screen instructions carefully! + +- + For a full list of `crm_shadow` options and +-commands, invoke it with the --help option. ++commands, invoke it with the `--help` option. + +-.Using a sandbox to make multiple changes atomically ++.Using a sandbox to make multiple changes atomically, discard them and verify the real configuration is untouched + ====== +-[source,Bash] +--------- ++---- + shadow[test] # crm_failcount -G -r rsc_c001n01 + name=fail-count-rsc_c001n01 value=0 +- shadow[test] # crm_standby -v on -n c001n02 +- shadow[test] # crm_standby -G -n c001n02 ++ shadow[test] # crm_standby -v on -N c001n02 ++ shadow[test] # crm_standby -G -N c001n02 + name=c001n02 scope=nodes value=on + shadow[test] # cibadmin --erase --force + shadow[test] # cibadmin --query +@@ -286,7 +311,7 @@ commands, invoke it with the --help option. + Now type Ctrl-D to exit the crm_shadow shell + shadow[test] # exit + # crm_shadow --which +- No shadow instance provided ++ No active shadow configuration defined + # cibadmin -Q + +@@ -295,38 +320,41 @@ commands, invoke it with the --help option. + + + +--------- ++---- + ====== + +-Making changes in a sandbox and verifying the real configuration is untouched +- + [[s-config-testing-changes]] + == Testing Your Configuration Changes == + + We saw previously how to make a series of changes to a "shadow" copy + of the configuration. Before loading the changes back into the +-cluster (eg. `crm_shadow --commit mytest --force`), it is often +-advisable to simulate the effect of the changes with +crm_simulate+, +-eg. ++cluster (e.g. `crm_shadow --commit mytest --force`), it is often ++advisable to simulate the effect of the changes with +crm_simulate+. ++For example: + +-[source,C] ++---- + # crm_simulate --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot ++---- + +- +-The tool uses the same library as the live cluster to show what it +-would have done given the supplied input. It's output, in addition to ++This tool uses the same library as the live cluster to show what it ++would have done given the supplied input. Its output, in addition to + a significant amount of logging, is stored in two files +tmp.graph+ +-and +tmp.dot+, both are representations of the same thing -- the ++and +tmp.dot+. Both files are representations of the same thing: the + cluster's response to your changes. + +-In the graph file is stored the complete transition, containing a list +-of all the actions, their parameters and their pre-requisites. +-Because the transition graph is not terribly easy to read, the tool +-also generates a Graphviz dot-file representing the same information. ++The graph file stores the complete transition from the existing cluster state ++to your desired new state, containing a list of all the actions, their ++parameters and their pre-requisites. Because the transition graph is not ++terribly easy to read, the tool also generates a Graphviz ++footnote:[Graph visualization software. See http://www.graphviz.org/ for details.] ++dot-file representing the same information. + +-== Interpreting the Graphviz output == ++For information on the options supported by `crm_simulate`, use ++its `--help` option. ++ ++.Interpreting the Graphviz output + * Arrows indicate ordering dependencies +- * Dashed-arrows indicate dependencies that are not present in the transition graph ++ * Dashed arrows indicate dependencies that are not present in the transition graph + * Actions with a dashed border of any color do not form part of the transition graph + * Actions with a green border form part of the transition graph + * Actions with a red border are ones the cluster would like to execute but cannot run +@@ -341,24 +369,21 @@ also generates a Graphviz dot-file representing the same information. + + image::images/Policy-Engine-small.png["An example transition graph as represented by Graphviz",width="16cm",height="6cm",align="center"] + +-In the above example, it appears that a new node, +pcmk-2+, has come +-online and that the cluster is checking to make sure +rsc1+, +rsc2+ +-and +rsc3+ are not already running there (Indicated by the +-+*_monitor_0+ entries). Once it did that, and assuming the resources +-were not active there, it would have liked to stop +rsc1+ and +rsc2+ +-on +pcmk-1+ and move them to +pcmk-2+. However, there appears to be ++In the above example, it appears that a new node, *pcmk-2*, has come ++online and that the cluster is checking to make sure *rsc1*, *rsc2* ++and *rsc3* are not already running there (Indicated by the ++*rscN_monitor_0* entries). Once it did that, and assuming the resources ++were not active there, it would have liked to stop *rsc1* and *rsc2* ++on *pcmk-1* and move them to *pcmk-2*. However, there appears to be + some problem and the cluster cannot or is not permitted to perform the + stop actions which implies it also cannot perform the start actions. +-For some reason the cluster does not want to start +rsc3+ anywhere. +- +-For information on the options supported by `crm_simulate`, use +-the `--help` option. ++For some reason the cluster does not want to start *rsc3* anywhere. + + === Complex Cluster Transition === + + image::images/Policy-Engine-big.png["Another, slightly more complex, transition graph that you're not expected to be able to read",width="16cm",height="20cm",align="center"] + +-== Do I Need to Update the Configuration on all Cluster Nodes? == ++== Do I Need to Update the Configuration on All Cluster Nodes? == + + No. Any changes are immediately synchronized to the other active + members of the cluster. +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt b/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt +index 8498ce0..cd722ff 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt +@@ -1,4 +1,4 @@ +-= Resource Constraints = ++= Resource Constraints = + + indexterm:[Resource,Constraints] + +@@ -9,19 +9,19 @@ Practically everything from moving a resource to deciding which + resource to stop in a degraded cluster is achieved by manipulating + scores in some way. + +-Scores are calculated on a per-resource basis and any node with a ++Scores are calculated on a per-resource basis, and any node with a + negative score for a resource can't run that resource. After + calculating the scores for a resource, the cluster then chooses the + node with the highest one. + + === Infinity Math === + +-+INFINITY+ is currently defined as 1,000,000 and addition/subtraction +-with it follows these three basic rules: ++Pacemaker implements +INFINITY+ internally as a score of 1,000,000. ++Addition/subtraction with it follows these three basic rules: + + * Any value + +INFINITY+ = +INFINITY+ +-* Any value - +INFINITY+ = -+INFINITY+ +-* +INFINITY+ - +INFINITY+ = -+INFINITY+ ++* Any value - +INFINITY+ = +-INFINITY+ ++* +INFINITY+ - +INFINITY+ = +-INFINITY+ + + == Deciding Which Nodes a Resource Can Run On == + +@@ -30,43 +30,76 @@ indexterm:[Resource,Constraints,Location] + There are two alternative strategies for specifying which nodes a + resources can run on. One way is to say that by default they can run + anywhere and then create location constraints for nodes that are not +-allowed. The other option is to have nodes "opt-in"... to start with ++allowed. The other option is to have nodes "opt-in" -- to start with + nothing able to run anywhere and selectively enable allowed nodes. +- +-=== Options === + +-.Options for Simple Location Constraints +-[width="95%",cols="2m,5<",options="header",align="center"] ++Whether you should choose opt-in or opt-out depends on your ++personal preference and the make-up of your cluster. If most of your ++resources can run on most of the nodes, then an opt-out arrangement is ++likely to result in a simpler configuration. On the other-hand, if ++most resources can only run on a small subset of nodes, an opt-in ++configuration might be simpler. ++ ++=== Location Properties === ++ ++.Properties for Simple Location Constraints ++[width="95%",cols="2m,1,5>). ++==== ++ ++=== Ordering Properties === ++ + .Properties of an Ordering Constraint +-[width="95%",cols="2m,5<",options="header",align="center"] ++[width="95%",cols="1m,1,4 +- +- ++ ++ + + ------- + ====== + +-Some additional information on ordering constraints can be found in +-the document http://clusterlabs.org/doc/Ordering_Explained.pdf[Ordering Explained]. ++Because the above example lets +symmetrical+ default to TRUE, +++Webserver+ must be stopped before +Database+ can be stopped, ++and +Webserver+ should be stopped before +IP+ ++if they both need to be stopped. + + [[s-resource-colocation]] + == Placing Resources Relative to other Resources == +@@ -255,10 +289,11 @@ indexterm:[Resource,Location Relative to other Resources] + When the location of one resource depends on the location of another + one, we call this colocation. + +-There is an important side-effect of creating a colocation constraint +-between two resources: it affects the order in which resources are +-assigned to a node. If you think about it, it's somewhat obvious. +-You can't place A relative to B unless you know where B is. ++Colocation has an important side-effect: it affects the order in which ++resources are assigned to a node. ++footnote:['Not' the order in which they are started. For that, see ++<>.] ++Think about it: You can't place A relative to B unless you know where B is. + footnote:[ + While the human brain is sophisticated enough to read the constraint + in any order and choose the correct one depending on the situation, +@@ -266,19 +301,18 @@ the cluster is not quite so smart. Yet. + ] + + So when you are creating colocation constraints, it is important to +-consider whether you should colocate A with B or B with A. ++consider whether you should colocate A with B, or B with A. + +-Another thing to keep in mind is that, assuming A is collocated with +-B, the cluster will also take into account A's preferences when ++Another thing to keep in mind is that, assuming A is colocated with ++B, the cluster will take into account A's preferences when + deciding which node to choose for B. + +-For a detailed look at exactly how this occurs, see the +-http://www.clusterlabs.org/mediawiki/images/6/61/Colocation_Explained.pdf[Colocation +-Explained] document. ++For a detailed look at exactly how this occurs, see ++http://clusterlabs.org/doc/Colocation_Explained.pdf[Colocation Explained]. + +-=== Options === ++=== Colocation Properties === + +-.Properties of a Collocation Constraint ++.Properties of a Colocation Constraint + [width="95%",cols="2m,5<",options="header",align="center"] + |========================================================= + +@@ -291,22 +325,20 @@ indexterm:[id,Colocation Constraints] + indexterm:[Constraints,Colocation,id] + + |rsc +-|The colocation source. If the constraint cannot be satisfied, the +- cluster may decide not to allow the resource to run at all. ++|The name of a resource that should be located relative to +with-rsc+. + indexterm:[rsc,Colocation Constraints] + indexterm:[Constraints,Colocation,rsc] + + |with-rsc +-|The colocation target. The cluster will decide where to put this +- resource first and then decide where to put the resource in the +rsc+ +- field. ++|The name of the resource used as the colocation target. The cluster will ++decide where to put this resource first and then decide where to put +rsc+. + indexterm:[with-rsc,Colocation Constraints] + indexterm:[Constraints,Colocation,with-rsc] + + |score +-|Positive values indicate the resource should run on the same +- node. Negative values indicate the resources should not run on the +- same node. Values of \+/- +INFINITY+ change "should" to "must". ++|Positive values indicate the resources should run on the same ++ node. Negative values indicate the resources should run on ++ different nodes. Values of \+/- +INFINITY+ change "should" to "must". + indexterm:[score,Colocation Constraints] + indexterm:[Constraints,Colocation,score] + +@@ -314,52 +346,61 @@ indexterm:[Constraints,Colocation,rsc] + + === Mandatory Placement === + +-Mandatory placement occurs any time the constraint's score is ++Mandatory placement occurs when the constraint's score is + ++INFINITY+ or +-INFINITY+. In such cases, if the constraint can't be + satisfied, then the +rsc+ resource is not permitted to run. For + +score=INFINITY+, this includes cases where the +with-rsc+ resource is + not active. + +-If you need +resource1+ to always run on the same machine as +-+resource2+, you would add the following constraint: ++If you need resource +A+ to always run on the same machine as ++resource +B+, you would add the following constraint: + +-.An example colocation constraint ++.Mandatory colocation constraint for two resources ++==== + [source,XML] +- ++ ++==== ++ ++Remember, because +INFINITY+ was used, if +B+ can't run on any ++of the cluster nodes (for whatever reason) then +A+ will not ++be allowed to run. Whether +A+ is running or not has no effect on +B+. + +-Remember, because +INFINITY+ was used, if +resource2+ can't run on any +-of the cluster nodes (for whatever reason) then +resource1+ will not +-be allowed to run. ++Alternatively, you may want the opposite -- that +A+ 'cannot' ++run on the same machine as +B+. In this case, use +++score="-INFINITY"+. + +-Alternatively, you may want the opposite... that +resource1+ cannot +-run on the same machine as +resource2+. In this case use +-+score="-INFINITY"+ +- +-.An example anti-colocation constraint ++.Mandatory anti-colocation constraint for two resources ++==== + [source,XML] +- ++ ++==== + +-Again, by specifying +-INFINTY+, the constraint is binding. So if the +-only place left to run is where +resource2+ already is, then +-+resource1+ may not run anywhere. ++Again, by specifying +-INFINITY+, the constraint is binding. So if the ++only place left to run is where +B+ already is, then +++A+ may not run anywhere. ++ ++As with +INFINITY+, +B+ can run even if +A+ is stopped. ++However, in this case +A+ also can run if +B+ is stopped, because it still ++meets the constraint of +A+ and +B+ not running on the same node. + + === Advisory Placement === + + If mandatory placement is about "must" and "must not", then advisory + placement is the "I'd prefer if" alternative. For constraints with + scores greater than +-INFINITY+ and less than +INFINITY+, the cluster +-will try and accommodate your wishes but may ignore them if the ++will try to accommodate your wishes but may ignore them if the + alternative is to stop some of the cluster resources. +- + +-Like in life, where if enough people prefer something it effectively ++As in life, where if enough people prefer something it effectively + becomes mandatory, advisory colocation constraints can combine with + other elements of the configuration to behave as if they were + mandatory. + +-.An example advisory-only colocation constraint ++.Advisory colocation constraint for two resources ++==== + [source,XML] +- ++ ++==== + + [[s-resource-sets-ordering]] + == Ordering Sets of Resources == +@@ -381,7 +422,7 @@ ordered resources, such as: + + .Visual representation of the four resources' start order for the above constraints + image::images/resource-set.png["Ordered set",width="16cm",height="2.5cm",align="center"] +- ++ + === Ordered Set === + + To simplify this situation, there is an alternate format for ordering +@@ -412,10 +453,10 @@ In some tools +create set A B+ is *NOT* equivalent to +create A then B+. + + While the set-based format is not less verbose, it is significantly + easier to get right and maintain. It can also be expanded to allow +-ordered sets of (un)ordered resources. In the example below, +rscA+ +-and +rscB+ can both start in parallel, as can +rscC+ and +rscD+, +-however +rscC+ and +rscD+ can only start once _both_ +rscA+ _and_ +- +rscB+ are active. ++ordered sets of (un)ordered resources. In the example below, +A+ ++and +B+ can both start in parallel, as can +C+ and +D+, ++however +C+ and +D+ can only start once _both_ +A+ _and_ ++ +B+ are active. + + .Ordered sets of unordered resources + ====== +@@ -435,7 +476,7 @@ however +rscC+ and +rscD+ can only start once _both_ +rscA+ _and_ + + ------- + ====== +- ++ + .Visual representation of the start order for two ordered sets of unordered resources + image::images/two-sets.png["Two ordered sets",width="13cm",height="7.5cm",align="center"] + +@@ -474,21 +515,21 @@ image::images/three-sets.png["Three ordered sets",width="16cm",height="7.5cm",al + + The unordered set logic discussed so far has all been "AND" logic. + To illustrate this take the 3 resource set figure in the previous section. +-Those sets can be expressed, +(A and B) then (C) then (D) then (E and F)+ ++Those sets can be expressed, +(A and B) then \(C) then (D) then (E and F)+. + +-Say for example we want change the first set, (A and B), to use "OR" logic +-so the sets look like this, +(A or B) then (C) then (D) then (E and F)+. ++Say for example we want to change the first set, +(A and B)+, to use "OR" logic ++so the sets look like this: +(A or B) then \(C) then (D) then (E and F)+. + This functionality can be achieved through the use of the +require-all+ +-option. By default this option is 'require-all=true' which is why the +-"AND" logic is used by default. Changing +require-all=false+ means only one ++option. This option defaults to TRUE which is why the ++"AND" logic is used by default. Setting +require-all=false+ means only one + resource in the set needs to be started before continuing on to the next set. + +-Note that the 'require-all=false' option only makes sense to use in conjunction +-with unordered sets, 'sequential=false'. Think of it like this, 'sequential=false' ++Note that the +require-all=false+ option only makes sense to use in conjunction ++with unordered sets, +sequential=false+. Think of it like this, +sequential=false+ + modifies the set to be an unordered set that uses "AND" logic by default, by adding +-'require-all=false' the unordered set's "AND" logic is flipped to "OR" logic. +++require-all=false+ the unordered set's "AND" logic is flipped to "OR" logic. + +-.Resource Set "OR" logic. Three ordered sets, where the first set is internally unordered with "OR" logic. ++.Resource Set "OR" logic: Three ordered sets, where the first set is internally unordered with "OR" logic + ====== + [source,XML] + ------- +@@ -513,41 +554,45 @@ modifies the set to be an unordered set that uses "AND" logic by default, by add + + + [[s-resource-sets-colocation]] +-== Collocating Sets of Resources == ++== Colocating Sets of Resources == + + Another common situation is for an administrator to create a set of +-collocated resources. Previously this was possible either by defining +-a resource group (See <>) which could not always +-accurately express the design; or by defining each relationship as an +-individual constraint, causing a constraint explosion as the number of +-resources and combinations grew. ++colocated resources. ++ ++One way to do this would be to define a resource group (see ++<>), but that cannot always accurately express the desired ++state. ++ ++Another way would be to define each relationship as an individual constraint, ++but that causes a constraint explosion as the number of resources and ++combinations grow. An example of this approach: + +-.A chain of collocated resources ++.Chain of colocated resources + ====== + [source,XML] + ------- + +- +- +- ++ ++ ++ + + ------- + ====== + + To make things easier, we allow an alternate form of colocation +-constraints using +resource_sets+. Just like the expanded version, a +-resource that can't be active also prevents any resource that must be +-collocated with it from being active. For example, if +B+ was not +-able to run, then both +C+ (and by inference +D+) must also remain +-stopped. ++constraints using +resource_set+. As with the chained version, a ++resource that can't be active prevents any resource that must be ++colocated with it from being active. For example, if +C+ is not ++able to run, then both +B+ and by inference +A+ must also remain ++stopped. Here is an example +resource_set+: + +-.The equivalent colocation chain expressed using +resource_sets+ ++.Equivalent colocation chain expressed using +resource_set+ + ====== + [source,XML] + ------- + + +- ++ + + + +@@ -561,38 +606,27 @@ stopped. + [WARNING] + ========= + Always pay attention to how your tools expose this functionality. +-In some tools +create set A B+ is *NOT* equivalent to +create A with B+. ++In some tools +create set A B+ is 'not' equivalent to +create A with B+. + ========= + +-.A group resource with the equivalent colocation rules +-[source,XML] +-------- +- +- +- +- +- +- +-------- +- +-This notation can also be used in this context to tell the cluster ++This notation can also be used to tell the cluster + that a set of resources must all be located with a common peer, but +-have no dependencies on each other. In this scenario, unlike the +-previous, +B would+ be allowed to remain active even if +A or+ +C+ (or ++have no dependencies on each other. In this scenario, unlike the ++previous, +B+ 'would' be allowed to remain active even if +A+ or +C+ (or + both) were inactive. + +-.Using colocation sets to specify a common peer. ++.Using colocation sets to specify a common peer + ====== + [source,XML] + ------- + + +- ++ + + + + +- ++ + + + +@@ -600,30 +634,30 @@ both) were inactive. + ------- + ====== + +-Of course there is no limit to the number and size of the sets used. +-The only thing that matters is that in order for any member of set N +-to be active, all the members of set N+1 must also be active (and +-naturally on the same node); and if a set has +sequential="true"+, +-then in order for member M to be active, member M+1 must also be +-active. You can even specify the role in which the members of a set +-must be in using the set's role attribute. +- +-.A colocation chain where the members of the middle set have no inter-dependencies and the last has master status. ++There is no inherent limit to the number and size of the sets used. ++The only thing that matters is that in order for any member of one set ++in the constraint to be active, all members of sets listed after it must also ++be active (and naturally on the same node); and if a set has +sequential="true"+, ++then in order for one member of that set to be active, all members listed after it ++must also be active. You can even specify the role in which the members of a set ++must be in using the set's +role+ attribute. ++ ++.A colocation chain where the members of the middle set have no interdependencies and the last has master status. + ====== + [source,XML] + ------- + + +- ++ + + + +- ++ + + + + +- ++ + + + +@@ -631,6 +665,6 @@ must be in using the set's role attribute. + + ------- + ====== +- ++ + .Visual representation of a colocation chain where the members of the middle set have no inter-dependencies + image::images/three-sets-complex.png["Colocation chain",width="16cm",height="9cm",align="center"] +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Intro.txt b/doc/Pacemaker_Explained/en-US/Ch-Intro.txt +index fd05c81..e610651 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Intro.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Intro.txt +@@ -15,150 +15,9 @@ footnote:[I hope, however, that the concepts explained here make the functionali + Additionally, this document is NOT a step-by-step how-to guide for + configuring a specific clustering scenario. + +-Although such guides exist, the purpose of this document is to provide +-an understanding of the building blocks that can be used to construct +-any type of Pacemaker cluster. ++Although such guides exist, ++footnote:[For example, see the http://www.clusterlabs.org/doc/[Clusters from Scratch] guide.] ++the purpose of this document is to provide an understanding of the building ++blocks that can be used to construct any type of Pacemaker cluster. + +-== What Is Pacemaker? == +- +-Pacemaker is a cluster resource manager. +- +-It achieves maximum availability for your cluster services +-(aka. resources) by detecting and recovering from node and +-resource-level failures by making use of the messaging and membership +-capabilities provided by your preferred cluster infrastructure (either +-http://www.corosync.org/[Corosync] or +-http://linux-ha.org/wiki/Heartbeat[Heartbeat]). +- +-Pacemaker's key features include: +- +- * Detection and recovery of node and service-level failures +- * Storage agnostic, no requirement for shared storage +- * Resource agnostic, anything that can be scripted can be clustered +- * Supports STONITH for ensuring data integrity +- * Supports large and small clusters +- * Supports both quorate and resource driven clusters +- * Supports practically any redundancy configuration +- * Automatically replicated configuration that can be updated from any node +- * Ability to specify cluster-wide service ordering, colocation and anti-colocation +- * Support for advanced service types +- ** Clones: for services which need to be active on multiple nodes +- ** Multi-state: for services with multiple modes (eg. master/slave, primary/secondary) +- * Unified, scriptable, cluster management tools. +- +-== Pacemaker Architecture == +- +-At the highest level, the cluster is made up of three pieces: +- +- * Non-cluster aware components. These pieces +- include the resources themselves, scripts that start, stop and +- monitor them, and also a local daemon that masks the differences +- between the different standards these scripts implement. +- +- * Resource management. Pacemaker provides the brain that processes +- and reacts to events regarding the cluster. These events include +- nodes joining or leaving the cluster; resource events caused by +- failures, maintenance, scheduled activities; and other +- administrative actions. Pacemaker will compute the ideal state of +- the cluster and plot a path to achieve it after any of these +- events. This may include moving resources, stopping nodes and even +- forcing them offline with remote power switches. +- +- * Low level infrastructure. Projects like Corosync, CMAN and +- Heartbeat provide reliable messaging, membership and quorum +- information about the cluster. +- +-When combined with Corosync, Pacemaker also supports popular open +-source cluster filesystems. +-footnote:[ +-Even though Pacemaker also supports Heartbeat, the filesystems need to +-use the stack for messaging and membership and Corosync seems to be +-what they're standardizing on. +- +-Technically it would be possible for them to support Heartbeat as +-well, however there seems little interest in this. +-] +- +-Due to past standardization within the cluster filesystem community, +-they make use of a common distributed lock manager which makes use of +-Corosync for its messaging and membership capabilities (which nodes +-are up/down) and Pacemaker for fencing services. +- +-.The Pacemaker Stack +-image::images/pcmk-stack.png["The Pacemaker stack",width="10cm",height="7.5cm",align="center"] +- +-=== Internal Components === +- +-Pacemaker itself is composed of five key components: +- +- * CIB (aka. Cluster Information Base) +- * CRMd (aka. Cluster Resource Management daemon) +- * LRMd (aka. Local Resource Management daemon) +- * PEngine (aka. PE or Policy Engine) +- * STONITHd +- +-.Internal Components +-image::images/pcmk-internals.png["Subsystems of a Pacemaker cluster",align="center",scaledwidth="65%"] +- +-The CIB uses XML to represent both the cluster's configuration and +-current state of all resources in the cluster. The contents of the CIB +-are automatically kept in sync across the entire cluster and are used +-by the PEngine to compute the ideal state of the cluster and how it +-should be achieved. +- +-This list of instructions is then fed to the DC (Designated +-Controller). Pacemaker centralizes all cluster decision making by +-electing one of the CRMd instances to act as a master. Should the +-elected CRMd process, or the node it is on, fail... a new one is +-quickly established. +- +-The DC carries out the PEngine's instructions in the required order by +-passing them to either the LRMd (Local Resource Management daemon) or +-CRMd peers on other nodes via the cluster messaging infrastructure +-(which in turn passes them on to their LRMd process). +- +-The peer nodes all report the results of their operations back to the +-DC and, based on the expected and actual results, will either execute +-any actions that needed to wait for the previous one to complete, or +-abort processing and ask the PEngine to recalculate the ideal cluster +-state based on the unexpected results. +- +-In some cases, it may be necessary to power off nodes in order to +-protect shared data or complete resource recovery. For this Pacemaker +-comes with STONITHd. +- +-STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is +-usually implemented with a remote power switch. +- +-In Pacemaker, STONITH devices are modeled as resources (and configured +-in the CIB) to enable them to be easily monitored for failure, however +-STONITHd takes care of understanding the STONITH topology such that +-its clients simply request a node be fenced and it does the rest. +- +-== Types of Pacemaker Clusters == +- +-Pacemaker makes no assumptions about your environment, this allows it +-to support practically any +-http://en.wikipedia.org/wiki/High-availability_cluster#Node_configurations[redundancy +-configuration] including Active/Active, Active/Passive, N+1, N+M, +-N-to-1 and N-to-N. +- +-.Active/Passive Redundancy +-image::images/pcmk-active-passive.png["Active/Passive Redundancy",width="10cm",height="7.5cm",align="center"] +- +-Two-node Active/Passive clusters using Pacemaker and DRBD are a +-cost-effective solution for many High Availability situations. +- +-.Shared Failover +-image::images/pcmk-shared-failover.png["Shared Failover",width="10cm",height="7.5cm",align="center"] +- +-By supporting many nodes, Pacemaker can dramatically reduce hardware +-costs by allowing several active/passive clusters to be combined and +-share a common backup node +- +-.N to N Redundancy +-image::images/pcmk-active-active.png["N to N Redundancy",width="10cm",height="7.5cm",align="center"] +- +-When shared storage is available, every node can potentially be used +-for failover. Pacemaker can even run multiple copies of services to +-spread out the workload. ++include::../../shared/en-US/pacemaker-intro.txt[] +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Multi-site-Clusters.txt b/doc/Pacemaker_Explained/en-US/Ch-Multi-site-Clusters.txt +index efd2f7a..5ca6cd0 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Multi-site-Clusters.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Multi-site-Clusters.txt +@@ -1,68 +1,61 @@ + = Multi-Site Clusters and Tickets = + +-[[Multisite]] +-== Abstract == + Apart from local clusters, Pacemaker also supports multi-site clusters. +-That means you can have multiple, geographically dispersed sites with a +-local cluster each. Failover between these clusters can be coordinated +-by a higher level entity, the so-called `CTR (Cluster Ticket Registry)`. +- ++That means you can have multiple, geographically dispersed sites, each with a ++local cluster. Failover between these clusters can be coordinated ++manually by the administrator, or automatically by a higher-level entity called ++a 'Cluster Ticket Registry (CTR)'. + + == Challenges for Multi-Site Clusters == + + Typically, multi-site environments are too far apart to support +-synchronous communication between the sites and synchronous data +-replication. That leads to the following challenges: ++synchronous communication and data replication between the sites. ++That leads to significant challenges: + +-- How to make sure that a cluster site is up and running? ++- How do we make sure that a cluster site is up and running? + +-- How to make sure that resources are only started once? ++- How do we make sure that resources are only started once? + +-- How to make sure that quorum can be reached between the different +-sites and a split brain scenario can be avoided? ++- How do we make sure that quorum can be reached between the different ++sites and a split-brain scenario avoided? + +-- How to manage failover between the sites? ++- How do we manage failover between sites? + +-- How to deal with high latency in case of resources that need to be ++- How do we deal with high latency in case of resources that need to be + stopped? + + In the following sections, learn how to meet these challenges. + +- + == Conceptual Overview == + + Multi-site clusters can be considered as “overlay” clusters where + each cluster site corresponds to a cluster node in a traditional cluster. +-The overlay cluster can be managed by a `CTR (Cluster Ticket Registry)` +-mechanism. It guarantees that the cluster resources will be highly +-available across different cluster sites. This is achieved by using +-so-called `tickets` that are treated as failover domain between cluster ++The overlay cluster can be managed by a CTR in order to ++guarantee that any cluster resource will be active ++on no more than one cluster site. This is achieved by using ++'tickets' that are treated as failover domain between cluster + sites, in case a site should be down. + +-The following list explains the individual components and mechanisms ++The following sections explain the individual components and mechanisms + that were introduced for multi-site clusters in more detail. + ++=== Ticket === + +-=== Components and Concepts === +- +-==== Ticket ==== +- +-"Tickets" are, essentially, cluster-wide attributes. A ticket grants the ++Tickets are, essentially, cluster-wide attributes. A ticket grants the + right to run certain resources on a specific cluster site. Resources can +-be bound to a certain ticket by `rsc_ticket` dependencies. Only if the +-ticket is available at a site, the respective resources are started. ++be bound to a certain ticket by +rsc_ticket+ constraints. Only if the ++ticket is available at a site can the respective resources be started there. + Vice versa, if the ticket is revoked, the resources depending on that +-ticket need to be stopped. +- +-The ticket thus is similar to a 'site quorum'; i.e., the permission to +-manage/own resources associated with that site. ++ticket must be stopped. + +-(One can also think of the current `have-quorum` flag as a special, cluster-wide +-ticket that is granted in case of node majority.) ++The ticket thus is similar to a 'site quorum', i.e. the permission to ++manage/own resources associated with that site. (One can also think of the ++current +have-quorum+ flag as a special, cluster-wide ticket that is granted in ++case of node majority.) + +-These tickets can be granted/revoked either manually by administrators +-(which could be the default for the classic enterprise clusters), or via +-an automated `CTR` mechanism described further below. ++Tickets can be granted and revoked either manually by administrators ++(which could be the default for classic enterprise clusters), or via ++the automated CTR mechanism described below. + + A ticket can only be owned by one site at a time. Initially, none + of the sites has a ticket. Each ticket must be granted once by the cluster +@@ -70,58 +63,60 @@ administrator. + + The presence or absence of tickets for a site is stored in the CIB as a + cluster status. With regards to a certain ticket, there are only two states +-for a site: `true` (the site has the ticket) or `false` (the site does ++for a site: +true+ (the site has the ticket) or +false+ (the site does + not have the ticket). The absence of a certain ticket (during the initial +-state of the multi-site cluster) is also reflected by the value `false`. ++state of the multi-site cluster) is the same as the value +false+. + ++=== Dead Man Dependency === + +-==== Dead Man Dependency ==== +- +-A site can only activate the resources safely if it can be sure that the ++A site can only activate resources safely if it can be sure that the + other site has deactivated them. However after a ticket is revoked, it can + take a long time until all resources depending on that ticket are stopped + "cleanly", especially in case of cascaded resources. To cut that process +-short, the concept of a `Dead Man Dependency` was introduced: ++short, the concept of a 'Dead Man Dependency' was introduced. + +-- If the ticket is revoked from a site, the nodes that are hosting +-dependent resources are fenced. This considerably speeds up the recovery +-process of the cluster and makes sure that resources can be migrated more +-quickly. ++If a dead man dependency is in force, if a ticket is revoked from a site, the ++nodes that are hosting dependent resources are fenced. This considerably speeds ++up the recovery process of the cluster and makes sure that resources can be ++migrated more quickly. + +-This can be configured by specifying a `loss-policy="fence"` in +-`rsc_ticket` constraints. ++This can be configured by specifying a +loss-policy="fence"+ in +++rsc_ticket+ constraints. + ++=== Cluster Ticket Registry === + +-==== CTR (Cluster Ticket Registry) ==== ++A CTR is a coordinated group of network daemons that automatically handles ++granting, revoking, and timing out tickets (instead of the administrator ++revoking the ticket somewhere, waiting for everything to stop, and then ++granting it on the desired site). + +-This is for those scenarios where the tickets management is supposed to +-be automatic (instead of the administrator revoking the ticket somewhere, +-waiting for everything to stop, and then granting it on the desired site). ++Pacemaker does not implement its own CTR, but interoperates with external ++software designed for that purpose (similar to how resource and fencing agents ++are not directly part of pacemaker). + +-A `CTR` is a network daemon that handles granting, +-revoking, and timing out "tickets". The participating clusters would run +-the daemons that would connect to each other, exchange information on +-their connectivity details, and vote on which site gets which ticket(s). ++Participating clusters run the CTR daemons, which connect to each other, exchange ++information about their connectivity, and vote on which sites gets which ++tickets. + +-A ticket would only be granted to a site once they can be sure that it +-has been relinquished by the previous owner, which would need to be +-implemented via a timer in most scenarios. If a site loses connection +-to its peers, its tickets time out and recovery occurs. After the +-connection timeout plus the recovery timeout has passed, the other sites +-are allowed to re-acquire the ticket and start the resources again. ++A ticket is granted to a site only once the CTR is sure that the ticket ++has been relinquished by the previous owner, implemented via a timer in most ++scenarios. If a site loses connection to its peers, its tickets time out and ++recovery occurs. After the connection timeout plus the recovery timeout has ++passed, the other sites are allowed to re-acquire the ticket and start the ++resources again. + + This can also be thought of as a "quorum server", except that it is not + a single quorum ticket, but several. + ++=== Configuration Replication === + +-==== Configuration Replication ==== +- +-As usual, the CIB is synchronized within each cluster, but it is not synchronized ++As usual, the CIB is synchronized within each cluster, but it is 'not' synchronized + across cluster sites of a multi-site cluster. You have to configure the resources + that will be highly available across the multi-site cluster for every site + accordingly. + + ++[[s-ticket-constraints]] + == Configuring Ticket Dependencies == + + The `rsc_ticket` constraint lets you specify the resources depending on a certain +@@ -130,67 +125,72 @@ what should happen to the respective resources if the ticket is revoked. + + The attribute `loss-policy` can have the following values: + +-fence:: Fence the nodes that are running the relevant resources. +- +-stop:: Stop the relevant resources. ++* +fence:+ Fence the nodes that are running the relevant resources. + +-freeze:: Do nothing to the relevant resources. ++* +stop:+ Stop the relevant resources. + +-demote:: Demote relevant resources that are running in master mode to slave mode. ++* +freeze:+ Do nothing to the relevant resources. + ++* +demote:+ Demote relevant resources that are running in master mode to slave mode. + +-An example to configure a `rsc_ticket` constraint: + ++.Constraint that fences node if +ticketA+ is revoked ++==== + [source,XML] + ------- + + ------- ++==== + +-This creates a constraint with the ID `rsc1-req-ticketA`. It defines that the +-resource `rsc1` depends on `ticketA` and that the node running the resource should +-be fenced in case `ticketA` is revoked. ++The example above creates a constraint with the ID +rsc1-req-ticketA+. It ++defines that the resource +rsc1+ depends on +ticketA+ and that the node running ++the resource should be fenced if +ticketA+ is revoked. + +-If resource `rsc1` was a multi-state resource that can run in master or +-slave mode, you may want to configure that only `rsc1's` master mode +-depends on `ticketA`. With the following configuration, `rsc1` will be +-demoted to slave mode if `ticketA` is revoked: ++If resource +rsc1+ were a multi-state resource (i.e. it could run in master or ++slave mode), you might want to configure that only master mode ++depends on +ticketA+. With the following configuration, +rsc1+ will be ++demoted to slave mode if +ticketA+ is revoked: + ++.Constraint that demotes +rsc1+ if +ticketA+ is revoked ++==== + [source,XML] + ------- + + ------- ++==== + +-You can create more `rsc_ticket` constraints to let multiple resources +-depend on the same ticket. +- +-`rsc_ticket` also supports resource sets. So one can easily list all the +-resources in one `rsc_ticket` constraint. For example: ++You can create multiple `rsc_ticket` constraints to let multiple resources ++depend on the same ticket. However, `rsc_ticket` also supports resource sets, ++so one can easily list all the resources in one `rsc_ticket` constraint instead. + ++.Ticket constraint for multiple resources ++==== + [source,XML] + ------- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + ------- ++==== + +-In the example, there are two resource sets for listing the resources with +-different `roles` in one `rsc_ticket` constraint. There's no dependency +-between the two resource sets. And there's no dependency among the ++In the example above, there are two resource sets, so we can list resources ++with different roles in a single +rsc_ticket+ constraint. There's no dependency ++between the two resource sets, and there's no dependency among the + resources within a resource set. Each of the resources just depends on +-`ticketA`. +++ticketA+. + +-Referencing resource templates in `rsc_ticket` constraints, and even ++Referencing resource templates in +rsc_ticket+ constraints, and even + referencing them within resource sets, is also supported. + + If you want other resources to depend on further tickets, create as many +-constraints as necessary with `rsc_ticket`. ++constraints as necessary with +rsc_ticket+. + + + == Managing Multi-Site Clusters == +@@ -198,43 +198,59 @@ constraints as necessary with `rsc_ticket`. + === Granting and Revoking Tickets Manually === + + You can grant tickets to sites or revoke them from sites manually. +-Though if you want to re-distribute a ticket, you should wait for +-the dependent resources to cleanly stop at the previous site before you +-grant the ticket to another desired site. ++If you want to re-distribute a ticket, you should wait for ++the dependent resources to stop cleanly at the previous site before you ++grant the ticket to the new site. + + Use the `crm_ticket` command line tool to grant and revoke tickets. + + To grant a ticket to this site: +-[source,C] + ------- + # crm_ticket --ticket ticketA --grant + ------- + + To revoke a ticket from this site: +-[source,C] + ------- + # crm_ticket --ticket ticketA --revoke + ------- + + [IMPORTANT] + ==== +-If you are managing tickets manually. Use the `crm_ticket` command with +-great care as they cannot help verify if the same ticket is already ++If you are managing tickets manually, use the `crm_ticket` command with ++great care, because it cannot check whether the same ticket is already + granted elsewhere. +- + ==== + + + === Granting and Revoking Tickets via a Cluster Ticket Registry === + +-==== Booth ==== +-Booth is an implementation of `Cluster Ticket Registry` or so-called +-`Cluster Ticket Manager`. ++We will use https://github.com/ClusterLabs/booth[Booth] here as an example of ++software that can be used with pacemaker as a Cluster Ticket Registry. Booth ++implements the ++http://en.wikipedia.org/wiki/Raft_%28computer_science%29[Raft] ++algorithm to guarantee the distributed consensus among different ++cluster sites, and manages the ticket distribution (and thus the failover ++process between sites). + +-Booth is the instance managing the ticket distribution and thus, +-the failover process between the sites of a multi-site cluster. Each of +-the participating clusters and arbitrators runs a service, the boothd. +-It connects to the booth daemons running at the other sites and ++Each of the participating clusters and 'arbitrators' runs the Booth daemon ++`boothd`. ++ ++An 'arbitrator' is the multi-site equivalent of a quorum-only node in a local ++cluster. If you have a setup with an even number of sites, ++you need an additional instance to reach consensus about decisions such ++as failover of resources across sites. In this case, add one or more ++arbitrators running at additional sites. Arbitrators are single machines ++that run a booth instance in a special mode. An arbitrator is especially ++important for a two-site scenario, otherwise there is no way for one site ++to distinguish between a network failure between it and the other site, and ++a failure of the other site. ++ ++The most common multi-site scenario is probably a multi-site cluster with two ++sites and a single arbitrator on a third site. However, technically, there are ++no limitations with regards to the number of sites and the number of ++arbitrators involved. ++ ++`Boothd` at each site connects to its peers running at the other sites and + exchanges connectivity details. Once a ticket is granted to a site, the + booth mechanism will manage the ticket automatically: If the site which + holds the ticket is out of service, the booth daemons will vote which +@@ -249,113 +265,68 @@ resources before will be treated according to the `loss-policy` you set + within the `rsc_ticket` constraint. + + Before the booth can manage a certain ticket within the multi-site cluster, +-you initially need to grant it to a site manually via `booth client` command. +-After you have initially granted a ticket to a site, the booth mechanism ++you initially need to grant it to a site manually via the `booth` command-line ++tool. After you have initially granted a ticket to a site, `boothd` + will take over and manage the ticket automatically. + + [IMPORTANT] + ==== +-The `booth client` command line tool can be used to grant, list, or +-revoke tickets. The `booth client` commands work on any machine where +-the booth daemon is running. +- +-If you are managing tickets via `Booth`, only use `booth client` for manual +-intervention instead of `crm_ticket`. That can make sure the same ticket ++The `booth` command-line tool can be used to grant, list, or ++revoke tickets and can be run on any machine where `boothd` is running. ++If you are managing tickets via Booth, use only `booth` for manual ++intervention, not `crm_ticket`. That ensures the same ticket + will only be owned by one cluster site at a time. + ==== + +-Booth includes an implementation of +-http://en.wikipedia.org/wiki/Paxos_algorithm['Paxos'] and 'Paxos Lease' +-algorithm, which guarantees the distributed consensus among different +-cluster sites. +- +-[NOTE] +-==== +-`Arbitrator` +- +-Each site runs one booth instance that is responsible for communicating +-with the other sites. If you have a setup with an even number of sites, +-you need an additional instance to reach consensus about decisions such +-as failover of resources across sites. In this case, add one or more +-arbitrators running at additional sites. Arbitrators are single machines +-that run a booth instance in a special mode. As all booth instances +-communicate with each other, arbitrators help to make more reliable +-decisions about granting or revoking tickets. +- +-An arbitrator is especially important for a two-site scenario: For example, +-if site `A` can no longer communicate with site `B`, there are two possible +-causes for that: +- +-- `A` network failure between `A` and `B`. +- +-- Site `B` is down. +- +-However, if site `C` (the arbitrator) can still communicate with site `B`, +-site `B` must still be up and running. +- +-==== +- +-===== Requirements ===== +- +-- All clusters that will be part of the multi-site cluster must be based on Pacemaker. +- +-- Booth must be installed on all cluster nodes and on all arbitrators that will +-be part of the multi-site cluster. ++==== Booth Requirements ==== + +-The most common scenario is probably a multi-site cluster with two sites and a +-single arbitrator on a third site. However, technically, there are no limitations +-with regards to the number of sites and the number of arbitrators involved. ++* All clusters that will be part of the multi-site cluster must be based on ++ Pacemaker. + +-Nodes belonging to the same cluster site should be synchronized via NTP. However, +-time synchronization is not required between the individual cluster sites. ++* Booth must be installed on all cluster nodes and on all arbitrators that will ++ be part of the multi-site cluster. + ++* Nodes belonging to the same cluster site should be synchronized via NTP. However, ++ time synchronization is not required between the individual cluster sites. + + === General Management of Tickets === + + Display the information of tickets: +-[source,C] + ------- + # crm_ticket --info + ------- + + Or you can monitor them with: +-[source,C] + ------- + # crm_mon --tickets + ------- + +-Display the rsc_ticket constraints that apply to a ticket: +-[source,C] ++Display the +rsc_ticket+ constraints that apply to a ticket: + ------- + # crm_ticket --ticket ticketA --constraints + ------- + +-When you want to do maintenance or manual switch-over of a ticket, the +-ticket could be revoked from the site for any reason, which would +-trigger the loss-policies. If `loss-policy="fence"`, the dependent +-resources could not be gracefully stopped/demoted, and even, other +-unrelated resources could be impacted. ++When you want to do maintenance or manual switch-over of a ticket, ++revoking the ticket would trigger the loss policies. If +++loss-policy="fence"+, the dependent resources could not be gracefully ++stopped/demoted, and other unrelated resources could even be affected. + +-The proper way is making the ticket `standby` first with: +-[source,C] ++The proper way is making the ticket 'standby' first with: + ------- + # crm_ticket --ticket ticketA --standby + ------- + + Then the dependent resources will be stopped or demoted gracefully without +-triggering the loss-policies. ++triggering the loss policies. + + If you have finished the maintenance and want to activate the ticket again, + you can run: +-[source,C] + ------- + # crm_ticket --ticket ticketA --activate + ------- + + == For more information == + +-`Multi-site Clusters` +-http://doc.opensuse.org/products/draft/SLE-HA/SLE-ha-guide_sd_draft/cha.ha.geo.html ++* https://www.suse.com/documentation/sle-ha-geo-12/art_ha_geo_quick/data/art_ha_geo_quick.html[SUSE's Geo Clustering quick start] + +-`Booth` +-https://github.com/ClusterLabs/booth ++* https://github.com/ClusterLabs/booth[Booth] +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Nodes.txt b/doc/Pacemaker_Explained/en-US/Ch-Nodes.txt +index 16bf13d..c7f1005 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Nodes.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Nodes.txt +@@ -27,28 +27,31 @@ to read an existing UUID or define a value before the cluster starts. + + Traditionally, Pacemaker required nodes to be referred to by the value + returned by `uname -n`. This can be problematic for services that +-require the `uname -n` to be a specific value (ie. for a licence ++require the `uname -n` to be a specific value (e.g. for a licence + file). + +-Since version 2.0.0 of Pacemaker, this requirement has been relaxed +-for clusters using Corosync 2.0 or later. The name Pacemaker uses is: ++This requirement has been relaxed for clusters using Corosync 2.0 or later. ++The name Pacemaker uses is: + +-. The value stored in 'corosync.conf' under +ring0_addr+ in the +nodelist+, if it does not contain an IP address; otherwise +-. The value stored in 'corosync.conf' under +name+ in the +nodelist+; otherwise ++. The value stored in +corosync.conf+ under *ring0_addr* in the *nodelist*, if it does not contain an IP address; otherwise ++. The value stored in +corosync.conf+ under *name* in the *nodelist*; otherwise + . The value of `uname -n` + + Pacemaker provides the `crm_node -n` command which displays the name + used by a running cluster. + +-If a Corosync nodelist is used, `crm_node --name-for-id $number` is also ++If a Corosync *nodelist* is used, `crm_node --name-for-id` pass:[number] is also + available to display the name used by the node with the corosync +-+nodeid+ of '$number', for example: `crm_node --name-for-id 2`. ++*nodeid* of pass:[number], for example: `crm_node --name-for-id 2`. + + [[s-node-attributes]] +-== Describing a Cluster Node == ++== Node Attributes == + + indexterm:[Node,attribute] +-Beyond the basic definition of a node the administrator can also ++'Node attributes' are a special type of option (name-value pair) that ++applies to a node object. ++ ++Beyond the basic definition of a node, the administrator can + describe the node's attributes, such as how much RAM, disk, what OS or + kernel version it has, perhaps even its physical location. This + information can then be used by the cluster when deciding where to +@@ -60,47 +63,51 @@ when the cluster is running, using `crm_attribute`. + + Below is what the node's definition would look like if the admin ran the command: + +-.The result of using crm_attribute to specify which kernel pcmk-1 is running ++.Result of using crm_attribute to specify which kernel pcmk-1 is running + ====== +-[source,C] + ------- +-# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r` ++# crm_attribute --type nodes --node pcmk-1 --name kernel --update $(uname -r) + ------- + [source,XML] + ------- + + +- ++ + + + ------- + ====== +-A simpler way to determine the current value of an attribute is to use `crm_attribute` command again: ++Rather than having to read the XML, a simpler way to determine the current ++value of an attribute is to use `crm_attribute` again: + +-[source,C] +-# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value ++---- ++# crm_attribute --type nodes --node pcmk-1 --name kernel --query ++scope=nodes name=kernel value=3.10.0-123.13.2.el7.x86_64 ++---- + + By specifying `--type nodes` the admin tells the cluster that this + attribute is persistent. There are also transient attributes which + are kept in the status section which are "forgotten" whenever the node + rejoins the cluster. The cluster uses this area to store a record of +-how many times a resource has failed on that node but administrators ++how many times a resource has failed on that node, but administrators + can also read and write to this section by specifying `--type status`. + +-== Corosync == ++== Managing Nodes in a Corosync-Based Cluster == + + === Adding a New Corosync Node === + + indexterm:[Corosync,Add Cluster Node] + indexterm:[Add Cluster Node,Corosync] + +-Adding a new node is as simple as installing Corosync and Pacemaker, +-and copying '/etc/corosync/corosync.conf' and '/etc/corosync/authkey' (if +-it exists) from an existing node. You may need to modify the +-+mcastaddr+ option to match the new node's IP address. ++To add a new node: + +-If a log message containing "Invalid digest" appears from Corosync, +-the keys are not consistent between the machines. ++. Install Corosync and Pacemaker on the new host. ++. Copy +/etc/corosync/corosync.conf+ and +/etc/corosync/authkey+ (if it exists) ++ from an existing node. You may need to modify the *mcastaddr* option to match ++ the new node's IP address. ++. Start the cluster software on the new host. If a log message containing ++ "Invalid digest" appears from Corosync, the keys are not consistent between ++ the machines. + + === Removing a Corosync Node === + +@@ -108,26 +115,24 @@ indexterm:[Corosync,Remove Cluster Node] + indexterm:[Remove Cluster Node,Corosync] + + Because the messaging and membership layers are the authoritative +-source for cluster nodes, deleting them from the CIB is not a reliable +-solution. First one must arrange for corosync to forget about the +-node (_pcmk-1_ in the example below). +- +-On the host to be removed: +- +-. Stop the cluster: `/etc/init.d/corosync stop` +- +-Next, from one of the remaining active cluster nodes: +- +-. Tell Pacemaker to forget about the removed host: ++source for cluster nodes, deleting them from the CIB is not a complete ++solution. First, one must arrange for corosync to forget about the ++node (*pcmk-1* in the example below). ++ ++. Stop the cluster on the host to be removed. How to do this will vary with ++ your operating system and installed versions of cluster software, for example, ++ `pcs cluster stop` if you are using pcs for cluster management, or ++ `service corosync stop` on a host using corosync 1.x with the pacemaker plugin. ++. From one of the remaining active cluster nodes, tell Pacemaker to forget ++ about the removed host, which will also delete the node from the CIB: + + +-[source,C] ++---- + # crm_node -R pcmk-1 +-+ +-This includes deleting the node from the CIB ++---- + + [NOTE] + ====== +-This proceedure only works for versions after 1.1.8 ++This procedure only works for pacemaker 1.1.8 and later. + ====== + + === Replacing a Corosync Node === +@@ -135,18 +140,14 @@ This proceedure only works for versions after 1.1.8 + indexterm:[Corosync,Replace Cluster Node] + indexterm:[Replace Cluster Node,Corosync] + +-The five-step guide to replacing an existing cluster node: +- +-. Make sure the old node is completely stopped +-. Give the new machine the same hostname and IP address as the old one +-. Install the cluster software :-) +-. Copy '/etc/corosync/corosync.conf' and '/etc/corosync/authkey' (if it exists) to the new node +-. Start the new cluster node ++To replace an existing cluster node: + +-If a log message containing "Invalid digest" appears from Corosync, +-the keys are not consistent between the machines. ++. Make sure the old node is completely stopped. ++. Give the new machine the same hostname and IP address as the old one. ++. Follow the procedure above for adding a node. + +-== CMAN == ++//// ++== Managing Nodes in a CMAN-based Cluster == + + === Adding a New CMAN Node === + +@@ -157,20 +158,25 @@ indexterm:[Add Cluster Node,CMAN] + + indexterm:[CMAN,Remove Cluster Node] + indexterm:[Remove Cluster Node,CMAN] ++//// + +-== Heartbeat == ++== Managing Nodes in a Heartbeat-based Cluster == + + === Adding a New Heartbeat Node === + + indexterm:[Heartbeat,Add Cluster Node] + indexterm:[Add Cluster Node,Heartbeat] + +-Provided you specified +autojoin any+ in 'ha.cf', adding a new node is +-as simple as installing heartbeat and copying 'ha.cf' and 'authkeys' +-from an existing node. ++To add a new node: + +-If you don't want to use +autojoin+, then after setting up 'ha.cf' and +-'authkeys', you must use `hb_addnode` before starting the new node. ++. Install heartbeat and pacemaker on the new host. ++. Copy +ha.cf+ and +authkeys+ from an existing node. ++. If you do not use *autojoin any* in +ha.cf+, run: +++ ++---- ++hb_addnode $(uname -n) ++---- ++. Start the cluster software on the new node. + + === Removing a Heartbeat Node === + +@@ -178,43 +184,42 @@ indexterm:[Heartbeat,Remove Cluster Node] + indexterm:[Remove Cluster Node,Heartbeat] + + Because the messaging and membership layers are the authoritative +-source for cluster nodes, deleting them from the CIB is not a reliable +-solution. +- +-First one must arrange for Heartbeat to forget about the node (pcmk-1 ++source for cluster nodes, deleting them from the CIB is not a complete ++solution. First, one must arrange for Heartbeat to forget about the node (pcmk-1 + in the example below). + +-On the host to be removed: +- +-. Stop the cluster: `/etc/init.d/corosync stop` +- +-Next, from one of the remaining active cluster nodes: +- +-. Tell Heartbeat the node should be removed +- +-[source,C] +-# hb_delnode pcmk-1 +- ++. On the host to be removed, stop the cluster: +++ ++---- ++service heartbeat stop ++---- ++. From one of the remaining active cluster nodes, tell Heartbeat the node ++should be removed: +++ ++---- ++hb_delnode pcmk-1 ++---- + . Tell Pacemaker to forget about the removed host: +- +-[source,C] +-# crm_node -R pcmk-1 +++ ++---- ++crm_node -R pcmk-1 ++---- + + [NOTE] + ====== +-This proceedure only works for versions after 1.1.8 ++This procedure only works for pacemaker versions after 1.1.8. + ====== + + === Replacing a Heartbeat Node === + + indexterm:[Heartbeat,Replace Cluster Node] + indexterm:[Replace Cluster Node,Heartbeat] +-The seven-step guide to replacing an existing cluster node: +- +-. Make sure the old node is completely stopped +-. Give the new machine the same hostname as the old one +-. Go to an active cluster node and look up the UUID for the old node in '/var/lib/heartbeat/hostcache' +-. Install the cluster software +-. Copy 'ha.cf' and 'authkeys' to the new node +-. On the new node, populate it's UUID using `crm_uuid -w` and the UUID from step 2 +-. Start the new cluster node ++To replace an existing cluster node: ++ ++. Make sure the old node is completely stopped. ++. Give the new machine the same hostname as the old one. ++. Go to an active cluster node and look up the UUID for the old node in +/var/lib/heartbeat/hostcache+. ++. Install the cluster software. ++. Copy +ha.cf+ and +authkeys+ to the new node. ++. On the new node, populate its UUID using `crm_uuid -w` and the UUID obtained earlier. ++. Start the new cluster node. +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Notifications.txt b/doc/Pacemaker_Explained/en-US/Ch-Notifications.txt +index 13b835d..134ab0c 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Notifications.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Notifications.txt +@@ -1,27 +1,27 @@ + = Receiving Notification for Cluster Events = + + //// +-We prefer [[ch-notifications]], but older versions of asciidoc dont deal well ++We prefer [[ch-notifications]], but older versions of asciidoc don't deal well + with that construct for chapter headings + //// + anchor:ch-notifications[Chapter 7, Receiving Notification for Cluster Events] + indexterm:[Resource,Notification] + +-A Pacemaker cluster is an event driven system. In this context, an event is a +-resource failure or configuration change (not exhaustive). ++A Pacemaker cluster is an event-driven system. In this context, an 'event' ++might be a resource failure or a configuration change, among others. + +-The +ocf:pacemaker:ClusterMon+ resource can monitor the cluster status and +-triggers alerts on each cluster event. This resource runs +crm_mon+ in the +-background at regular intervals (configurable) and uses +crm_mon+ capabilities +-to send emails (SMTP), SNMP traps or to execute an external program via the +-+extra_options+ parameter. ++The *ocf:pacemaker:ClusterMon* resource can monitor the cluster status and ++trigger alerts on each cluster event. This resource runs `crm_mon` in the ++background at regular (configurable) intervals and uses `crm_mon` capabilities ++to trigger emails (SMTP), SNMP traps or external programs (via the +++extra_options+ parameter). + + [NOTE] + ===== + Depending on your system settings and compilation settings, SNMP or email +-alerts might be unavailable. Check +crm_mon --help+ output to see if these ++alerts might be unavailable. Check the output of `crm_mon --help` to see whether these + options are available to you. In any case, executing an external agent will +-always be available, and you can have this agent to send emails, SNMP traps, ++always be available, and you can use this agent to send emails, SNMP traps + or whatever action you develop. + ===== + +@@ -29,8 +29,12 @@ or whatever action you develop. + == Configuring SNMP Notifications == + indexterm:[Resource,Notification,SNMP] + +-Requires an IP to send SNMP traps to, and a SNMP community. +-Pacemaker MIB is found in _/usr/share/snmp/mibs/PCMK-MIB.txt_ ++Requires an IP to send SNMP traps to, and an SNMP community string. ++The Pacemaker MIB is provided with the source, and is typically ++installed in +/usr/share/snmp/mibs/PCMK-MIB.txt+. ++ ++This example uses +snmphost.example.com+ as the SNMP IP and +++public+ as the community string: + + .Configuring ClusterMon to send SNMP traps + ===== +@@ -52,7 +56,9 @@ Pacemaker MIB is found in _/usr/share/snmp/mibs/PCMK-MIB.txt_ + == Configuring Email Notifications == + indexterm:[Resource,Notification,SMTP,Email] + +-Requires a user to send mail alerts to. "Mail-From", SMTP relay and Subject prefix can also be configured. ++Requires the recipient e-mail address. You can also optionally configure ++the sender e-mail address, the hostname of the SMTP relay, and a prefix string ++for the subject line. + + .Configuring ClusterMon to send email alerts + ===== +@@ -74,8 +80,8 @@ Requires a user to send mail alerts to. "Mail-From", SMTP relay and Subject pref + == Configuring Notifications via External-Agent == + + Requires a program (external-agent) to run when resource operations take +-place, and an external-recipient (IP address, Email address, URI). When +-triggered, the external-agent is fed with dynamically filled environnement ++place, and an external-recipient (IP address, email address, URI). When ++triggered, the external-agent is fed with dynamically filled environment + variables describing precisely the cluster event that occurred. By making + smart usage of these variables in your external-agent code, you can trigger + any action. +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Options.txt b/doc/Pacemaker_Explained/en-US/Ch-Options.txt +index cf1478f..f8bca12 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Options.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Options.txt +@@ -1,133 +1,98 @@ +-= Cluster Options = ++= Cluster-Wide Configuration = + +-== Special Options == ++== CIB Properties == + +-The reason for these fields to be placed at the top level instead of +-with the rest of cluster options is simply a matter of parsing. These +-options are used by the configuration database which is, by design, +-mostly ignorant of the content it holds. So the decision was made to +-place them in an easy to find location. ++Certain settings are defined by CIB properties (that is, attributes of the +++cib+ tag) rather than with the rest of the cluster configuration in the +++configuration+ section. + +-== Configuration Version == ++The reason is simply a matter of parsing. These options are used by the ++configuration database which is, by design, mostly ignorant of the content it ++holds. So the decision was made to place them in an easy-to-find location. + +-indexterm:[Configuration Version,Cluster] +-indexterm:[Cluster,Option,Configuration Version] +- +-When a node joins the cluster, the cluster will perform a check to see +-who has the best configuration based on the fields below. It then +-asks the node with the highest (+admin_epoch+, +epoch+, +num_updates+) +-tuple to replace the configuration on all the nodes - which makes +-setting them, and setting them correctly, very important. +- +-.Configuration Version Properties ++.CIB Properties + [width="95%",cols="2m,5<",options="header",align="center"] + |========================================================= + |Field |Description + + | admin_epoch | ++indexterm:[Configuration Version,Cluster] ++indexterm:[Cluster,Option,Configuration Version] + indexterm:[admin_epoch,Cluster Option] + indexterm:[Cluster,Option,admin_epoch] +-Never modified by the cluster. Use this to make the configurations on +-any inactive nodes obsolete. +- +-_Never set this value to zero_, in such cases the cluster cannot tell +-the difference between your configuration and the "empty" one used +-when nothing is found on disk. ++When a node joins the cluster, the cluster performs a check to see ++which node has the best configuration. It asks the node with the highest ++(+admin_epoch+, +epoch+, +num_updates+) tuple to replace the configuration on ++all the nodes -- which makes setting them, and setting them correctly, very ++important. +admin_epoch+ is never modified by the cluster; you can use this ++to make the configurations on any inactive nodes obsolete. _Never set this ++value to zero_. In such cases, the cluster cannot tell the difference between ++your configuration and the "empty" one used when nothing is found on disk. + + | epoch | + indexterm:[epoch,Cluster Option] + indexterm:[Cluster,Option,epoch] +-Incremented every time the configuration is updated (usually by the admin) ++The cluster increments this every time the configuration is updated (usually by ++the administrator). + + | num_updates | + indexterm:[num_updates,Cluster Option] + indexterm:[Cluster,Option,num_updates] +-Incremented every time the configuration or status is updated (usually by the cluster) +- +-|========================================================= +- +-== Other Fields == +-.Properties Controlling Validation +-[width="95%",cols="2m,5<",options="header",align="center"] +-|========================================================= +-|Field |Description ++The cluster increments this every time the configuration or status is updated ++(usually by the cluster) and resets it to 0 when epoch changes. + + | validate-with | + indexterm:[validate-with,Cluster Option] + indexterm:[Cluster,Option,validate-with] +-Determines the type of validation being done on the configuration. If +-set to "none", the cluster will not verify that updates conform to the ++Determines the type of XML validation that will be done on the configuration. ++If set to +none+, the cluster will not verify that updates conform to the + DTD (nor reject ones that don't). This option can be useful when +-operating a mixed version cluster during an upgrade. +- +-|========================================================= +- +-== Fields Maintained by the Cluster == +- +-.Properties Maintained by the Cluster +-[width="95%",cols="2m,5<",options="header",align="center"] +-|========================================================= +-|Field |Description ++operating a mixed-version cluster during an upgrade. + + |cib-last-written | + indexterm:[cib-last-written,Cluster Property] + indexterm:[Cluster,Property,cib-last-written] +-Indicates when the configuration was last written to disk. Informational purposes only. +- +-|dc-uuid | +-indexterm:[dc-uuid,Cluster Property] +-indexterm:[Cluster,Property,dc-uuid] +-Indicates which cluster node is the current leader. Used by the +-cluster when placing resources and determining the order of some +-events. ++Indicates when the configuration was last written to disk. Maintained by the ++cluster; for informational purposes only. + + |have-quorum | + indexterm:[have-quorum,Cluster Property] + indexterm:[Cluster,Property,have-quorum] + Indicates if the cluster has quorum. If false, this may mean that the +-cluster cannot start resources or fence other nodes. See +-+no-quorum-policy+ below. +- +-| dc-version | +-indexterm:[dc-version,Cluster Peroperty] +-indexterm:[Cluster,Peroperty,dc-version] +-Version of Pacemaker on the cluster's DC. +- +-Often includes the hash which identifies the exact Git changeset it +-was built from. Used for diagnostic purposes. +- +-| cluster-infrastructure | +-indexterm:[cluster-infrastructure,Cluster Peroperty] +-indexterm:[Cluster,Peroperty,cluster-infrastructure] +-The messaging stack on which Pacemaker is currently running. +-Used for informational and diagnostic purposes. ++cluster cannot start resources or fence other nodes (see +++no-quorum-policy+ below). Maintained by the cluster. + +-| expected-quorum-votes | +-indexterm:[expected-quorum-votes,Cluster Peroperty] +-indexterm:[Cluster,Peroperty,expected-quorum-votes] +-The number of nodes expected to be in the cluster +- +-Used to calculate quorum in Corosync 1.x (not CMAN) based clusters. ++|dc-uuid | ++indexterm:[dc-uuid,Cluster Property] ++indexterm:[Cluster,Property,dc-uuid] ++Indicates which cluster node is the current leader. Used by the ++cluster when placing resources and determining the order of some ++events. Maintained by the cluster. + + |========================================================= + +-Note that although these fields can be written to by the admin, in ++=== Working with CIB Properties === ++ ++Although these fields can be written to by the user, in + most cases the cluster will overwrite any values specified by the +-admin with the "correct" ones. To change the +admin_epoch+, for +-example, one would use: ++user with the "correct" ones. + +-[source,C] ++To change the ones that can be specified by the user, ++for example +admin_epoch+, one should use: ++---- + # cibadmin --modify --crm_xml '' ++---- + +-A complete set of fields will look something like this: ++A complete set of CIB properties will look something like this: + +-.An example of the fields set for a cib object ++.Attributes set for a cib object + ====== + [source,XML] + ------- +- ++ + ------- + ====== + +@@ -136,82 +101,78 @@ A complete set of fields will look something like this: + Cluster options, as you might expect, control how the cluster behaves + when confronted with certain situations. + +-They are grouped into sets and, in advanced configurations, there may +-be more than one. +-footnote:[This will be described later in the section on +-<> where we will show how to have the cluster use +-different sets of options during working hours (when downtime is +-usually to be avoided at all costs) than it does during the weekends +-(when resources can be moved to the their preferred hosts without +-bothering end users)] +-For now we will describe the simple case where each option is present at most once. +- +-== Available Cluster Options == ++They are grouped into sets within the +crm_config+ section, and, in advanced ++configurations, there may be more than one set. (This will be described later ++in the section on <> where we will show how to have the cluster use ++different sets of options during working hours than during weekends.) For now, ++we will describe the simple case where each option is present at most once. ++ ++You can obtain an up-to-date list of cluster options, including ++their default values, by running the `man pengine` and `man crmd` commands. ++ + .Cluster Options +-[width="95%",cols="5m,2,11<",options="header",align="center"] ++[width="95%",cols="5m,2,11> instead ++Should a failure to start be treated as fatal for a resource? ++If FALSE, the cluster will instead use the resource's +++failcount+ and value for +migration-threshold+ (see <>). + +-| is-managed-default | TRUE | +-indexterm:[is-managed-default,Cluster Option] +-indexterm:[Cluster,Option,is-managed-default] +-+Deprecated:+ See <> instead ++| enable-startup-probes | TRUE | ++indexterm:[enable-startup-probes,Cluster Option] ++indexterm:[Cluster,Option,enable-startup-probes] ++Should the cluster check for active resources during startup? + + | maintenance-mode | FALSE | + indexterm:[maintenance-mode,Cluster Option] + indexterm:[Cluster,Option,maintenance-mode] +-Should the cluster monitor resources and start/stop them as required ++Should the cluster refrain from monitoring, starting and stopping resources? ++ ++| stonith-enabled | TRUE | ++indexterm:[stonith-enabled,Cluster Option] ++indexterm:[Cluster,Option,stonith-enabled] ++Should failed nodes and nodes with resources that can't be stopped be ++shot? If you value your data, set up a STONITH device and enable this. ++ ++If true, or unset, the cluster will refuse to start resources unless ++one or more STONITH resources have been configured. ++ ++| stonith-action | reboot | ++indexterm:[stonith-action,Cluster Option] ++indexterm:[Cluster,Option,stonith-action] ++Action to send to STONITH device. Allowed values are +reboot+ and +off+. ++The value +poweroff+ is also allowed, but is only used for ++legacy devices. + + | stonith-timeout | 60s | + indexterm:[stonith-timeout,Cluster Option] + indexterm:[Cluster,Option,stonith-timeout] +-How long to wait for the STONITH action to complete ++How long to wait for STONITH actions (reboot, on, off) to complete + +-| default-action-timeout | 20s | +-indexterm:[default-action-timeout,Cluster Option] +-indexterm:[Cluster,Option,default-action-timeout] +-+Deprecated:+ See <> instead ++| cluster-delay | 60s | ++indexterm:[cluster-delay,Cluster Option] ++indexterm:[Cluster,Option,cluster-delay] ++Estimated maximum round-trip delay over the network (excluding action ++execution). If the TE requires an action to be executed on another node, ++it will consider the action failed if it does not get a response ++from the other node in this time (after considering the action's ++own timeout). The "correct" value will depend on the speed and load of your ++network and cluster nodes. + + | dc-deadtime | 20s | + indexterm:[dc-deadtime,Cluster Option] +@@ -277,111 +240,159 @@ The "correct" value will depend on the speed/load of your network and the type o + | cluster-recheck-interval | 15min | + indexterm:[cluster-recheck-interval,Cluster Option] + indexterm:[Cluster,Option,cluster-recheck-interval] +-Polling interval for time based changes to options, resource parameters and constraints. ++Polling interval for time-based changes to options, resource parameters and constraints. ++ ++The Cluster is primarily event-driven, but your configuration can have ++elements that take effect based on the time of day. To ensure these changes ++take effect, we can optionally poll the cluster's status for changes. A value ++of 0 disables polling. Positive values are an interval (in seconds unless other ++SI units are specified, e.g. 5min). ++ ++| pe-error-series-max | -1 | ++indexterm:[pe-error-series-max,Cluster Option] ++indexterm:[Cluster,Option,pe-error-series-max] ++The number of PE inputs resulting in ERRORs to save. Used when reporting problems. ++A value of -1 means unlimited (report all). ++ ++| pe-warn-series-max | -1 | ++indexterm:[pe-warn-series-max,Cluster Option] ++indexterm:[Cluster,Option,pe-warn-series-max] ++The number of PE inputs resulting in WARNINGs to save. Used when reporting problems. ++A value of -1 means unlimited (report all). ++ ++| pe-input-series-max | -1 | ++indexterm:[pe-input-series-max,Cluster Option] ++indexterm:[Cluster,Option,pe-input-series-max] ++The number of "normal" PE inputs to save. Used when reporting problems. ++A value of -1 means unlimited (report all). + +-The Cluster is primarily event driven, however the configuration can have elements that change based on time. To ensure these changes take effect, we can optionally poll the cluster's status for changes. ++| remove-after-stop | FALSE | ++indexterm:[remove-after-stop,Cluster Option] ++indexterm:[Cluster,Option,remove-after-stop] ++_Advanced Use Only:_ Should the cluster remove resources from the LRM after ++they are stopped? Values other than the default are, at best, poorly tested and ++potentially dangerous. + +-Allowed values: Zero disables polling. Positive values are an interval in seconds (unless other SI units are specified. eg. 5min) ++| startup-fencing | TRUE | ++indexterm:[startup-fencing,Cluster Option] ++indexterm:[Cluster,Option,startup-fencing] ++_Advanced Use Only:_ Should the cluster shoot unseen nodes? ++Not using the default is very unsafe! + + | election-timeout | 2min | + indexterm:[election-timeout,Cluster Option] + indexterm:[Cluster,Option,election-timeout] +-+Advanced Use Only+ +- +-If need to adjust this value, it probably indicates the presence of a bug. ++_Advanced Use Only:_ If you need to adjust this value, it probably indicates ++the presence of a bug. + + | shutdown-escalation | 20min | + indexterm:[shutdown-escalation,Cluster Option] + indexterm:[Cluster,Option,shutdown-escalation] +-+Advanced Use Only+ +- +-If need to adjust this value, it probably indicates the presence of a bug. ++_Advanced Use Only:_ If you need to adjust this value, it probably indicates ++the presence of a bug. + + | crmd-integration-timeout | 3min | + indexterm:[crmd-integration-timeout,Cluster Option] + indexterm:[Cluster,Option,crmd-integration-timeout] +-+Advanced Use Only+ +- +-If need to adjust this value, it probably indicates the presence of a bug. ++_Advanced Use Only:_ If you need to adjust this value, it probably indicates ++the presence of a bug. + + | crmd-finalization-timeout | 30min | + indexterm:[crmd-finalization-timeout,Cluster Option] + indexterm:[Cluster,Option,crmd-finalization-timeout] +-+Advanced Use Only+ +- +-If need to adjust this value, it probably indicates the presence of a bug. ++_Advanced Use Only:_ If you need to adjust this value, it probably indicates ++the presence of a bug. + +-| crmd-transition-delay | | ++| crmd-transition-delay | 0s | + indexterm:[crmd-transition-delay,Cluster Option] + indexterm:[Cluster,Option,crmd-transition-delay] +-+Advanced Use Only+ Enabling this option will slow down cluster recovery under all conditions. ++_Advanced Use Only:_ Delay cluster recovery for the configured interval to ++allow for additional/related events to occur. Useful if your configuration is ++sensitive to the order in which ping updates arrive. ++Enabling this option will slow down cluster recovery under ++all conditions. + +-Delay cluster recovery for the configured interval to allow for additional/related events to occur. Useful if your configuration is sensitive to the order in which ping updates arrive. ++|default-resource-stickiness | 0 | ++indexterm:[default-resource-stickiness,Cluster Option] ++indexterm:[Cluster,Option,default-resource-stickiness] ++_Deprecated:_ See <> instead + +-|========================================================= ++| is-managed-default | TRUE | ++indexterm:[is-managed-default,Cluster Option] ++indexterm:[Cluster,Option,is-managed-default] ++_Deprecated:_ See <> instead + +-You can always obtain an up-to-date list of cluster options, including +-their default values, by running the `man pengine` and `man crmd` commands. ++| default-action-timeout | 20s | ++indexterm:[default-action-timeout,Cluster Option] ++indexterm:[Cluster,Option,default-action-timeout] ++_Deprecated:_ See <> instead ++ ++|========================================================= + +-== Querying and Setting Cluster Options == ++=== Querying and Setting Cluster Options === + + indexterm:[Querying,Cluster Option] + indexterm:[Setting,Cluster Option] + indexterm:[Cluster,Querying Options] + indexterm:[Cluster,Setting Options] + +-Cluster options can be queried and modified using the +-`crm_attribute` tool. To get the current +-value of +cluster-delay+, simply use: ++Cluster options can be queried and modified using the `crm_attribute` tool. To ++get the current value of +cluster-delay+, you can run: + +-[source,C] +-# crm_attribute --attr-name cluster-delay --get-value ++---- ++# crm_attribute --query --name cluster-delay ++---- + + which is more simply written as + +-[source,C] +-# crm_attribute --get-value -n cluster-delay ++---- ++# crm_attribute -G -n cluster-delay ++---- + + If a value is found, you'll see a result like this: + +-[source,C] +-# crm_attribute --get-value -n cluster-delay +- name=cluster-delay value=60s ++---- ++# crm_attribute -G -n cluster-delay ++scope=crm_config name=cluster-delay value=60s ++---- + +-However, if no value is found, the tool will display an error: ++If no value is found, the tool will display an error: + +-[source,C] +-# crm_attribute --get-value -n clusta-deway` +-name=clusta-deway value=(null) +-Error performing operation: The object/attribute does not exist ++---- ++# crm_attribute -G -n clusta-deway ++scope=crm_config name=clusta-deway value=(null) ++Error performing operation: No such device or address ++---- + +-To use a different value, eg. +30+, simply run: ++To use a different value (for example, 30 seconds), simply run: + +-[source,C] +-# crm_attribute --attr-name cluster-delay --attr-value 30s ++---- ++# crm_attribute --name cluster-delay --update 30s ++---- + +-To go back to the cluster's default value you can delete the value, for example with this command: ++To go back to the cluster's default value, you can delete the value, for example: + +-[source,C] +-# crm_attribute --attr-name cluster-delay --delete-attr ++---- ++# crm_attribute --name cluster-delay --delete ++Deleted crm_config option: id=cib-bootstrap-options-cluster-delay name=cluster-delay ++---- + +-== When Options are Listed More Than Once == ++=== When Options are Listed More Than Once === + + If you ever see something like the following, it means that the option you're modifying is present more than once. + + .Deleting an option that is listed twice + ======= +-[source,C] + ------ +-# crm_attribute --attr-name batch-limit --delete-attr ++# crm_attribute --name batch-limit --delete + + Multiple attributes match name=batch-limit in crm_config: + Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit) + Value: 100 (set=custom, id=custom-batch-limit) +-Please choose from one of the matches above and supply the 'id' with --attr-id ++Please choose from one of the matches above and supply the 'id' with --id + ------- + ======= + +-In such cases follow the on-screen instructions to perform the ++In such cases, follow the on-screen instructions to perform the + requested action. To determine which value is currently being used by +-the cluster, please refer to <>. ++the cluster, refer to <>. +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Resource-Templates.txt b/doc/Pacemaker_Explained/en-US/Ch-Resource-Templates.txt +index 5c34ae7..06cf32e 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Resource-Templates.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Resource-Templates.txt +@@ -1,16 +1,13 @@ + = Resource Templates = + +-== Abstract == +- + If you want to create lots of resources with similar configurations, defining a + resource template simplifies the task. Once defined, it can be referenced in + primitives or in certain types of constraints. +- + + == Configuring Resources with Templates == + +-The primitives referencing the template will inherit all meta +-attributes, instance attributes, utilization attributes and operations defined ++The primitives referencing the template will inherit all meta-attributes, ++instance attributes, utilization attributes and operations defined + in the template. And you can define specific attributes and operations for any + of the primitives. If any of these are defined in both the template and the + primitive, the values defined in the primitive will take precedence over the +@@ -21,8 +18,10 @@ If any changes are needed, they can be done to the template definition and + will take effect globally in all resource definitions referencing that + template. + +-Resource templates have a similar syntax like primitives. For example: ++Resource templates have a syntax similar to that of primitives. + ++.Resource template for a migratable Xen virtual machine ++==== + [source,XML] + ---- + + ---- ++==== + +-Once you defined the new resource template, you can use it in primitives: ++Once you define a resource template, you can use it in primitives by specifying the +++template+ property. + ++.Xen primitive resource using a resource template ++==== + [source,XML] + ---- + +@@ -50,10 +53,13 @@ Once you defined the new resource template, you can use it in primitives: + + + ---- ++==== + +-The new primitive `vm1` is going to inherit everything from the `vm-template`. For +-example, the equivalent of the above two would be: ++In the example above, the new primitive +vm1+ will inherit everything from +vm-template+. For ++example, the equivalent of the above two examples would be: + ++.Equivalent Xen primitive resource not using a resource template ++==== + [source,XML] + ---- + +@@ -73,14 +79,13 @@ example, the equivalent of the above two would be: + + + ---- ++==== + + If you want to overwrite some attributes or operations, add them to the + particular primitive's definition. + +-For instance, the following new primitive `vm2` has special +-attribute values. Its `monitor` operation has a longer `timeout` and `interval`, and +-the primitive has an additional `stop` operation. +- ++.Xen resource overriding template values ++==== + [source,XML] + ---- + +@@ -100,24 +105,31 @@ the primitive has an additional `stop` operation. + + + ---- ++==== + +-The following command shows the resulting definition of a resource: ++In the example above, the new primitive +vm2+ has special ++attribute values. Its +monitor+ operation has a longer +timeout+ and +interval+, and ++the primitive has an additional +stop+ operation. ++ ++To see the resulting definition of a resource, run: + +-[source,C] ++---- + # crm_resource --query-xml --resource vm2 ++---- + +-The following command shows its raw definition in cib: ++To see the raw definition of a resource in the CIB, run: + +-[source,C] ++---- + # crm_resource --query-xml-raw --resource vm2 ++---- + + == Referencing Templates in Constraints == + + A resource template can be referenced in the following types of constraints: + +-- `order` constraints +-- `colocation` constraints, +-- `rsc_ticket` constraints (for multi-site clusters). ++- +order+ constraints (see <>) ++- +colocation+ constraints (see <>) ++- +rsc_ticket+ constraints (for multi-site clusters as described in <>) + + Resource templates referenced in constraints stand for all primitives which are + derived from that template. This means, the constraint applies to all primitive +@@ -125,12 +137,12 @@ resources referencing the resource template. Referencing resource templates in + constraints is an alternative to resource sets and can simplify the cluster + configuration considerably. + +-For example: ++For example, given the example templates earlier in this chapter: + + [source,XML] + + +-is the equivalent of the following constraint configuration: ++would colocate all VMs with +base-rsc+ and is the equivalent of the following constraint configuration: + + [source,XML] + ---- +@@ -148,9 +160,11 @@ is the equivalent of the following constraint configuration: + [NOTE] + ====== + In a colocation constraint, only one template may be referenced from either +-`rsc` or `with-rsc`, and the other reference must be a regular resource. ++`rsc` or `with-rsc`; the other reference must be a regular resource. + ====== + ++=== Referencing Resource Templates in Sequential Resource Sets === ++ + Resource templates can also be referenced in resource sets. + + For example: +@@ -180,6 +194,8 @@ is the equivalent of the following constraint configuration: + + ---- + ++=== Referencing Resource Templates in Parallel Resource Sets === ++ + If the resources referencing the template can run in parallel: + + [source,XML] +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Resources.txt b/doc/Pacemaker_Explained/en-US/Ch-Resources.txt +index 552c1b9..5d5fa33 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Resources.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Resources.txt +@@ -1,49 +1,42 @@ + = Cluster Resources = + +-== What is a Cluster Resource == ++== What is a Cluster Resource? == + + indexterm:[Resource] + +-The role of a resource agent is to abstract the service it provides +-and present a consistent view to the cluster, which allows the cluster +-to be agnostic about the resources it manages. ++A resource is a service made highly available by a cluster. ++The simplest type of resource, a 'primitive' resource, is described ++in this chapter. More complex forms, such as groups and clones, ++are described in later chapters. + ++Every primitive resource has a 'resource agent'. A resource agent is an ++external program that abstracts the service it provides and present a ++consistent view to the cluster. ++ ++This allows the cluster to be agnostic about the resources it manages. + The cluster doesn't need to understand how the resource works because + it relies on the resource agent to do the right thing when given a +-+start+, +stop+ or +monitor+ command. +- +-For this reason it is crucial that resource agents are well tested. ++`start`, `stop` or `monitor` command. For this reason, it is crucial that ++resource agents are well-tested. + +-Typically resource agents come in the form of shell scripts, however ++Typically, resource agents come in the form of shell scripts. However, + they can be written using any technology (such as C, Python or Perl) + that the author is comfortable with. + + [[s-resource-supported]] +-== Supported Resource Classes == ++== Resource Classes == + + indexterm:[Resource,class] + +-There are six classes of agents supported by Pacemaker: ++Pacemaker supports several classes of agents: + + * OCF + * LSB + * Upstart + * Systemd +-* Fencing + * Service +-* Nagios +- +-indexterm:[Resource,Heartbeat] +-indexterm:[Heartbeat,Resources] +- +-Version 1 of Heartbeat came with its own style of resource agents and +-it is highly likely that many people have written their own agents +-based on its conventions. footnote:[ See +-http://wiki.linux-ha.org/HeartbeatResourceAgent for more information ] +- +-Although deprecated with the release of Heartbeat v2, they were +-supported by Pacemaker up until the release of 1.1.8 to enable +-administrators to continue to use these agents. ++* Fencing ++* Nagios Plugins + + === Open Cluster Framework === + +@@ -52,24 +45,22 @@ indexterm:[OCF,Resources] + indexterm:[Open Cluster Framework,Resources] + + The OCF standard +-footnote:[ +-http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD - at least as it relates to resource agents. +-] footnote:[ +-The Pacemaker implementation has been somewhat extended from the OCF +-Specs, but none of those changes are incompatible with the original +-OCF specification. +-] ++footnote:[See ++http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD ++ -- at least as it relates to resource agents. The Pacemaker implementation has ++been somewhat extended from the OCF specs, but none of those changes are ++incompatible with the original OCF specification.] + is basically an extension of the Linux Standard Base conventions for + init scripts to: + + * support parameters, +-* make them self describing and +-* extensible ++* make them self-describing, and ++* make them extensible + + OCF specs have strict definitions of the exit codes that actions must return. + footnote:[ +-Included with the cluster is the ocf-tester script, which can be +-useful in this regard. ++The resource-agents source code includes the `ocf-tester` script, which ++can be useful in this regard. + ] + + The cluster follows these specifications exactly, and giving the wrong +@@ -78,15 +69,14 @@ find puzzling and annoying. In particular, the cluster needs to + distinguish a completely stopped resource from one which is in some + erroneous and indeterminate state. + +-Parameters are passed to the script as environment variables, with the ++Parameters are passed to the resource agent as environment variables, with the + special prefix +OCF_RESKEY_+. So, a parameter which the user thinks +-of as ip it will be passed to the script as +OCF_RESKEY_ip+. The +-number and purpose of the parameters is completely arbitrary, however +-your script should advertise any that it supports using the +-+meta-data+ command. ++of as +ip+ will be passed to the resource agent as +OCF_RESKEY_ip+. The ++number and purpose of the parameters is left to the resource agent; however, ++the resource agent should use the `meta-data` command to advertise any that it ++supports. + +- +-The OCF class is the most preferred one as it is an industry standard, ++The OCF class is the most preferred as it is an industry standard, + highly flexible (allowing parameters to be passed to agents in a + non-positional manner) and self-describing. + +@@ -99,72 +89,84 @@ indexterm:[Resource,LSB] + indexterm:[LSB,Resources] + indexterm:[Linux Standard Base,Resources] + +-LSB resource agents are those found in '/etc/init.d'. ++LSB resource agents are those found in +/etc/init.d+. + +-Generally they are provided by the OS/distribution and, in order to be used with the cluster, they must conform to the LSB Spec. ++Generally, they are provided by the OS distribution and, in order to be used ++with the cluster, they must conform to the LSB Spec. + footnote:[ + See + http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html +-for the LSB Spec (as it relates to init scripts). ++for the LSB Spec as it relates to init scripts. + ] + ++[WARNING] ++==== + Many distributions claim LSB compliance but ship with broken init +-scripts. For details on how to check if your init script is +-LSB-compatible, see <>. The most common problems are: ++scripts. For details on how to check whether your init script is ++LSB-compatible, see <>. Common problematic violations of ++the LSB standard include: + + * Not implementing the status operation at all +-* Not observing the correct exit status codes for start/stop/status actions +-* Starting a started resource returns an error (this violates the LSB spec) +-* Stopping a stopped resource returns an error (this violates the LSB spec) ++* Not observing the correct exit status codes for `start/stop/status` actions ++* Starting a started resource returns an error ++* Stopping a stopped resource returns an error ++==== ++ ++[IMPORTANT] ++==== ++Remember to make sure the computer is _not_ configured to start any ++services at boot time -- that should be controlled by the cluster. ++==== + + === Systemd === + indexterm:[Resource,Systemd] + indexterm:[Systemd,Resources] + + Some newer distributions have replaced the old +-http://en.wikipedia.org/wiki/Init#SysV-style[SYS-V] style of +-initialization daemons (and scripts) with an alternative called ++http://en.wikipedia.org/wiki/Init#SysV-style["SysV"] style of ++initialization daemons and scripts with an alternative called + http://www.freedesktop.org/wiki/Software/systemd[Systemd]. + + Pacemaker is able to manage these services _if they are present_. + +-Instead of +init scripts+, systemd has +unit files+. Generally the +-services (or unit files) are provided by the OS/distribution but there +-are some instructions for converting from init scripts at: +-http://0pointer.de/blog/projects/systemd-for-admins-3.html ++Instead of init scripts, systemd has 'unit files'. Generally, the ++services (unit files) are provided by the OS distribution, but there ++are online guides for converting from init scripts. ++footnote:[For example, ++http://0pointer.de/blog/projects/systemd-for-admins-3.html] + +-[NOTE] +-====== +-Remember to make sure the computer is +not+ configured to start any +-services at boot time that should be controlled by the cluster. +-====== ++[IMPORTANT] ++==== ++Remember to make sure the computer is _not_ configured to start any ++services at boot time -- that should be controlled by the cluster. ++==== + + === Upstart === + indexterm:[Resource,Upstart] + indexterm:[Upstart,Resources] + + Some newer distributions have replaced the old +-http://en.wikipedia.org/wiki/Init#SysV-style[SYS-V] style of ++http://en.wikipedia.org/wiki/Init#SysV-style["SysV"] style of + initialization daemons (and scripts) with an alternative called +-http://upstart.ubuntu.com[Upstart]. ++http://upstart.ubuntu.com/[Upstart]. + + Pacemaker is able to manage these services _if they are present_. + +-Instead of +init scripts+, upstart has +jobs+. Generally the +-services (or jobs) are provided by the OS/distribution. ++Instead of init scripts, upstart has 'jobs'. Generally, the ++services (jobs) are provided by the OS distribution. + +-[NOTE] +-====== +-Remember to make sure the computer is +not+ configured to start any +-services at boot time that should be controlled by the cluster. +-====== ++[IMPORTANT] ++==== ++Remember to make sure the computer is _not_ configured to start any ++services at boot time -- that should be controlled by the cluster. ++==== + + === System Services === + indexterm:[Resource,System Services] + indexterm:[System Service,Resources] + +-Since there are now many "common" types of system services (+systemd+, +-+upstart+, and +lsb+), Pacemaker supports a special alias which ++Since there are various types of system services (+systemd+, +++upstart+, and +lsb+), Pacemaker supports a special +service+ alias which + intelligently figures out which one applies to a given cluster node. + + This is particularly useful when the cluster contains a mix of +@@ -172,7 +174,7 @@ This is particularly useful when the cluster contains a mix of + + In order, Pacemaker will try to find the named service as: + +-. an LSB (SYS-V) init script ++. an LSB init script + . a Systemd unit file + . an Upstart job + +@@ -180,32 +182,35 @@ In order, Pacemaker will try to find the named service as: + indexterm:[Resource,STONITH] + indexterm:[STONITH,Resources] + +-There is also an additional class, STONITH, which is used exclusively +-for fencing related resources. This is discussed later in +-<>. ++The STONITH class is used exclusively for fencing-related resources. This is ++discussed later in <>. + + === Nagios Plugins === + indexterm:[Resource,Nagios Plugins] + indexterm:[Nagios Plugins,Resources] + +-Nagios plugins allow us to monitor services on the remote hosts. +-http://nagiosplugins.org[Nagios Plugins]. ++Nagios Plugins ++footnote:[The project has two independent forks, hosted at ++https://www.nagios-plugins.org/ and https://www.monitoring-plugins.org/. Output ++from both projects' plugins is similar, so plugins from either project can be ++used with pacemaker.] ++allow us to monitor services on remote hosts. + + Pacemaker is able to do remote monitoring with the plugins _if they are + present_. + +-An use case is to configure them as resources belonging to a resource +-container, which usually is a VM, and the container will be restarted +-if any of them has failed. While they can also be configured as ordinary +-resources to be just used for monitoring hosts or services via network. ++A common use case is to configure them as resources belonging to a resource ++container (usually a virtual machine), and the container will be restarted ++if any of them has failed. Another use is to configure them as ordinary ++resources to be used for monitoring hosts or services via the network. + +-The supported parameters are same as the long options of a nagios plugin. ++The supported parameters are same as the long options of the plugin. + + [[primitive-resource]] + == Resource Properties == + +-These values tell the cluster which script to use for the resource, +-where to find that script and what standards it conforms to. ++These values tell the cluster which resource agent to use for the resource, ++where to find that resource agent and what standards it conforms to. + + .Properties of a Primitive Resource + [width="95%",cols="1m,6<",options="header",align="center"] +@@ -221,33 +226,35 @@ where to find that script and what standards it conforms to. + + |class + +-|The standard the script conforms to. Allowed values: +ocf+, +- +service+, +upstart+, +systemd+, +lsb+, +stonith+ ++|The standard the resource agent conforms to. Allowed values: +++lsb+, +nagios+, +ocf+, +service+, +stonith+, +systemd+, +upstart+ + indexterm:[class,Resource] + indexterm:[Resource,Property,class] + + |type +-|The name of the Resource Agent you wish to use. Eg. _IPaddr_ or _Filesystem_ ++|The name of the Resource Agent you wish to use. E.g. +IPaddr+ or +Filesystem+ + indexterm:[type,Resource] + indexterm:[Resource,Property,type] + + |provider + |The OCF spec allows multiple vendors to supply the same +- ResourceAgent. To use the OCF resource agents supplied with +- Heartbeat, you should specify +heartbeat+ here. ++ resource agent. To use the OCF resource agents supplied by ++ the Heartbeat project, you would specify +heartbeat+ here. + indexterm:[provider,Resource] + indexterm:[Resource,Property,provider] + + |========================================================= + +-Resource definitions can be queried with the `crm_resource` tool. For example ++The XML definition of a resource can be queried with the `crm_resource` tool. ++For example: + +-[source,C] ++---- + # crm_resource --resource Email --query-xml ++---- + + might produce: + +-.An example system resource ++.A system resource definition + ===== + [source,XML] + +@@ -255,17 +262,21 @@ might produce: + + [NOTE] + ===== +-One of the main drawbacks to system services (such as LSB, Systemd and ++One of the main drawbacks to system services (LSB, systemd or + Upstart) resources is that they do not allow any parameters! + ===== + +-.An example OCF resource ++//// ++See https://tools.ietf.org/html/rfc5737 for choice of example IP address ++//// ++ ++.An OCF resource definition + ===== + [source,XML] + ------- + +- +- ++ ++ + + + ------- +@@ -274,12 +285,18 @@ Upstart) resources is that they do not allow any parameters! + [[s-resource-options]] + == Resource Options == + +-Options are used by the cluster to decide how your resource should ++Resources have two types of options: 'meta-attributes' and 'instance attributes'. ++Meta-attributes apply to any type of resource, while instance attributes ++are specific to each resource agent. ++ ++=== Resource Meta-Attributes === ++ ++Meta-attributes are used by the cluster to decide how a resource should + behave and can be easily set using the `--meta` option of the + `crm_resource` command. + +-.Options for a Primitive Resource +-[width="95%",cols="1m,1,4<",options="header",align="center"] ++.Meta-attributes of a Primitive Resource ++[width="95%",cols="2m,2,5> resources, they will not promoted to + master) +- +-* 'Master' - Allow the resource to be started and, if appropriate, promoted ++* +master:+ Allow the resource to be started and, if appropriate, promoted + indexterm:[target-role,Resource Option] + indexterm:[Resource,Option,target-role] + + |is-managed +-|+TRUE+ ++|TRUE + |Is the cluster allowed to start and stop the resource? Allowed + values: +true+, +false+ + indexterm:[is-managed,Resource Option] + indexterm:[Resource,Option,is-managed] + + |resource-stickiness +-|Calculated +-|How much does the resource prefer to stay where it is? Defaults to +- the value of +resource-stickiness+ in the +rsc_defaults+ section ++|value of +resource-stickiness+ in the +rsc_defaults+ section ++|How much does the resource prefer to stay where it is? + indexterm:[resource-stickiness,Resource Option] + indexterm:[Resource,Option,resource-stickiness] + + |requires +-|Calculated +-|Under what conditions can the resource be started. ('Since 1.1.8') +- +- Defaults to +fencing+ unless +stonith-enabled+ is 'false' or +class+ +- is 'stonith' - under those conditions the default is +quorum+. +- Possible values: +- +- * 'nothing' - can always be started +- +- * 'quorum' - The cluster can only start this resource if a majority of +- the configured nodes are active +- +- * 'fencing' - The cluster can only start this resource if a majority +- of the configured nodes are active _and_ any failed or unknown nodes +- have been powered off. +- +- * 'unfencing' - The cluster can only start this resource if a majority +- of the configured nodes are active _and_ any failed or unknown nodes +- have been powered off _and_ only on nodes that have been 'unfenced' +- indexterm: Option[requires,Resource] +- indexterm:[Resource,Option,requires] ++|fencing (unless +stonith-enabled+ is +false+ or +class+ is +++stonith+, in which case it defaults to quorum) ++|Conditions under which the resource can be started ('Since 1.1.8') ++Allowed values: ++ ++* +nothing:+ can always be started ++* +quorum:+ The cluster can only start this resource if a majority of ++ the configured nodes are active ++* +fencing:+ The cluster can only start this resource if a majority ++ of the configured nodes are active _and_ any failed or unknown nodes ++ have been powered off ++* +unfencing:+ The cluster can only start this resource if a majority ++ of the configured nodes are active _and_ any failed or unknown nodes ++ have been powered off _and_ only on nodes that have been 'unfenced' ++ ++indexterm:[requires,Resource Option] ++indexterm:[Resource,Option,requires] + + |migration-threshold +-|+INFINITY+ (disabled) ++|INFINITY + |How many failures may occur for this resource on a node, before this +- node is marked ineligible to host this resource. ++ node is marked ineligible to host this resource. A value of INFINITY ++ indicates that this feature is disabled. + indexterm:[migration-threshold,Resource Option] + indexterm:[Resource,Option,migration-threshold] + + |failure-timeout +-|+0+ (disabled) ++|0 + |How many seconds to wait before acting as if the failure had not + occurred, and potentially allowing the resource back to the node on +- which it failed. ++ which it failed. A value of 0 indicates that this feature is disabled. + indexterm:[failure-timeout,Resource Option] + indexterm:[Resource,Option,failure-timeout] + + |multiple-active +-|+stop_start+ ++|stop_start + |What should the cluster do if it ever finds the resource active on +- more than one node. Allowed values: +- +-* 'block' - mark the resource as unmanaged ++ more than one node? Allowed values: + +-* 'stop_only' - stop all active instances and leave them that way +- +-* 'stop_start' - stop all active instances and start the resource in ++* +block:+ mark the resource as unmanaged ++* +stop_only:+ stop all active instances and leave them that way ++* +stop_start:+ stop all active instances and start the resource in + one location only + + indexterm:[multiple-active,Resource Option] + indexterm:[Resource,Option,multiple-active] + + |remote-node +-|++ (disabled) +-|The name of the remote-node this resource defines. This both enables the resource as a remote-node and defines the unique name used to identify the remote-node. If no other parameters are set, this value will also be assumed as the hostname to connect to at port 3121. +WARNING+ This value cannot overlap with any resource or node IDs. ++| ++|The name of the remote-node this resource defines. This both enables the ++resource as a remote-node and defines the unique name used to identify the ++remote-node. If no other parameters are set, this value will also be assumed as ++the hostname to connect to at the port specified by +remote-port+. +WARNING:+ ++This value cannot overlap with any resource or node IDs. If not specified, ++this feature is disabled. + + |remote-port +-|+3121+ +-|Configure a custom port to use for the guest connection to pacemaker_remote. ++|3121 ++|Port to use for the guest connection to pacemaker_remote + + |remote-addr +-|+remote-node+ value used as hostname +-|The ip address or hostname to connect to if remote-node's name is not the hostname of the guest. ++|value of +remote-node+ ++|The IP address or hostname to connect to if remote-node's name is not the ++hostname of the guest. + + |+remote-connect-timeout+ +-|+60s+ ++|60s + |How long before a pending guest connection will time out. + + |========================================================= + +-If you performed the following commands on the previous LSB Email resource ++[NOTE] ++==== ++Support for remote nodes was added in pacemaker 1.1.10. If you are using an ++earlier version, options related to remote nodes will not be available. ++==== ++ ++As an example of setting resource options, if you performed the following ++commands on an LSB Email resource: + +-[source,C] + ------- +-# crm_resource --meta --resource Email --set-parameter priority --property-value 100 +-# crm_resource --meta --resource Email --set-parameter multiple-active --property-value block ++# crm_resource --meta --resource Email --set-parameter priority --parameter-value 100 ++# crm_resource -m -r Email -p multiple-active -v block + ------- + +-the resulting resource definition would be ++the resulting resource definition might be: + + .An LSB resource with cluster options + ===== + [source,XML] + ------- + +- +- +- +- ++ ++ ++ ++ + + ------- + ===== + + [[s-resource-defaults]] +-== Setting Global Defaults for Resource Options == ++=== Setting Global Defaults for Resource Meta-Attributes === + +-To set a default value for a resource option, simply add it to the +-+rsc_defaults+ section with `crm_attribute`. Thus, ++To set a default value for a resource option, add it to the +++rsc_defaults+ section with `crm_attribute`. For example, + +-[source,C] +-# crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false ++---- ++# crm_attribute --type rsc_defaults --name is-managed --update false ++---- + + would prevent the cluster from starting or stopping any of the + resources in the configuration (unless of course the individual +-resources were specifically enabled and had +is-managed+ set to ++resources were specifically enabled by having their +is-managed+ set to + +true+). + +-== Instance Attributes == ++=== Resource Instance Attributes === + +-The scripts of some resource classes (LSB not being one of them) can +-be given parameters which determine how they behave and which instance ++The resource agents of some resource classes (lsb, systemd and upstart 'not' among them) ++can be given parameters which determine how they behave and which instance + of a service they control. + + If your resource agent supports parameters, you can add them with the +-`crm_resource` command. For instance ++`crm_resource` command. For example, + +-[source,C] +-# crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4 ++---- ++# crm_resource --resource Public-IP --set-parameter ip --parameter-value 192.0.2.2 ++---- + + would create an entry in the resource like this: + +@@ -449,70 +472,86 @@ would create an entry in the resource like this: + ------- + + +- ++ + + + ------- + ===== + + For an OCF resource, the result would be an environment variable +-called +OCF_RESKEY_ip+ with a value of +1.2.3.4+. ++called +OCF_RESKEY_ip+ with a value of +192.0.2.2+. + +-The list of instance attributes supported by an OCF script can be +-found by calling the resource script with the `meta-data` command. ++The list of instance attributes supported by an OCF resource agent can be ++found by calling the resource agent with the `meta-data` command. + The output contains an XML description of all the supported + attributes, their purpose and default values. + + .Displaying the metadata for the Dummy resource agent template + ===== +-[source,C] +-------- ++---- + # export OCF_ROOT=/usr/lib/ocf + # $OCF_ROOT/resource.d/pacemaker/Dummy meta-data +-------- ++---- + [source,XML] + ------- + +- +- +- 1.0 +- +- +- This is a Dummy Resource Agent. It does absolutely nothing except +- keep track of whether its running or not. +- Its purpose in life is for testing and to serve as a template for RA writers. +- +- Dummy resource agent +- +- +- +- +- Location to store the resource state in. +- +- State file +- +- +- +- +- +- Dummy attribute that can be changed to cause a reload +- +- Dummy attribute that can be changed to cause a reload +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++1.0 ++ ++ ++This is a Dummy Resource Agent. It does absolutely nothing except ++keep track of whether its running or not. ++Its purpose in life is for testing and to serve as a template for RA writers. ++ ++NB: Please pay attention to the timeouts specified in the actions ++section below. They should be meaningful for the kind of resource ++the agent manages. They should be the minimum advised timeouts, ++but they shouldn't/cannot cover _all_ possible resource ++instances. So, try to be neither overly generous nor too stingy, ++but moderate. The minimum timeouts should never be below 10 seconds. ++ ++Example stateless resource agent ++ ++ ++ ++ ++Location to store the resource state in. ++ ++State file ++ ++ ++ ++ ++ ++Fake attribute that can be changed to cause a reload ++ ++Fake attribute that can be changed to cause a reload ++ ++ ++ ++ ++ ++Number of seconds to sleep during operations. This can be used to test how ++the cluster reacts to operation timeouts. ++ ++Operation sleep duration in seconds. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + ------- + ===== + +@@ -520,9 +559,10 @@ attributes, their purpose and default values. + + indexterm:[Resource,Action] + +-=== Monitoring Resources for Failure === ++Operations are actions the cluster can perform on a resource, ++such as start, stop and monitor. + +-By default, the cluster will not ensure your resources are still ++As an example, by default the cluster will not ensure your resources are still + healthy. To instruct the cluster to do this, you need to add a + +monitor+ operation to the resource's definition. + +@@ -535,88 +575,98 @@ healthy. To instruct the cluster to do this, you need to add a + + + +- ++ + + + ------- + ===== + + .Properties of an Operation +-[width="95%",cols="1m,6<",options="header",align="center"] ++[width="95%",cols="2m,3,6 + + +- ++ + + + ------- + ===== + +-==== Multiple Monitor Operations ==== ++=== Multiple Monitor Operations === + + Provided no two operations (for a single resource) have the same name +-and interval you can have as many monitor operations as you like. In +-this way you can do a superficial health check every minute and ++and interval, you can have as many monitor operations as you like. In ++this way, you can do a superficial health check every minute and + progressively more intense ones at higher intervals. + + To tell the resource agent what kind of check to perform, you need to + provide each monitor with a different value for a common parameter. + The OCF standard creates a special parameter called +OCF_CHECK_LEVEL+ +-for this purpose and dictates that it is _"made available to the +-resource agent without the normal +OCF_RESKEY+ prefix"_. ++for this purpose and dictates that it is "made available to the ++resource agent without the normal +OCF_RESKEY+ prefix". + + Whatever name you choose, you can specify it by adding an +-+instance_attributes+ block to the op tag. Note that it is up to each +++instance_attributes+ block to the +op+ tag. It is up to each + resource agent to look for the parameter and decide how to use it. + +-.An OCF resource with two recurring health checks, performing different levels of checks - specified via +OCF_CHECK_LEVEL+. ++.An OCF resource with two recurring health checks, performing different levels of checks specified via +OCF_CHECK_LEVEL+. + ===== + [source,XML] + ------- +@@ -670,13 +720,13 @@ resource agent to look for the parameter and decide how to use it. + + + +- ++ + + + ------- + ===== + +-==== Disabling a Monitor Operation ==== ++=== Disabling a Monitor Operation === + + The easiest way to stop a recurring monitor is to just delete it. + However, there can be times when you only want to disable it +@@ -692,15 +742,19 @@ operation's definition. + + + +- ++ + + + ------- + ===== + +-This can be achieved from the command-line by executing ++This can be achieved from the command line by executing: + +-[source,C] +-# cibadmin -M -X '' ++---- ++# cibadmin --modify --xml-text '' ++---- + + Once you've done whatever you needed to do, you can then re-enable it with ++---- ++# cibadmin --modify --xml-text '' ++---- +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Rules.txt b/doc/Pacemaker_Explained/en-US/Ch-Rules.txt +index 4f80983..c65c268 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Rules.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Rules.txt +@@ -1,7 +1,7 @@ + = Rules = + + //// +-We prefer [[ch-rules]], but older versions of asciidoc dont deal well ++We prefer [[ch-rules]], but older versions of asciidoc don't deal well + with that construct for chapter headings + //// + +@@ -24,29 +24,35 @@ on the rule's +boolean-op+ field to determine if the rule ultimately + evaluates to +true+ or +false+. What happens next depends on the + context in which the rule is being used. + ++== Rule Properties == ++ + .Properties of a Rule +-[width="95%",cols="2m,5<",options="header",align="center"] ++[width="95%",cols="2m,1,5<",options="header",align="center"] + |========================================================= + + |Field ++|Default + |Description + + |role +-|Limits the rule to apply only when the resource is in that +- role. Allowed values: _Started_, +Slave,+ and +Master+. NOTE: A rule +- with +role="Master"+ can not determine the initial location of a +- clone instance. It will only affect which of the active instances ++|+started+ ++|Limits the rule to apply only when the resource is in the specified ++ role. Allowed values are +started+, +slave+, and +master+. A rule ++ with +role="master"+ cannot determine the initial location of a ++ clone instance and will only affect which of the active instances + will be promoted. + indexterm:[role,Constraint Rule] + indexterm:[Constraint,Rule,role] + + |score ++| + |The score to apply if the rule evaluates to +true+. Limited to use in + rules that are part of location constraints. + indexterm:[score,Constraint Rule] + indexterm:[Constraint,Rule,score] + + |score-attribute ++| + |The node attribute to look up and use as a score if the rule + evaluates to +true+. Limited to use in rules that are part of + location constraints. +@@ -54,8 +60,9 @@ context in which the rule is being used. + indexterm:[Constraint,Rule,score-attribute] + + |boolean-op ++|+and+ + |How to combine the result of multiple expression objects. Allowed +- values: _and_ and +or+. ++ values are +and+ and +or+. + indexterm:[boolean-op,Constraint Rule] + indexterm:[Constraint,Rule,boolean-op] + +@@ -71,75 +78,75 @@ added by the administrator, each node has a built-in node attribute + called +#uname+ that can also be used. + + .Properties of an Expression +-[width="95%",cols="2m,5<",options="header",align="center"] ++[width="95%",cols="1m,1,5 +- + + ------- +@@ -455,9 +460,9 @@ would have its preference increased by +5678+. + + == Using Rules to Control Resource Options == + +-Often some cluster nodes will be different from their peers; sometimes +-these differences (the location of a binary or the names of network +-interfaces) require resources to be configured differently depending ++Often some cluster nodes will be different from their peers. Sometimes, ++these differences -- e.g. the location of a binary or the names of network ++interfaces -- require resources to be configured differently depending + on the machine they're hosted on. + + By defining multiple +instance_attributes+ objects for the resource +@@ -497,12 +502,21 @@ port 9999 for all other nodes. + + The order in which +instance_attributes+ objects are evaluated is + determined by their score (highest to lowest). If not supplied, score +-defaults to zero and objects with an equal score are processed in +-listed order. If the +instance_attributes+ object does not have a +-+rule+ or has a +rule+ that evaluates to +true+, then for any +-parameter the resource does not yet have a value for, the resource +-will use the parameter values defined by the +instance_attributes+ +-object. ++defaults to zero, and objects with an equal score are processed in ++listed order. If the +instance_attributes+ object has no rule ++or a +rule+ that evaluates to +true+, then for any parameter the resource does ++not yet have a value for, the resource will use the parameter values defined by ++the +instance_attributes+. ++ ++For example, given the configuration above, if the resource is placed on node1: ++ ++. +special-node1+ has the highest score (3) and so is evaluated first; ++ its rule evaluates to +true+, so +interface+ is set to +eth1+. ++. +special-node2+ is evaluated next with score 2, but its rule evaluates to +false+, ++ so it is ignored. ++. +defaults+ is evaluated last with score 1, and has no rule, so its values ++ are examined; +interface+ is already defined, so the value here is not used, ++ but +port+ is not yet defined, so +port+ is set to +9999+. + + == Using Rules to Control Cluster Options == + indexterm:[Rule,Controlling Cluster Options] +@@ -512,9 +526,9 @@ Controlling cluster options is achieved in much the same manner as + specifying different resource options on different nodes. + + The difference is that because they are cluster options, one cannot +-(or should not, because they won't work) use attribute based ++(or should not, because they won't work) use attribute-based + expressions. The following example illustrates how to set a different +-+resource-stickiness+ value during and outside of work hours. This +++resource-stickiness+ value during and outside work hours. This + allows resources to automatically move back to their most preferred + hosts, but at a time that (in theory) does not interfere with business + activities. +@@ -540,22 +554,20 @@ activities. + ===== + + [[s-rules-recheck]] +-== Ensuring Time Based Rules Take Effect == ++== Ensuring Time-Based Rules Take Effect == + +-A Pacemaker cluster is an event driven system. As such, it won't +-recalculate the best place for resources to run in unless something ++A Pacemaker cluster is an event-driven system. As such, it won't ++recalculate the best place for resources to run unless something + (like a resource failure or configuration change) happens. This can + mean that a location constraint that only allows resource X to run + between 9am and 5pm is not enforced. + +-If you rely on time based rules, it is essential that you set the +-+cluster-recheck-interval+ option. This tells the cluster to +-periodically recalculate the ideal state of the cluster. For example, +-if you set +cluster-recheck-interval=5m+, then sometime between 9:00 +-and 9:05 the cluster would notice that it needs to start resource X, +-and between 17:00 and 17:05 it would realize that X needed to be +-stopped. +- +-Note that the timing of the actual start and stop actions depends on +-what else needs to be performed first +-. ++If you rely on time-based rules, the +cluster-recheck-interval+ cluster option ++(which defaults to 15 minutes) is essential. This tells the cluster to ++periodically recalculate the ideal state of the cluster. ++ ++For example, if you set +cluster-recheck-interval="5m"+, then sometime between ++09:00 and 09:05 the cluster would notice that it needs to start resource X, ++and between 17:00 and 17:05 it would realize that X needed to be stopped. ++The timing of the actual start and stop actions depends on what other actions ++the cluster may need to perform first. +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Status.txt b/doc/Pacemaker_Explained/en-US/Ch-Status.txt +index 0d19e2f..8083a34 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Status.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Status.txt +@@ -1,4 +1,4 @@ +-= Status - Here be dragons = ++= Status -- Here be dragons = + + Most users never need to understand the contents of the status section + and can be happy with the output from `crm_mon`. +@@ -12,9 +12,9 @@ indexterm:[Node,Status] + indexterm:[Status of a Node] + + In addition to the cluster's configuration, the CIB holds an +-up-to-date representation of each cluster node in the status section. ++up-to-date representation of each cluster node in the +status+ section. + +-.A bare-bones status entry for a healthy node called +cl-virt-1+ ++.A bare-bones status entry for a healthy node *cl-virt-1* + ====== + [source,XML] + ----- +@@ -25,34 +25,32 @@ up-to-date representation of each cluster node in the status section. + ----- + ====== + +-Users are highly recommended _not to modify_ any part of a node's ++Users are highly recommended _not_ to modify any part of a node's + state _directly_. The cluster will periodically regenerate the entire +-section from authoritative sources. So any changes should be done +-with the tools for those subsystems. ++section from authoritative sources, so any changes should be done ++with the tools appropriate to those sources. + + .Authoritative Sources for State Information +-[width="95%",cols="5m,5<",options="header",align="center"] ++[width="95%",cols="1m,1<",options="header",align="center"] + |========================================================= + +-|Dataset |Authoritative Source ++| CIB Object | Authoritative Source + +-|node_state fields |crmd ++|node_state|crmd + +-|transient_attributes tag |attrd ++|transient_attributes|attrd + +-|lrm tag |lrmd ++|lrm|lrmd + + |========================================================= + + The fields used in the +node_state+ objects are named as they are + largely for historical reasons and are rooted in Pacemaker's origins +-as the Heartbeat resource manager. +- +-They have remained unchanged to preserve compatibility with older +-versions. ++as the Heartbeat resource manager. They have remained unchanged to preserve ++compatibility with older versions. + + .Node Status Fields +-[width="95%",cols="2m,5<",options="header",align="center"] ++[width="95%",cols="1m,4<",options="header",align="center"] + |========================================================= + + |Field |Description +@@ -61,9 +59,8 @@ versions. + | id | + indexterm:[id,Node Status] + indexterm:[Node,Status,id] +-Unique identifier for the node. Corosync based clusters use the uname +-of the machine, Heartbeat clusters use a human-readable (but annoying) +-UUID. ++Unique identifier for the node. Corosync-based clusters use a numeric ++counter, while Heartbeat clusters use a (barely) human-readable UUID. + + | uname | + indexterm:[uname,Node Status] +@@ -73,24 +70,23 @@ The node's machine name (output from `uname -n`). + | ha | + indexterm:[ha,Node Status] + indexterm:[Node,Status,ha] +-Flag specifying whether the cluster software is active on the +-node. Allowed values: +active+, +dead+. ++Is the cluster software active on this node? Allowed values: +active+, +dead+. + + | in_ccm | + indexterm:[in_ccm,Node Status] + indexterm:[Node,Status,in_ccm] +-Flag for cluster membership; allowed values: +true+, +false+. ++Is the node a member of the cluster? Allowed values: +true+, +false+. + + | crmd | + indexterm:[crmd,Node Status] + indexterm:[Node,Status,crmd] +-Flag: is the crmd process active on the node? One of +online+, +offline+. ++Is the crmd process active on the node? Allowed values: +online+, +offline+. + + | join | + indexterm:[join,Node Status] + indexterm:[Node,Status,join] +-Flag saying whether the node participates in hosting +-resources. Possible values: +down+, +pending+, +member+, +banned+. ++Does the node participate in hosting resources? Allowed values: +down+, +++pending+, +member+, +banned+. + + | expected | + indexterm:[expected,Node Status] +@@ -100,47 +96,46 @@ Expected value for +join+. + | crm-debug-origin | + indexterm:[crm-debug-origin,Node Status] + indexterm:[Node,Status,crm-debug-origin] +-Diagnostic indicator: the origin of the most recent change(s). ++The origin of the most recent change(s). For diagnostic purposes. + + |========================================================= + +-The cluster uses these fields to determine if, at the node level, the ++The cluster uses these fields to determine whether, at the node level, the + node is healthy or is in a failed state and needs to be fenced. + + == Transient Node Attributes == + + Like regular <>, the name/value +-pairs listed here also help to describe the node. However they are +-forgotten by the cluster when the node goes offline. This can be +-useful, for instance, when you want a node to be in standby mode (not +-able to run resources) until the next reboot. ++pairs listed in the +transient_attributes+ section help to describe the ++node. However they are forgotten by the cluster when the node goes offline. ++This can be useful, for instance, when you want a node to be in standby mode ++(not able to run resources) just until the next reboot. + + In addition to any values the administrator sets, the cluster will + also store information about failed resources here. + +-.Example set of transient node attributes for node "cl-virt-1" ++.A set of transient node attributes for node *cl-virt-1* + ====== + [source,XML] + ----- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + ----- + ====== + + In the above example, we can see that the +pingd:0+ resource has +-failed once, at +Mon Apr 6 11:22:22 2009+. ++failed once, at 09:22:22 UTC 6 April 2009. + footnote:[ +-You can use the standard +date+ command to print a human readable of +-any seconds-since-epoch value: +- # `date -d @number` ++You can use the standard `date` command to print a human-readable version of ++any seconds-since-epoch value, for example `date -d @1239009742`. + ] +-We also see that the node is connected to three "pingd" peers and that ++We also see that the node is connected to three *pingd* peers and that + all known resources have been checked for on this machine (+probe_complete+). + + == Operation History == +@@ -149,17 +144,17 @@ indexterm:[Operation History] + A node's resource history is held in the +lrm_resources+ tag (a child + of the +lrm+ tag). The information stored here includes enough + information for the cluster to stop the resource safely if it is +-removed from the +configuration+ section. Specifically the resource's ++removed from the +configuration+ section. Specifically, the resource's + +id+, +class+, +type+ and +provider+ are stored. + +-.A record of the apcstonith resource ++.A record of the +apcstonith+ resource + ====== + [source,XML] + + ====== + + Additionally, we store the last job for every combination of +-+resource, action+ and +interval+. The concatenation of the values in +++resource+, +action+ and +interval+. The concatenation of the values in + this tuple are used to create the id of the +lrm_rsc_op+ object. + + .Contents of an +lrm_rsc_op+ job +@@ -214,27 +209,30 @@ details on what the values here mean and how they are interpreted. + indexterm:[last-run,Action Status] + indexterm:[Action,Status,last-run] + +-Diagnostic indicator. Machine local date/time, in seconds since epoch, +-at which the job was executed. ++Machine-local date/time, in seconds since epoch, ++at which the job was executed. For diagnostic purposes. + + | last-rc-change | + indexterm:[last-rc-change,Action Status] + indexterm:[Action,Status,last-rc-change] + +-Diagnostic indicator. Machine local date/time, in seconds since epoch, ++Machine-local date/time, in seconds since epoch, + at which the job first returned the current value of +rc-code+. ++For diagnostic purposes. + + | exec-time | + indexterm:[exec-time,Action Status] + indexterm:[Action,Status,exec-time] + +-Diagnostic indicator. Time, in milliseconds, that the job was running for. ++Time, in milliseconds, that the job was running for. ++For diagnostic purposes. + + | queue-time | + indexterm:[queue-time,Action Status] + indexterm:[Action,Status,queue-time] + +-Diagnostic indicator. Time, in seconds, that the job was queued for in the LRMd. ++Time, in seconds, that the job was queued for in the LRMd. ++For diagnostic purposes. + + | crm_feature_set | + indexterm:[crm_feature_set,Action Status] +@@ -274,13 +272,14 @@ necessary. + indexterm:[crm-debug-origin,Action Status] + indexterm:[Action,Status,crm-debug-origin] + +-Diagnostic indicator. The origin of the current values. ++The origin of the current values. ++For diagnostic purposes. + + |========================================================= + +-=== Simple Example === ++=== Simple Operation History Example === + +-.A monitor operation (determines current state of the apcstonith resource) ++.A monitor operation (determines current state of the +apcstonith+ resource) + ====== + [source,XML] + ----- +@@ -299,26 +298,24 @@ Diagnostic indicator. The origin of the current values. + In the above example, the job is a non-recurring monitor operation + often referred to as a "probe" for the +apcstonith+ resource. + +-The cluster schedules probes for every configured resource on when a +-new node starts, in order to determine the resource's current state ++The cluster schedules probes for every configured resource on a node when ++the node first starts, in order to determine the resource's current state + before it takes any further action. + + From the +transition-key+, we can see that this was the 22nd action of + the 2nd graph produced by this instance of the crmd + (2668bbeb-06d5-40f9-936d-24cb7f87006a). + +-The third field of the +transition-key+ contains a 7, this indicates +-that the job expects to find the resource inactive. +- +-By looking at the +rc-code+ property, we see that this was the case. +- ++The third field of the +transition-key+ contains a 7, which indicates ++that the job expects to find the resource inactive. By looking at the +rc-code+ ++property, we see that this was the case. + +-As that is the only job recorded for this node we can conclude that ++As that is the only job recorded for this node, we can conclude that + the cluster started the resource elsewhere. + +-=== Complex Resource History Example === ++=== Complex Operation History Example === + +-.Resource history of a pingd clone with multiple jobs ++.Resource history of a +pingd+ clone with multiple jobs + ====== + [source,XML] + ----- +@@ -364,7 +361,7 @@ Once sorted, the above example can be summarized as: + + The cluster processes each job record to build up a picture of the + resource's state. After the first and second entries, it is +-considered stopped and after the third it considered active. ++considered stopped, and after the third it considered active. + + Based on the last operation, we can tell that the resource is + currently active. +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Stonith.txt b/doc/Pacemaker_Explained/en-US/Ch-Stonith.txt +index fae0fe5..a3c02cb 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Stonith.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Stonith.txt +@@ -1,16 +1,16 @@ +-= Configure STONITH = ++= STONITH = + + //// +-We prefer [[ch-stonith]], but older versions of asciidoc dont deal well ++We prefer [[ch-stonith]], but older versions of asciidoc don't deal well + with that construct for chapter headings + //// + anchor:ch-stonith[Chapter 13, STONITH] + indexterm:[STONITH, Configuration] + +-== What Is STONITH == ++== What Is STONITH? == + +-STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it +-protects your data from being corrupted by rogue nodes or concurrent ++STONITH (an acronym for "Shoot The Other Node In The Head"), also called ++'fencing', protects your data from being corrupted by rogue nodes or concurrent + access. + + Just because a node is unresponsive, this doesn't mean it isn't +@@ -18,19 +18,18 @@ accessing your data. The only way to be 100% sure that your data is + safe, is to use STONITH so we can be certain that the node is truly + offline, before allowing the data to be accessed from another node. + +- + STONITH also has a role to play in the event that a clustered service + cannot be stopped. In this case, the cluster uses STONITH to force the + whole node offline, thereby making it safe to start the service + elsewhere. + +-== What STONITH Device Should You Use == ++== What STONITH Device Should You Use? == + + It is crucial that the STONITH device can allow the cluster to + differentiate between a node failure and a network one. + + The biggest mistake people make in choosing a STONITH device is to +-use remote power switch (such as many on-board IMPI controllers) that ++use a remote power switch (such as many on-board IPMI controllers) that + shares power with the node it controls. In such cases, the cluster + cannot be sure if the node is really offline, or active and suffering + from a network fault. +@@ -38,46 +37,47 @@ from a network fault. + Likewise, any device that relies on the machine being active (such as + SSH-based "devices" used during testing) are inappropriate. + +-== Differences of STONITH Resources == ++== Special Treatment of STONITH Resources == ++ ++STONITH resources are somewhat special in Pacemaker. + +-Stonith resources are somewhat special in Pacemaker. ++STONITH may be initiated by pacemaker or by other parts of the cluster ++(such as resources like DRBD or DLM). To accommodate this, pacemaker ++does not require the STONITH resource to be in the 'started' state ++in order to be used, thus allowing reliable use of STONITH devices in such a ++case. + +-In previous versions, only "running" resources could be used by +-Pacemaker for fencing. This requirement has been relaxed to allow +-other parts of the cluster (such as resources like DRBD) to reliably +-initiate fencing. footnote:[Fencing a node while Pacemaker was moving +-stonith resources around would otherwise fail] ++[NOTE] ++==== ++In pacemaker versions 1.1.9 and earlier, this feature either did not exist or ++did not work well. Only "running" STONITH resources could be used by Pacemaker ++for fencing, and if another component tried to fence a node while Pacemaker was ++moving STONITH resources, the fencing could fail. ++==== + +-Now all nodes have access to their definitions and instantiate them +-on-the-fly when needed, however preference is given to 'verified' +-instances which are the ones the cluster has explicitly started. ++All nodes have access to STONITH devices' definitions and instantiate them ++on-the-fly when needed, but preference is given to 'verified' instances, which ++are the ones that are 'started' according to the cluster's knowledge. + + In the case of a cluster split, the partition with a verified instance +-will have a slight advantage as stonith-ng in the other partition will +-have to hear from all its current peers before choosing a node to ++will have a slight advantage, because the STONITH daemon in the other partition ++will have to hear from all its current peers before choosing a node to + perform the fencing. + +-[NOTE] +-=========== +-To disable a fencing device/resource, 'target-role' can be set as you would for a normal resource. +-=========== ++Fencing resources do work the same as regular resources in some respects: + +-[NOTE] +-=========== +-To prevent a specific node from using a fencing device, location constraints will work as expected. +-=========== ++* +target-role+ can be used to enable or disable the resource ++* Location constraints can be used to prevent a specific node from using the resource + + [IMPORTANT] + =========== +- +-Currently there is a limitation that fencing resources may only have a +-one set of meta-attributes and one set of instance-attributes. This ++Currently there is a limitation that fencing resources may only have ++one set of meta-attributes and one set of instance attributes. This + can be revisited if it becomes a significant limitation for people. +- + =========== + +-.Properties of Fencing Devices +-[width="95%",cols="1m,1m,1m,5<",options="header",align="center"] ++.Properties of Fencing Resources ++[width="95%",cols="5m,2,3,10+ ++. Find the required parameters associated with the device ++ (replacing $AGENT_NAME with the name obtained from the previous step): +++ ++---- ++# stonith_admin --metadata --agent $AGENT_NAME ++---- + + . Create a file called +stonith.xml+ containing a primitive resource +- with a class of 'stonith', a type of and a parameter +- for each of the values returned in step 2. ++ with a class of +stonith+, a type equal to the agent name obtained earlier, ++ and a parameter for each of the values returned in the previous step. + + . If the device does not know how to fence nodes based on their uname, + you may also need to set the special +pcmk_host_map+ parameter. See +- +man stonithd+ for details. ++ `man stonithd` for details. + +-. If the device does not support the list command, you may also need ++. If the device does not support the `list` command, you may also need + to set the special +pcmk_host_list+ and/or +pcmk_host_check+ +- parameters. See +man stonithd+ for details. ++ parameters. See `man stonithd` for details. + + . If the device does not expect the victim to be specified with the +- port parameter, you may also need to set the special +- +pcmk_host_argument+ parameter. See +man stonithd+ for details. ++ `port` parameter, you may also need to set the special ++ +pcmk_host_argument+ parameter. See `man stonithd` for details. + +-. Upload it into the CIB using cibadmin: +cibadmin -C -o resources --xml-file stonith.xml+ ++. Upload it into the CIB using cibadmin: +++ ++---- ++# cibadmin -C -o resources --xml-file stonith.xml ++---- + +-. Set stonith-enabled to true. +crm_attribute -t crm_config -n stonith-enabled -v true+ ++. Set +stonith-enabled+ to true: +++ ++---- ++# crm_attribute -t crm_config -n stonith-enabled -v true ++---- + +-. Once the stonith resource is running, you can test it by executing: +- +stonith_admin --reboot nodename+. Although you might want to stop the +- cluster on that machine first. ++. Once the stonith resource is running, you can test it by executing the ++ following (although you might want to stop the cluster on that machine ++ first): +++ ++---- ++# stonith_admin --reboot nodename ++---- + +-=== Example === ++=== Example STONITH Configuration === + +-Assuming we have an chassis containing four nodes and an IPMI device +-active on 10.0.0.1, then we would chose the fence_ipmilan driver in step +-2 and obtain the following list of parameters ++Assume we have an chassis containing four nodes and an IPMI device ++active on 192.0.2.1. We would choose the `fence_ipmilan` driver, ++and obtain the following list of parameters: + + .Obtaining a list of STONITH Parameters +- +-[source,C] ++==== + ---- + # stonith_admin --metadata -a fence_ipmilan + ---- + + [source,XML] + ---- +- + +- +-fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/). +- +-To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4) +- +- +- +- +- IPMI Lan Auth type (md5, password, or none) +- +- +- +- +- IPMI Lan IP to talk to +- +- +- +- +- Password (if required) to control power on IPMI device +- +- +- +- +- Script to retrieve password (if required) +- +- +- +- +- Use Lanplus +- +- +- +- +- Username/Login (if required) to control power on IPMI device +- +- +- +- +- Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata +- +- +- +- +- Timeout (sec) for IPMI operation +- +- +- +- +- Ciphersuite to use (same as ipmitool -C parameter) +- +- +- +- +- Method to fence (onoff or cycle) +- +- +- +- +- Wait X seconds after on/off operation +- +- +- +- +- Wait X seconds before fencing is started +- +- +- +- +- Verbose mode +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + ---- ++==== + +-from which we would create a STONITH resource fragment that might look ++Based on that, we would create a STONITH resource fragment that might look + like this: + +-.Sample STONITH Resource ++.An IPMI-based STONITH Resource ++==== + [source,XML] + ---- + + + + +- ++ + + + +@@ -413,40 +501,39 @@ like this: + + + ---- ++==== + +-And finally, since we disabled it earlier, we need to re-enable STONITH. +- +-[source,Bash] ++Finally, we need to enable STONITH: + ---- + # crm_attribute -t crm_config -n stonith-enabled -v true + ---- + +-== Advanced Fencing Configurations == ++== Advanced STONITH Configurations == + + Some people consider that having one fencing device is a single point + of failure footnote:[Not true, since a node or resource must fail +-before fencing even has a chance to], others prefer removing the node ++before fencing even has a chance to]; others prefer removing the node + from the storage and network instead of turning it off. + + Whatever the reason, Pacemaker supports fencing nodes with multiple +-devices through a feature called fencing topologies. ++devices through a feature called 'fencing topologies'. + +-Simply create the individual devices as you normally would and then +-define one or more fencing levels in the fencing-topology section in ++Simply create the individual devices as you normally would, then ++define one or more +fencing-level+ entries in the +fencing-topology+ section of + the configuration. + +-* Each level is attempted in +ascending index+ order +-* If a device fails, +processing terminates+ for the current level. +- No further devices in that level are exercised and the next level is attempted instead. +-* If the operation succeeds for all the listed devices in a level, the level is deemed to have passed +-* The operation is finished +when a level has passed+ (success), or all levels have been attempted (failed) +-* If the operation failed, the next step is determined by the Policy Engine and/or crmd. ++* Each fencing level is attempted in order of ascending +index+. ++* If a device fails, processing terminates for the current level. ++ No further devices in that level are exercised, and the next level is attempted instead. ++* If the operation succeeds for all the listed devices in a level, the level is deemed to have passed. ++* The operation is finished when a level has passed (success), or all levels have been attempted (failed). ++* If the operation failed, the next step is determined by the Policy Engine and/or `crmd`. + + Some possible uses of topologies include: + +-* try poison-pill and fail back to power +-* try disk and network, and fall back to power if either fails +-* initiate a kdump and then poweroff the node ++* Try poison-pill and fail back to power ++* Try disk and network, and fall back to power if either fails ++* Initiate a kdump and then poweroff the node + + .Properties of Fencing Levels + [width="95%",cols="1m,6<",options="header",align="center"] +@@ -456,7 +543,7 @@ Some possible uses of topologies include: + |Description + + |id +-|Your name for the level ++|A unique name for the level + indexterm:[id,fencing-level] + indexterm:[Fencing,fencing-level,id] + +@@ -467,18 +554,19 @@ Some possible uses of topologies include: + + |index + |The order in which to attempt the levels. +- Levels are attempted in +ascending index+ order +until one succeeds+. ++ Levels are attempted in ascending order 'until one succeeds'. + indexterm:[index,fencing-level] + indexterm:[Fencing,fencing-level,index] + + |devices +-|A comma separated list of devices for which the ++|A comma-separated list of devices that must all be tried for this level + indexterm:[devices,fencing-level] + indexterm:[Fencing,fencing-level,devices] + + |========================================================= + +-=== Example use of Fencing Topologies === ++.Fencing topology with different devices for different nodes ++==== + [source,XML] + ---- + +@@ -498,21 +586,24 @@ Some possible uses of topologies include: + + + ---- ++==== + +-=== Example use of advanced Fencing Topologies: dual layer and dual devices === ++=== Example Dual-Layer, Dual-Device Fencing Topologies === + +-The following example illustrates an advanced use of +fencing_topology+ in a cluster with the following properties: ++The following example illustrates an advanced use of +fencing-topology+ in a cluster with the following properties: + + * 3 nodes (2 active prod-mysql nodes, 1 prod_mysql-rep in standby for quorum purposes) +-* the active nodes have an IPMI-controlled power board reached at 10.10.10.1 and 10.10.10.2 +-* the active nodes also have two independant PSUs (Power Supplu Units) connected to two independant PDUs (Power Distribution Unit) reached at 10.20.1.1 (port 10 and port 11) and 10.20.2.1 (port 10 and port 11) +-* the first fencing method uses the +fence_ipmi+ agent +-* the second fencing method uses the +fence_apc_snmp+ agent targetting 2 fencing devices (one per PSU, either port 10 or 11) ++* the active nodes have an IPMI-controlled power board reached at 192.0.2.1 and 192.0.2.2 ++* the active nodes also have two independent PSUs (Power Supply Units) ++ connected to two independent PDUs (Power Distribution Units) reached at ++ 198.51.100.1 (port 10 and port 11) and 203.0.113.1 (port 10 and port 11) ++* the first fencing method uses the `fence_ipmi` agent ++* the second fencing method uses the `fence_apc_snmp` agent targetting 2 fencing devices (one per PSU, either port 10 or 11) + * fencing is only implemented for the active nodes and has location constraints + * fencing topology is set to try IPMI fencing first then default to a "sure-kill" dual PDU fencing + +-In a normal failure scenario, STONITH will first select +fence_ipmi+ to try and kill the faulty node. +-Using a +fencing_topology+, if that first method fails, STONITH will then move on to selecting +fence_apc_snmp+ twice: ++In a normal failure scenario, STONITH will first select +fence_ipmi+ to try to kill the faulty node. ++Using a fencing topology, if that first method fails, STONITH will then move on to selecting +fence_apc_snmp+ twice: + + * once for the first PDU + * again for the second PDU +@@ -524,33 +615,34 @@ The fence action is considered successful only if both PDUs report the required + Each cluster node has it own dedicated IPMI channel that can be called for fencing using the following primitives: + [source,XML] + ---- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + ---- + + .Second fencing method: dual PDU devices + +-Each cluster node also has two distinct power channels controlled by two distinct PDUs. That means a total of 4 fencing devices configured as follows: ++Each cluster node also has two distinct power channels controlled by two ++distinct PDUs. That means a total of 4 fencing devices configured as follows: + + - Node 1, PDU 1, PSU 1 @ port 10 + - Node 1, PDU 2, PSU 2 @ port 10 +@@ -560,62 +652,62 @@ Each cluster node also has two distinct power channels controlled by two distinc + The matching fencing agents are configured as follows: + [source,XML] + ---- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + ---- + + .Location Constraints + +-To prevent STONITH from running a fencing agent on the very same node it is supposed to fence, constraints are placed on all the fencing primitives: ++To prevent STONITH from trying to run a fencing agent on the same node it is ++supposed to fence, constraints are placed on all the fencing primitives: + [source,XML] + ---- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + ---- + + .Fencing topology +@@ -624,14 +716,14 @@ Now that all the fencing resources are defined, it's time to create the right to + We want to first fence using IPMI and if that does not work, fence both PDUs to effectively and surely kill the node. + [source,XML] + ---- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + ---- +-Please note, in +fencing_topology+, the lower index value determines the priority of the first fencing method. ++Please note, in +fencing-topology+, the lowest +index+ value determines the priority of the first fencing method. + + .Final configuration + +@@ -660,7 +752,7 @@ Put together, the configuration looks like this: + + + +- ++ + + + +@@ -671,7 +763,7 @@ Put together, the configuration looks like this: + + + +- ++ + + + +@@ -682,7 +774,7 @@ Put together, the configuration looks like this: + + + +- ++ + + + +@@ -692,7 +784,7 @@ Put together, the configuration looks like this: + + + +- ++ + + + +@@ -702,7 +794,7 @@ Put together, the configuration looks like this: + + + +- ++ + + + +@@ -712,7 +804,7 @@ Put together, the configuration looks like this: + + + +- ++ + + + +@@ -739,3 +831,29 @@ Put together, the configuration looks like this: + + + ---- ++ ++== Remapping Reboots == ++ ++When the cluster needs to reboot a node, whether because +stonith-action+ is +reboot+ or because ++a reboot was manually requested (such as by `stonith_admin --reboot`), it will remap that to ++other commands in two cases: ++ ++. If the chosen fencing device does not support the +reboot+ command, the cluster ++ will ask it to perform +off+ instead. ++ ++. If a fencing topology level with multiple devices must be executed, the cluster ++ will ask all the devices to perform +off+, then ask the devices to perform +on+. ++ ++To understand the second case, consider the example of a node with redundant ++power supplies connected to intelligent power switches. Rebooting one switch ++and then the other would have no effect on the node. Turning both switches off, ++and then on, actually reboots the node. ++ ++In such a case, the fencing operation will be treated as successful as long as ++the +off+ commands succeed, because then it is safe for the cluster to recover ++any resources that were on the node. Timeouts and errors in the +on+ phase will ++be logged but ignored. ++ ++When a reboot operation is remapped, any action-specific timeout for the ++remapped action will be used (for example, +pcmk_off_timeout+ will be used when ++executing the +off+ command, not +pcmk_reboot_timeout+). +diff --git a/doc/Pacemaker_Explained/en-US/Ch-Utilization.txt b/doc/Pacemaker_Explained/en-US/Ch-Utilization.txt +index 6eeb063..afba0a9 100644 +--- a/doc/Pacemaker_Explained/en-US/Ch-Utilization.txt ++++ b/doc/Pacemaker_Explained/en-US/Ch-Utilization.txt +@@ -1,39 +1,38 @@ + = Utilization and Placement Strategy = + +-== Background == +- + Pacemaker decides where to place a resource according to the resource + allocation scores on every node. The resource will be allocated to the +-node where the resource has the highest score. If the resource allocation +-scores on all the nodes are equal, by the `default` placement strategy, +-Pacemaker will choose a node with the least number of allocated resources +-for balancing the load. If the number of resources on each node is equal, +-the first eligible node listed in cib will be chosen to run the resource. ++node where the resource has the highest score. + +-Though resources are different. They may consume different amounts of the +-capacities of the nodes. Actually, we cannot ideally balance the load just +-according to the number of resources allocated to a node. Besides, if +-resources are placed such that their combined requirements exceed the +-provided capacity, they may fail to start completely or run with degraded +-performance. ++If the resource allocation scores on all the nodes are equal, by the default ++placement strategy, Pacemaker will choose a node with the least number of ++allocated resources for balancing the load. If the number of resources on each ++node is equal, the first eligible node listed in the CIB will be chosen to run ++the resource. + +-To take these into account, Pacemaker allows you to specify the following +-configurations: ++Often, in real-world situations, different resources use significantly ++different proportions of a node's capacities (memory, I/O, etc.). ++We cannot balance the load ideally just according to the number of resources ++allocated to a node. Besides, if resources are placed such that their combined ++requirements exceed the provided capacity, they may fail to start completely or ++run with degraded performance. + +-. The `capacity` a certain `node provides`. +-. The `capacity` a certain `resource requires`. +-. An overall `strategy` for placement of resources. ++To take these factors into account, Pacemaker allows you to configure: + ++. The capacity a certain node provides. ++. The capacity a certain resource requires. ++. An overall strategy for placement of resources. + + == Utilization attributes == + +-To configure the capacity a node provides and the resource's requirements, +-use `utilization` attributes. You can name the `utilization` attributes +-according to your preferences and define as many `name/value` pairs as your +-configuration needs. However, the attribute's values must be `integers`. +- +-First, specify the capacities the nodes provide: ++To configure the capacity that a node provides or a resource requires, ++you can use 'utilization attributes' in +node+ and +resource+ objects. ++You can name utilization attributes according to your preferences and define as ++many name/value pairs as your configuration needs. However, the attributes' ++values must be integers. + ++.Specifying CPU and RAM capacities of two nodes ++==== + [source,XML] + ---- + +@@ -49,9 +48,10 @@ First, specify the capacities the nodes provide: + + + ---- ++==== + +-Then, specify the capacities the resources require: +- ++.Specifying CPU and RAM consumed by several resources ++==== + [source,XML] + ---- + +@@ -73,115 +73,118 @@ Then, specify the capacities the resources require: + + + ---- ++==== + + A node is considered eligible for a resource if it has sufficient free + capacity to satisfy the resource's requirements. The nature of the required +-or provided capacities is completely irrelevant for Pacemaker, it just makes ++or provided capacities is completely irrelevant to Pacemaker -- it just makes + sure that all capacity requirements of a resource are satisfied before placing + a resource to a node. + +- + == Placement Strategy == + + After you have configured the capacities your nodes provide and the +-capacities your resources require, you need to set the `placement-strategy` ++capacities your resources require, you need to set the +placement-strategy+ + in the global cluster options, otherwise the capacity configurations have +-`no effect`. ++'no effect'. + +-Four values are available for the `placement-strategy`: ++Four values are available for the +placement-strategy+: + +-`default`:: +++default+:: + +-Utilization values are not taken into account at all, per default. ++Utilization values are not taken into account at all. + Resources are allocated according to allocation scores. If scores are equal, + resources are evenly distributed across nodes. + +-`utilization`:: +++utilization+:: + +-Utilization values are taken into account when deciding whether a node +-is considered eligible if it has sufficient free capacity to satisfy the +-resource's requirements. However, load-balancing is still done based on the ++Utilization values are taken into account 'only' when deciding whether a node ++is considered eligible (i.e. whether it has sufficient free capacity to satisfy ++the resource's requirements). Load-balancing is still done based on the + number of resources allocated to a node. + +-`balanced`:: +++balanced+:: + + Utilization values are taken into account when deciding whether a node +-is eligible to serve a resource; an attempt is made to spread the resources +-evenly, optimizing resource performance. ++is eligible to serve a resource 'and' when load-balancing, so an attempt is ++made to spread the resources in a way that optimizes resource performance. + +-`minimal`:: +++minimal+:: + +-Utilization values are taken into account when deciding whether a node +-is eligible to serve a resource; an attempt is made to concentrate the +-resources on as few nodes as possible, thereby enabling possible power savings +-on the remaining nodes. ++Utilization values are taken into account 'only' when deciding whether a node ++is eligible to serve a resource. For load-balancing, an attempt is made to ++concentrate the resources on as few nodes as possible, thereby enabling ++possible power savings on the remaining nodes. + + +-Set `placement-strategy` with `crm_attribute`: +-[source,C] +-# crm_attribute --attr-name placement-strategy --attr-value balanced ++Set +placement-strategy+ with `crm_attribute`: ++---- ++# crm_attribute --name placement-strategy --update balanced ++---- + + Now Pacemaker will ensure the load from your resources will be distributed +-evenly throughout the cluster - without the need for convoluted sets of ++evenly throughout the cluster, without the need for convoluted sets of + colocation constraints. + +- + == Allocation Details == + +-=== Which node is preferred to be chosen to get consumed first on allocating resources? === ++=== Which node is preferred to get consumed first when allocating resources? === + +-- The node that is most healthy (which has the highest node weight) gets +-consumed first. ++- The node with the highest node weight gets consumed first. Node weight ++ is a score maintained by the cluster to represent node health. + +-- If their weights are equal: +- * If `placement-strategy="default|utilization"`, ++- If multiple nodes have the same node weight: ++ * If +placement-strategy+ is +default+ or +utilization+, + the node that has the least number of allocated resources gets consumed first. + ** If their numbers of allocated resources are equal, +- the first eligible node listed in cib gets consumed first. ++ the first eligible node listed in the CIB gets consumed first. + +- * If `placement-strategy="balanced"`, +- the node that has more free capacity gets consumed first. ++ * If +placement-strategy+ is +balanced+, ++ the node that has the most free capacity gets consumed first. + ** If the free capacities of the nodes are equal, + the node that has the least number of allocated resources gets consumed first. + *** If their numbers of allocated resources are equal, +- the first eligible node listed in cib gets consumed first. ++ the first eligible node listed in the CIB gets consumed first. + +- * If `placement-strategy="minimal"`, +- the first eligible node listed in cib gets consumed first. ++ * If +placement-strategy+ is +minimal+, ++ the first eligible node listed in the CIB gets consumed first. + ++=== Which node has more free capacity? === + +-==== Which node has more free capacity? ==== ++If only one type of utilization attribute has been defined, free capacity ++is a simple numeric comparison. + +-This will be quite clear if we only define one type of `capacity`. While if we +-define multiple types of `capacity`, for example: ++If multiple types of utilization attributes have been defined, then ++the node that is numerically highest in the the most attribute types ++has the most free capacity. For example: + +-- If `nodeA` has more free `cpus`, `nodeB` has more free `memory`, +- their free capacities are equal. ++- If +nodeA+ has more free +cpus+, and +nodeB+ has more free +memory+, ++ then their free capacities are equal. + +-- If `nodeA` has more free `cpus`, while `nodeB` has more free `memory` and `storage`, +- `nodeB` has more free capacity. ++- If +nodeA+ has more free +cpus+, while +nodeB+ has more free +memory+ and +storage+, ++ then +nodeB+ has more free capacity. + ++=== Which resource is preferred to be assigned first? === + +-=== Which resource is preferred to be chosen to get assigned first? === ++- The resource that has the highest +priority+ (see <>) gets allocated first. + +-- The resource that has the highest priority gets allocated first. ++- If their priorities are equal, check whether they are already running. The ++ resource that has the highest score on the node where it's running gets allocated ++ first, to prevent resource shuffling. + +-- If their priorities are equal, check if they are already running. The +-resource that has the highest score on the node where it's running gets allocated +-first (to prevent resource shuffling). +- +-- If the scores above are equal or they are not running, the resource has ++- If the scores above are equal or the resources are not running, the resource has + the highest score on the preferred node gets allocated first. + +-- If the scores above are equal, the first runnable resource listed in cib gets allocated first. ++- If the scores above are equal, the first runnable resource listed in the CIB ++ gets allocated first. + + +-== Limitations == ++== Limitations and Workarounds == + +-This type of problem Pacemaker is dealing with here is known as the ++The type of problem Pacemaker is dealing with here is known as the + http://en.wikipedia.org/wiki/Knapsack_problem[knapsack problem] and falls into + the http://en.wikipedia.org/wiki/NP-complete[NP-complete] category of computer +-science problems - which is fancy way of saying "it takes a really long time ++science problems -- a fancy way of saying "it takes a really long time + to solve". + + Clearly in a HA cluster, it's not acceptable to spend minutes, let alone hours +@@ -193,29 +196,32 @@ service. This means it arrives at a solution much faster than traditional + linear programming algorithms, but by doing so at the price of leaving some + services stopped. + +-In the contrived example above: ++In the contrived example at the start of this chapter: + +-- `rsc-small` would be allocated to `node1` +-- `rsc-medium` would be allocated to `node2` +-- `rsc-large` would remain inactive ++- +rsc-small+ would be allocated to +node1+ ++- +rsc-medium+ would be allocated to +node2+ ++- +rsc-large+ would remain inactive + + Which is not ideal. + ++There are various approaches to dealing with the limitations of ++pacemaker's placement strategy: + +-== Strategies for Dealing with the Limitations == ++Ensure you have sufficient physical capacity.:: + +-- Ensure you have sufficient physical capacity. +-It might sounds obvious, but if the physical capacity of your nodes is (close to) ++It might sound obvious, but if the physical capacity of your nodes is (close to) + maxed out by the cluster under normal conditions, then failover isn't going to +-go well. Even without the Utilization feature, you'll start hitting timeouts and +-getting secondary failures'. ++go well. Even without the utilization feature, you'll start hitting timeouts and ++getting secondary failures. ++ ++Build some buffer into the capabilities advertised by the nodes.:: ++ ++Advertise slightly more resources than we physically have, on the (usually valid) ++assumption that a resource will not use 100% of the configured amount of ++CPU, memory and so forth 'all' the time. This practice is sometimes called 'overcommit'. + +-- Build some buffer into the capabilities advertised by the nodes. +-Advertise slightly more resources than we physically have on the (usually valid) +-assumption that a resource will not use 100% of the configured number of +-cpu/memory/etc `all` the time. This practice is also known as 'over commit'. ++Specify resource priorities.:: + +-- Specify resource priorities. + If the cluster is going to sacrifice services, it should be the ones you care +-(comparatively) about the least. Ensure that resource priorities are properly set ++about (comparatively) the least. Ensure that resource priorities are properly set + so that your most important resources are scheduled first. +diff --git a/doc/Pacemaker_Explained/en-US/NOTES b/doc/Pacemaker_Explained/en-US/NOTES +index ae5069b..d6c6f2f 100644 +--- a/doc/Pacemaker_Explained/en-US/NOTES ++++ b/doc/Pacemaker_Explained/en-US/NOTES +@@ -1,69 +1,16 @@ ++why sometimes and sometimes
? examples have title at top, figures have title at bottom + +-That's a "+", not a hyphen: +- +-Key combinations can be distinguished from keycaps by the hyphen connecting each part of a key +-combination. For example: +-Press Enter to execute the command. +-Press Ctrl+Alt+F2 to switch to the first virtual terminal. Press Ctrl+Alt+F1 to +-return to your X-Windows session. +- +- +- +- +-doesn't apply here: +- +-If source code is discussed, class names, methods, functions, v +- including application names; dialog box text; labeled buttons; check-box and radio button labels; menu titles and sub-menu titles. +- +- +-1.2 terminal output has page-break +- +- +-2.3 editing via VI +-isn't that racy? Are concurrent changes detected? +- +- +-why sometimes and sometimes
? example 2.2 has title at top, different to the figures +- +- +-2.8 header slightly too long, line broken +- ++Example 2.8 (and others) XML line too long, line broken + + some are in , some in ... I'd like the latter more, or perhaps in a . + Indentation makes whitespace at start of lines ... remove? + +-Chapter 3 +-========= +-- table 3.3 "Properties maintained by the Cluster" incomplete (crm-feature-set, ...) +- +- +-4.4.2 structure different from 4.4.1 ... numbered lists +- +- +-5.3 Notes have next content overlaid +- +- +-ex 5.6: 1.0 ???? +- +- +-perhaps use 10.20.30.40 instead of the 1.2.3.4 example IP address? +- +- +-6.5 images/resource-set.png missing, "images/two-sets.png" too; images/three-sets; "images/three-sets-complex.png" +- ++tables 3.1 and 3.2 incomplete (crm-feature-set, ...) + + Ch 7 missing? + +- + Remove Ex9.9? + +- +-collocate or colocate? Eg. in C.1: +-Multi-dimensional colocation and ordering constraints. See Section 6.5, “Ordering Sets of +-Resources” and Section 6.6, “Collocating Sets of Resources” +- +- + Ap-Debug.xml not used? + +- + alias for primary? +diff --git a/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.ent b/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.ent +index b9137bc..74004c8 100644 +--- a/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.ent ++++ b/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.ent +@@ -1,4 +1,4 @@ + + +- ++ + +diff --git a/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.xml b/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.xml +index aa1eab4..fe054f3 100644 +--- a/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.xml ++++ b/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.xml +@@ -32,10 +32,10 @@ + + Further Reading + +- Project Website +- Project Documentation ++ Project Website: ++ Project Documentation: + +- A comprehensive guide to cluster commands has been written by Novell ++ SUSE High Availibility Guide: + + Heartbeat configuration: + Corosync Configuration: +diff --git a/doc/Pacemaker_Explained/en-US/Preface.xml b/doc/Pacemaker_Explained/en-US/Preface.xml +index eadd41d..e63c4be 100644 +--- a/doc/Pacemaker_Explained/en-US/Preface.xml ++++ b/doc/Pacemaker_Explained/en-US/Preface.xml +@@ -1,11 +1,11 @@ + +- + Preface +- ++ + + +- ++ + + + +diff --git a/doc/Pacemaker_Explained/en-US/Revision_History.xml b/doc/Pacemaker_Explained/en-US/Revision_History.xml +index 0afc90b..eecd34b 100644 +--- a/doc/Pacemaker_Explained/en-US/Revision_History.xml ++++ b/doc/Pacemaker_Explained/en-US/Revision_History.xml +@@ -2,6 +2,7 @@ + + ++ + Revision History + + +@@ -42,6 +43,18 @@ + + + ++ ++ 5-0 ++ Mon Feb 23 2015 ++ KenGaillotkgaillot@redhat.com ++ ++ ++ ++ Update for clarity, stylistic consistency and current command-line syntax ++ ++ ++ ++ + + + +diff --git a/doc/Pacemaker_Remote/en-US/Ch-Baremetal-Tutorial.txt b/doc/Pacemaker_Remote/en-US/Ch-Baremetal-Tutorial.txt +index 9bf6dc6..d0fd14b 100644 +--- a/doc/Pacemaker_Remote/en-US/Ch-Baremetal-Tutorial.txt ++++ b/doc/Pacemaker_Remote/en-US/Ch-Baremetal-Tutorial.txt +@@ -42,7 +42,7 @@ Now install and start the pacemaker_remote daemon on the baremetal remote-node. + + [source,C] + ---- +-# yum install -y paceamaker-remote resource-agents pcs ++# yum install -y pacemaker-remote resource-agents pcs + # systemctl enable pacemaker_remote.service + # systemctl start pacemaker_remote.service + ---- +diff --git a/doc/Pacemaker_Remote/en-US/Ch-Intro.txt b/doc/Pacemaker_Remote/en-US/Ch-Intro.txt +index d8699b3..777bb97 100644 +--- a/doc/Pacemaker_Remote/en-US/Ch-Intro.txt ++++ b/doc/Pacemaker_Remote/en-US/Ch-Intro.txt +@@ -48,7 +48,7 @@ In the past, users desiring this deployment had to make a decision. They would e + + With the pacemaker_remote service we have a new option. + +-* The baremetal cluster-nodes run the cluster stack (paceamaker+corosync). ++* The baremetal cluster-nodes run the cluster stack (pacemaker+corosync). + * The virtual remote-nodes run the pacemaker_remote service (nearly zero configuration required on the virtual machine side) + * The cluster stack on the cluster-nodes launch the virtual machines and immediately connect to the pacemaker_remote service, allowing the virtual machines to integrate into the cluster just as if they were a real cluster-node. + +@@ -66,7 +66,7 @@ With this deployment you would have 64 webservers and databases running on 64 vi + + +"I want my traditional High Availability cluster to scale beyond the limits imposed by the corosync messaging layer."+ + +-Ultimately the primary advantage of baremetal remote-nodes over traditional nodes running the Corosync+Pacemaker stack is scalability. There are likely some other use cases related to geographically distributed HA clusters that baremetal remote-nodes may serve a purpose in, but those use cases not well understood at this point. The only limitations baremetal remote-nodes have that cluster-nodes do not is the ability to take place in cluster quorum, and the ability to execute fencing agents via stonith. That is not to say however that fencing of a baremetal node works any differently than that of a normal cluster-node. The Pacemaker policy engine understands how to fence baremetal remote-nodes. As long as a fencing device exists, the cluster is capable of ensuring baremetal nodes are fenced in the exact same way as normal cluster-nodes are fenced. ++Ultimately the primary advantage of baremetal remote-nodes over traditional nodes running the Corosync+Pacemaker stack is scalability. There are likely some other use cases related to geographically distributed HA clusters that baremetal remote-nodes may serve a purpose in, but those use cases are not well understood at this point. The only limitations baremetal remote-nodes have that cluster-nodes do not is the ability to take place in cluster quorum, and the ability to execute fencing agents via stonith. That is not to say however that fencing of a baremetal node works any differently than that of a normal cluster-node. The Pacemaker policy engine understands how to fence baremetal remote-nodes. As long as a fencing device exists, the cluster is capable of ensuring baremetal nodes are fenced in the exact same way as normal cluster-nodes are fenced. + + == Linux Container Use Case == + +diff --git a/doc/Pacemaker_Remote/en-US/Ch-KVM-Tutorial.txt b/doc/Pacemaker_Remote/en-US/Ch-KVM-Tutorial.txt +index adf3422..7b150aa 100644 +--- a/doc/Pacemaker_Remote/en-US/Ch-KVM-Tutorial.txt ++++ b/doc/Pacemaker_Remote/en-US/Ch-KVM-Tutorial.txt +@@ -192,7 +192,7 @@ Now on the +GUEST+ install pacemaker-remote package and enable the daemon to run + + [source,C] + ---- +-# yum install -y pacemaker paceamaker-remote resource-agents ++# yum install -y pacemaker pacemaker-remote resource-agents + # systemctl enable pacemaker_remote.service + ---- + +diff --git a/doc/asciidoc.reference b/doc/asciidoc.reference +index a9a171b..9323864 100644 +--- a/doc/asciidoc.reference ++++ b/doc/asciidoc.reference +@@ -1,31 +1,49 @@ ++= Single-chapter part of the documentation = ++ ++== Go-to reference chapter for how we use AsciiDoc on this project == ++ ++[NOTE] ++====== ++This is *not* an attempt for fully self-hosted AsciiDoc document, ++consider it a plaintext full of AsciiDoc samples (it's up to the reader ++to recognize the borderline) at documentation writers' disposal ++to somewhat standardize the style{empty}footnote:[ ++ style of both source notation and final visual appearance ++]. ++ + See also: + http://powerman.name/doc/asciidoc ++====== + +-Commands: `some-tool --with option` +-Files: '/tmp/file.name' +-Italic: _some text_ ++Emphasis: _some test_ + Mono: +some text+ +-Bold: *some text* +-Super: ^some text^ +-Sub: ~some text~ ++Strong: *some text* ++Super: ^some text^ ++Sub: ~some text~ + Quotes: + ``double quoted'' + `single quoted' + +-Tool: command ++Command: `some-tool --with option` ++Newly introduced term: ++ 'some text' (another form of emphasis as of this edit) ++ ++File: mono + Literal: mono ++Tool: command ++Option: mono ++Replaceable: emphasis mono + Varname: mono +-Option: italic +-Emphasis: italic bold +-Replaceable: italic mono ++Term encountered on system (e.g., menu choice, hostname): ++ strong + + +-.Title for Eaxmple ++.Title for Example + ===== + Some text + ===== + +-.Title for Eaxmple with XML Listing ++.Title for Example with XML Listing + ===== + [source,XML] + ----- +@@ -49,4 +67,4 @@ Section anchors: + + References to section anchors: + +-<> or <> +\ No newline at end of file ++<> or <> +diff --git a/doc/coding_guidelines.txt b/doc/coding_guidelines.txt +index 079d7c7..a95134e 100644 +--- a/doc/coding_guidelines.txt ++++ b/doc/coding_guidelines.txt +@@ -89,8 +89,7 @@ code that will be a part of the Pacemaker project. + is indented by one level. Opening brace is on the same line as switch. + + ``` +- switch (expression) +- { ++ switch (expression) { + case 0: + command0; + break; +diff --git a/doc/shared/en-US/pacemaker-intro.txt b/doc/shared/en-US/pacemaker-intro.txt +new file mode 100644 +index 0000000..6b898c9 +--- /dev/null ++++ b/doc/shared/en-US/pacemaker-intro.txt +@@ -0,0 +1,169 @@ ++ ++== What Is 'Pacemaker'? == ++ ++Pacemaker is a 'cluster resource manager', that is, a logic responsible ++for a life-cycle of deployed software -- indirectly perhaps even whole ++systems or their interconnections -- under its control within a set of ++computers (a.k.a. 'cluster nodes', 'nodes' for short) and driven by ++prescribed rules. ++ ++It achieves maximum availability for your cluster services ++(a.k.a. 'resources') by detecting and recovering from node- and ++resource-level failures by making use of the messaging and membership ++capabilities provided by your preferred cluster infrastructure (either ++http://www.corosync.org/[Corosync] or ++http://linux-ha.org/wiki/Heartbeat[Heartbeat]), and possibly by ++utilizing other parts of the overall cluster stack. ++ ++.High Availability Clusters ++[NOTE] ++For *the goal of minimal downtime* a term 'high availability' was coined ++and together with its acronym, 'HA', is well-established in the sector. ++To differentiate this sort of clusters from high performance computing ++('HPC') ones, should a context require it (apparently, not the case in ++this document), using 'HA cluster' is an option. ++ ++Pacemaker's key features include: ++ ++ * Detection and recovery of node and service-level failures ++ * Storage agnostic, no requirement for shared storage ++ * Resource agnostic, anything that can be scripted can be clustered ++ * Supports 'fencing' (also referred to as the 'STONITH' acronym, ++ <> later on) for ensuring data integrity ++ * Supports large and small clusters ++ * Supports both quorate and resource-driven clusters ++ * Supports practically any redundancy configuration ++ * Automatically replicated configuration that can be updated ++ from any node ++ * Ability to specify cluster-wide service ordering, ++ colocation and anti-colocation ++ * Support for advanced service types ++ ** Clones: for services which need to be active on multiple nodes ++ ** Multi-state: for services with multiple modes ++ (e.g. master/slave, primary/secondary) ++ * Unified, scriptable cluster management tools ++ ++== Pacemaker Architecture == ++ ++At the highest level, the cluster is made up of three pieces: ++ ++ * *Non-cluster-aware components*. These pieces ++ include the resources themselves; scripts that start, stop and ++ monitor them; and a local daemon that masks the differences ++ between the different standards these scripts implement. ++ Even though interactions of these resources when run as multiple ++ instances can resemble a distributed system, they still lack ++ the proper HA mechanisms and/or autonomous cluster-wide governance ++ as subsumed in the following item. ++ ++ * *Resource management*. Pacemaker provides the brain that processes ++ and reacts to events regarding the cluster. These events include ++ nodes joining or leaving the cluster; resource events caused by ++ failures, maintenance and scheduled activities; and other ++ administrative actions. Pacemaker will compute the ideal state of ++ the cluster and plot a path to achieve it after any of these ++ events. This may include moving resources, stopping nodes and even ++ forcing them offline with remote power switches. ++ ++ * *Low-level infrastructure*. Projects like 'Corosync', 'CMAN' and ++ 'Heartbeat' provide reliable messaging, membership and quorum ++ information about the cluster. ++ ++When combined with Corosync, Pacemaker also supports popular open ++source cluster filesystems.{empty}footnote:[ ++ Even though Pacemaker also supports Heartbeat, the filesystems need to ++ use the stack for messaging and membership, and Corosync seems to be ++ what they're standardizing on. Technically, it would be possible for ++ them to support Heartbeat as well, but there seems little interest ++ in this. ++] ++ ++Due to past standardization within the cluster filesystem community, ++cluster filesystems make use of a common 'distributed lock manager', ++which makes use of Corosync for its messaging and membership ++capabilities (which nodes are up/down) and Pacemaker for fencing ++services. ++ ++.The Pacemaker Stack ++image::images/pcmk-stack.png["The Pacemaker stack",width="10cm",height="7.5cm",align="center"] ++ ++=== Internal Components === ++ ++Pacemaker itself is composed of five key components: ++ ++ * 'Cluster Information Base' ('CIB') ++ * 'Cluster Resource Management daemon' ('CRMd') ++ * 'Local Resource Management daemon' ('LRMd') ++ * 'Policy Engine' ('PEngine' or 'PE') ++ * Fencing daemon ('STONITHd') ++ ++.Internal Components ++image::images/pcmk-internals.png["Subsystems of a Pacemaker cluster",align="center",scaledwidth="65%"] ++ ++The CIB uses XML to represent both the cluster's configuration and ++current state of all resources in the cluster. The contents of the CIB ++are automatically kept in sync across the entire cluster and are used by ++the PEngine to compute the ideal state of the cluster and how it should ++be achieved. ++ ++This list of instructions is then fed to the 'Designated Controller' ++('DC'). Pacemaker centralizes all cluster decision making by electing ++one of the CRMd instances to act as a master. Should the elected CRMd ++process (or the node it is on) fail, a new one is quickly established. ++ ++The DC carries out the PEngine's instructions in the required order by ++passing them to either the Local Resource Management daemon (LRMd) or ++CRMd peers on other nodes via the cluster messaging infrastructure ++(which in turn passes them on to their LRMd process). ++ ++The peer nodes all report the results of their operations back to the DC ++and, based on the expected and actual results, will either execute any ++actions that needed to wait for the previous one to complete, or abort ++processing and ask the PEngine to recalculate the ideal cluster state ++based on the unexpected results. ++ ++In some cases, it may be necessary to power off nodes in order to ++protect shared data or complete resource recovery. For this, Pacemaker ++comes with STONITHd. ++ ++[[s-intro-stonith]] ++.STONITH ++[NOTE] ++*STONITH* is an acronym for 'Shoot-The-Other-Node-In-The-Head', ++a recommended practice that misbehaving node is best to be promptly ++'fenced' (shut off, cut from shared resources or otherwise immobilized), ++and is usually implemented with a remote power switch. ++ ++In Pacemaker, STONITH devices are modeled as resources (and configured ++in the CIB) to enable them to be easily monitored for failure, however ++STONITHd takes care of understanding the STONITH topology such that its ++clients simply request a node be fenced, and it does the rest. ++ ++== Types of Pacemaker Clusters == ++ ++Pacemaker makes no assumptions about your environment. This allows it ++to support practically any ++http://en.wikipedia.org/wiki/High-availability_cluster#Node_configurations[redundancy ++configuration] including 'Active/Active', 'Active/Passive', 'N+1', ++'N+M', 'N-to-1' and 'N-to-N'. ++ ++.Active/Passive Redundancy ++image::images/pcmk-active-passive.png["Active/Passive Redundancy",width="10cm",height="7.5cm",align="center"] ++ ++Two-node Active/Passive clusters using Pacemaker and 'DRBD' are ++a cost-effective solution for many High Availability situations. ++ ++.Shared Failover ++image::images/pcmk-shared-failover.png["Shared Failover",width="10cm",height="7.5cm",align="center"] ++ ++By supporting many nodes, Pacemaker can dramatically reduce hardware ++costs by allowing several active/passive clusters to be combined and ++share a common backup node. ++ ++.N to N Redundancy ++image::images/pcmk-active-active.png["N to N Redundancy",width="10cm",height="7.5cm",align="center"] ++ ++When shared storage is available, every node can potentially be used for ++failover. Pacemaker can even run multiple copies of services to spread ++out the workload. ++ +diff --git a/extra/Makefile.am b/extra/Makefile.am +index daaf137..40e6cad 100644 +--- a/extra/Makefile.am ++++ b/extra/Makefile.am +@@ -18,7 +18,7 @@ + + MAINTAINERCLEANFILES = Makefile.in + +-SUBDIRS = resources rgmanager logrotate ++SUBDIRS = resources logrotate + + mibdir = $(datadir)/snmp/mibs + mib_DATA = PCMK-MIB.txt +diff --git a/extra/buildbot.helper b/extra/buildbot.helper +index 2f2d7d8..459f175 100755 +--- a/extra/buildbot.helper ++++ b/extra/buildbot.helper +@@ -5,7 +5,7 @@ self=`basename $0` + + if [ x$1 = xinstall ]; then + # Basic test phase +- mock --configdir=$PWD --root=mock --resultdir=./mock -v --install ./mock/*.rpm nano sudo valgrind lcov psmisc ++ mock --configdir=$PWD --root=mock --resultdir=./mock -v --install nano lcov psmisc sudo valgrind ./mock/*.rpm + elif [ x$1 = xdownloads ]; then + # Extra test phase + mock --configdir=$PWD --root=mock --resultdir=./mock -v --install ./downloads/*.rpm nano sudo valgrind lcov +diff --git a/extra/resources/Dummy b/extra/resources/Dummy +index 2410c4d..8a38ef5 100644 +--- a/extra/resources/Dummy ++++ b/extra/resources/Dummy +@@ -66,6 +66,14 @@ Location to store the resource state in. + + + ++ ++ ++Fake password field ++ ++Password ++ ++ ++ + + + Fake attribute that can be changed to cause a reload +@@ -129,6 +137,7 @@ dummy_stop() { + if [ $? = $OCF_SUCCESS ]; then + rm ${OCF_RESKEY_state} + fi ++ rm -f ${VERIFY_SERIALIZED_FILE} + return $OCF_SUCCESS + } + +@@ -137,10 +146,21 @@ dummy_monitor() { + # (SUCCESS), failed (ERROR) or _cleanly_ stopped (NOT RUNNING). + # That is THREE states, not just yes/no. + +- sleep ${OCF_RESKEY_op_sleep} ++ if [ "$OCF_RESKEY_op_sleep" -ne "0" ]; then ++ if [ -f ${VERIFY_SERIALIZED_FILE} ]; then ++ # two monitor ops have occurred at the same time. ++ # this is to verify a condition in the lrmd regression tests. ++ ocf_log err "$VERIFY_SERIALIZED_FILE exists already" ++ return $OCF_ERR_GENERIC ++ fi ++ ++ touch ${VERIFY_SERIALIZED_FILE} ++ sleep ${OCF_RESKEY_op_sleep} ++ rm ${VERIFY_SERIALIZED_FILE} ++ fi + + if [ -f ${OCF_RESKEY_state} ]; then +- return $OCF_SUCCESS ++ return $OCF_SUCCESS + fi + if false ; then + return $OCF_ERR_GENERIC +@@ -176,6 +196,7 @@ if [ "x$OCF_RESKEY_state" = "x" ]; then + OCF_RESKEY_state="${HA_VARRUN}/Dummy-${OCF_RESOURCE_INSTANCE}.state" + fi + fi ++VERIFY_SERIALIZED_FILE="${OCF_RESKEY_state}.serialized" + + case $__OCF_ACTION in + meta-data) meta_data +diff --git a/extra/resources/HealthSMART b/extra/resources/HealthSMART +index 45bb0f1..3747bfa 100644 +--- a/extra/resources/HealthSMART ++++ b/extra/resources/HealthSMART +@@ -63,7 +63,7 @@ Location to store the resource state in. + + + +- ++ + + The drive(s) to check as a SPACE separated list. Enter the full path to the device, e.g. "/dev/sda". + +@@ -71,7 +71,7 @@ The drive(s) to check as a SPACE separated list. Enter the full path to the devi + + + +- ++ + + The device type(s) to assume for the drive(s) being tested as a SPACE separated list. + +@@ -79,7 +79,7 @@ The device type(s) to assume for the drive(s) being tested as a SPACE separated + + + +- ++ + + Lower limit of the temperature in deg C of the drive(s). Below this limit the status will be red. + +@@ -87,7 +87,7 @@ Lower limit of the temperature in deg C of the drive(s). Below this limit the st + + + +- ++ + + Upper limit of the temperature if deg C of the drives(s). If the drive reports + a temperature higher than this value the status of #health-smart will be red. +@@ -96,7 +96,7 @@ a temperature higher than this value the status of #health-smart will be red. + + + +- ++ + + Number of deg C below/above the upper/lower temp limits at which point the status of #health-smart will change to yellow. + +@@ -170,7 +170,7 @@ init_smart() { + upper_yellow_limit=$((${upper_red_limit}-${yellow_threshold})) + + #Set disk defaults +- if [ -z ${OCF_RESKEY_drives} ] ; then ++ if [ -z "${OCF_RESKEY_drives}" ] ; then + DRIVES="/dev/sda" + else + DRIVES=${OCF_RESKEY_drives} +diff --git a/extra/resources/Makefile.am b/extra/resources/Makefile.am +index cc162e5..a090a16 100644 +--- a/extra/resources/Makefile.am ++++ b/extra/resources/Makefile.am +@@ -21,6 +21,9 @@ include $(top_srcdir)/Makefile.common + + EXTRA_DIST = $(ocf_SCRIPTS) + ++ ++isolationtechdir = @OCF_RA_DIR@/.isolation ++ + ocfdir = @OCF_RA_DIR@/pacemaker + + ocf_SCRIPTS = ClusterMon \ +@@ -36,6 +39,8 @@ ocf_SCRIPTS = ClusterMon \ + SystemHealth \ + remote + ++isolationtech_SCRIPTS = docker-wrapper ++ + if BUILD_XML_HELP + + man7_MANS = $(ocf_SCRIPTS:%=ocf_pacemaker_%.7) +diff --git a/extra/resources/docker-wrapper b/extra/resources/docker-wrapper +new file mode 100755 +index 0000000..4b0b87b +--- /dev/null ++++ b/extra/resources/docker-wrapper +@@ -0,0 +1,536 @@ ++#!/bin/bash ++# ++# Copyright (c) 2015 David Vossel ++# All Rights Reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it would be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++# ++# Further, this software is distributed without any warranty that it is ++# free of the rightful claim of any third person regarding infringement ++# or the like. Any license provided herein, whether implied or ++# otherwise, applies only to this software file. Patent licenses, if ++# any, provided herein do not apply to combinations of this program with ++# other software, or any other product whatsoever. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write the Free Software Foundation, ++# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++# ++ ++####################################################################### ++# Initialization: ++ ++: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++ ++####################################################################### ++ ++CONF_PREFIX="pcmk_docker" ++ ++meta_data() { ++ cat < ++ ++ ++1.0 ++ ++ ++Docker technology wrapper for pacemaker remote. ++ ++docker wrapper ++ ++ ++ ++ ++Docker image to run resources within ++ ++docker image ++ ++ ++ ++ ++ ++Give resources within container access to cluster resources ++such as the CIB and the ability to manage cluster attributes. ++ ++NOTE: Do not confuse this with the docker run command's ++'--priviledged' option which gives a container permission ++to access system devices. To toggle the docker run option, ++ set --priviledged=true as part of the ${CONF_PREFIS}_run_opts ++arguments. The ${CONF_PREFIX}_privileged option only pertains ++to whether or not the container has access to the cluster's ++CIB or not. Some multistate resources need to be able to write ++values to the cib, which would require enabling ${CONF_PREFIX}_privileged ++ ++is privileged ++ ++ ++ ++ ++ ++Add options to be appended to the 'docker run' command which is used ++when creating the container during the start action. This option allows ++users to do things such as setting a custom entry point and injecting ++environment variables into the newly created container. Note the '-d' ++option is supplied regardless of this value to force containers to run ++in the background. ++ ++NOTE: Do not explicitly specify the --name argument in the run_opts. This ++agent will set --name using the resource's instance name ++ ++ ++run options ++ ++ ++ ++ ++ ++Allow the container to be reused after stopping the container. By default ++containers are removed after stop. With the reuse option containers ++will persist after the container stops. ++ ++reuse container ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++END ++} ++ ++####################################################################### ++ ++ ++CLIENT="/usr/libexec/pacemaker/lrmd_internal_ctl" ++DOCKER_AGENT="/usr/lib/ocf/resource.d/heartbeat/docker" ++KEY_VAL_STR="" ++PROVIDER=$OCF_RESKEY_CRM_meta_provider ++CLASS=$OCF_RESKEY_CRM_meta_class ++TYPE=$OCF_RESKEY_CRM_meta_type ++ ++CONTAINER=$OCF_RESKEY_CRM_meta_isolation_instance ++if [ -z "$CONTAINER" ]; then ++ CONTAINER=$OCF_RESOURCE_INSTANCE ++fi ++ ++RSC_STATE_DIR="${HA_RSCTMP}/docker-wrapper/${CONTAINER}-data/" ++RSC_STATE_FILE="$RSC_STATE_DIR/$OCF_RESOURCE_INSTANCE.state" ++CONNECTION_FAILURE=0 ++HOST_LOG_DIR="${HA_RSCTMP}/docker-wrapper/${CONTAINER}-logs" ++HOST_LOG_FILE="$HOST_LOG_DIR/pacemaker.log" ++GUEST_LOG_DIR="/var/log/pcmk" ++GUEST_LOG_FILE="$GUEST_LOG_DIR/pacemaker.log" ++ ++pcmk_docker_wrapper_usage() { ++ cat < $RSC_STATE_FILE ++ fi ++} ++ ++clear_state_file() ++{ ++ if [ -f "$RSC_STATE_FILE" ]; then ++ rm -f $RSC_STATE_FILE ++ fi ++} ++ ++clear_state_dir() ++{ ++ [ -d "$RSC_STATE_DIR" ] || return 0 ++ ++ rm -rf $RSC_STATE_DIR ++} ++ ++num_active_resources() ++{ ++ local count ++ ++ [ -d "$RSC_STATE_DIR" ] || return 0 ++ ++ count="$(ls $RSC_STATE_DIR | wc -w)" ++ if [ $? -ne 0 ] || [ -z "$count" ]; then ++ return 0 ++ fi ++ return $count ++} ++ ++random_port() ++{ ++ local port=$(python -c 'import socket; s=socket.socket(); s.bind(("localhost", 0)); print(s.getsockname()[1]); s.close()') ++ if [ $? -eq 0 ] && [ -n "$port" ]; then ++ echo "$port" ++ fi ++} ++ ++get_active_port() ++{ ++ PORT="$(docker port $CONTAINER 3121 | awk -F: '{ print $2 }')" ++} ++ ++# separate docker args from ocf resource args. ++separate_args() ++{ ++ local env key value ++ ++ # write out arguments to key value string for ocf agent ++ while read -r line; ++ do ++ key="$(echo $line | awk -F= '{print $1}' | sed 's/^OCF_RESKEY_//g')" ++ val="$(echo $line | awk -F= '{print $2}')" ++ KEY_VAL_STR="$KEY_VAL_STR -k '$key' -v '$val'" ++ done < <(printenv | grep "^OCF.*" | grep -v "^OCF_RESKEY_${CONF_PREFIX}_.*") ++ ++ # sanitize args for DOCKER agent's consumption ++ while read -r line; ++ do ++ env="$(echo $line | awk -F= '{print $1}')" ++ val="$(echo $line | awk -F= '{print $2}')" ++ key="$(echo "$env" | sed "s/^OCF_RESKEY_${CONF_PREFIX}/OCF_RESKEY/g")" ++ export $key="$val" ++ done < <(printenv | grep "^OCF_RESKEY_${CONF_PREFIX}_.*") ++ ++ if ocf_is_true $OCF_RESKEY_privileged ; then ++ export OCF_RESKEY_run_cmd="/usr/sbin/pacemaker_remoted" ++ # on start set random port to run_opts ++ # write port to state file... or potentially get from ps? maybe docker info or inspect as well? ++ ++ else ++ export OCF_RESKEY_run_cmd="/usr/libexec/pacemaker/lrmd" ++ fi ++ export OCF_RESKEY_name="$CONTAINER" ++} ++ ++monitor_container() ++{ ++ local rc ++ ++ $DOCKER_AGENT monitor ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ clear_state_dir ++ return $rc ++ fi ++ ++ poke_remote ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ # container is up without an active daemon. this is bad ++ ocf_log err "Container, $CONTAINER, is active without a responsive pacemaker_remote instance" ++ CONNECTION_FAILURE=1 ++ return $OCF_ERR_GENERIC ++ fi ++ CONNECTION_FAILURE=0 ++ ++ return $rc ++} ++ ++pcmk_docker_wrapper_monitor() { ++ local rc ++ ++ monitor_container ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ return $rc ++ fi ++ ++ client_action "monitor" ++ rc=$? ++ if [ $rc -eq $OCF_SUCCESS ] || [ $rc -eq $OCF_RUNNING_MASTER ]; then ++ write_state_file ++ else ++ clear_state_file ++ fi ++ ++ return $rc ++} ++ ++pcmk_docker_wrapper_generic_action() ++{ ++ local rc ++ ++ monitor_container ++ rc=$? ++ if [ $? -ne $OCF_SUCCESS ]; then ++ return $rc ++ fi ++ ++ client_action "$1" ++} ++ ++client_action() ++{ ++ local action=$1 ++ local agent_type="-T $TYPE -C $CLASS" ++ local rc=0 ++ ++ if [ -n "$PROVIDER" ]; then ++ agent_type="$agent_type -P $PROVIDER" ++ fi ++ ++ if ocf_is_true $OCF_RESKEY_privileged ; then ++ if [ -z "$PORT" ]; then ++ get_active_port ++ fi ++ export PCMK_logfile=$HOST_LOG_FILE ++ ocf_log info "$CLIENT -c 'exec' -S '127.0.0.1' -p '$PORT' -a '$action' -r '$OCF_RESOURCE_INSTANCE' -n '$CONTAINER' '$agent_type' $KEY_VAL_STR " ++ eval $CLIENT -c 'exec' -S '127.0.0.1' -p '$PORT' -a '$action' -r '$OCF_RESOURCE_INSTANCE' -n '$CONTAINER' '$agent_type' $KEY_VAL_STR ++ else ++ export PCMK_logfile=$GUEST_LOG_FILE ++ ocf_log info "$CLIENT -c \"exec\" -a $action -r \"$OCF_RESOURCE_INSTANCE\" $agent_type $KEY_VAL_STR" ++ echo "$CLIENT -c \"exec\" -a $action -r \"$OCF_RESOURCE_INSTANCE\" $agent_type $KEY_VAL_STR " | nsenter --target $(docker inspect --format {{.State.Pid}} ${CONTAINER}) --mount --uts --ipc --net --pid ++ fi ++ rc=$? ++ ++ ocf_log debug "Client action $action with result $rc" ++ return $rc ++} ++ ++poke_remote() ++{ ++ # verifies daemon in container is active ++ if ocf_is_true $OCF_RESKEY_privileged ; then ++ get_active_port ++ ocf_log info "Attempting to contect $CONTAINER on port $PORT" ++ $CLIENT -c "poke" -S "127.0.0.1" -p $PORT -n $CONTAINER ++ fi ++ # no op for non privileged containers since we handed the ++ # client monitor action as the monitor_cmd for the docker agent ++} ++ ++start_container() ++{ ++ local rc ++ ++ monitor_container ++ rc=$? ++ if [ $rc -eq $OCF_SUCCESS ]; then ++ return $rc ++ fi ++ ++ mkdir -p $HOST_LOG_DIR ++ export OCF_RESKEY_run_opts="-e PCMK_logfile=$GUEST_LOG_FILE $OCF_RESKEY_run_opts" ++ export OCF_RESKEY_run_opts="-v $HOST_LOG_DIR:$GUEST_LOG_DIR $OCF_RESKEY_run_opts" ++ if ocf_is_true $OCF_RESKEY_privileged ; then ++ if ! [ -f "/etc/pacemaker/authkey" ]; then ++ # generate an authkey if it doesn't exist. ++ mkdir -p /etc/pacemaker/ ++ dd if=/dev/urandom of=/etc/pacemaker/authkey bs=4096 count=1 > /dev/null 2>&1 ++ chmod 600 /etc/pacemaker/authkey ++ fi ++ ++ PORT=$(random_port) ++ if [ -z "$PORT" ]; then ++ ocf_exit_reason "Unable to assign random port for pacemaker remote" ++ return $OCF_ERR_GENERIC ++ fi ++ export OCF_RESKEY_run_opts="-p 127.0.0.1:${PORT}:3121 $OCF_RESKEY_run_opts" ++ export OCF_RESKEY_run_opts="-v /etc/pacemaker/authkey:/etc/pacemaker/authkey $OCF_RESKEY_run_opts" ++ ocf_log debug "using privileged mode: run_opts=$OCF_RESKEY_run_opts" ++ else ++ export OCF_RESKEY_monitor_cmd="$CLIENT -c poke" ++ fi ++ ++ $DOCKER_AGENT start ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ ++ docker ps > /dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ ocf_exit_reason "docker daemon is inactive." ++ fi ++ return $rc ++ fi ++ ++ monitor_container ++} ++ ++pcmk_docker_wrapper_start() { ++ local rc ++ ++ start_container ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ return $rc ++ fi ++ ++ client_action "start" ++ rc=$? ++ if [ $? -ne "$OCF_SUCCESS" ]; then ++ ocf_exit_reason "Failed to start agent within container" ++ return $rc ++ fi ++ ++ pcmk_docker_wrapper_monitor ++ rc=$? ++ if [ $rc -eq $OCF_SUCCESS ]; then ++ ocf_log notice "$OCF_RESOURCE_INSTANCE started successfully. Container's logfile can be found at $HOST_LOG_FILE" ++ fi ++ ++ return $rc ++} ++ ++stop_container() ++{ ++ local rc ++ local count ++ ++ num_active_resources ++ count=$? ++ if [ $count -ne 0 ]; then ++ ocf_log err "Failed to stop agent within container. Killing container $CONTAINER with $count active resources" ++ fi ++ ++ $DOCKER_AGENT "stop" ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ ocf_exit_reason "Docker container failed to stop" ++ return $rc ++ fi ++ clear_state_dir ++ return $rc ++} ++ ++stop_resource() ++{ ++ local rc ++ ++ client_action "stop" ++ rc=$? ++ if [ $? -ne "$OCF_SUCCESS" ]; then ++ export OCF_RESKEY_force_stop="true" ++ kill_now=1 ++ else ++ clear_state_file ++ fi ++} ++ ++pcmk_docker_wrapper_stop() { ++ local rc ++ local kill_now=0 ++ local all_stopped=0 ++ ++ pcmk_docker_wrapper_monitor ++ rc=$? ++ if [ $rc -eq $OCF_NOT_RUNNING ]; then ++ rc=$OCF_SUCCESS ++ num_active_resources ++ if [ $? -eq 0 ]; then ++ # stop container if no more resources are running ++ ocf_log info "Gracefully stopping container $CONTAINER because no resources are left running." ++ stop_container ++ rc=$? ++ fi ++ return $rc ++ fi ++ ++ # if we can't talk to the remote daemon but the container is ++ # active, we have to force kill the container. ++ if [ $CONNECTION_FAILURE -eq 1 ]; then ++ export OCF_RESKEY_force_kill="true" ++ stop_container ++ return $? ++ fi ++ ++ ++ # If we've gotten this far, the container is up, and we ++ # need to gracefully stop a resource within the container. ++ client_action "stop" ++ rc=$? ++ if [ $? -ne "$OCF_SUCCESS" ]; then ++ export OCF_RESKEY_force_stop="true" ++ # force kill the container if we fail to stop a resource. ++ stop_container ++ rc=$? ++ else ++ clear_state_file ++ num_active_resources ++ if [ $? -eq 0 ]; then ++ # stop container if no more resources are running ++ ocf_log info "Gracefully stopping container $CONTAINER because last resource has stopped" ++ stop_container ++ rc=$? ++ fi ++ fi ++ ++ return $rc ++} ++ ++pcmk_docker_wrapper_validate() { ++ check_binary docker ++ ++ if [ -z "$CLASS" ] || [ -z "$TYPE" ]; then ++ ocf_exit_reason "Update pacemaker to a version that supports container wrappers." ++ return $OCF_ERR_CONFIGURED ++ fi ++ ++ if ! [ -f "$DOCKER_AGENT" ]; then ++ ocf_exit_reason "Requires $DOCKER_AGENT to be installed. update the resource-agents package" ++ return $OCF_ERR_INSTALLED ++ fi ++ $DOCKER_AGENT validate-all ++ return $? ++} ++ ++case $__OCF_ACTION in ++meta-data) meta_data ++ exit $OCF_SUCCESS ++ ;; ++usage|help) pcmk_docker_wrapper_usage ++ exit $OCF_SUCCESS ++ ;; ++esac ++ ++separate_args ++pcmk_docker_wrapper_validate ++rc=$? ++if [ $rc -ne 0 ]; then ++ case $__OCF_ACTION in ++ stop) exit $OCF_SUCCESS;; ++ monitor) exit $OCF_NOT_RUNNING;; ++ *) exit $rc;; ++ esac ++fi ++ ++case $__OCF_ACTION in ++ start) pcmk_docker_wrapper_start;; ++ stop) pcmk_docker_wrapper_stop;; ++ monitor|status) pcmk_docker_wrapper_monitor;; ++ reload|promote|demote|notify) ++ pcmk_docker_wrapper_generic_action $__OCF_ACTION;; ++ validate-all) pcmk_docker_wrapper_validate;; ++ *) pcmk_docker_wrapper_usage ++ exit $OCF_ERR_UNIMPLEMENTED ++ ;; ++esac ++rc=$? ++ocf_log debug "Docker-wrapper ${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" ++exit $rc ++ +diff --git a/extra/resources/ping b/extra/resources/ping +index b9a69b8..ca9db75 100755 +--- a/extra/resources/ping ++++ b/extra/resources/ping +@@ -43,8 +43,7 @@ meta_data() { + 1.0 + + +-Every time the monitor action is run, this resource agent records (in the CIB) the current number of ping nodes the host can connect to. +-It is essentially the same as pingd except that it uses the system ping tool to obtain the results. ++Every time the monitor action is run, this resource agent records (in the CIB) the current number of nodes the host can connect to using the system fping (preferred) or ping tool. + + node connectivity + +@@ -77,7 +76,7 @@ The name of the attributes to set. This is the name to be used in the constrain + The number by which to multiply the number of connected ping nodes by + + Value multiplier +- ++ + + + +@@ -93,7 +92,7 @@ The list of ping nodes to count. + Number of ping attempts, per host, before declaring it dead + + no. of ping attempts +- ++ + + + +@@ -121,6 +120,15 @@ Default never fails. + + + ++ ++ ++Use fping rather than ping, if found. If set to 0, fping ++will not be used even if present. ++ ++Use fping if available ++ ++ ++ + + + Enables to use default attrd_updater verbose logging on every call. +@@ -154,7 +162,7 @@ ping_conditional_log() { + + ping_usage() { + cat <$f_out 2>$f_err; rc=$? + active=`grep alive $f_out|wc -l` + +@@ -274,7 +282,7 @@ ping_check() { + + ping_update() { + +- if have_binary fping; then ++ if ocf_is_true "$OCF_RESKEY_use_fping" && have_binary fping; then + fping_check + active=$? + else +@@ -306,6 +314,7 @@ ping_update() { + : ${OCF_RESKEY_multiplier:="1"} + : ${OCF_RESKEY_debug:="false"} + : ${OCF_RESKEY_failure_score:="0"} ++: ${OCF_RESKEY_use_fping:="1"} + + : ${OCF_RESKEY_CRM_meta_timeout:="20000"} + : ${OCF_RESKEY_CRM_meta_globally_unique:="true"} +diff --git a/extra/resources/remote b/extra/resources/remote +index 9e0482b..c481863 100644 +--- a/extra/resources/remote ++++ b/extra/resources/remote +@@ -44,7 +44,8 @@ meta_data() { + + + +- 0.1 ++0.1 ++remote resource agent + + + +@@ -53,20 +54,33 @@ meta_data() { + Server location + + +- ++ + + tcp port to connect to. + + tcp port +- ++ ++ ++ ++ ++ Time in seconds to wait before attempting to reconnect to a remote node ++ after an active connection to the remote node has been severed. This wait ++ is recurring. If reconnect fails after the wait period, a new reconnect ++ attempt will be made after observing the wait time. When this option is ++ in use, pacemaker will keep attempting to reach out and connect to the ++ remote node indefinitely after each wait interval. ++ ++ reconnect interval ++ + + + +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +@@ -96,8 +110,9 @@ start) remote_unsupported;; + stop) remote_unsupported;; + monitor) remote_unsupported;; + migrate_to) remote_unsupported;; +-migrate_from) remote_unsupported;; +-validate-all) remote_unsupported;; ++migrate_from) remote_unsupported;; ++reload) remote_unsupported;; ++validate-all) remote_unsupported;; + usage|help) remote_usage + exit $OCF_SUCCESS + ;; +diff --git a/extra/rgmanager/Makefile.am b/extra/rgmanager/Makefile.am +deleted file mode 100644 +index 7fa7299..0000000 +--- a/extra/rgmanager/Makefile.am ++++ /dev/null +@@ -1,39 +0,0 @@ +-# +-# Copyright (C) 2004-2009 Andrew Beekhof +-# +-# This program is free software; you can redistribute it and/or +-# modify it under the terms of the GNU General Public License +-# as published by the Free Software Foundation; either version 2 +-# of the License, or (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program; if not, write to the Free Software +-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-# +- +-MAINTAINERCLEANFILES = Makefile.in +- +-if BUILD_CMAN +- +-# Migration tools +-bin_PROGRAMS = ccs_flatten disable_rgmanager +-bin_SCRIPTS = ccs2cib +-ccs_flatten_SOURCES = reslist.c resrules.c restree.c flatten.c xmlconf.c +-disable_rgmanager_SOURCES = disable_rgmanager.c +- +-dist_pkgdata_DATA = cluconf2cib.xsl +- +-ccs2cib: ccs2cib.in +- echo "#!/bin/sh" > $@ +- echo >> $@ +- echo XSL_FILE=\"$(pkgdatadir)/cluconf2cib.xsl\" >> $@ +- echo SAXON_JAR=\"$(datadir)/java/saxon.jar\" >> $@ +- echo >> $@ +- cat $^ >> $@ +- chmod +x $@ +-endif +diff --git a/extra/rgmanager/README b/extra/rgmanager/README +index b32a990..24e10e7 100644 +--- a/extra/rgmanager/README ++++ b/extra/rgmanager/README +@@ -1,21 +1,30 @@ +-Linux-cluster cluster.conf to Pacemaker CIB translation +-utility. ++# Legacy: Linux-cluster cluster.conf to Pacemaker CIB translation utility + +-Development is on Fedora 14+ ++This directory used contain several parts related to the procedure of ++cluster stacks/configuration migration, in particular and as the directory ++name suggests: from (CMAN+RGManager)-based stack of HA components to ++the (Corosync+Pacemaker)-based one. + +-2 phases: +- Step 1: Flatten tree +- Step 2: Convert ++This initial effort laid here was used as a foundation for a more ++sophisticated and maintained tool, [clufter](https://github.com/jnpkrn/clufter), ++which has made local tool-set obsolete since then. + +-Requires: +- resource-agents +- libxml2 +- java +- saxon >= 9.1 +- java-1.6.0-openjdk ++In case any dependencies on previously offered bits arose as time was ++passing by, a mapping to the clufter-provided alternatives is provided: + +-TODO: +- * Fencing +- * Resource-defaults [ skipping ] +- ... +- * Profit ++* `ccs2cib.in` resulting in `ccs2cib` conversion launcher ++ - use `clufter ccs2pcs` (perhaps with some switches) and wrap it with ++ some usage-specific script if suitable ++* `ccs_flatten.c` and the rest of C-files resulting in `ccs_flatten` binary ++ - you can find the same modulo few modifications in `ccs-flatten` ++ subdirectory within the released tarballs or repo itself ++ and the resulting binary is a crucial part of clufter installation ++* `cluconf2cib.xsl` ++ - deprecated in favor of multiple, sequentially chained XSL stylesheets ++ decomposed into tree-like structure (refer to `filters/cluster` ++ subdirectory but beware, it is accompanied with transformations for ++ various other purposes) ++* `disable_rgmanager.c` resulting in `disable_rgmanager` utility ++ - use `clufter ccs-disable-rg` (since `clufter-0.12.0`) ++* `tests` subdirectory ++ - configs have been put under `tests/cluster.conf/orig` in clufter repo +diff --git a/extra/rgmanager/README.markdown b/extra/rgmanager/README.markdown +new file mode 120000 +index 0000000..100b938 +--- /dev/null ++++ b/extra/rgmanager/README.markdown +@@ -0,0 +1 @@ ++README +\ No newline at end of file +diff --git a/extra/rgmanager/ccs2cib.in b/extra/rgmanager/ccs2cib.in +deleted file mode 100644 +index e49ce2f..0000000 +--- a/extra/rgmanager/ccs2cib.in ++++ /dev/null +@@ -1,169 +0,0 @@ +-# Above is autogenerated; DEBUG here is run-time +-DEBUG=0 +- +-export XSL_FILE SAXON_JAR DEBUG +- +-die() +-{ +- echo "$*" +- exit 1 +-} +- +-_validate() +-{ +- if [ $DEBUG -eq 1 ]; then +- echo "debug: adding . to $PATH" +- export PATH="$PATH:." +- fi +- +- which ccs_flatten &> /dev/null || die "Can't find ccs_flatten in path!" +- which java &> /dev/null || die "Can not find java in path!" +- +- if [ -z "$XSL_FILE" ]; then +- if [ $DEBUG -eq 1 ]; then +- XSL_FILE=./cluconf2cib.xsl +- echo "debug: using $XSL_FILE" +- else +- die "Please specify path to XSLT script using -X ." +- fi +- fi +- +- if [ -z "$SAXON_JAR" ]; then +- if [ $DEBUG -eq 1 ]; then +- SAXON_JAR=/usr/share/java/saxon.jar +- echo "debug: using $SAXON_JAR" +- else +- die "Please specify path to saxon.jar using -J ." +- fi +- fi +- +- [ -d /usr/share/cluster ] || die "/usr/share/cluster does not exist." +- [ -f /usr/share/cluster/service.sh ] || die "Missing rgmanager resource agents?" +- +- [ -f "$XSL_FILE" ] || die "$XSL_FILE does not exist!" +- [ -f "$SAXON_JAR" ] || die "$SAXON_JAR does not exist!" +- +- [ -f "$1" ] || die "Input file $1 not found" +- if [ -f "$2" ]; then +- [ $3 -ne 0 ] || die "Output file $2 exists; please remove or use -f" +- fi +- +- return 0 +-} +- +- +-help() +-{ +-cat < Specify path to XSLT script +- -J Specify path to Saxon jar file +- -h This message +-EOT +-} +- +- +-# main +-declare conf_in cib_out xsl_file saxon_jar conf_out opt do_update tmp +-declare force_update no_verify +- +-# defaults +-conf_in="/etc/cluster/cluster.conf" +-cib_out="cib-converted.xml" +-conf_out="" +-do_update=0 +-no_verify=0 +-force_update=0 +-tmp=$(mktemp /tmp/ccs2cib.tmp.XXXXXX) +- +-while getopts i:o:X:J:Rr:dnhf opt; do +- case $opt in +- d) +- DEBUG=1 +- ;; +- i) +- conf_in="$OPTARG" +- ;; +- o) +- cib_out="$OPTARG" +- ;; +- R) +- do_update=1 +- ;; +- r) +- do_update=1 +- conf_out="$OPTARG" +- ;; +- n) +- no_verify=1 +- ;; +- f) +- force_update=1 +- ;; +- X) +- XSL_FILE="$OPTARG" +- ;; +- J) +- SAXON_JAR="$OPTARG" +- ;; +- h) +- help $0 +- exit 0 +- ;; +- *) +- echo "Error parsing $opt" +- help $0 +- exit 1 +- ;; +- esac +-done +- +-[ -z "$conf_out" ] && conf_out="$conf_in" +- +-_validate "$conf_in" "$cib_out" $force_update +- +-echo " * Converting configuration" +-if ! ccs_flatten "$conf_in" > $tmp; then +- rm -f $tmp +- die "Flattening of configuration file failed." +-fi +- +-if ! java -jar $SAXON_JAR -xsl:$XSL_FILE $tmp > $cib_out; then +- rm -f $tmp +- die "Conversion failed." +-fi +- +-echo " * Calling crm_verify to validate the configuration." +- +-if [ $no_verify -eq 0 ]; then +- crm_verify --xml-file $cib_out -V || die "Validation failed." +-fi +- +-if [ $do_update -ne 0 ]; then +- echo " * Disabling rgmanager in $conf_out" +- rm -f $tmp +- disable_rgmanager "$conf_in" > "$tmp" || die "Failed to disable rgmanager" +- mv "$tmp" "$conf_out" +- if [ "$conf_out" = "/etc/cluster/cluster.conf" ]; then +- if clustat -Q &> /dev/null; then +- echo " * Calling cman_tool to update cluster.conf" +- cman_tool version -r +- else +- echo " * You will need to manually copy $conf_out to the other cluster" +- echo " nodes using scp, ccs_sync, or some other utility." +- fi +- fi +-fi +- +-echo " * Proposed cib stored in $cib_out" +- +-exit 0 +diff --git a/extra/rgmanager/cluconf2cib.xsl b/extra/rgmanager/cluconf2cib.xsl +deleted file mode 100644 +index 885bc51..0000000 +--- a/extra/rgmanager/cluconf2cib.xsl ++++ /dev/null +@@ -1,242 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- 500000 +- +- +- +- +- 1000000 +- +- +- +- +- +- +- +- INFINITY +- -INFINITY +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/extra/rgmanager/disable_rgmanager.c b/extra/rgmanager/disable_rgmanager.c +deleted file mode 100644 +index 05c2695..0000000 +--- a/extra/rgmanager/disable_rgmanager.c ++++ /dev/null +@@ -1,121 +0,0 @@ +-/* +- Copyright Red Hat, Inc. 2004-2006 +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 2, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, but +- WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to the +- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +- MA 02110-1301 USA +-*/ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define shift() {++argv; --argc;} +- +-static int +-disable_rgmanager(xmlDocPtr doc) +-{ +- char buf[32]; +- xmlNodePtr n, o; +- char *a; +- int x; +- +- if (!doc) +- return 0; +- n = xmlDocGetRootElement(doc); +- if (!n) +- return 0; +- if (strcmp((char *)n->name, "cluster")) { +- fprintf(stderr, "Expected cluster tag, got %s\n", (char *)n->name); +- return 0; +- } +- +- a = (char *)xmlGetProp(n, (xmlChar *) "config_version"); +- if (!a) { +- fprintf(stderr, "No config_version found on cluster tag\n"); +- return 0; +- } +- +- x = atoi(a); +- if (x == 0) { +- fprintf(stderr, "config_version was invalid\n"); +- return 0; +- } +- +- ++x; +- snprintf(buf, sizeof(buf), "%d", x); +- if (xmlSetProp(n, (xmlChar *) "config_version", (xmlChar *) buf) == NULL) { +- fprintf(stderr, "Failed to update config_version\n"); +- return 0; +- } +- +- for (o = n->xmlChildrenNode; o; o = o->next) { +- if (o->type != XML_ELEMENT_NODE) +- continue; +- if (!strcmp((char *)o->name, "rm")) +- break; +- } +- +- if (!o) +- return 0; +- +- if (xmlSetProp(o, (xmlChar *) "disabled", (xmlChar *) "1") == NULL) { +- fprintf(stderr, "Failed to disable rgmanager\n"); +- return 0; +- } +- +- return 1; +-} +- +-static void +-usage(const char *arg0, int ret) +-{ +- fprintf(stderr, "usage: %s [output.conf]\n", arg0); +- exit(ret); +-} +- +-int +-main(int argc, char **argv) +-{ +- char *arg0 = basename(argv[0]); +- int ret = 0; +- xmlDocPtr doc = NULL; +- +- if (argc < 2) { +- usage(arg0, 1); +- } +- +- if (!strcasecmp(argv[1], "-h") || !strcasecmp(argv[1], "-?")) { +- usage(arg0, 0); +- } +- +- xmlInitParser(); +- xmlIndentTreeOutput = 1; +- xmlKeepBlanksDefault(0); +- +- shift(); +- doc = xmlParseFile(argv[0]); +- +- if (disable_rgmanager(doc)) { +- xmlDocFormatDump(stdout, doc, 1); +- } +- +- if (doc) +- xmlFreeDoc(doc); +- xmlCleanupParser(); +- return ret; +-} +diff --git a/extra/rgmanager/flatten.c b/extra/rgmanager/flatten.c +deleted file mode 100644 +index d500bd4..0000000 +--- a/extra/rgmanager/flatten.c ++++ /dev/null +@@ -1,240 +0,0 @@ +-/* +- Copyright Red Hat, Inc. 2004-2006 +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 2, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, but +- WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to the +- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +- MA 02110-1301 USA +-*/ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define shift() {++argv; --argc;} +- +-const char *agentpath = RESOURCE_ROOTDIR; +- +-static xmlNode * +-get_rm_node(xmlDocPtr doc) +-{ +- xmlNodePtr n, o; +- +- if (!doc) +- return NULL; +- n = xmlDocGetRootElement(doc); +- if (!n) +- return NULL; +- if (strcmp((char *)n->name, "cluster")) { +- fprintf(stderr, "Expected cluster tag, got %s\n", (char *)n->name); +- return NULL; +- } +- +- for (o = n->xmlChildrenNode; o; o = o->next) { +- if (o->type != XML_ELEMENT_NODE) +- continue; +- if (!strcmp((char *)o->name, "rm")) +- return o; +- } +- +- return NULL; +-} +- +-static void +-remove_resources_block(xmlNodePtr rm) +-{ +- xmlNodePtr o, r = NULL; +- +- for (o = rm->xmlChildrenNode; o; o = o->next) { +- if (o->type != XML_ELEMENT_NODE) +- continue; +- if (!strcmp((char *)o->name, "resources")) { +- r = o; +- break; +- } +- } +- +- if (!r) +- return; +- +- xmlUnlinkNode(r); +- xmlFreeNode(r); +-} +- +-static int +-replace_resource(xmlNodePtr rm, char *restype, char *primattr, char *ident, xmlNodePtr n) +-{ +- xmlNodePtr o, r = NULL; +- char *p; +- +- for (o = rm->xmlChildrenNode; o; o = o->next) { +- if (o->type != XML_ELEMENT_NODE) +- continue; +- if (!strcmp((char *)o->name, restype)) { +- p = (char *)xmlGetProp(o, (xmlChar *) primattr); +- if (!strcmp(p, ident)) { +- r = o; +- break; +- } +- } +- } +- +- if (!r) +- return -1; +- +- xmlUnlinkNode(r); +- xmlFreeNode(r); +- +- xmlAddChild(rm, n); +- +- return 0; +-} +- +-static int +-flatten(int argc, char **argv, xmlDocPtr * doc) +-{ +- xmlDocPtr d = NULL; +- xmlNode *n = NULL, *rm = NULL, *new_rb = NULL; +- resource_rule_t *rulelist = NULL; +- resource_t *reslist = NULL, *curres; +- resource_node_t *tree = NULL, *rn; +- FILE *f = stdout; +- int ret = 0; +- +- conf_setconfig(argv[0]); +- if (conf_open() < 0) { +- xmlFree(new_rb); +- goto out; +- } +- +- while (argc >= 2) { +- shift(); +- if (!strcmp(argv[0], "-r")) { +- if (!new_rb) +- new_rb = xmlNewNode(NULL, (xmlChar *) "rm"); +- } else { +- if (f == stdout) +- f = fopen(argv[0], "w+"); +- } +- } +- +- d = conf_get_doc(); +- rm = get_rm_node(d); +- +- load_resource_rules(agentpath, &rulelist); +- if (!rulelist) { +- fprintf(stderr, "No resource rules available\n"); +- goto out; +- } +- load_resources(&reslist, &rulelist); +- build_resource_tree(&tree, &rulelist, &reslist); +- if (!tree) { +- fprintf(stderr, "No resource trees defined; nothing to do\n"); +- goto out; +- } +-#ifdef DEBUG +- fprintf(stderr, "Resources %p tree %p\n", reslist, tree); +-#endif +- +- shift(); +- +- list_do(&tree, rn) { +- n = NULL; +- +- curres = rn->rn_resource; +- +-#ifdef DEBUG +- fprintf(stderr, "Flatten %s:%s ... \n", curres->r_rule->rr_type, +- curres->r_attrs[0].ra_value); +-#endif +- if (res_flatten(&n, new_rb, &tree, curres)) { +- fprintf(stderr, "FAIL 1\n"); +- ret = -1; +- goto out; +- } +- +- if (replace_resource(rm, curres->r_rule->rr_type, +- curres->r_attrs[0].ra_name, curres->r_attrs[0].ra_value, n) != 0) { +- fprintf(stderr, "FAIL 2\n"); +- ret = -1; +- goto out; +- } +- +- } +- while (!list_done(&tree, rn)) ; +- +- remove_resources_block(rm); +- if (new_rb) { +- xmlAddChild(rm, new_rb); +- } +- +- xmlDocFormatDump(f, d, 1); +- if (f != stdout) +- fclose(f); +- +- out: +- if (ret < 0) { +- xmlFreeDoc(d); +- } else { +- *doc = d; +- } +- conf_close(); +- destroy_resource_tree(&tree); +- destroy_resources(&reslist); +- destroy_resource_rules(&rulelist); +- +- return ret; +-} +- +-static void +-usage(const char *arg0, int ret) +-{ +- fprintf(stderr, "usage: %s [output.conf] [-r]\n", arg0); +- exit(ret); +-} +- +-int +-main(int argc, char **argv) +-{ +- char *arg0 = basename(argv[0]); +- int ret = 0; +- xmlDocPtr doc = NULL; +- +- if (argc < 2) { +- usage(arg0, 1); +- } +- +- if (!strcasecmp(argv[1], "-h") || !strcasecmp(argv[1], "-?")) { +- usage(arg0, 0); +- } +- +- xmlInitParser(); +- xmlIndentTreeOutput = 1; +- xmlKeepBlanksDefault(0); +- +- shift(); +- ret = flatten(argc, argv, &doc); +- +- //if (doc) +- //xmlFreeDoc(doc); +- xmlCleanupParser(); +- return ret; +-} +diff --git a/extra/rgmanager/list.h b/extra/rgmanager/list.h +deleted file mode 100644 +index 6cd5511..0000000 +--- a/extra/rgmanager/list.h ++++ /dev/null +@@ -1,91 +0,0 @@ +-#ifndef _LIST_H +-# define _LIST_H +- +-/** +- Simple list handlig macros. +- Needs rewrite or inclusion of /usr/include/linux/list.h as a replacement. +- */ +- +-/* Must be first if structure is going to use it. */ +-struct list_entry { +- struct list_entry *le_next, *le_prev; +-}; +- +-# define list_head() struct list_entry _list_head +- +-# define le(p) (&((*p)._list_head)) +- +-# define list_insert(list, newnode) \ +-do { \ +- if (!(*list)) { \ +- le(newnode)->le_next = \ +- le(newnode)->le_prev = le(newnode); \ +- *list = (void *)le(newnode); \ +- } else { \ +- le(*list)->le_prev->le_next = le(newnode); \ +- le(newnode)->le_next = le(*list); \ +- le(newnode)->le_prev = le(*list)->le_prev; \ +- le(*list)->le_prev = le(newnode); \ +- } \ +-} while (0) +- +-# define list_prepend(list, newnode) \ +-do { \ +- list_insert(list, newnode); \ +- *list = newnode; \ +-} while (0) +- +-# define list_remove(list, oldnode) \ +-do { \ +- if (le(oldnode) == le(*list)) { \ +- *list = (void *)le(*list)->le_next; \ +- } \ +- if (le(oldnode) == le(*list)) { \ +- le(oldnode)->le_next = NULL; \ +- le(oldnode)->le_prev = NULL; \ +- *list = NULL; \ +- } else { \ +- le(oldnode)->le_next->le_prev = le(oldnode)->le_prev; \ +- le(oldnode)->le_prev->le_next = le(oldnode)->le_next; \ +- le(oldnode)->le_prev = NULL; \ +- le(oldnode)->le_next = NULL; \ +- } \ +-} while (0) +- +-/* +- list_do(list, node) { +- stuff; +- } while (!list_done(list, node)); +- */ +-# define list_do(list, curr) \ +- if (*list && (curr = *list)) do +- +-# define list_done(list, curr) \ +- (curr && (((curr = (void *)le(curr)->le_next)) && (curr == *list))) +- +-/* +- * list_for(list, tmp, counter) { +- * stuff; +- * } +- * +- * counter = # of items in list when done. +- * * sets cnt to 0 before even checking list; +- * * checks for valid list +- * * traverses list, incrementing counter. If we get to the for loop, +- * there must be at least one item in the list +- */ +-# define list_for(list, curr, cnt) \ +- if (!(cnt=0) && (list != NULL) && (*list != NULL)) \ +- for (curr = *list; \ +- (cnt == 0) || (curr != *list); \ +- curr = (void*)le(curr)->le_next, \ +- cnt++) +- +-# define list_for_rev(list, curr, cnt) \ +- if (!(cnt=0) && list && *list) \ +- for (curr = (void *)(le(*list)->le_prev); \ +- (cnt == 0) || ((void *)curr != le(*list)->le_prev); \ +- curr = (void*)(le(curr)->le_prev), \ +- cnt++) +- +-#endif +diff --git a/extra/rgmanager/resgroup.h b/extra/rgmanager/resgroup.h +deleted file mode 100644 +index dbaecb4..0000000 +--- a/extra/rgmanager/resgroup.h ++++ /dev/null +@@ -1,122 +0,0 @@ +-#ifndef __RESGROUP_H +-# define __RESGROUP_H +- +-# include +-# include +-# include +-# include +-# include +-# include +-# include +-# include +- +-/* Requests */ +-# define RG_SUCCESS 0 +-# define RG_FAIL 1 +-# define RG_START 2 +-# define RG_STOP 3 +-# define RG_STATUS 4 +-# define RG_DISABLE 5 +-# define RG_STOP_RECOVER 6 +-# define RG_START_RECOVER 7 +-# define RG_RESTART 8 +-# define RG_EXITING 9 +-# define RG_INIT 10 +-# define RG_ENABLE 11 +-# define RG_STATUS_NODE 12 +-# define RG_RELOCATE 13 +-# define RG_CONDSTOP 14 +-# define RG_CONDSTART 15 +-# define RG_START_REMOTE 16 /* Part of a relocate */ +-# define RG_STOP_USER 17 /* User-stop request */ +-# define RG_STOP_EXITING 18 +- /* Exiting. */ +-# define RG_LOCK 19 +-# define RG_UNLOCK 20 +-# define RG_QUERY_LOCK 21 +-# define RG_MIGRATE 22 +-# define RG_FREEZE 23 +-# define RG_UNFREEZE 24 +-# define RG_STATUS_INQUIRY 25 +-# define RG_CONVALESCE 26 +-# define RG_NONE 999 +- +-/* Resource group states (for now) */ +-# define RG_STATE_BASE 110 +-# define RG_STATE_STOPPED 110 /** Resource group is stopped */ +-# define RG_STATE_STARTING 111 /** Resource is starting */ +-# define RG_STATE_STARTED 112 /** Resource is started */ +-# define RG_STATE_STOPPING 113 /** Resource is stopping */ +-# define RG_STATE_FAILED 114 +- /** Resource has failed */ +-# define RG_STATE_UNINITIALIZED 115 +- /** Thread not running yet */ +-# define RG_STATE_CHECK 116 +- /** Checking status */ +-# define RG_STATE_ERROR 117 +- /** Recoverable error */ +-# define RG_STATE_RECOVER 118 /** Pending recovery */ +-# define RG_STATE_DISABLED 119 /** Resource not allowd to run */ +-# define RG_STATE_MIGRATE 120 /** Resource migrating */ +- +-# define DEFAULT_CHECK_INTERVAL 10 +- +-/* Resource group flags (for now) */ +-# define RG_FLAG_FROZEN (1<<0) +- /** Resource frozen */ +-# define RG_FLAG_PARTIAL (1<<1) +- /** One or more non-critical +- resources offline */ +- +-/* Return codes */ +-# define RG_EEXCL -16 /* Service not runnable due to +- the fact that it is tagged +- exclusive and there are no +- empty nodes. */ +-# define RG_EDOMAIN -15 /* Service not runnable given the +- set of nodes and its failover +- domain */ +-# define RG_ESCRIPT -14 /* S/Lang script failed */ +-# define RG_EFENCE -13 /* Fencing operation pending */ +-# define RG_ENODE -12 /* Node is dead/nonexistent */ +-# define RG_EFROZEN -11 /* Forward compat. with -HEAD */ +-# define RG_ERUN -10 +- /* Service is already running */ +-# define RG_EQUORUM -9 /* Operation requires quorum */ +-# define RG_EINVAL -8 /* Invalid operation for resource */ +-# define RG_EDEPEND -7 /* Operation violates dependency */ +-# define RG_EAGAIN -6 /* Try again */ +-# define RG_EDEADLCK -5 /* Aborted - would deadlock */ +-# define RG_ENOSERVICE -4 /* Service does not exist */ +-# define RG_EFORWARD -3 /* Service not mastered locally */ +-# define RG_EABORT -2 /* Abort; service unrecoverable */ +-# define RG_EFAIL -1 /* Generic failure */ +-# define RG_ESUCCESS 0 +-# define RG_YES 1 +-# define RG_NO 2 +- +-const char *rg_strerror(int val); +- +-/* +- * Fail-over domain states +- */ +-# define FOD_ILLEGAL 0 +-# define FOD_GOOD 1 +-# define FOD_BETTER 2 +-# define FOD_BEST 3 +- +-/* +- Fail-over domain flags +- */ +-# define FOD_ORDERED (1<<0) +-# define FOD_RESTRICTED (1<<1) +-# define FOD_NOFAILBACK (1<<2) +- +-/* +- Status tree flags +- */ +-# define SFL_FAILURE (1<<0) +-# define SFL_RECOVERABLE (1<<1) +-# define SFL_PARTIAL (1<<2) +- +-#endif +diff --git a/extra/rgmanager/reslist.c b/extra/rgmanager/reslist.c +deleted file mode 100644 +index c0b0699..0000000 +--- a/extra/rgmanager/reslist.c ++++ /dev/null +@@ -1,518 +0,0 @@ +-/* +- Copyright Red Hat, Inc. 2004 +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 2, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, but +- WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to the +- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +- MA 02110-1301 USA +-*/ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-void +-res_build_name(char *buf, size_t buflen, resource_t * res) +-{ +- snprintf(buf, buflen, "%s:%s", res->r_rule->rr_type, res->r_attrs[0].ra_value); +-} +- +-/** +- Find and determine an attribute's value. +- +- @param res Resource node to look examine +- @param attrname Attribute to retrieve. +- @return value of attribute or NULL if not found +- */ +-char * +-res_attr_value(resource_t * res, const char *attrname) +-{ +- resource_attr_t *ra; +- int x; +- +- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { +- if (strcmp(attrname, res->r_attrs[x].ra_name)) +- continue; +- +- ra = &res->r_attrs[x]; +- +- if (ra->ra_flags & RA_INHERIT) +- /* Can't check inherited resources */ +- return NULL; +- +- return ra->ra_value; +- } +- +- return NULL; +-} +- +-/** +- Find and determine an attribute's value. Takes into account inherited +- attribute flag, and append attribute flag, which isn't implemented yet. +- +- @param node Resource tree node to look examine +- @param attrname Attribute to retrieve. +- @param ptype Resource type to look for (if inheritance) +- @return value of attribute or NULL if not found +- */ +-static char * +-_attr_value(resource_node_t * node, const char *attrname, const char *ptype) +-{ +- resource_t *res; +- resource_attr_t *ra; +- char *c, p_type[32]; +- ssize_t len; +- int x; +- +- if (!node) +- return NULL; +- +- res = node->rn_resource; +- +- /* Go up the tree if it's not the right parent type */ +- if (ptype && strcmp(res->r_rule->rr_type, ptype)) +- return _attr_value(node->rn_parent, attrname, ptype); +- +- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { +- if (strcmp(attrname, res->r_attrs[x].ra_name)) +- continue; +- +- ra = &res->r_attrs[x]; +- +- if (!(ra->ra_flags & RA_INHERIT)) +- return ra->ra_value; +- /* +- Handle resource_type%field to be more precise, so we +- don't have to worry about this being a child +- of an unexpected type. E.g. lots of things have the +- "name" attribute. +- */ +- c = strchr(ra->ra_value, '%'); +- if (!c) { +- /* Someone doesn't care or uses older +- semantics on inheritance */ +- return _attr_value(node->rn_parent, ra->ra_value, NULL); +- } +- +- len = (c - ra->ra_value); +- memset(p_type, 0, sizeof(p_type)); +- memcpy(p_type, ra->ra_value, len); +- +- /* Skip the "%" and recurse */ +- return _attr_value(node->rn_parent, ++c, p_type); +- } +- +- return NULL; +-} +- +-char * +-attr_value(resource_node_t * node, const char *attrname) +-{ +- return _attr_value(node, attrname, NULL); +-} +- +-char * +-primary_attr_value(resource_t * res) +-{ +- int x; +- resource_attr_t *ra; +- +- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { +- ra = &res->r_attrs[x]; +- +- if (!(ra->ra_flags & RA_PRIMARY)) +- continue; +- +- return ra->ra_value; +- } +- +- return NULL; +-} +- +-/** +- Find a resource given its reference. A reference is the value of the +- primary attribute. +- +- @param reslist List of resources to traverse. +- @param type Type of resource to look for. +- @param ref Reference +- @return Resource matching type/ref or NULL if none. +- */ +-resource_t * +-find_resource_by_ref(resource_t ** reslist, char *type, char *ref) +-{ +- resource_t *curr; +- int x; +- +- list_do(reslist, curr) { +- if (strcmp(curr->r_rule->rr_type, type)) +- continue; +- +- /* +- This should be one operation - the primary attr +- is generally at the head of the array. +- */ +- for (x = 0; curr->r_attrs && curr->r_attrs[x].ra_name; x++) { +- if (!(curr->r_attrs[x].ra_flags & RA_PRIMARY)) +- continue; +- if (strcmp(ref, curr->r_attrs[x].ra_value)) +- continue; +- +- return curr; +- } +- } +- while (!list_done(reslist, curr)) ; +- +- return NULL; +-} +- +-/** +- Store a resource in the resource list if it's legal to do so. +- Otherwise, don't store it. +- Note: This function needs to be rewritten; it's way too long and way +- too indented. +- +- @param reslist Resource list to store the new resource. +- @param newres Resource to store +- @return 0 on succes; nonzero on failure. +- */ +-int +-store_resource(resource_t ** reslist, resource_t * newres) +-{ +- resource_t *curr; +- int x, y; +- +- if (!*reslist) { +- /* first resource */ +- list_insert(reslist, newres); +- return 0; +- } +- +- list_do(reslist, curr) { +- +- if (strcmp(curr->r_rule->rr_type, newres->r_rule->rr_type)) +- continue; +- +- for (x = 0; newres->r_attrs && newres->r_attrs[x].ra_name; x++) { +- /* +- Look for conflicting primary/unique keys +- */ +- if (!(newres->r_attrs[x].ra_flags & (RA_PRIMARY | RA_UNIQUE))) +- continue; +- +- for (y = 0; curr->r_attrs[y].ra_name; y++) { +- if (curr->r_attrs[y].ra_flags & RA_INHERIT) +- continue; +- +- if (strcmp(curr->r_attrs[y].ra_name, newres->r_attrs[x].ra_name)) +- continue; +- if (!strcmp(curr->r_attrs[y].ra_value, newres->r_attrs[x].ra_value)) { +- /* +- Unique/primary is not unique +- */ +- fprintf(stderr, +- "%s attribute collision. " +- "type=%s attr=%s value=%s\n", +- (newres->r_attrs[x].ra_flags & +- RA_PRIMARY) ? "Primary" : +- "Unique", +- newres->r_rule->rr_type, +- newres->r_attrs[x].ra_name, newres->r_attrs[x].ra_value); +- return -1; +- } +- break; +- } +- } +- } +- while (!list_done(reslist, curr)) ; +- +- list_insert(reslist, newres); +- return 0; +-} +- +-/** +- Obliterate a resource_t structure. +- +- @param res Resource to free. +- */ +-void +-destroy_resource(resource_t * res) +-{ +- int x; +- +- if (res->r_name) +- free(res->r_name); +- +- if (res->r_attrs) { +- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { +- free(res->r_attrs[x].ra_name); +- free(res->r_attrs[x].ra_value); +- } +- +- free(res->r_attrs); +- } +- +- if (res->r_actions) { +- /* Don't free the strings; they're part of the rule */ +- free(res->r_actions); +- } +- +- free(res); +-} +- +-/** +- Obliterate a resource_t list. +- +- @param list Resource list to free. +- */ +-void +-destroy_resources(resource_t ** list) +-{ +- resource_t *res; +- +- while ((res = *list)) { +- list_remove(list, res); +- destroy_resource(res); +- } +-} +- +-void * +-act_dup(resource_act_t * acts) +-{ +- int x; +- resource_act_t *newacts; +- +- for (x = 0; acts[x].ra_name; x++) ; +- +- ++x; +- x *= sizeof(resource_act_t); +- +- newacts = malloc(x); +- if (!newacts) +- return NULL; +- +- memcpy(newacts, acts, x); +- +- return newacts; +-} +- +-/* Copied from resrules.c -- _get_actions */ +-static void +-_get_actions_ccs(const char *base, resource_t * res) +-{ +- char xpath[256]; +- int idx = 0; +- char *act, *ret; +- int interval, timeout, depth; +- +- do { +- /* setting these to -1 prevents overwriting with 0 */ +- interval = -1; +- depth = -1; +- act = NULL; +- timeout = -1; +- +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@name", base, ++idx); +- +- if (conf_get(xpath, &act) != 0) +- break; +- +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@timeout", base, idx); +- if (conf_get(xpath, &ret) == 0 && ret) { +- timeout = expand_time(ret); +- if (timeout < 0) +- timeout = 0; +- free(ret); +- } +- +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@interval", base, idx); +- if (conf_get(xpath, &ret) == 0 && ret) { +- interval = expand_time(ret); +- if (interval < 0) +- interval = 0; +- free(ret); +- } +- +- if (!strcmp(act, "status") || !strcmp(act, "monitor")) { +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@depth", base, idx); +- if (conf_get(xpath, &ret) == 0 && ret) { +- depth = atoi(ret); +- if (depth < 0) +- depth = 0; +- +- /* */ +- if (ret[0] == '*') +- depth = -1; +- free(ret); +- } +- } +- +- if (store_action(&res->r_actions, act, depth, timeout, interval) != 0) +- free(act); +- } while (1); +-} +- +-/** +- Try to load all the attributes in our rule set. If none are found, +- or an error occurs, return NULL and move on to the next one. +- +- @param rule Resource rule set to use when looking for data +- @param base Base XPath path to start with. +- @return New resource if legal or NULL on failure/error +- */ +-resource_t * +-load_resource(resource_rule_t * rule, const char *base) +-{ +- resource_t *res; +- char ccspath[1024]; +- char *attrname, *attr; +- int x, found = 0, flags; +- +- res = malloc(sizeof(*res)); +- if (!res) { +- fprintf(stderr, "Out of memory\n"); +- return NULL; +- } +- +- memset(res, 0, sizeof(*res)); +- res->r_rule = rule; +- +- for (x = 0; res->r_rule->rr_attrs && res->r_rule->rr_attrs[x].ra_name; x++) { +- +- flags = rule->rr_attrs[x].ra_flags; +- attrname = strdup(rule->rr_attrs[x].ra_name); +- if (!attrname) { +- destroy_resource(res); +- return NULL; +- } +- +- /* +- Ask CCS for the respective attribute +- */ +- attr = NULL; +- snprintf(ccspath, sizeof(ccspath), "%s/@%s", base, attrname); +- +- if (conf_get(ccspath, &attr) != 0) { +- +- if (flags & (RA_REQUIRED | RA_PRIMARY)) { +- /* Missing required attribute. We're done. */ +- free(attrname); +- destroy_resource(res); +- return NULL; +- } +- +- if (!(flags & RA_INHERIT)) { +- /* +- If we don't have the inherit flag, see if +- we have a value anyway. If we do, +- this value is the default value, and +- should be used. +- */ +- if (!rule->rr_attrs[x].ra_value) { +- free(attrname); +- continue; +- } +- +- /* Copy default value from resource rule */ +- attr = strdup(rule->rr_attrs[x].ra_value); +- } +- } +- +- found = 1; +- +- /* +- If we are supposed to inherit and we don't have an +- instance of the specified attribute in CCS, then we +- keep the inherit flag and use it as the attribute. +- +- However, if we _do_ have the attribute for this instance, +- we drop the inherit flag and use the attribute. +- */ +- if (flags & RA_INHERIT) { +- if (attr) { +- flags &= ~RA_INHERIT; +- } else { +- attr = strdup(rule->rr_attrs[x].ra_value); +- if (!attr) { +- destroy_resource(res); +- free(attrname); +- return NULL; +- } +- } +- } +- +- /* +- Store the attribute. We'll ensure all required +- attributes are present soon. +- */ +- if (attrname && attr) +- store_attribute(&res->r_attrs, attrname, attr, flags); +- } +- +- if (!found) { +- destroy_resource(res); +- return NULL; +- } +- +- res->r_actions = act_dup(rule->rr_actions); +- _get_actions_ccs(base, res); +- +- return res; +-} +- +-/** +- Read all resources in the resource manager block in CCS. +- +- @param reslist Empty list to fill with resources. +- @param rulelist List of rules to use when searching CCS. +- @return 0 on success, nonzero on failure. +- */ +-int +-load_resources(resource_t ** reslist, resource_rule_t ** rulelist) +-{ +- int resID = 0; +- resource_t *newres; +- resource_rule_t *currule; +- char tok[256]; +- +- list_do(rulelist, currule) { +- +- for (resID = 1;; resID++) { +- snprintf(tok, sizeof(tok), RESOURCE_BASE "/%s[%d]", currule->rr_type, resID); +- +- newres = load_resource(currule, tok); +- if (!newres) +- break; +- +- if (store_resource(reslist, newres) != 0) { +- fprintf(stderr, "Error storing %s resource\n", newres->r_rule->rr_type); +- +- destroy_resource(newres); +- } +- +- /* Just information */ +- newres->r_flags = RF_DEFINED; +- } +- } +- while (!list_done(rulelist, currule)) ; +- +- return 0; +-} +diff --git a/extra/rgmanager/reslist.h b/extra/rgmanager/reslist.h +deleted file mode 100644 +index 07c84fe..0000000 +--- a/extra/rgmanager/reslist.h ++++ /dev/null +@@ -1,205 +0,0 @@ +-/* +- Copyright Red Hat, Inc. 2004 +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 2, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, but +- WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to the +- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +- MA 02110-1301 USA +-*/ +-#ifndef _RESLIST_H +-# define _RESLIST_H +- +-# include +-# include +-# include +-# include +- +-# define RA_PRIMARY (1<<0) /** Primary key */ +-# define RA_UNIQUE (1<<1) /** Unique for given type */ +-# define RA_REQUIRED (1<<2) /** Required (or an error if not present */ +-# define RA_INHERIT (1<<3) /** Inherit a parent resource's attr */ +-# define RA_RECONFIG (1<<4) /** Allow inline reconfiguration */ +- +-# define RF_INLINE (1<<0) +-# define RF_DEFINED (1<<1) +-# define RF_NEEDSTART (1<<2) /** Used when adding/changing resources */ +-# define RF_NEEDSTOP (1<<3) /** Used when deleting/changing resources */ +-# define RF_COMMON (1<<4) /** " */ +-# define RF_INDEPENDENT (1<<5) +- /** Define this for a resource if it is +- otherwise an independent subtree */ +-# define RF_RECONFIG (1<<6) +- +-# define RF_INIT (1<<7) +- /** Resource rule: Initialize this resource +- class on startup */ +-# define RF_DESTROY (1<<8) /** Resource rule flag: Destroy this +- resource class if you delete it from +- the configuration */ +-# define RF_ENFORCE_TIMEOUTS (1<<9) +- /** Enforce timeouts for this node */ +-# define RF_NON_CRITICAL (1<<10) +- /** stop this resource if it fails */ +-# define RF_QUIESCE (1<<11) /** don't restart this resource */ +- +-# define RES_STOPPED (0) +-# define RES_STARTED (1) +-# define RES_FAILED (2) +-# define RES_DISABLED (3) +- +-# ifndef SHAREDIR +-# define SHAREDIR "/usr/share/cluster" +-# endif +- +-# define RESOURCE_ROOTDIR SHAREDIR +-# define RESOURCE_TREE_ROOT "//rm" +-# define RESOURCE_BASE RESOURCE_TREE_ROOT "/resources" +-# define RESOURCE_ROOT_FMT RESOURCE_TREE_ROOT "/%s[%d]" +- +-# define RESOURCE_MAX_LEVELS 100 +- +-/* Include OCF definitions */ +-//#include +- +-typedef struct _resource_attribute { +- char *ra_name; +- char *ra_value; +- int ra_flags; +- int _pad_; +-} resource_attr_t; +- +-typedef struct _resource_child { +- char *rc_name; +- int rc_startlevel; +- int rc_stoplevel; +- int rc_forbid; +- int rc_flags; +-} resource_child_t; +- +-typedef struct _resource_act { +- char *ra_name; +- time_t ra_timeout; +- time_t ra_last; +- time_t ra_interval; +- int ra_depth; +- int _pad_; +-} resource_act_t; +- +-typedef struct _resource_rule { +- list_head(); +- char *rr_type; +- char *rr_agent; +- char *rr_version; /** agent XML spec version; OCF-ism */ +- int rr_flags; +- int rr_maxrefs; +- resource_attr_t *rr_attrs; +- resource_child_t *rr_childtypes; +- resource_act_t *rr_actions; +-} resource_rule_t; +- +-typedef struct _resource { +- list_head(); +- resource_rule_t *r_rule; +- char *r_name; +- resource_attr_t *r_attrs; +- resource_act_t *r_actions; +- int r_flags; +- int r_refs; +- int r_incarnations; /** Number of instances running locally */ +- int _pad_; /* align */ +-} resource_t; +- +-typedef struct _rg_node { +- list_head(); +- struct _rg_node *rn_child, *rn_parent; +- resource_t *rn_resource; +- resource_act_t *rn_actions; +- int rn_state; /* State of this instance of rn_resource */ +- int rn_flags; +- int rn_last_status; +- int rn_last_depth; +- int rn_checked; +- int rn_pad; +-} resource_node_t; +- +-typedef struct _fod_node { +- list_head(); +- char *fdn_name; +- int fdn_prio; +- int fdn_nodeid; /* on rhel4 this will be 64-bit int */ +-} fod_node_t; +- +-typedef struct _fod { +- list_head(); +- char *fd_name; +- fod_node_t *fd_nodes; +- int fd_flags; +- int _pad_; /* align */ +-} fod_t; +- +-/* +- Exported Functions +- */ +-int res_flatten(xmlNode ** n, xmlNode * r, resource_node_t ** tree, resource_t * res); +- +-int expand_time(char *val); +-int store_action(resource_act_t ** actsp, char *name, int depth, int timeout, int interval); +- +-/* +- Load/kill resource rule sets +- */ +-int load_resource_rules(const char *rpath, resource_rule_t ** rules); +-void destroy_resource_rules(resource_rule_t ** rules); +- +-/* +- Load/kill resource sets +- */ +-int load_resources(resource_t ** reslist, resource_rule_t ** rulelist); +-void dump_resources(FILE * fp, resource_t ** reslist); +-void destroy_resources(resource_t ** list); +- +-/* +- Construct/deconstruct resource trees +- */ +-int build_resource_tree(resource_node_t ** tree, +- resource_rule_t ** rulelist, resource_t ** reslist); +-void destroy_resource_tree(resource_node_t ** tree); +- +-/* +- Construct/deconstruct failover domains +- */ +-int construct_domains(fod_t ** domains); +-void deconstruct_domains(fod_t ** domains); +- +-/* +- Handy functions +- */ +-resource_t *find_resource_by_ref(resource_t ** reslist, char *type, char *ref); +-resource_rule_t *find_rule_by_type(resource_rule_t ** rulelist, char *type); +-void res_build_name(char *, size_t, resource_t *); +- +-/* +- Internal functions; shouldn't be needed. +- */ +-int store_attribute(resource_attr_t ** attrsp, char *name, char *value, int flags); +- +-resource_t *load_resource(resource_rule_t * rule, const char *base); +-int store_resource(resource_t ** reslist, resource_t * newres); +-void destroy_resource(resource_t * res); +- +-char *attr_value(resource_node_t * node, const char *attrname); +-char *res_attr_value(resource_t * res, const char *attrname); +-char *primary_attr_value(resource_t *); +-void *act_dup(resource_act_t * acts); +- +-#endif /* _RESLIST_H */ +diff --git a/extra/rgmanager/resrules.c b/extra/rgmanager/resrules.c +deleted file mode 100644 +index cb003c3..0000000 +--- a/extra/rgmanager/resrules.c ++++ /dev/null +@@ -1,971 +0,0 @@ +-/* +- Copyright Red Hat, Inc. 2004-2010 +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 2, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, but +- WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to the +- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +- MA 02110-1301 USA +-*/ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/** +- Store a new resource rule in the given rule list. +- +- @param rulelist List of rules to store new rule in. +- @param newrule New rule to store. +- @return 0 on success or -1 if rule with same name +- already exists in rulelist +- */ +-static int +-store_rule(resource_rule_t ** rulelist, resource_rule_t * newrule) +-{ +- resource_rule_t *curr; +- +- list_do(rulelist, curr) { +- if (!strcmp(newrule->rr_type, curr->rr_type)) { +- fprintf(stderr, "Error storing %s: Duplicate\n", newrule->rr_type); +- return -1; +- } +- +- } +- while (!list_done(rulelist, curr)) ; +- +- list_insert(rulelist, newrule); +- return 0; +-} +- +-/** +- Obliterate a resource_rule_t structure. +- +- @param rr Resource rule to free. +- */ +-static void +-destroy_resource_rule(resource_rule_t * rr) +-{ +- int x; +- +- if (rr->rr_type) +- free(rr->rr_type); +- if (rr->rr_agent) +- free(rr->rr_agent); +- if (rr->rr_version) +- free(rr->rr_version); +- +- if (rr->rr_attrs) { +- for (x = 0; rr->rr_attrs && rr->rr_attrs[x].ra_name; x++) { +- free(rr->rr_attrs[x].ra_name); +- if (rr->rr_attrs[x].ra_value) +- free(rr->rr_attrs[x].ra_value); +- } +- +- free(rr->rr_attrs); +- } +- +- if (rr->rr_actions) { +- for (x = 0; rr->rr_actions && rr->rr_actions[x].ra_name; x++) { +- free(rr->rr_actions[x].ra_name); +- } +- +- free(rr->rr_actions); +- } +- +- if (rr->rr_childtypes) { +- for (x = 0; rr->rr_childtypes && rr->rr_childtypes[x].rc_name; x++) +- free(rr->rr_childtypes[x].rc_name); +- free(rr->rr_childtypes); +- } +- +- free(rr); +-} +- +-/** +- Destroy a list of resource rules. +- +- @param rules List of rules to destroy. +- */ +-void +-destroy_resource_rules(resource_rule_t ** rules) +-{ +- resource_rule_t *rr; +- +- while ((rr = *rules)) { +- list_remove(rules, rr); +- destroy_resource_rule(rr); +- } +-} +- +-/** +- Get and store the maxparents (max instances) attribute for a given +- resource rule set. +- +- @param doc Pre-parsed XML document pointer. +- @param ctx Pre-allocated XML XPath context pointer. +- @param base XPath prefix to search +- @param rr Resource rule to store new information in. +- */ +-static void +-_get_maxparents(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) +-{ +- char xpath[256]; +- char *ret = NULL; +- +- snprintf(xpath, sizeof(xpath), "%s/attributes/@maxinstances", base); +- ret = xpath_get_one(doc, ctx, xpath); +- if (ret) { +- rr->rr_maxrefs = atoi(ret); +- if (rr->rr_maxrefs < 0) +- rr->rr_maxrefs = 0; +- free(ret); +- } +-} +- +-/** +- Get and store a bit field. +- +- @param doc Pre-parsed XML document pointer. +- @param ctx Pre-allocated XML XPath context pointer. +- @param base XPath prefix to search +- @param rr Resource rule to store new information in. +- */ +-static void +-_get_rule_flag(xmlDocPtr doc, xmlXPathContextPtr ctx, const char *base, +- resource_rule_t * rr, const char *flag, int bit) +-{ +- char xpath[256]; +- char *ret = NULL; +- +- snprintf(xpath, sizeof(xpath), "%s/attributes/@%s", base, flag); +- ret = xpath_get_one(doc, ctx, xpath); +- if (ret) { +- if (atoi(ret)) { +- rr->rr_flags |= bit; +- } else { +- rr->rr_flags &= ~bit; +- } +- free(ret); +- } +-} +- +-/** +- Get and store the version +- +- @param doc Pre-parsed XML document pointer. +- @param ctx Pre-allocated XML XPath context pointer. +- @param base XPath prefix to search +- @param rr Resource rule to store new information in. +- */ +-static void +-_get_version(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) +-{ +- char xpath[256]; +- char *ret = NULL; +- +- snprintf(xpath, sizeof(xpath), "%s/@version", base); +- ret = xpath_get_one(doc, ctx, xpath); +- if (ret) { +- rr->rr_version = ret; +- free(ret); +- } +- rr->rr_version = NULL; +-} +- +-int +-expand_time(char *val) +-{ +- int curval, len; +- int ret = 0; +- char *start = val, ival[16]; +- +- if (!val) +- return (time_t) 0; +- +- while (start[0]) { +- +- len = 0; +- curval = 0; +- memset(ival, 0, sizeof(ival)); +- +- while (isdigit(start[len])) { +- ival[len] = start[len]; +- len++; +- } +- +- if (len) { +- curval = atoi(ival); +- } else { +- len = 1; +- } +- +- switch (start[len]) { +- case 0: +- case 'S': +- case 's': +- break; +- case 'M': +- case 'm': +- curval *= 60; +- break; +- case 'h': +- case 'H': +- curval *= 3600; +- break; +- case 'd': +- case 'D': +- curval *= 86400; +- break; +- case 'w': +- case 'W': +- curval *= 604800; +- break; +- case 'y': +- case 'Y': +- curval *= 31536000; +- break; +- default: +- curval = 0; +- } +- +- ret += (time_t) curval; +- start += len; +- } +- +- return ret; +-} +- +-/** +- * Store a resource action +- * @param actsp Action array; may be modified and returned! +- * @param name Name of the action +- * @param depth Resource depth (status/monitor; -1 means *ALL LEVELS* +- * ... this means that only the highest-level check depth +- * will ever be performed!) +- * @param timeout Timeout (not used) +- * @param interval Time interval for status/monitor +- * @return 0 on success, -1 on failure +- * +- */ +-int +-store_action(resource_act_t ** actsp, char *name, int depth, int timeout, int interval) +-{ +- int x = 0, replace = 0; +- resource_act_t *acts = *actsp; +- +- if (!name) +- return -1; +- +- if (depth < 0 && timeout < 0 && interval < 0) +- return -1; +- +- if (!acts) { +- /* Can't create with anything < 0 */ +- if (depth < 0 || timeout < 0 || interval < 0) +- return -1; +- +- acts = malloc(sizeof(resource_act_t) * 2); +- if (!acts) +- return -1; +- acts[0].ra_name = name; +- acts[0].ra_depth = depth; +- acts[0].ra_timeout = timeout; +- acts[0].ra_interval = interval; +- acts[0].ra_last = 0; +- acts[1].ra_name = NULL; +- +- *actsp = acts; +- return 0; +- } +- +- for (x = 0; acts[x].ra_name; x++) { +- if (!strcmp(acts[x].ra_name, name) && (depth == acts[x].ra_depth || depth == -1)) { +- fprintf(stderr, "Replacing action '%s' depth %d: ", name, acts[x].ra_depth); +- if (timeout >= 0) { +- fprintf(stderr, "timeout: %d->%d ", (int)acts[x].ra_timeout, (int)timeout); +- acts[x].ra_timeout = timeout; +- } +- if (interval >= 0) { +- fprintf(stderr, "interval: %d->%d", (int)acts[x].ra_interval, (int)interval); +- acts[x].ra_interval = interval; +- } +- fprintf(stderr, "\n"); +- replace = 1; +- } +- } +- +- if (replace) +- /* If we replaced something, we're done */ +- return 1; +- +- /* Can't create with anything < 0 */ +- if (depth < 0 || timeout < 0 || interval < 0) +- return -1; +- +- acts = realloc(acts, sizeof(resource_act_t) * (x + 2)); +- if (!acts) +- return -1; +- +- acts[x].ra_name = name; +- acts[x].ra_depth = depth; +- acts[x].ra_timeout = timeout; +- acts[x].ra_interval = interval; +- acts[x].ra_last = 0; +- +- acts[x + 1].ra_name = NULL; +- +- *actsp = acts; +- return 0; +-} +- +-static void +-_get_actions(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) +-{ +- char xpath[256]; +- int idx = 0; +- char *act, *ret; +- int interval, timeout, depth; +- +- do { +- interval = 0; +- depth = 0; +- act = NULL; +- timeout = 0; +- +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@name", base, ++idx); +- +- act = xpath_get_one(doc, ctx, xpath); +- if (!act) +- break; +- +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@timeout", base, idx); +- ret = xpath_get_one(doc, ctx, xpath); +- if (ret) { +- timeout = expand_time(ret); +- if (timeout < 0) +- timeout = 0; +- free(ret); +- } +- +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@interval", base, idx); +- ret = xpath_get_one(doc, ctx, xpath); +- if (ret) { +- interval = expand_time(ret); +- if (interval < 0) +- interval = 0; +- free(ret); +- } +- +- if (!strcmp(act, "status") || !strcmp(act, "monitor")) { +- snprintf(xpath, sizeof(xpath), "%s/action[%d]/@depth", base, idx); +- ret = xpath_get_one(doc, ctx, xpath); +- if (ret) { +- depth = atoi(ret); +- if (depth < 0) +- depth = 0; +- free(ret); +- } +- } +- +- if (store_action(&rr->rr_actions, act, depth, timeout, interval) != 0) +- free(act); +- } while (1); +-} +- +-/** +- Store an attribute with the given name, value, and flags in a resource_t +- structure. +- XXX This could be rewritten to use the list macros. +- +- @param attrsp Attribute array to store new attribute in. +- @param name Name of attribute (must be non-null) +- @param value Value of attribute +- @param flags Attribute flags, or 0 if none. +- @return 0 on success, nonzero on error/failure +- */ +-int +-store_attribute(resource_attr_t ** attrsp, char *name, char *value, int flags) +-{ +- int x = 0; +- resource_attr_t *attrs = *attrsp; +- +- if (!name) +- return -1; +- +- if (!attrs) { +- attrs = malloc(sizeof(resource_attr_t) * 2); +- if (!attrs) +- return -1; +- attrs[0].ra_name = name; +- attrs[0].ra_value = value; +- attrs[0].ra_flags = flags; +- attrs[1].ra_name = NULL; +- attrs[1].ra_value = NULL; +- +- *attrsp = attrs; +- return 0; +- } +- +- for (x = 0; attrs[x].ra_name; x++) ; +- +- attrs = realloc(attrs, sizeof(resource_attr_t) * (x + 2)); +- if (!attrs) +- return -1; +- +- /* Primary attribute goes first. This makes this interaction +- with CCS work way faster. */ +- if (flags & RA_PRIMARY) { +- attrs[x].ra_name = attrs[0].ra_name; +- attrs[x].ra_value = attrs[0].ra_value; +- attrs[x].ra_flags = attrs[0].ra_flags; +- attrs[0].ra_name = name; +- attrs[0].ra_value = value; +- attrs[0].ra_flags = flags; +- } else { +- attrs[x].ra_name = name; +- attrs[x].ra_value = value; +- attrs[x].ra_flags = flags; +- } +- attrs[x + 1].ra_name = NULL; +- attrs[x + 1].ra_value = NULL; +- +- *attrsp = attrs; +- return 0; +-} +- +-/** +- Store a child type in the child array of a resource rule. +- XXX Could be rewritten to use list macros. +- +- @param childp Child array. Might be modified. +- @param name Name of child type +- @param start Start level +- @param stop Stop level +- @param forbid Do NOT allow this child type to exist +- @param flags set to 1 to note that it was defined inline +- @return 0 on success, nonzero on failure +- */ +-static int +-store_childtype(resource_child_t ** childp, char *name, int start, int stop, int forbid, int flags) +-{ +- int x = 0; +- resource_child_t *child = *childp; +- +- if (!name) +- return -1; +- +- if (!child) { +- child = malloc(sizeof(resource_child_t) * 2); +- if (!child) +- return -1; +- child[0].rc_name = name; +- child[0].rc_startlevel = start; +- child[0].rc_stoplevel = stop; +- child[0].rc_forbid = forbid; +- child[0].rc_flags = flags; +- child[1].rc_name = NULL; +- +- *childp = child; +- return 0; +- } +- +- for (x = 0; child[x].rc_name; x++) ; +- +- child = realloc(child, sizeof(resource_child_t) * (x + 2)); +- if (!child) +- return -1; +- +- child[x].rc_name = name; +- child[x].rc_startlevel = start; +- child[x].rc_stoplevel = stop; +- child[x].rc_forbid = forbid; +- child[x].rc_flags = flags; +- child[x + 1].rc_name = NULL; +- +- *childp = child; +- return 0; +-} +- +-/** +- Get and store attributes for a given instance of a resource rule. +- +- @param doc Pre-parsed XML document pointer. +- @param ctx Pre-allocated XML XPath context pointer. +- @param base XPath prefix to search +- @param rr Resource rule to store new information in. +- @return 0 +- */ +-static int +-_get_rule_attrs(xmlDocPtr doc, xmlXPathContextPtr ctx, const char *base, resource_rule_t * rr) +-{ +- char *ret, *attrname, *dflt = NULL, xpath[256]; +- int x, flags, primary_found = 0; +- +- for (x = 1; 1; x++) { +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@name", base, x); +- +- ret = xpath_get_one(doc, ctx, xpath); +- if (!ret) +- break; +- +- flags = 0; +- attrname = ret; +- +- /* +- See if there's a default value. +- */ +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/content/@default", base, x); +- dflt = xpath_get_one(doc, ctx, xpath); +- +- /* +- See if this is either the primary identifier or +- a required field. +- */ +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@required", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- if ((atoi(ret) != 0) || (ret[0] == 'y')) +- flags |= RA_REQUIRED; +- free(ret); +- } +- +- /* +- See if this is supposed to be unique +- */ +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@unique", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- if ((atoi(ret) != 0) || (ret[0] == 'y')) +- flags |= RA_UNIQUE; +- free(ret); +- } +- +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@primary", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- if ((atoi(ret) != 0) || (ret[0] == 'y')) { +- if (primary_found) { +- free(ret); +- fprintf(stderr, "Multiple primary " +- "definitions for " "resource type %s\n", rr->rr_type); +- return -1; +- } +- flags |= RA_PRIMARY; +- primary_found = 1; +- } +- free(ret); +- } +- +- /* +- See if this can be reconfigured on the fly without a +- stop/start +- */ +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@reconfig", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- if ((atoi(ret) != 0) || (ret[0] == 'y')) +- flags |= RA_RECONFIG; +- free(ret); +- } +- +- /* +- See if this is supposed to be inherited +- */ +- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@inherit", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- flags |= RA_INHERIT; +- +- if (flags & (RA_REQUIRED | RA_PRIMARY | RA_UNIQUE)) { +- free(ret); +- fprintf(stderr, "Can not inherit and be primary, " "unique, or required\n"); +- return -1; +- } +- /* +- don't free ret. Store as attr value. If we had +- a default value specified from above, free it; +- inheritance supercedes a specified default value. +- */ +- if (dflt) +- free(dflt); +- } else { +- /* +- Use default value, if specified, as the attribute +- value. +- */ +- ret = dflt; +- } +- +- /* +- Store the attribute. We'll ensure all required +- attributes are present soon. +- */ +- if (attrname) +- store_attribute(&rr->rr_attrs, attrname, ret, flags); +- } +- +- return 0; +-} +- +-/** +- Get and store attributes for a given instance of a resource. +- +- @param doc Pre-parsed XML document pointer. +- @param ctx Pre-allocated XML XPath context pointer. +- @param base XPath prefix to search +- @param rr Resource rule to store new information in. +- @return 0 +- */ +-static int +-_get_childtypes(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) +-{ +- char *ret, *childname, xpath[256]; +- int x, startlevel = 0, stoplevel = 0, forbid = 0; +- +- for (x = 1; 1; x++) { +- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@type", base, x); +- +- ret = xpath_get_one(doc, ctx, xpath); +- if (!ret) +- break; +- +- startlevel = stoplevel = forbid = 0; +- childname = ret; +- +- /* +- Try to get the start level if it exists +- */ +- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@start", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- startlevel = atoi(ret); +- free(ret); +- } +- +- /* +- Try to get the stop level if it exists +- */ +- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@stop", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- stoplevel = atoi(ret); +- free(ret); +- } +- +- /* +- Get the 'forbidden' flag if it exists +- */ +- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@forbid", base, x); +- if ((ret = xpath_get_one(doc, ctx, xpath))) { +- forbid = atoi(ret); +- free(ret); +- } +- +- /* +- Store the attribute. We'll ensure all required +- attributes are present soon. +- */ +- if (childname) +- store_childtype(&rr->rr_childtypes, childname, startlevel, stoplevel, forbid, 0); +- } +- +- return 0; +-} +- +-/** +- Read a file from a stdout pipe. +- */ +-static int +-read_pipe(int fd, char **file, size_t * length) +-{ +- char buf[4096]; +- int n, done = 0; +- +- *file = NULL; +- *length = 0; +- +- while (!done) { +- +- n = read(fd, buf, sizeof(buf)); +- if (n < 0) { +- +- if (errno == EINTR) +- continue; +- +- if (*file) +- free(*file); +- return -1; +- } +- +- if (n == 0 && (!*length)) +- return 0; +- +- if (n == 0) { +- done = 1; +- } +- +- if (*file) +- *file = realloc(*file, (*length) + n + done); +- else +- *file = malloc(n + done); +- +- if (!*file) +- return -1; +- +- memcpy((*file) + (*length), buf, n); +- *length += (done + n); +- } +- +- /* Null terminator */ +- (*file)[(*length) - 1] = 0; +- +- return 0; +-} +- +-static xmlDocPtr +-read_resource_agent_metadata(char *filename) +-{ +- int pid; +- int _pipe[2]; +- char *data; +- size_t size; +- xmlDocPtr doc; +- +- if (pipe(_pipe) == -1) +- return NULL; +- +- pid = fork(); +- if (pid == -1) { +- close(_pipe[0]); +- close(_pipe[1]); +- } +- +- if (pid == 0) { +- /* child */ +- close(0); +- close(1); +- close(2); +- +- close(_pipe[0]); +- dup2(_pipe[1], 1); +- close(_pipe[1]); +- +- /* exec */ +- execl(filename, filename, "meta-data", NULL); +- exit(1); +- } +- +- close(_pipe[1]); +- /* parent */ +- if (read_pipe(_pipe[0], &data, &size) == -1) { +- close(_pipe[0]); +- return NULL; +- } +- +- waitpid(pid, NULL, 0); +- close(_pipe[0]); +- +- if (!size) +- return NULL; +- +- doc = xmlParseMemory(data, size); +- free(data); +- return doc; +-} +- +-/** +- Load the XML rule set for a resource and store attributes, constructing +- a new resource_t structure. +- +- @param filename File name to load rules from +- @param rules Rule list to add new rules to +- @return 0 +- */ +-static int +-load_resource_rulefile(char *filename, resource_rule_t ** rules) +-{ +- resource_rule_t *rr = NULL; +- xmlDocPtr doc = NULL; +- xmlXPathContextPtr ctx = NULL; +- int ruleid = 0; +- char *type; +- char base[256]; +- +- doc = read_resource_agent_metadata(filename); +- if (!doc) +- return 0; +- ctx = xmlXPathNewContext(doc); +- +- do { +- /* Look for resource types */ +- snprintf(base, sizeof(base), "/resource-agent[%d]/@name", ++ruleid); +- type = xpath_get_one(doc, ctx, base); +- if (!type) +- break; +- +- if (!strcasecmp(type, "action")) { +- fprintf(stderr, "Error: Resource type '%s' is reserved", type); +- free(type); +- break; +- } +- +- rr = malloc(sizeof(*rr)); +- if (!rr) +- break; +- memset(rr, 0, sizeof(*rr)); +- +- rr->rr_flags = RF_INIT | RF_DESTROY; +- rr->rr_type = type; +- snprintf(base, sizeof(base), "/resource-agent[%d]", ruleid); +- +- /* +- First, grab the global attributes if existent +- */ +- _get_version(doc, ctx, base, rr); +- +- snprintf(base, sizeof(base), "/resource-agent[%d]/special[@tag=\"rgmanager\"]", ruleid); +- _get_maxparents(doc, ctx, base, rr); +- _get_rule_flag(doc, ctx, base, rr, "init_on_add", RF_INIT); +- _get_rule_flag(doc, ctx, base, rr, "destroy_on_delete", RF_DESTROY); +- rr->rr_agent = strdup(filename); +- +- /* +- Second, add the children fields +- */ +- _get_childtypes(doc, ctx, base, rr); +- +- /* +- Get the OCF status check intervals/monitor. +- */ +- snprintf(base, sizeof(base), "/resource-agent[%d]/actions", ruleid); +- _get_actions(doc, ctx, base, rr); +- +- /* +- Last, load the attributes from our XML file and their +- respective instantiations from CCS +- */ +- snprintf(base, sizeof(base), "/resource-agent[%d]/parameters", ruleid); +- if (_get_rule_attrs(doc, ctx, base, rr) < 0) { +- destroy_resource_rule(rr); +- rr = NULL; +- } +- +- if (!rr) +- continue; +- +- if (store_rule(rules, rr) != 0) { +- destroy_resource_rule(rr); +- rr = NULL; +- } +- } while (1); +- +- if (ctx) +- xmlXPathFreeContext(ctx); +- if (doc) +- xmlFreeDoc(doc); +- +- return 0; +-} +- +-/** +- Load all the resource rules we can find from our resource root +- directory. +- +- @param rules Rule list to create/add to +- @return 0 on success, -1 on failure. Sucess does not +- imply any rules have been found; only that no +- errors were encountered. +- */ +-int +-load_resource_rules(const char *rpath, resource_rule_t ** rules) +-{ +- DIR *dir; +- struct dirent *de; +- char *fn, *dot; +- char path[2048]; +- struct stat st_buf; +- +- dir = opendir(rpath); +- if (!dir) +- return -1; +- +- xmlInitParser(); +- while ((de = readdir(dir))) { +- +- fn = basename(de->d_name); +- if (!fn) +- continue; +- +- /* Ignore files with common backup extension */ +- if ((fn != NULL) && (strlen(fn) > 0) && (fn[strlen(fn) - 1] == '~')) +- continue; +- +- /* Ignore hidden files */ +- if (*fn == '.') +- continue; +- +- dot = strrchr(fn, '.'); +- if (dot) { +- /* Ignore RPM installed save files, patches, +- diffs, etc. */ +- if (!strncasecmp(dot, ".rpm", 4)) { +- fprintf(stderr, "Warning: " +- "Ignoring %s/%s: Bad extension %s\n", rpath, de->d_name, dot); +- continue; +- } +- } +- +- snprintf(path, sizeof(path), "%s/%s", rpath, de->d_name); +- +- if (stat(path, &st_buf) < 0) +- continue; +- +- if (S_ISDIR(st_buf.st_mode)) +- continue; +- +- if (st_buf.st_mode & (S_IXUSR | S_IXOTH | S_IXGRP)) { +- //printf("Loading resource rule from %s\n", path); +- load_resource_rulefile(path, rules); +- } +- } +- +- closedir(dir); +- +- return 0; +-} +- +-/** +- Find a resource rule given its type. +- +- @param rulelist Rule list to search +- @param type Rule type identifier +- @return Resource rule or NULL if not found. +- */ +-resource_rule_t * +-find_rule_by_type(resource_rule_t ** rulelist, char *type) +-{ +- resource_rule_t *curr = NULL; +- +- list_do(rulelist, curr) { +- if (!strcmp(curr->rr_type, type)) +- return curr; +- } +- while (!list_done(rulelist, curr)) ; +- +- return NULL; +-} +diff --git a/extra/rgmanager/restree.c b/extra/rgmanager/restree.c +deleted file mode 100644 +index d06be85..0000000 +--- a/extra/rgmanager/restree.c ++++ /dev/null +@@ -1,723 +0,0 @@ +-/* +- Copyright Red Hat, Inc. 2004-2006 +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 2, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, but +- WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING. If not, write to the +- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +- MA 02110-1301 USA +- +- Fix for #193859 - relocation of a service w/o umounting file-systems +- by Navid Sheikhol-Eslami [ navid at redhat dot com ] +-*/ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* XXX from resrules.c */ +-int store_childtype(resource_child_t ** childp, char *name, int start, +- int stop, int forbid, int flags); +-int _res_op(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first, char *type); +-static inline int +- +- +-_res_op_internal(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first, +- char *type, resource_node_t * node); +- +-/* XXX from reslist.c */ +-void *act_dup(resource_act_t * acts); +- +-/** +- Fold a resource into an XML node. +- +- @param xpp XML node pp +- @param rmp resources block pp +- @param node Resource tree node we're dealing with +- @param op Operation to perform (stop/start/etc.) +- @param depth OCF Check level/depth +- @return Return value of script. +- @see build_env +- */ +-static int +-res_do_flatten(xmlNode ** xpp, xmlNode * rmp, resource_node_t * node, const char *arg, int depth) +-{ +- xmlNode *n, *r; +- resource_attr_t *ra; +- resource_t *res = node->rn_resource; +- char *val; +- char buf[256]; +- int x, y; +- +- n = xmlNewNode(NULL, (xmlChar *) node->rn_resource->r_rule->rr_type); +- +- xmlSetProp(n, (xmlChar *) "rgmanager-meta-agent", +- (xmlChar *) basename(node->rn_resource->r_rule->rr_agent)); +- +- /* Multiple-instance resources must be decomposed into separate +- resources */ +- if (node->rn_resource->r_refs > 1) { +- snprintf(buf, sizeof(buf), "%s_%d", +- primary_attr_value(node->rn_resource), node->rn_resource->r_incarnations); +- ++node->rn_resource->r_incarnations; +- } else { +- snprintf(buf, sizeof(buf), "%s", primary_attr_value(node->rn_resource)); +- } +- +- for (x = 0; node->rn_resource->r_attrs && node->rn_resource->r_attrs[x].ra_name; x++) { +- ra = &node->rn_resource->r_attrs[x]; +- +- if (ra->ra_flags & RA_PRIMARY) { +- xmlSetProp(n, (xmlChar *) ra->ra_name, (xmlChar *) buf); +- } else { +- val = attr_value(node, res->r_attrs[x].ra_name); +- if (!val) +- continue; +- +- for (y = 0; res->r_rule->rr_attrs[y].ra_name; y++) { +- if (strcmp(ra->ra_name, res->r_rule->rr_attrs[y].ra_name)) +- continue; +- +- if (!res->r_rule->rr_attrs[y].ra_value || +- strcmp(val, res->r_rule->rr_attrs[y].ra_value)) +- xmlSetProp(n, (xmlChar *) ra->ra_name, (xmlChar *) val); +- } +- } +- } +- +- if (!*xpp) { +- /* Add top-level container */ +- *xpp = n; +- } else { +- if (!rmp) { +- xmlAddChild(*xpp, n); +- } else { +- r = xmlNewNode(NULL, (xmlChar *) node->rn_resource->r_rule->rr_type); +- xmlSetProp(r, (xmlChar *) "ref", (xmlChar *) primary_attr_value(node->rn_resource)); +- xmlAddChild(rmp, n); +- xmlAddChild(*xpp, r); +- } +- } +- +- return 0; +-} +- +-static inline void +-assign_restart_policy(resource_t * curres, resource_node_t * parent, +- resource_node_t * node, char *base) +-{ +- char *val; +- int max_restarts = 0; +- time_t restart_expire_time = 0; +- char tok[1024]; +- +- if (!curres || !node) +- return; +- if (parent && !(node->rn_flags & RF_INDEPENDENT)) +- return; +- +- if (node->rn_flags & RF_INDEPENDENT) { +- /* per-resource-node failures / expire times */ +- snprintf(tok, sizeof(tok), "%s/@__max_restarts", base); +- if (conf_get(tok, &val) == 0) { +- max_restarts = atoi(val); +- if (max_restarts <= 0) +- max_restarts = 0; +- free(val); +- } +- +- snprintf(tok, sizeof(tok), "%s/@__restart_expire_time", base); +- if (conf_get(tok, &val) == 0) { +- restart_expire_time = (time_t) expand_time(val); +- if ((int64_t) restart_expire_time <= 0) +- restart_expire_time = 0; +- free(val); +- } +- //if (restart_expire_time == 0 || max_restarts == 0) +- return; +- //goto out_assign; +- } +- +- val = (char *)res_attr_value(curres, "max_restarts"); +- if (!val) +- return; +- max_restarts = atoi(val); +- if (max_restarts <= 0) +- return; +- val = res_attr_value(curres, "restart_expire_time"); +- if (val) { +- restart_expire_time = (time_t) expand_time(val); +- if ((int64_t) restart_expire_time < 0) +- return; +- } +-//out_assign: +- return; +-} +- +-static inline int +-do_load_resource(char *base, +- resource_rule_t * rule, +- resource_node_t ** tree, +- resource_t ** reslist, resource_node_t * parent, resource_node_t ** newnode) +-{ +- char tok[512]; +- char *ref; +- resource_node_t *node; +- resource_t *curres; +- time_t failure_expire = 0; +- int max_failures = 0; +- +- snprintf(tok, sizeof(tok), "%s/@ref", base); +- +- if (conf_get(tok, &ref) != 0) { +- /* There wasn't an existing resource. See if there +- is one defined inline */ +- curres = load_resource(rule, base); +- if (!curres) { +- /* No ref and no new one inline == +- no more of the selected type */ +- return 1; +- } +- +- if (store_resource(reslist, curres) != 0) { +- fprintf(stderr, "Error storing %s resource\n", curres->r_rule->rr_type); +- destroy_resource(curres); +- return -1; +- } +- +- curres->r_flags = RF_INLINE; +- +- } else { +- +- curres = find_resource_by_ref(reslist, rule->rr_type, ref); +- if (!curres) { +- fprintf(stderr, "Error: Reference to nonexistent " +- "resource %s (type %s)\n", ref, rule->rr_type); +- free(ref); +- return -1; +- } +- +- if (curres->r_flags & RF_INLINE) { +- fprintf(stderr, "Error: Reference to inlined " +- "resource %s (type %s) is illegal\n", ref, rule->rr_type); +- free(ref); +- return -1; +- } +- free(ref); +- } +- +- /* Load it if its max refs hasn't been exceeded */ +- if (rule->rr_maxrefs && (curres->r_refs >= rule->rr_maxrefs)) { +- fprintf(stderr, "Warning: Max references exceeded for resource" +- " %s (type %s)\n", curres->r_attrs[0].ra_name, rule->rr_type); +- return -1; +- } +- +- node = malloc(sizeof(*node)); +- if (!node) +- return -1; +- +- memset(node, 0, sizeof(*node)); +- +- //printf("New resource tree node: %s:%s \n", curres->r_rule->rr_type,curres->r_attrs->ra_value); +- +- node->rn_child = NULL; +- node->rn_parent = parent; +- node->rn_resource = curres; +- node->rn_state = RES_STOPPED; +- node->rn_flags = 0; +- node->rn_actions = (resource_act_t *) act_dup(curres->r_actions); +- +- if (parent) { +- /* Independent subtree / non-critical for top-level is +- * not useful and can interfere with restart thresholds for +- * non critical resources */ +- snprintf(tok, sizeof(tok), "%s/@__independent_subtree", base); +- if (conf_get(tok, &ref) == 0) { +- if (atoi(ref) == 1 || strcasecmp(ref, "yes") == 0) +- node->rn_flags |= RF_INDEPENDENT; +- if (atoi(ref) == 2 || strcasecmp(ref, "non-critical") == 0) { +- curres->r_flags |= RF_NON_CRITICAL; +- } +- free(ref); +- } +- } +- +- snprintf(tok, sizeof(tok), "%s/@__enforce_timeouts", base); +- if (conf_get(tok, &ref) == 0) { +- if (atoi(ref) > 0 || strcasecmp(ref, "yes") == 0) +- node->rn_flags |= RF_ENFORCE_TIMEOUTS; +- free(ref); +- } +- +- /* per-resource-node failures / expire times */ +- snprintf(tok, sizeof(tok), "%s/@__max_failures", base); +- if (conf_get(tok, &ref) == 0) { +- max_failures = atoi(ref); +- if (max_failures < 0) +- max_failures = 0; +- free(ref); +- } +- +- snprintf(tok, sizeof(tok), "%s/@__failure_expire_time", base); +- if (conf_get(tok, &ref) == 0) { +- failure_expire = (time_t) expand_time(ref); +- if ((int64_t) failure_expire < 0) +- failure_expire = 0; +- free(ref); +- } +- +- if (max_failures && failure_expire) { +- /* +- node->rn_failure_counter = restart_init(failure_expire, +- max_failures); +- */ +- } +- +- curres->r_refs++; +- +- if (curres->r_refs > 1 && (curres->r_flags & RF_NON_CRITICAL)) { +- res_build_name(tok, sizeof(tok), curres); +- fprintf(stderr, "Non-critical flag for %s is being cleared due to multiple references.\n", +- tok); +- curres->r_flags &= ~RF_NON_CRITICAL; +- } +- +- if (curres->r_flags & RF_NON_CRITICAL) { +- /* Independent subtree is implied if a +- * resource is non-critical +- */ +- node->rn_flags |= RF_NON_CRITICAL | RF_INDEPENDENT; +- +- } +- +- assign_restart_policy(curres, parent, node, base); +- +- *newnode = node; +- +- list_insert(tree, node); +- +- return 0; +-} +- +-/** +- Build the resource tree. If a new resource is defined inline, add it to +- the resource list. All rules, however, must have already been read in. +- +- @param tree Tree to modify/insert on to +- @param parent Parent node, if one exists. +- @param rule Rule surrounding the new node +- @param rulelist List of all rules allowed in the tree. +- @param reslist List of all currently defined resources +- @param base Base CCS path. +- @see destroy_resource_tree +- */ +-#define RFL_FOUND 0x1 +-#define RFL_FORBID 0x2 +-static int +-build_tree(resource_node_t ** tree, +- resource_node_t * parent, +- resource_rule_t * rule, resource_rule_t ** rulelist, resource_t ** reslist, char *base) +-{ +- char tok[512]; +- resource_rule_t *childrule; +- resource_node_t *node; +- char *ref; +- char *tmp; +- int ccount = 0, x = 0, y = 0, flags = 0; +- +- //printf("DESCEND: %s / %s\n", rule?rule->rr_type:"(none)", base); +- +- /* Pass 1: typed / defined children */ +- for (y = 0; rule && rule->rr_childtypes && rule->rr_childtypes[y].rc_name; y++) { +- +- flags = 0; +- list_for(rulelist, childrule, x) { +- if (strcmp(rule->rr_childtypes[y].rc_name, childrule->rr_type)) +- continue; +- +- flags |= RFL_FOUND; +- +- if (rule->rr_childtypes[y].rc_forbid) +- flags |= RFL_FORBID; +- +- break; +- } +- +- if (flags & RFL_FORBID) +- /* Allow all *but* forbidden */ +- continue; +- +- if (!(flags & RFL_FOUND)) +- /* Not found? Wait for pass 2 */ +- continue; +- +- //printf("looking for %s %s @ %s\n", +- //rule->rr_childtypes[y].rc_name, +- //childrule->rr_type, base); +- for (x = 1;; x++) { +- +- /* Search for base/type[x]/@ref - reference an existing +- resource */ +- snprintf(tok, sizeof(tok), "%s/%s[%d]", base, childrule->rr_type, x); +- +- flags = 1; +- switch (do_load_resource(tok, childrule, tree, reslist, parent, &node)) { +- case -1: +- continue; +- case 1: +- /* 1 == no more */ +- //printf("No resource found @ %s\n", tok); +- flags = 0; +- break; +- case 0: +- break; +- } +- if (!flags) +- break; +- +- /* Got a child :: bump count */ +- snprintf(tok, sizeof(tok), "%s/%s[%d]", base, childrule->rr_type, x); +- +- /* Kaboom */ +- build_tree(&node->rn_child, node, childrule, rulelist, reslist, tok); +- +- } +- } +- +- /* Pass 2: untyped children */ +- for (ccount = 1;; ccount++) { +- snprintf(tok, sizeof(tok), "%s/child::*[%d]", base, ccount); +- +- if (conf_get(tok, &ref) != 0) { +- /* End of the line. */ +- //printf("End of the line: %s\n", tok); +- break; +- } +- +- tmp = strchr(ref, '='); +- if (tmp) { +- *tmp = 0; +- } else { +- /* no = sign... bad */ +- free(ref); +- continue; +- } +- +- /* Find the resource rule */ +- flags = 0; +- list_for(rulelist, childrule, x) { +- if (!strcasecmp(childrule->rr_type, ref)) { +- /* Ok, matching rule found */ +- flags = 1; +- break; +- } +- } +- /* No resource rule matching the child? Press on... */ +- if (!flags) { +- free(ref); +- continue; +- } +- +- flags = 0; +- /* Don't descend on anything we should have already picked +- up on in the above loop */ +- for (y = 0; rule && rule->rr_childtypes && rule->rr_childtypes[y].rc_name; y++) { +- /* SKIP defined child types of any type */ +- if (strcmp(rule->rr_childtypes[y].rc_name, ref)) +- continue; +- if (rule->rr_childtypes[y].rc_flags == 0) { +- /* 2 = defined as a real child */ +- flags = 2; +- break; +- } +- +- flags = 1; +- break; +- } +- +- free(ref); +- if (flags == 2) +- continue; +- +- x = 1; +- switch (do_load_resource(tok, childrule, tree, reslist, parent, &node)) { +- case -1: +- continue; +- case 1: +- /* no more found */ +- x = 0; +- fprintf(stderr, "No resource found @ %s\n", tok); +- break; +- case 0: +- /* another is found */ +- break; +- } +- if (!x) /* no more found */ +- break; +- +- /* childrule = rule set of this child at this point */ +- /* tok = set above; if we got this far, we're all set */ +- /* Kaboom */ +- +- build_tree(&node->rn_child, node, childrule, rulelist, reslist, tok); +- } +- +- //printf("ASCEND: %s / %s\n", rule?rule->rr_type:"(none)", base); +- return 0; +-} +- +-/** +- Set up to call build_tree. Hides the nastiness from the user. +- +- @param tree Tree pointer. Should start as a pointer to NULL. +- @param rulelist List of all rules allowed +- @param reslist List of all currently defined resources +- @return 0 +- @see build_tree destroy_resource_tree +- */ +-int +-build_resource_tree(resource_node_t ** tree, resource_rule_t ** rulelist, resource_t ** reslist) +-{ +- resource_node_t *root = NULL; +- char tok[512]; +- +- snprintf(tok, sizeof(tok), "%s", RESOURCE_TREE_ROOT); +- +- /* Find and build the list of root nodes */ +- build_tree(&root, NULL, NULL /*curr */ , rulelist, reslist, tok); +- +- if (root) +- *tree = root; +- +- return 0; +-} +- +-/** +- Deconstruct a resource tree. +- +- @param tree Tree to obliterate. +- @see build_resource_tree +- */ +-void +-destroy_resource_tree(resource_node_t ** tree) +-{ +- resource_node_t *node; +- +- while ((node = *tree)) { +- if ((*tree)->rn_child) +- destroy_resource_tree(&(*tree)->rn_child); +- +- list_remove(tree, node); +- +- if (node->rn_actions) { +- free(node->rn_actions); +- } +- free(node); +- } +-} +- +-static inline int +-_do_child_levels(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first) +-{ +- resource_node_t *node = *tree; +- resource_t *res = node->rn_resource; +- resource_rule_t *rule = res->r_rule; +- int l, lev, x, rv = 0; +- +- for (l = 1; l <= RESOURCE_MAX_LEVELS; l++) { +- +- for (x = 0; rule->rr_childtypes && rule->rr_childtypes[x].rc_name; x++) { +- +- lev = rule->rr_childtypes[x].rc_startlevel; +- +- if (!lev || lev != l) +- continue; +- +- /* Do op on all children at our level */ +- rv |= _res_op(xpp, rmp, &node->rn_child, first, rule->rr_childtypes[x].rc_name); +- +- if (rv & SFL_FAILURE) +- return rv; +- } +- +- if (rv != 0) +- return rv; +- } +- +- return rv; +-} +- +-static inline int +-_xx_child_internal(xmlNode ** xpp, xmlNode * rmp, resource_node_t * node, resource_t * first, +- resource_node_t * child) +-{ +- int x; +- resource_rule_t *rule = node->rn_resource->r_rule; +- +- for (x = 0; rule->rr_childtypes && rule->rr_childtypes[x].rc_name; x++) { +- if (!strcmp(child->rn_resource->r_rule->rr_type, rule->rr_childtypes[x].rc_name)) { +- if (rule->rr_childtypes[x].rc_startlevel || rule->rr_childtypes[x].rc_stoplevel) { +- return 0; +- } +- } +- } +- +- return _res_op_internal(xpp, rmp, &child, first, child->rn_resource->r_rule->rr_type, child); +-} +- +-static inline int +-_do_child_default_level(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first) +-{ +- resource_node_t *node = *tree, *child; +- int y, rv = 0; +- +- list_for(&node->rn_child, child, y) { +- rv |= _xx_child_internal(xpp, rmp, node, first, child); +- +- if (rv & SFL_FAILURE) +- return rv; +- } +- +- return rv; +-} +- +-/** +- Nasty codependent function. Perform an operation by numerical level +- at some point in the tree. This allows indirectly-dependent resources +- (such as IP addresses and user scripts) to have ordering without requiring +- a direct dependency. +- +- @param tree Resource tree to search/perform operations on +- @param first Resource we're looking to perform the operation on, +- if one exists. +- @param ret Unused, but will be used to store status information +- such as resources consumed, etc, in the future. +- @param op Operation to perform if either first is found, +- or no first is declared (in which case, all nodes +- in the subtree). +- @see _res_op res_exec +- */ +-static int +-_res_op_by_level(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first) +-{ +- resource_node_t *node = *tree; +- resource_t *res = node->rn_resource; +- resource_rule_t *rule = res->r_rule; +- int rv = 0; +- +- if (!rule->rr_childtypes) +- return _res_op(xpp, rmp, &node->rn_child, first, NULL); +- +- rv |= _do_child_levels(xpp, rmp, tree, first); +- if (rv & SFL_FAILURE) +- return rv; +- +- /* default level after specified ones */ +- rv |= _do_child_default_level(xpp, rmp, tree, first); +- +- return rv; +-} +- +-/** +- Nasty codependent function. Perform an operation by type for all siblings +- at some point in the tree. This allows indirectly-dependent resources +- (such as IP addresses and user scripts) to have ordering without requiring +- a direct dependency. +- +- @param tree Resource tree to search/perform operations on +- @param first Resource we're looking to perform the operation on, +- if one exists. +- @param type Type to look for. +- @see _res_op_by_level res_exec +- */ +-static inline int +-_res_op_internal(xmlNode ** xpp, xmlNode * rmp, +- resource_node_t __attribute__ ((unused)) ** tree, +- resource_t * first, char *type, resource_node_t * node) +-{ +- int rv = 0, me; +- +- /* Restore default operation. */ +- +- /* If we're starting by type, do that funky thing. */ +- if (type && strlen(type) && strcmp(node->rn_resource->r_rule->rr_type, type)) +- return 0; +- +- /* If the resource is found, all nodes in the subtree must +- have the operation performed as well. */ +- me = !first || (node->rn_resource == first); +- +- /* Start starts before children */ +- if (me) { +- +- rv = res_do_flatten(xpp, rmp, node, NULL, 0); +- +- } +- +- if (node->rn_child) { +- rv |= _res_op_by_level(xpp, rmp, &node, me ? NULL : first); +- } +- +- return rv; +-} +- +-/** +- Nasty codependent function. Perform an operation by type for all siblings +- at some point in the tree. This allows indirectly-dependent resources +- (such as IP addresses and user scripts) to have ordering without requiring +- a direct dependency. +- +- @param tree Resource tree to search/perform operations on +- @param first Resource we're looking to perform the operation on, +- if one exists. +- @param type Type to look for. +- @see _res_op_by_level res_exec +- */ +-int +-_res_op(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first, char *type) +-{ +- resource_node_t *node; +- int count = 0, rv = 0; +- +- list_for(tree, node, count) { +- rv |= _res_op_internal(xpp, rmp, tree, first, type, node); +- +- if (rv & SFL_FAILURE) +- return rv; +- } +- +- return rv; +-} +- +-/** +- Flatten resources for a service and return the pointer to it. +- +- @param tree Tree to search for our resource. +- @param res Resource to start/stop +- @param ret Unused +- */ +-int +-res_flatten(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * res) +-{ +- return _res_op(xpp, rmp, tree, res, NULL); +-} +diff --git a/extra/rgmanager/tests/test1.conf b/extra/rgmanager/tests/test1.conf +deleted file mode 100644 +index 4b0354f..0000000 +--- a/extra/rgmanager/tests/test1.conf ++++ /dev/null +@@ -1,38 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-