diff --git a/crmd/te_callbacks.c b/crmd/te_callbacks.c
index 3be6d06b98..ed2bc54f55 100644
--- a/crmd/te_callbacks.c
+++ b/crmd/te_callbacks.c
@@ -1,499 +1,502 @@
 /* 
  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
  * 
  * 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.1 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <crm_internal.h>
 
 #include <sys/stat.h>
 
 #include <crm/crm.h>
 #include <crm/common/xml.h>
 #include <crm/msg_xml.h>
 #include <crm/cib.h>
 
 #include <tengine.h>
 #include <te_callbacks.h>
 #include <crmd_fsa.h>
 
 #include <crm/common/cluster.h> /* For ONLINESTATUS etc */
 
 void te_update_confirm(const char *event, xmlNode *msg);
 
 extern char *te_uuid;
 gboolean shuttingdown = FALSE;
 crm_graph_t *transition_graph;
 crm_trigger_t *transition_trigger = NULL;
 
 /* #define rsc_op_template "//"XML_TAG_DIFF_ADDED"//"XML_TAG_CIB"//"XML_CIB_TAG_STATE"[@uname='%s']"//"XML_LRM_TAG_RSC_OP"[@id='%s]" */
 #define rsc_op_template "//"XML_TAG_DIFF_ADDED"//"XML_TAG_CIB"//"XML_LRM_TAG_RSC_OP"[@id='%s']"
 
 static const char *get_node_id(xmlNode *rsc_op) 
 {
     xmlNode *node = rsc_op;
     while(node != NULL && safe_str_neq(XML_CIB_TAG_STATE, TYPE(node))) {
 	node = node->parent;
     }
     
     CRM_CHECK(node != NULL, return NULL);
     return ID(node);
 }
 
 
 static void process_resource_updates(xmlXPathObject *xpathObj) 
 {
 /*
     <status>
        <node_state id="node1" state=CRMD_STATE_ACTIVE exp_state="active">
           <lrm>
              <lrm_resources>
         	<rsc_state id="" rsc_id="rsc4" node_id="node1" rsc_state="stopped"/>
 */
     int lpc = 0, max = xpathObj->nodesetval->nodeNr;
     for(lpc = 0; lpc < max; lpc++) {
 	xmlNode *rsc_op = getXpathResult(xpathObj, lpc);
 	const char *node = get_node_id(rsc_op);
 	process_graph_event(rsc_op, node);
     }
 }
 
 void
 te_update_diff(const char *event, xmlNode *msg)
 {
 	int rc = -1;
 	const char *op = NULL;
 
 	xmlNode *diff = NULL;
 	xmlNode *cib_top = NULL;
 	xmlXPathObject *xpathObj = NULL;
 
 	int diff_add_updates     = 0;
 	int diff_add_epoch       = 0;
 	int diff_add_admin_epoch = 0;
 
 	int diff_del_updates     = 0;
 	int diff_del_epoch       = 0;
 	int diff_del_admin_epoch = 0;
 	
 	CRM_CHECK(msg != NULL, return);
 	crm_element_value_int(msg, F_CIB_RC, &rc);	
 
 	if(transition_graph == NULL) {
 	    crm_debug_3("No graph");
 	    return;
 
 	} else if(rc < cib_ok) {
 	    crm_debug_3("Filter rc=%d (%s)", rc, cib_error2string(rc));
 	    return;
 
 	} else if(transition_graph->complete == TRUE
 		  && fsa_state != S_IDLE
 		  && fsa_state != S_TRANSITION_ENGINE
 		  && fsa_state != S_POLICY_ENGINE) {
 	    crm_debug_2("Filter state=%s, complete=%d", fsa_state2string(fsa_state), transition_graph->complete);
 	    return;
 	} 	
 
 	op = crm_element_value(msg, F_CIB_OPERATION);
 	diff = get_message_xml(msg, F_CIB_UPDATE_RESULT);
 
 	cib_diff_version_details(
 		diff,
 		&diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, 
 		&diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates);
 	
 	crm_debug("Processing diff (%s): %d.%d.%d -> %d.%d.%d (%s)", op,
 		  diff_del_admin_epoch,diff_del_epoch,diff_del_updates,
 		  diff_add_admin_epoch,diff_add_epoch,diff_add_updates,
 		  fsa_state2string(fsa_state));
 	log_cib_diff(LOG_DEBUG_2, diff, op);
 
 	/* Process crm_config updates */ 
 	cib_top = get_xpath_object("//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_CIB_TAG_CRMCONFIG, diff, LOG_DEBUG);
 	if(cib_top != NULL) {
 	    mainloop_set_trigger(config_read);	    
 	}
 	
 	/* Process anything that was added */
 	cib_top = get_xpath_object("//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_TAG_CIB, diff, LOG_ERR);
 	if(need_abort(cib_top)) {
 	    goto bail; /* configuration changed */
 	}
 
 	/* Process anything that was removed */
 	cib_top = get_xpath_object("//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_REMOVED"//"XML_TAG_CIB, diff, LOG_ERR);
 	if(need_abort(cib_top)) {
 	    goto bail; /* configuration changed */
 	}
 
 	/* Transient Attributes - Added/Updated */
 	xpathObj = xpath_search(diff,"//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_TAG_TRANSIENT_NODEATTRS);
 	if(xpathObj && xpathObj->nodesetval->nodeNr > 0) {
 	    xmlNode *aborted = getXpathResult(xpathObj, 0);
 	    abort_transition(INFINITY, tg_restart, "Transient attribute: update", aborted);
 	    goto bail;
 
 	} else if(xpathObj) {
 	    xmlXPathFreeObject(xpathObj);
 	}
 	
 	/* Transient Attributes - Removed */
 	xpathObj = xpath_search(diff,"//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_REMOVED"//"XML_TAG_TRANSIENT_NODEATTRS);
 	if(xpathObj && xpathObj->nodesetval->nodeNr > 0) {
 	    xmlNode *aborted = getXpathResult(xpathObj, 0);
 	    abort_transition(INFINITY, tg_restart, "Transient attribute: removal", aborted);
 	    goto bail;
 
 	} else if(xpathObj) {
 	    xmlXPathFreeObject(xpathObj);
 	}
 
 	/* Check for node state updates... possibly from a shutdown we requested */
 	xpathObj = xpath_search(diff, "//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_CIB_TAG_STATE);
 	if(xpathObj) {
 	    int lpc = 0, max = xpathObj->nodesetval->nodeNr;
 	    for(lpc = 0; lpc < max; lpc++) {
 		xmlNode *node = getXpathResult(xpathObj, lpc);
 		const char *event_node = crm_element_value(node, XML_ATTR_ID);
 		const char *ccm_state  = crm_element_value(node, XML_CIB_ATTR_INCCM);
 		const char *ha_state   = crm_element_value(node, XML_CIB_ATTR_HASTATE);
 		const char *shutdown_s = crm_element_value(node, XML_CIB_ATTR_SHUTDOWN);
 		const char *crmd_state = crm_element_value(node, XML_CIB_ATTR_CRMDSTATE);
 
 		if(safe_str_eq(ccm_state, XML_BOOLEAN_FALSE)
 		   || safe_str_eq(ha_state, DEADSTATUS)
 		   || safe_str_eq(crmd_state, CRMD_JOINSTATE_DOWN)) {
 		    crm_action_t *shutdown = match_down_event(0, event_node, NULL);
 		    
 		    if(shutdown != NULL) {
 			const char *task = crm_element_value(shutdown->xml, XML_LRM_ATTR_TASK);
 			if(safe_str_neq(task, CRM_OP_FENCE)) {
 			    /* Wait for stonithd to tell us it is complete via tengine_stonith_callback() */
 			    crm_debug("Confirming %s op %d", task, shutdown->id);
 			    /* match->confirmed = TRUE; */
 			    stop_te_timer(shutdown->timer);
 			    update_graph(transition_graph, shutdown);
 			    trigger_graph();			    
 			}
 			
 		    } else {
 			crm_info("Stonith/shutdown of %s not matched", event_node);
 			abort_transition(INFINITY, tg_restart, "Node failure", node);
 		    }			
 		    fail_incompletable_actions(transition_graph, event_node);
 		}
 	 
 		if(shutdown_s) {
 		    int shutdown = crm_parse_int(shutdown_s, NULL);
 		    if(shutdown > 0) {
 			crm_info("Aborting on "XML_CIB_ATTR_SHUTDOWN" attribute for %s", event_node);
 			abort_transition(INFINITY, tg_restart, "Shutdown request", node);
 		    }
 		}
 	    }
 	    xmlXPathFreeObject(xpathObj);
 	}
 
 	/*
 	 * Check for and fast-track the processing of LRM refreshes
 	 * In large clusters this can result in _huge_ speedups
 	 *
 	 * Unfortunately we can only do so when there are no pending actions
 	 * Otherwise we could miss updates we're waiting for and stall 
 	 *
 	 */
 	xpathObj = NULL;
 	if(transition_graph->pending == 0) {
 	    xpathObj = xpath_search(diff, "//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_LRM_TAG_RESOURCE);
 	}
 	
 	if(xpathObj) {
 	    int updates = xpathObj->nodesetval->nodeNr;
 	    if(updates > 1) {
 		/* Updates by, or in response to, TE actions will never contain updates
 		 * for more than one resource at a time
 		 */
 		crm_info("Detected LRM refresh - %d resources updated: Skipping all resource events", updates);
 		abort_transition(INFINITY, tg_restart, "LRM Refresh", diff);
 		goto bail;
 	    }
 	    xmlXPathFreeObject(xpathObj);
 	}
 
 	/* Process operation updates */
 	xpathObj = xpath_search(diff, "//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_LRM_TAG_RSC_OP);
 	if(xpathObj) {
 	    process_resource_updates(xpathObj);
 	    xmlXPathFreeObject(xpathObj);
 	}
 	
 	/* Detect deleted (as opposed to replaced or added) actions - eg. crm_resource -C */ 
 	xpathObj = xpath_search(diff, "//"XML_TAG_DIFF_REMOVED"//"XML_LRM_TAG_RSC_OP);
 	if(xpathObj) {
 	    int lpc = 0, max = xpathObj->nodesetval->nodeNr;
 	    
 	    for(lpc = 0; lpc < max; lpc++) {
 		int max = 0;
 		const char *op_id = NULL;
 		char *rsc_op_xpath = NULL;
 		xmlXPathObject *op_match = NULL;
 		xmlNode *match = getXpathResult(xpathObj, lpc);
 		CRM_CHECK(match != NULL, continue);
 
 		op_id = ID(match);
 
 		max = strlen(rsc_op_template) + strlen(op_id) + 1;
 		crm_malloc0(rsc_op_xpath, max);
 		snprintf(rsc_op_xpath, max, rsc_op_template, op_id);
 		
 		op_match = xpath_search(diff, rsc_op_xpath);
 		if(op_match == NULL || op_match->nodesetval->nodeNr == 0) {
 		    /* Prevent false positives by matching cancelations too */
 		    const char *node = get_node_id(match);
 		    crm_action_t *cancelled = get_cancel_action(op_id, node);
 
 		    if(cancelled == NULL) {
 			crm_debug("No match for deleted action %s (%s on %s)", rsc_op_xpath, op_id, node);
 			abort_transition(INFINITY, tg_restart, "Resource op removal", match);
 			goto bail;
 
 		    } else {
 			crm_debug("Deleted lrm_rsc_op %s on %s was for graph event %d",
 				  op_id, node, cancelled->id);
 		    }
 		}
 
 		if(op_match) {
 		    xmlXPathFreeObject(op_match);
 		}
 		crm_free(rsc_op_xpath);
 	    }
 	}
 
   bail:
 	if(xpathObj) {
 	    xmlXPathFreeObject(xpathObj);
 	}
 }
 
 gboolean
 process_te_message(xmlNode *msg, xmlNode *xml_data)
 {
 	const char *from     = crm_element_value(msg, F_ORIG);
 	const char *sys_to   = crm_element_value(msg, F_CRM_SYS_TO);
 	const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM);
 	const char *ref      = crm_element_value(msg, XML_ATTR_REFERENCE);
 	const char *op       = crm_element_value(msg, F_CRM_TASK);
 	const char *type     = crm_element_value(msg, F_CRM_MSG_TYPE);
 
 	crm_debug_2("Processing %s (%s) message", op, ref);
 	crm_log_xml(LOG_DEBUG_3, "ipc", msg);
 	
 	if(op == NULL){
 		/* error */
 
 	} else if(sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_TENGINE) != 0) {
 		crm_debug_2("Bad sys-to %s", crm_str(sys_to));
 		return FALSE;
 		
 	} else if(safe_str_eq(op, CRM_OP_INVOKE_LRM)
 		  && safe_str_eq(sys_from, CRM_SYSTEM_LRMD)
 /* 		  && safe_str_eq(type, XML_ATTR_RESPONSE) */
 		){
 	    xmlXPathObject *xpathObj = NULL;
 	    crm_log_xml(LOG_DEBUG_2, "Processing (N)ACK", msg);
 	    crm_info("Processing (N)ACK %s from %s",
 		     crm_element_value(msg, XML_ATTR_REFERENCE), from);
 	    
 	    xpathObj = xpath_search(xml_data, "//"XML_LRM_TAG_RSC_OP);
 	    if(xpathObj) {
 		process_resource_updates(xpathObj);
 		xmlXPathFreeObject(xpathObj);
 		xpathObj = NULL;
 		
 	    } else {
 		crm_log_xml(LOG_ERR, "Invalid (N)ACK", msg);
 		return FALSE;
 	    }
 		
 	} else {
 		crm_err("Unknown command: %s::%s from %s", type, op, sys_from);
 	}
 
 	crm_debug_3("finished processing message");
 	
 	return TRUE;
 }
 
 void
 tengine_stonith_callback(
     stonith_t *stonith, const xmlNode *msg, int call_id, int rc, xmlNode *output, void *userdata)
 {
 	char *uuid = NULL;
 	int target_rc = -1;
 	int stonith_id = -1;
 	int transition_id = -1;
 	crm_action_t *action = NULL;
 
 	CRM_CHECK(userdata != NULL, return);
 	crm_log_xml_info(output, "StonithOp");
 	crm_info("Stonith operation %d/%s result=%d", call_id, (char*)userdata, rc);
-	
+
+	if(AM_I_DC == FALSE) {
+	    return;
+	}
 	/* crm_info("call=%d, optype=%d, node_name=%s, result=%d, node_list=%s, action=%s", */
 	/* 	 op->call_id, op->optype, op->node_name, op->op_result, */
 	/* 	 (char *)op->node_list, op->private_data); */
 	
 
 	/* filter out old STONITH actions */
 	CRM_CHECK(decode_transition_key(userdata, &uuid, &transition_id, &stonith_id, &target_rc),
 		  crm_err("Invalid event detected");
 		  goto bail;
 		);
 	
 	if(transition_graph->complete
 	   || stonith_id < 0
 	   || safe_str_neq(uuid, te_uuid)
 	   || transition_graph->id != transition_id) {
 		crm_info("Ignoring STONITH action initiated outside"
 			 " of the current transition");
 		goto bail;
 	}
 
 	/* this will mark the event complete if a match is found */
 	action = get_action(stonith_id, TRUE);	
 	if(action == NULL) {
 		crm_err("Stonith action not matched");
 		goto bail;
 	}
 	
 	if(rc == stonith_ok) {
 	    crm_info("Stonith of %s passed",
 		     crm_element_value_const(action->xml, XML_LRM_ATTR_TARGET));
 	    send_stonith_update(action);
 
 	} else {
 	    const char *target = crm_element_value_const(action->xml, XML_LRM_ATTR_TARGET);
 	    const char *allow_fail = crm_meta_value(action->params, XML_ATTR_TE_ALLOWFAIL);
 	    
 	    action->failed = TRUE;
 	    if(crm_is_true(allow_fail) == FALSE) {
 		crm_err("Stonith of %s failed (%d)... aborting transition.", target, rc);
 		abort_transition(INFINITY, tg_restart, "Stonith failed", NULL);
 	    }
 	}
 	
 	update_graph(transition_graph, action);
 	trigger_graph();
 
   bail:
 	crm_free(userdata);
 	crm_free(uuid);
 	return;
 }
 
 void
 cib_fencing_updated(xmlNode *msg, int call_id, int rc,
 		    xmlNode *output, void *user_data)
 {
     if(rc < cib_ok) {
 	crm_err("CIB update failed: %s", cib_error2string(rc));
 	crm_log_xml_warn(msg, "Failed update");
     }
     crm_free(user_data);
 }
 
 void
 cib_action_updated(xmlNode *msg, int call_id, int rc,
 		   xmlNode *output, void *user_data)
 {
 	if(rc < cib_ok) {
 		crm_err("Update %d FAILED: %s", call_id, cib_error2string(rc));
 	}
 }
 
 void
 cib_failcount_updated(xmlNode *msg, int call_id, int rc,
 		      xmlNode *output, void *user_data)
 {
 	if(rc < cib_ok) {
 		crm_err("Update %d FAILED: %s", call_id, cib_error2string(rc));
 	}
 }
 
 gboolean
 action_timer_callback(gpointer data)
 {
 	crm_action_timer_t *timer = NULL;
 	
 	CRM_CHECK(data != NULL, return FALSE);
 	
 	timer = (crm_action_timer_t*)data;
 	stop_te_timer(timer);
 
 	crm_warn("Timer popped (timeout=%d, abort_level=%d, complete=%s)",
 		 timer->timeout,
 		 transition_graph->abort_priority,
 		 transition_graph->complete?"true":"false");
 
 	CRM_CHECK(timer->action != NULL, return FALSE);
 
 	if(transition_graph->complete) {
 		crm_warn("Ignoring timeout while not in transition");
 		
 	} else if(timer->reason == timeout_action_warn) {
 		print_action(
 			LOG_WARNING,"Action missed its timeout: ", timer->action);
 		
 	} else if(fsa_state != S_TRANSITION_ENGINE && fsa_state != S_POLICY_ENGINE) {
 	    crm_err("Discarding action timeout in state: %s", fsa_state2string(fsa_state));
 	    
 	} else if(transition_graph->complete) {
 	    crm_err("Ignoring action timeout while not in transition");
 		
 	} else {
 	    /* fail the action */
 	    gboolean send_update = TRUE;
 	    const char *task = crm_element_value(timer->action->xml, XML_LRM_ATTR_TASK);
 	    print_action(LOG_ERR, "Aborting transition, action lost: ", timer->action);
 
 	    timer->action->failed = TRUE;
 	    timer->action->confirmed = TRUE;
 	    abort_transition(INFINITY, tg_restart, "Action lost", NULL);
 	    
 	    update_graph(transition_graph, timer->action);
 	    trigger_graph();
 
 	    if(timer->action->type != action_type_rsc) {
 		send_update = FALSE;
 	    } else if(safe_str_eq(task, "cancel")) {
 		/* we dont need to update the CIB with these */
 		send_update = FALSE;
 	    } else if(safe_str_eq(task, "stop")) {
 		/* *never* update the CIB with these */
 		send_update = FALSE;
 	    }
 
 	    if(send_update) {
 		/* cib_action_update(timer->action, LRM_OP_PENDING, EXECRA_STATUS_UNKNOWN); */
 		cib_action_update(timer->action, LRM_OP_TIMEOUT, EXECRA_UNKNOWN_ERROR);
 	    }
 	}
 
 	return FALSE;
 }
 
 
 
diff --git a/crmd/te_utils.c b/crmd/te_utils.c
index f49767750c..de28cbbc6e 100644
--- a/crmd/te_utils.c
+++ b/crmd/te_utils.c
@@ -1,300 +1,301 @@
 /* 
  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
  * 
  * 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.1 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <crm_internal.h>
 
 #include <sys/param.h>
 #include <crm/crm.h>
 #include <crm/cib.h>
 #include <crm/msg_xml.h>
 #include <crm/common/msg.h>
 #include <crm/common/xml.h>
 #include <tengine.h>
 #include <crmd_fsa.h>
 #include <crmd_messages.h>
 
 GCHSource *stonith_src = NULL;
 crm_trigger_t *stonith_reconnect = NULL;
 
 static gboolean
 fail_incompletable_stonith(crm_graph_t *graph) 
 {
     const char *task = NULL;
     xmlNode *last_action = NULL;
 
     if(graph == NULL) {
 	return FALSE;
     }
     
     slist_iter(
 	synapse, synapse_t, graph->synapses, lpc,
 	if (synapse->confirmed) {
 	    continue;
 	}
 
 	slist_iter(
 	    action, crm_action_t, synapse->actions, lpc,
 
 	    if(action->type != action_type_crm || action->confirmed) {
 		continue;
 	    }
 
 	    task = crm_element_value(action->xml, XML_LRM_ATTR_TASK);
 	    if(task && safe_str_eq(task, CRM_OP_FENCE)) {
 		action->failed = TRUE;
 		last_action = action->xml;
 		update_graph(graph, action);
 		crm_notice("Failing action %d (%s): STONITHd terminated",
 			   action->id, ID(action->xml));
 	    }
 	    );
 	);
 
     if(last_action != NULL) {
 	crm_warn("STONITHd failure resulted in un-runnable actions");
 	abort_transition(INFINITY, tg_restart, "Stonith failure", last_action);
 	return TRUE;
     }
 	
     return FALSE;
 }
 
 static void
 tengine_stonith_connection_destroy(stonith_t *st, const char *event, xmlNode *msg)
 {
     if(is_set(fsa_input_register, R_ST_REQUIRED)) {
 	crm_crit("Fencing daemon connection failed");	
 	mainloop_set_trigger(stonith_reconnect);
 
     } else {
 	crm_info("Fencing daemon disconnected");
     }
 
     /* cbchan will be garbage at this point, arrange for it to be reset */
     stonith_api->state = stonith_disconnected;
 
-    fail_incompletable_stonith(transition_graph);
-    trigger_graph();
-    return;
+    if(AM_I_DC) {
+	fail_incompletable_stonith(transition_graph);
+	trigger_graph();
+    }
 }
 
 gboolean
 te_connect_stonith(gpointer user_data)
 {
 	int lpc = 0;
 	int rc = stonith_ok;
 
 	if(stonith_api == NULL) {
 	    stonith_api = stonith_api_new();
 	}
 
 	if(stonith_api->state != stonith_disconnected) {
 	    crm_debug_2("Still connected");
 	    return TRUE;
 	}
 	
 	for(lpc = 0; lpc < 30; lpc++) {
 	    crm_info("Attempting connection to fencing daemon...");
 	    
 	    sleep(1);
 	    rc = stonith_api->cmds->connect(stonith_api, crm_system_name, NULL, NULL);
 	    
 	    if(rc == stonith_ok) {
 		break;
 	    }
 	    
 	    if(user_data != NULL) {
 		crm_err("Sign-in failed: triggered a retry");
 		mainloop_set_trigger(stonith_reconnect);
 		return TRUE;
 	    } 
 
 	    crm_err("Sign-in failed: pausing and trying again in 2s...");
 	    sleep(1);
 	}
 	
 	CRM_CHECK(rc == stonith_ok, return TRUE); /* If not, we failed 30 times... just get out */
 	rc = stonith_api->cmds->register_notification(
 	    stonith_api, T_STONITH_NOTIFY_DISCONNECT, tengine_stonith_connection_destroy);
 
 	crm_info("Connected");
 	return TRUE;
 }
 
 gboolean
 stop_te_timer(crm_action_timer_t *timer)
 {
 	const char *timer_desc = "action timer";
 	
 	if(timer == NULL) {
 		return FALSE;
 	}
 	if(timer->reason == timeout_abort) {
 		timer_desc = "global timer";
 		crm_debug_2("Stopping %s", timer_desc);
 	}
 	
 	if(timer->source_id != 0) {
 		crm_debug_2("Stopping %s", timer_desc);
 		g_source_remove(timer->source_id);
 		timer->source_id = 0;
 
 	} else {
 		crm_debug_2("%s was already stopped", timer_desc);
 		return FALSE;
 	}
 
 	return TRUE;
 }
 
 gboolean
 te_graph_trigger(gpointer user_data) 
 {
     enum transition_status graph_rc = -1;
     if(transition_graph == NULL) {
 	crm_debug("Nothing to do");
 	return TRUE;
     }
     
     crm_debug_2("Invoking graph %d in state %s",
 	      transition_graph->id, fsa_state2string(fsa_state));
 
     switch(fsa_state) {
 	case S_STARTING:
 	case S_PENDING:
 	case S_NOT_DC:
 	case S_HALT:
 	case S_ILLEGAL:
 	case S_STOPPING:
 	case S_TERMINATE:
 	    return TRUE;
 	    break;
 	default:
 	    break;
     }
     
     if(transition_graph->complete == FALSE) {
 	graph_rc = run_graph(transition_graph);
 	print_graph(LOG_DEBUG_3, transition_graph);
 
 	if(graph_rc == transition_active) {
 		crm_debug_3("Transition not yet complete");
 		return TRUE;		
 
 	} else if(graph_rc == transition_pending) {
 		crm_debug_3("Transition not yet complete - no actions fired");
 		return TRUE;		
 	}
 	
 	if(graph_rc != transition_complete) {
 		crm_err("Transition failed: %s", transition_status(graph_rc));
 		print_graph(LOG_WARNING, transition_graph);
 	}
     }
     
     crm_info("Transition %d is now complete", transition_graph->id);
     transition_graph->complete = TRUE;
     notify_crmd(transition_graph);
     
     return TRUE;	
 }
 
 void
 trigger_graph_processing(const char *fn, int line) 
 {
 	mainloop_set_trigger(transition_trigger);
 	crm_debug_2("%s:%d - Triggered graph processing", fn, line);
 }
 
 void
 abort_transition_graph(
 	int abort_priority, enum transition_action abort_action,
 	const char *abort_text, xmlNode *reason, const char *fn, int line) 
 {
 	int log_level = LOG_INFO;
 	const char *magic = NULL;
 	CRM_CHECK(transition_graph != NULL, return);
 	
 	if(reason) {
 	    int diff_add_updates     = 0;
 	    int diff_add_epoch       = 0;
 	    int diff_add_admin_epoch = 0;
 	    
 	    int diff_del_updates     = 0;
 	    int diff_del_epoch       = 0;
 	    int diff_del_admin_epoch = 0;
 	    xmlNode *diff = get_xpath_object("//"F_CIB_UPDATE_RESULT"//diff", reason, LOG_DEBUG_2);
 	    magic = crm_element_value(reason, XML_ATTR_TRANSITION_MAGIC);
 
 	    if(diff) {
 		cib_diff_version_details(
 		    diff,
 		    &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, 
 		    &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates);
 		do_crm_log(log_level,
 			   "%s:%d - Triggered transition abort (complete=%d, tag=%s, id=%s, magic=%s, cib=%d.%d.%d) : %s",
 			   fn, line, transition_graph->complete, TYPE(reason), ID(reason), magic?magic:"NA",
 			   diff_add_admin_epoch,diff_add_epoch,diff_add_updates, abort_text);
 		
 	    } else {
 		do_crm_log(log_level,
 			   "%s:%d - Triggered transition abort (complete=%d, tag=%s, id=%s, magic=%s) : %s",
 			   fn, line, transition_graph->complete, TYPE(reason), ID(reason), magic?magic:"NA", abort_text);
 	    }
 
 	} else {
 	    do_crm_log(log_level,
 		       "%s:%d - Triggered transition abort (complete=%d) : %s",
 		       fn, line, transition_graph->complete, abort_text);
 	}
 	
 	switch(fsa_state) {
 	    case S_STARTING:
 	    case S_PENDING:
 	    case S_NOT_DC:
 	    case S_HALT:
 	    case S_ILLEGAL:
 	    case S_STOPPING:
 	    case S_TERMINATE:
 		do_crm_log(log_level,
 			   "Abort suppressed: state=%s (complete=%d)",
 			   fsa_state2string(fsa_state), transition_graph->complete);
 		return;
 	    default:
 		break;
 	}
 
 	if(magic == NULL && reason != NULL) {
 	    crm_log_xml(log_level+1, "Cause", reason);
 	}
 	
 	/* Make sure any queued calculations are discarded ASAP */
 	crm_free(fsa_pe_ref);
 	fsa_pe_ref = NULL;
 	
 	if(transition_graph->complete) {
 	    register_fsa_input(C_FSA_INTERNAL, I_PE_CALC, NULL);
 	    return;
 	}
 
 	update_abort_priority(
 		transition_graph, abort_priority, abort_action, abort_text);	
 	
 	mainloop_set_trigger(transition_trigger);
 }