msg_options = set_xml_attr( NULL, XML_TAG_OPTIONS, XML_ATTR_OP, CRM_OP_UPDATE, TRUE);  request = create_request( msg_options, fragment, NULL, CRM_SYSTEM_DCIB, CRM_SYSTEM_DC, NULL, NULL);  register_fsa_input( C_FSA_INTERNAL, I_CIB_OP, request);
update_local_cib(fragment, TRUE);
do_ccm_event(long long action,	     enum crmd_fsa_cause cause,	     enum crmd_fsa_state cur_state,	     enum crmd_fsa_input current_input,	     fsa_data_t *msg_data){	enum crmd_fsa_input return_input = I_NULL;	oc_ed_t *event = NULL;	const oc_ev_membership_t *oc = NULL;	if(msg_data == NULL || msg_data->data == NULL) {		crm_err("No data provided to FSA function");		return I_FAIL;	} else if(msg_data->fsa_cause != C_CCM_CALLBACK) {		crm_err("FSA function called in response to incorect input");		return I_NULL;	}	event = ((struct crmd_ccm_data_s *)msg_data->data)->event;	oc = ((struct crmd_ccm_data_s *)msg_data->data)->oc;		crm_info("event=%s", 	       *event==OC_EV_MS_NEW_MEMBERSHIP?"NEW MEMBERSHIP":	       *event==OC_EV_MS_NOT_PRIMARY?"NOT PRIMARY":	       *event==OC_EV_MS_PRIMARY_RESTORED?"PRIMARY RESTORED":	       *event==OC_EV_MS_EVICTED?"EVICTED":	       "NO QUORUM MEMBERSHIP");		if(CCM_EVENT_DETAIL) {		ccm_event_detail(oc, *event);	}	if (OC_EV_MS_EVICTED == *event) {		/* get out... NOW! */		return_input = I_SHUTDOWN;	}		if(AM_I_DC == FALSE || return_input == I_SHUTDOWN) {		return return_input;	}		/* My understanding is that we will never get both	 * node leaving *and* node joining callbacks at the	 * same time.	 *	 * This logic would need to change if this is not	 * the case	 */		if(oc->m_n_out != 0) {		int lpc = 0;		int offset = oc->m_out_idx;		for(lpc=0; lpc < oc->m_n_out; lpc++) {			xmlNodePtr request = NULL;			xmlNodePtr fragment = NULL;			xmlNodePtr node_state = NULL;			xmlNodePtr msg_options = NULL;						const char *uname = oc->m_array[offset+lpc].node_uname;						crm_info("Node %s has left the cluster,"				 " updating the CIB.", uname);			if(uname == NULL) {				crm_err("CCM node had no name");				continue;			}						node_state = create_node_state(				NULL, uname, NULL,				XML_BOOLEAN_NO, NULL, NULL, NULL);						fragment = create_cib_fragment(node_state, NULL);			msg_options = set_xml_attr(				NULL, XML_TAG_OPTIONS,				XML_ATTR_OP, CRM_OP_UPDATE, TRUE);				request = create_request(				msg_options, fragment, NULL,				CRM_SYSTEM_DCIB, CRM_SYSTEM_DC, NULL, NULL);				register_fsa_input(				C_FSA_INTERNAL, I_CIB_OP, request);			free_xml(msg_options);			free_xml(node_state);			free_xml(fragment);						free_xml(request);			s_crmd_fsa(C_FSA_INTERNAL);					}			} else if(oc->m_n_in !=0) {		/* delay the I_NODE_JOIN until they acknowledge our		 * DC status and send us their CIB		 */	} else {		crm_warn("So why are we here?  What CCM event happened?");	}	return return_input;}