next_state = crmd_fsa_state[cur_input][cur_state];
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 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 = I_NULL;		cur_state = starting_state;	next_state = cur_state;	CRM_DEBUG4("FSA invoked with Cause: %s\n"		   "\tState: %s, Input: %s",		   fsa_cause2string(cause),		   fsa_state2string(cur_state),		   fsa_input2string(cur_input));	/*	 * 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(cur_input != I_NULL || actions != A_NOTHING) {		CRM_DEBUG3("FSA while loop:\tState: %s, Input: %s",			   fsa_state2string(cur_state),			   fsa_input2string(cur_input));						if(cur_input != I_NULL) {			new_actions =				crmd_fsa_actions[cur_input][cur_state];			CRM_DEBUG2("Adding actions %.16llx", new_actions);			actions |= new_actions;		}		/* safe to do every time, I_NULL gets us to the same state */		next_state = crmd_fsa_state[cur_input][cur_state];		if(next_state != cur_state) {						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("live.dot", "w");				fprintf(dot_strm, "%s", dot_intro);			}			fprintf(dot_strm,				"\t\"%s\" -> \"%s\" [ label =\"%s\" ]\n",				state_from, state_to, input);			fflush(dot_strm);		}		cur_state = next_state;		fsa_state = cur_state;		/* this is always run, some inputs/states may make various		 * actions irrelevant/invalid		 */		actions = clear_flags(actions, cur_state, cur_input);				/* regular action processing in order of action priority		 * and/or ease of processing		 */		/*		 * Make sure all actions that connect to required systems		 * are performed first		 */				/* External connect		 * These will drop existing connections if present		 */	if(is_set(actions, A_NOTHING)) {		cl_log(LOG_INFO, "Nothing to do??");	}		/* 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_CCM_CONNECT,do_ccm_register)		ELSEIF_FSA_ACTION(A_LRM_CONNECT,do_lrm_register)		/* sub-system start */		ELSEIF_FSA_ACTION(A_PE_START,	do_pe_control)		ELSEIF_FSA_ACTION(A_TE_START,	do_te_control)		ELSEIF_FSA_ACTION(A_STARTED,	do_started)				/* sub-system restart		 */		ELSEIF_FSA_ACTION(A_CIB_RESTART,do_cib_control)		ELSEIF_FSA_ACTION(A_PE_RESTART, do_pe_control)		ELSEIF_FSA_ACTION(A_TE_RESTART, do_te_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)		ELSEIF_FSA_ACTION(A_TICKLE_DC_TIMER,	do_tickle_dc_timer)		/*		 * "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_join_welcome)		ELSEIF_FSA_ACTION(A_JOIN_WELCOME,	do_join_welcome)		ELSEIF_FSA_ACTION(A_JOIN_ACK,		do_join_ack)		ELSEIF_FSA_ACTION(A_JOIN_PROCESS_ACK,	do_process_join_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_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_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) {			data = get_message()->message;			next_input = I_REQUEST;			/* any more queued messages? */			if(is_message() == FALSE)				actions = clear_bit(actions, A_MSG_PROCESS);						/* 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 (%d,%d)",			       cur_input,			       cur_state);						next_input = I_NULL;					} else if(cur_input == I_NULL && is_set(actions, A_NOTHING)) {			cl_log(LOG_INFO, "Nothing left to do");					} else {			cl_log(LOG_ERR, "Action not supported %llx", actions);		}			cur_input = next_input;	}	FNRET(fsa_state);}