ELSEIF_FSA_ACTION(A_CIB_BUMPGEN,	do_cib_invoke)
s_crmd_fsa(enum crmd_fsa_cause cause,	   enum crmd_fsa_input initial_input,	   void *data){	long long actions = fsa_actions;	long long new_actions = A_NOTHING;	long long last_action = 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 last_state, cur_state, next_state, starting_state;		FNIN();	starting_state = fsa_state;	cur_input  = initial_input;	next_input = initial_input;		last_state = starting_state;	cur_state  = starting_state;	next_state = starting_state;#ifdef FSA_TRACE	CRM_DEBUG("FSA invoked with Cause: %s\n\tState: %s, Input: %s",		   fsa_cause2string(cause),		   fsa_state2string(cur_state),		   fsa_input2string(cur_input));#endif	if(dot_strm == NULL) {		dot_strm = fopen("/tmp/live.dot", "w");		fprintf(dot_strm, "%s", dot_intro);	}		/*	 * 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			 *			 * Re-add the last action			 */			actions |= last_action;								cl_log(LOG_INFO, "Wait until something else happens");			break;		}#ifdef FSA_TRACE		CRM_DEBUG("FSA while loop:\tState: %s, Input: %s",			   fsa_state2string(cur_state),			   fsa_input2string(cur_input));#endif				/* update input variables */		cur_input = next_input;		if(cur_input != I_NULL) {			last_input = cur_input;		}		/* get the next batch of actions */		new_actions = crmd_fsa_actions[cur_input][cur_state];		if(new_actions != A_NOTHING) {#ifdef FSA_TRACE			CRM_DEBUG("Adding actions %.16llx", new_actions);#endif			actions |= new_actions;		}		/* logging : *before* the state is changed */		IF_FSA_ACTION(A_ERROR, do_log)		ELSEIF_FSA_ACTION(A_WARN, do_log)		ELSEIF_FSA_ACTION(A_LOG,  do_log)		/* update state variables */		next_state  = crmd_fsa_state[cur_input][cur_state];		last_state  = cur_state;		cur_state   = next_state;		fsa_state   = next_state;		/* start doing things... */		/*		 * Hook for change of state.		 * Allows actions to be added or removed when entering a state		 */		if(last_state != cur_state){			actions = do_state_transition(actions, cause,						      last_state, cur_state,						      last_input, data);		}		/* 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");			}*/		}				/* 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_control)		ELSEIF_FSA_ACTION(A_LRM_CONNECT,do_lrm_control)		ELSEIF_FSA_ACTION(A_CCM_CONNECT,do_ccm_control)		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_TE_COPYTO,		do_te_copyto)		ELSEIF_FSA_ACTION(A_SHUTDOWN_REQ,	do_shutdown_req)		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_ELECT_TIMER_START,	do_election_timer_ctrl)		ELSEIF_FSA_ACTION(A_ELECT_TIMER_STOP,	do_election_timer_ctrl)		ELSEIF_FSA_ACTION(A_ELECTION_COUNT,	do_election_count_vote)		ELSEIF_FSA_ACTION(A_ELECTION_TIMEOUT,	do_election_timer_ctrl)				/*		 * "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_UPDATE_NODESTATUS,	do_lrm_invoke)		ELSEIF_FSA_ACTION(A_CIB_INVOKE_LOCAL,	do_cib_invoke)		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_LRM_EVENT,		do_lrm_event)		ELSEIF_FSA_ACTION(A_TE_CANCEL,		do_te_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_HA_DISCONNECT,	do_ha_control)		ELSEIF_FSA_ACTION(A_CCM_DISCONNECT,	do_ccm_control)		ELSEIF_FSA_ACTION(A_LRM_DISCONNECT,	do_lrm_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) != 0			|| is_message()) {			xmlNodePtr stored_msg = NULL;						fsa_message_queue_t msg = get_message();			if(is_message() == FALSE) {				actions = clear_bit(actions, A_MSG_PROCESS);			}						if(msg == NULL || msg->message == NULL) {				cl_log(LOG_ERR,				       "Invalid stored message");				continue;			}			/*			 * This is where we should clean up old messages			 * The problem is that we dont always know the			 * type of the data (and therefore the correct way			 * to free it).  A wrapper is probably required.			 */			data = msg->message;#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_DEBUG("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_DEBUG("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;		}		if(is_message()) {			actions |= A_MSG_PROCESS;		}	}	#ifdef FSA_TRACE	CRM_DEBUG("################# Exiting the FSA (%s) ##################",		  fsa_state2string(fsa_state));#endif#ifdef DOT_FSA_ACTIONS	fprintf(dot_strm,					"\t// ### Exiting the FSA (%s)\n",		fsa_state2string(fsa_state));	fflush(dot_strm);#endif	// cleanup inputs?	fsa_actions = actions;		FNRET(fsa_state);}