ELSEIF_FSA_ACTION(A_ELECTION_TIMEOUT,	do_election_timeout)
ELSEIF_FSA_ACTION(A_ELECTION_TIMEOUT,	do_election_timer_ctrl)
s_crmd_fsa(enum crmd_fsa_cause cause,	   enum crmd_fsa_input initial_input,	   void *data){	long long           actions = A_NOTHING, new_actions = A_NOTHING;	enum crmd_fsa_input last_input = initial_input;	enum crmd_fsa_input cur_input;	enum crmd_fsa_input next_input;	enum crmd_fsa_state cur_state, next_state, starting_state;		FNIN();	starting_state = fsa_state;	cur_input = initial_input;	next_input = initial_input;		cur_state = starting_state;	next_state = cur_state;#ifdef FSA_TRACE	CRM_DEBUG4("FSA invoked with Cause: %s\n\tState: %s, Input: %s",		   fsa_cause2string(cause),		   fsa_state2string(cur_state),		   fsa_input2string(cur_input));#endif	/*	 * Process actions in order of priority but do only one	 * action at a time to avoid complicating the ordering.	 *	 * Actions may result in a new I_ event, these are added to	 * (not replace) existing actions before the next iteration.	 *	 */	while(next_input != I_NULL || actions != A_NOTHING) {		if(next_input == I_WAIT_FOR_EVENT) {			/* we may be waiting for an a-sync task to "happen"			 * and until it does, we cant do anything else			 */			cl_log(LOG_INFO, "Wait until something else happens");			break;		}		cur_input = next_input;#ifdef FSA_TRACE		CRM_DEBUG3("FSA while loop:\tState: %s, Input: %s",			   fsa_state2string(cur_state),			   fsa_input2string(cur_input));#endif				/* safe to do every time, I_NULL gets us to the same state */		next_state = crmd_fsa_state[cur_input][cur_state];		if(cur_input != I_NULL		   && (cur_input != I_DC_HEARTBEAT || cur_state != S_NOT_DC)){#ifndef DOT_ALL_FSA_INPUTS			if(next_state != cur_state) {#endif							const char *state_from =					fsa_state2string(cur_state);				const char *state_to =					fsa_state2string(next_state);				const char *input =					fsa_input2string(cur_input);								if(dot_strm == NULL) {					dot_strm = fopen("/tmp/live.dot", "w");					fprintf(dot_strm, "%s", dot_intro);				}								time_t now = time(NULL);								fprintf(dot_strm,					"\t\"%s\" -> \"%s\" [ label =\"%s\" ] // %s",					state_from, state_to, input,					asctime(localtime(&now)));				fflush(dot_strm);				#ifndef DOT_ALL_FSA_INPUTS			}#endif		}				new_actions = crmd_fsa_actions[cur_input][cur_state];		if(new_actions != A_NOTHING) {#ifdef FSA_TRACE			CRM_DEBUG2("Adding actions %.16llx", new_actions);#endif			actions |= new_actions;		}		switch(cur_input) {			case I_NULL:				break;#if 0			case I_SOME_EVENT:			case I_SOME_OTHER_EVENT:				cc_transitioner(cur_input, data);				/* flow through... */#endif			default:				last_input = cur_input;				break;		}			cur_state = next_state;		fsa_state = cur_state;#if 0		if(fsa_state == S_RECOVERY || fsa_state == S_RECOVERY_DC) {			set_bit(actions, A_RECOVER);		}#endif					/* this is always run, some inputs/states may make various		 * actions irrelevant/invalid		 */		actions = clear_flags(actions, cause, cur_state, cur_input);				/* regular action processing in order of action priority		 *		 * Make sure all actions that connect to required systems		 * are performed first		 */		if(actions == A_NOTHING) {			cl_log(LOG_INFO, "Nothing to do");			next_input = I_NULL;					// check registers, see if anything is pending			if(is_set(fsa_input_register, R_SHUTDOWN)) {				CRM_DEBUG("(Re-)invoking shutdown");				next_input = I_SHUTDOWN;			} else if(is_set(fsa_input_register, R_INVOKE_PE)) {				CRM_DEBUG("Invoke the PE somehow");			}		}		/* logging */	ELSEIF_FSA_ACTION(A_ERROR, do_log)		ELSEIF_FSA_ACTION(A_WARN, do_log)		ELSEIF_FSA_ACTION(A_LOG,  do_log)				/* get out of here NOW! before anything worse happens */		ELSEIF_FSA_ACTION(A_EXIT_1,	do_exit)				ELSEIF_FSA_ACTION(A_STARTUP,	do_startup)				ELSEIF_FSA_ACTION(A_CIB_START,  do_cib_control)		ELSEIF_FSA_ACTION(A_HA_CONNECT, do_ha_register)		ELSEIF_FSA_ACTION(A_LRM_CONNECT,do_lrm_register)		ELSEIF_FSA_ACTION(A_CCM_CONNECT,do_ccm_register)		ELSEIF_FSA_ACTION(A_ANNOUNCE,	do_announce)				/* sub-system start */		ELSEIF_FSA_ACTION(A_PE_START,	do_pe_control)		ELSEIF_FSA_ACTION(A_TE_START,	do_te_control)				/* sub-system restart		 */		ELSEIF_FSA_ACTION(O_CIB_RESTART,do_cib_control)		ELSEIF_FSA_ACTION(O_PE_RESTART, do_pe_control)		ELSEIF_FSA_ACTION(O_TE_RESTART, do_te_control)				ELSEIF_FSA_ACTION(A_STARTED,	do_started)				/* DC Timer */		ELSEIF_FSA_ACTION(O_DC_TIMER_RESTART,	do_dc_timer_control)		ELSEIF_FSA_ACTION(A_DC_TIMER_STOP,	do_dc_timer_control)		ELSEIF_FSA_ACTION(A_DC_TIMER_START,	do_dc_timer_control)				/*		 * Highest priority actions		 */		ELSEIF_FSA_ACTION(A_MSG_ROUTE,		do_msg_route)		ELSEIF_FSA_ACTION(A_RECOVER,		do_recover)		ELSEIF_FSA_ACTION(A_ELECTION_VOTE,	do_election_vote)		ELSEIF_FSA_ACTION(A_ELECTION_COUNT,	do_election_count_vote)		ELSEIF_FSA_ACTION(A_ELECTION_TIMEOUT,	do_election_timeout)				/*		 * "Get this over with" actions		 */		ELSEIF_FSA_ACTION(A_MSG_STORE,		do_msg_store)		ELSEIF_FSA_ACTION(A_NODE_BLOCK,		do_node_block)				/*		 * High priority actions		 * Update the cache first		 */		ELSEIF_FSA_ACTION(A_CCM_UPDATE_CACHE,	do_ccm_update_cache)		ELSEIF_FSA_ACTION(A_CCM_EVENT,		do_ccm_event)				/*		 * Medium priority actions		 */		ELSEIF_FSA_ACTION(A_DC_TAKEOVER,	do_dc_takeover)		ELSEIF_FSA_ACTION(A_DC_RELEASE,		do_dc_release)		ELSEIF_FSA_ACTION(A_JOIN_WELCOME_ALL,	do_send_welcome)		ELSEIF_FSA_ACTION(A_JOIN_WELCOME,	do_send_welcome)		ELSEIF_FSA_ACTION(A_JOIN_ACK,		do_ack_welcome)		ELSEIF_FSA_ACTION(A_JOIN_PROCESS_ACK,	do_process_welcome_ack)				/*		 * Low(er) priority actions		 * Make sure the CIB is always updated before invoking the		 * PE, and the PE before the TE		 */		ELSEIF_FSA_ACTION(A_CIB_INVOKE,		do_cib_invoke)		ELSEIF_FSA_ACTION(A_CIB_BUMPGEN,	do_cib_invoke)		ELSEIF_FSA_ACTION(A_LRM_INVOKE,		do_lrm_invoke)		ELSEIF_FSA_ACTION(A_PE_INVOKE,		do_pe_invoke)		ELSEIF_FSA_ACTION(A_TE_INVOKE,		do_te_invoke)				/* sub-system stop */		ELSEIF_FSA_ACTION(A_PE_STOP,	do_pe_control)		ELSEIF_FSA_ACTION(A_TE_STOP,	do_te_control)		ELSEIF_FSA_ACTION(A_DC_RELEASED,do_dc_release)		ELSEIF_FSA_ACTION(A_CIB_STOP,	do_cib_control)				/* time to go now... */				/* Some of these can probably be consolidated */		ELSEIF_FSA_ACTION(A_SHUTDOWN,   do_shutdown)		ELSEIF_FSA_ACTION(A_STOP,	do_stop)				/* exit gracefully */		ELSEIF_FSA_ACTION(A_EXIT_0,	do_exit)//		ELSEIF_FSA_ACTION(A_, do_)				else if(actions & A_MSG_PROCESS) {			xmlNodePtr stored_msg = NULL;						/* any more queued messages? */			if(is_message() == FALSE) {				CRM_DEBUG("No more messages");				actions = clear_bit(actions, A_MSG_PROCESS);				continue;			} else {				data = get_message()->message;				if(data == NULL) {					cl_log(LOG_ERR,					       "Invalid stored message");					continue;				}			}#ifdef DOT_FSA_ACTIONS			fprintf(dot_strm,				"\t// %s:\t%s\t(data? %s)",					fsa_input2string(cur_input),				fsa_action2string(A_MSG_PROCESS),				stored_msg==NULL?"no":"yes");			fflush(dot_strm);#endif#ifdef FSA_TRACE			CRM_DEBUG3("Invoking action %s (%.16llx)",				   fsa_action2string(A_MSG_PROCESS),				   A_MSG_PROCESS);#endif			stored_msg = (xmlNodePtr)data;#ifdef FSA_TRACE			xml_message_debug(stored_msg,"FSA processing message");#endif			next_input = handle_message(stored_msg);#ifdef DOT_FSA_ACTIONS			fprintf(dot_strm, "\t(result=%s)\n",				fsa_input2string(next_input));#endif			CRM_DEBUG3("Result of action %s was %s",				   fsa_action2string(A_MSG_PROCESS),				   fsa_input2string(next_input));					/* Error checking and reporting */		} else if(cur_input != I_NULL && is_set(actions, A_NOTHING)) {			cl_log(LOG_WARNING,			       "No action specified for input,state (%s,%s)",			       fsa_input2string(cur_input),			       fsa_state2string(cur_state));						next_input = I_NULL;					} else if(cur_input == I_NULL && is_set(actions, A_NOTHING)) {#ifdef FSA_TRACE			cl_log(LOG_INFO, "Nothing left to do");#endif					} else {			cl_log(LOG_ERR, "Action %s (0x%llx) not supported ",			       fsa_action2string(actions), actions);			next_input = I_ERROR;		}	}	#ifdef FSA_TRACE	CRM_DEBUG2("################# Exiting the FSA (%s) ##################",		  fsa_state2string(fsa_state));#endif	// cleanup inputs?		FNRET(fsa_state);}