/************************************************************************** Function: plms_amf_register Purpose: Function which registers PLMS with AMF. Input: Pointer to the PLMS control block. Returns: NCSCC_RC_SUCCESSS/NCSCC_RC_FAILURE Notes: Here we call plms_amf_init after reading the component name file and setting the environment varaiable in our own context. Proceed to register with AMF, since it has come up. **************************************************************************/ SaUint32T plms_amf_register() { SaAisErrorT error; uint32_t rc = NCSCC_RC_SUCCESS; PLMS_CB * cb = plms_cb; m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE); /* Initialize amf framework for hc interface */ if ((rc = plms_amf_init()) != NCSCC_RC_SUCCESS) { LOG_ER("AMF init failed"); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); return NCSCC_RC_FAILURE; } LOG_IN("AMF init SUCCESS"); /* register PLMS component with AvSv */ error = saAmfComponentRegister(cb->amf_hdl, &cb->comp_name, (SaNameT *)NULL); if (error != SA_AIS_OK) { LOG_ER("AMF Component Register failed"); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); return NCSCC_RC_FAILURE; } LOG_IN("AMF Component Register SUCCESS"); if (NCSCC_RC_SUCCESS != (rc = plms_healthcheck_start())) { LOG_ER("PLMS Health Check Start failed"); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); return NCSCC_RC_FAILURE; } LOG_IN("PLMS Health Check Started Successfully SUCCESS"); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); return NCSCC_RC_SUCCESS; }
void parseArgs(QStringList args) { QSettings settings; QString sDefaultHostName = QHostInfo::localHostName(); QString sHostName = settings.value("hostname", QVariant(sDefaultHostName)).toString(); settings.setValue("hostname", QVariant(sHostName)); LOG_IN(QString("SETTINGS host name: %1").arg(sHostName)); QString sDefaultPort = "54340"; QString sPort = settings.value("port", QVariant(sDefaultPort)).toString(); settings.setValue("port", QVariant(sPort)); LOG_IN(QString("SETTINGS host port: %1").arg(sPort)); QString sDefaultRootPath = QString("%1/.Hobbyist_Software/VLC_Streamer/Root").arg(QDir::homePath()); QString sRootPath = settings.value("root", QVariant(sDefaultRootPath)).toString(); settings.setValue("root", QVariant(sRootPath)); LOG_IN(QString("SETTINGS root: %1").arg(sRootPath)); LOG_IN(QString("SETTINGS settings file %1").arg(settings.fileName())); if (!settings.isWritable()) { LOG_ER(QString("SETTINGS could not write file")); } settings.sync(); }
/**************************************************************************** * Name : plms_amf_init * * Description : PLMS initializes AMF for invoking process and registers * the various callback functions. * * Arguments : PLMS_CB - PLMS control block pointer. * * Return Values : NCSCC_RC_SUCCESS/Error Code. * * Notes : None. *****************************************************************************/ SaUint32T plms_amf_init() { PLMS_CB * cb = plms_cb; SaAmfCallbacksT amfCallbacks; SaVersionT amf_version; uint32_t rc = NCSCC_RC_SUCCESS; TRACE_ENTER(); if (cb->nid_started && amf_comp_name_get_set_from_file("PLMD_COMP_NAME_FILE", &cb->comp_name) != NCSCC_RC_SUCCESS) goto done; /* Initialize amf callbacks */ memset(&amfCallbacks, 0, sizeof(SaAmfCallbacksT)); amfCallbacks.saAmfHealthcheckCallback = plms_amf_health_chk_callback; amfCallbacks.saAmfCSISetCallback = plms_amf_CSI_set_callback; amfCallbacks.saAmfComponentTerminateCallback = plms_amf_comp_terminate_callback; amfCallbacks.saAmfCSIRemoveCallback = plms_amf_csi_rmv_callback; m_PLMS_GET_AMF_VER(amf_version); /*Initialize the amf library */ rc = saAmfInitialize(&cb->amf_hdl, &amfCallbacks, &amf_version); if (rc != SA_AIS_OK) { LOG_ER(" plms_amf_init: saAmfInitialize() AMF initialization FAILED\n"); goto done; } LOG_IN(" plms_amf_init: saAmfInitialize() AMF initialization SUCCESS\n"); /* Obtain the amf selection object to wait for amf events */ if (SA_AIS_OK != (rc = saAmfSelectionObjectGet(cb->amf_hdl, &cb->amf_sel_obj))) { LOG_ER("saAmfSelectionObjectGet() FAILED\n"); goto done; } LOG_IN("saAmfSelectionObjectGet() SUCCESS\n"); /* get the component name */ rc = saAmfComponentNameGet(cb->amf_hdl, &cb->comp_name); if (rc != SA_AIS_OK) { LOG_ER(" plmss_amf_init: saAmfComponentNameGet() FAILED\n"); goto done ; } rc = NCSCC_RC_SUCCESS; done: TRACE_LEAVE2("%u, %s", rc, cb->comp_name.value); return rc; } /*End plms_amf_init */
int main(int argc, char *argv[]) { QApplication a(argc, argv); int nLevel = 1; if (a.arguments().contains("--verbose")) { nLevel = 0; } Logger::setInstance(new Logger(nLevel, QString("%1/.Hobbyist_Software/VLC_Streamer/").arg(QDir::homePath()))); LOG_IN("VLCStreamer Client Started"); a.setOrganizationName("Hobbyist_Software"); a.setOrganizationDomain("Hobbyist_Software.Com"); a.setApplicationName("VLC_Streamer"); a.setApplicationVersion(APP_VERSION); LOG_IN(QString(" Version %1").arg(a.applicationVersion())); LOG_IN(QString(" Beta")); //LOG_IN(QString(" (c) J.Stockhausen")); parseArgs(a.arguments()); if (!VLCEncoder::hasSystemValidVLC()) { return 1; } VLCStreamer streamer; MainDialog w(&streamer); w.show(); streamer.slotStartService(); int ret = a.exec(); streamer.slotStopService(); Logger::setInstance(0); return ret; }
/**************************************************************************** * Name : fm_mds_node_evt * * Description : Function to process MDS NODE/control events. * * Arguments : pointer to FM CB & MDS_CALLBACK_NODE_EVENT_INFO * * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t fm_mds_node_evt(FM_CB *cb, MDS_CALLBACK_NODE_EVENT_INFO * node_evt) { uint32_t return_val = NCSCC_RC_SUCCESS; TRACE_ENTER(); switch (node_evt->node_chg) { case NCSMDS_NODE_DOWN: if (node_evt->node_id == cb->peer_node_id && cb->control_tipc) { /* Process NODE_DOWN only if OpenSAF is controling TIPC */ LOG_NO("Node Down event for node id %x:", node_evt->node_id); return_val = fm_send_node_down_to_mbx(cb, node_evt->node_id); } break; case NCSMDS_NODE_UP: break; default: LOG_IN("Wrong MDS event from GFM."); break; } TRACE_LEAVE(); return return_val; }
/** * Open/create a file for append in non blocking mode. * Note: The file is opened in NONBLOCK mode directly. This makes it possible * that the open succeeds but the following write will fail. To avoid * this the file can be opened without the O_NONBLOCK flag and set this * flag using fcntl(). But write handling is done so that if a write * fails the log file will always be reopened. * * @param indata[in], Null-terminated string containing filename to open * @param outdata[out], int errno, 0 if no error * @param max_outsize[in], always sizeof(int) * @return file descriptor or -1 if error */ int fileopen_hdl(void *indata, void *outdata, size_t max_outsize) { int errno_save = 0; char *filepath = (char *) indata; int *errno_out_p = (int *) outdata; int fd; TRACE_ENTER(); TRACE("%s - filepath \"%s\"",__FUNCTION__,filepath); open_retry: fd = open(filepath, O_CREAT | O_RDWR | O_APPEND | O_NONBLOCK, S_IRUSR | S_IWUSR | S_IRGRP); if (fd == -1) { if (errno == EINTR) goto open_retry; /* save errno for caller logging */ errno_save = errno; /* Do not log with higher severity here to avoid flooding the log. * Can be called in context of log_stream_write */ LOG_IN("Could not open: %s - %s", filepath, strerror(errno)); } *errno_out_p = errno_save; TRACE_LEAVE(); return fd; }
SaUint32T plms_quiesced_state_handler(SaInvocationT invocation) { PLMS_CB * cb = plms_cb; V_DEST_RL mds_role; /* Unregister with IMM as OI */ plms_proc_active_quiesced_role_change(); mds_role = V_DEST_RL_QUIESCED; TRACE_ENTER(); m_NCS_LOCK(&cb->cb_lock,NCS_LOCK_WRITE); /** set the CB's anchor value & mds role */ cb->mds_role = mds_role; plms_mds_change_role(); cb->amf_invocation_id = invocation; cb->is_quisced_set = true; LOG_IN("I AM IN HA AMF QUIESCED STATE\n"); m_NCS_UNLOCK(&cb->cb_lock,NCS_LOCK_WRITE); TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
/*************************************************************************** * Name : fm_mds_rcv_evt * * Description : Top level function that receives/processes MDS events. * * Arguments : Pointer to FM control block & MDS_CALLBACK_RECEIVE_INFO * * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE * * Notes : None. ***************************************************************************/ static uint32_t fm_mds_rcv_evt(FM_CB *cb, MDS_CALLBACK_RECEIVE_INFO *rcv_info) { uint32_t return_val = NCSCC_RC_SUCCESS; GFM_GFM_MSG *gfm_rcv_msg = NULL; if (NULL == rcv_info) { syslog(LOG_INFO, "fm_mds_rcv_evt: rcv_info NULL."); return NCSCC_RC_FAILURE; } if (NCSMDS_SVC_ID_GFM == rcv_info->i_fr_svc_id) { gfm_rcv_msg = (GFM_GFM_MSG *)rcv_info->i_msg; switch (gfm_rcv_msg->msg_type) { case GFM_GFM_EVT_NODE_INFO_EXCHANGE: cb->peer_node_id = gfm_rcv_msg->info.node_info.node_id; cb->peer_node_name.length = gfm_rcv_msg->info.node_info.node_name.length; memcpy(cb->peer_node_name.value, gfm_rcv_msg->info.node_info.node_name.value, cb->peer_node_name.length); LOG_IN("Peer Node_id %u : EE_ID %s", cb->peer_node_id, cb->peer_node_name.value); break; default: syslog(LOG_INFO, "Wrong MDS event from GFM."); return_val = NCSCC_RC_FAILURE; break; } /* Free gfm_rcv_msg here. Mem allocated in decode. */ m_MMGR_FREE_FM_FM_MSG(gfm_rcv_msg); } return return_val; }
/**************************************************************************** * Name : amf_active_state_handler * * Description : This function is called upon receving an active state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the IMMD control block. *****************************************************************************/ static SaAisErrorT amf_active_state_handler(IMMD_CB *cb, SaInvocationT invocation) { SaAisErrorT error = SA_AIS_OK; LOG_IN("AMF HA ACTIVE request"); cb->mds_role = V_DEST_RL_ACTIVE; return error; }
/**************************************************************************** * Name : immd_amf_csi_rmv_callback * * Description : TBD * * * Return Values : None *****************************************************************************/ static void immd_amf_csi_rmv_callback(SaInvocationT invocation, const SaNameT *compName, const SaNameT *csiName, SaAmfCSIFlagsT csiFlags) { IMMD_CB *cb = immd_cb; SaAisErrorT saErr = SA_AIS_OK; TRACE_ENTER(); LOG_IN("IMMD - AMF CSI Remove Callback Invoked"); saAmfResponse(cb->amf_hdl, invocation, saErr); TRACE_LEAVE(); }
SaUint32T plms_quiescing_state_handler(SaInvocationT invocation) { SaAisErrorT error = SA_AIS_OK; PLMS_CB * cb = plms_cb; TRACE_ENTER(); error = saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, error); saAmfResponse(cb->amf_hdl, invocation, error); LOG_IN("I AM IN HA AMF QUIESCING STATE\n"); TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
/** * Function to reset poll fdlist * * @param fd * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ uint32_t dtm_internode_reset_poll_fdlist(int fd) { int i = 0; for (i = 0; i < nfds; i++) { if (fd == fds[i].fd) { fds[i].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; LOG_IN("event set success, in the poll fd list"); return NCSCC_RC_SUCCESS; } } LOG_ER("\nUnable to set the event in the poll list"); return NCSCC_RC_FAILURE; }
/**************************************************************************** * Name : immd_amf_comp_terminate_callback * * Description : This function SAF callback function which will be called * when the AMF framework needs to terminate GLSV. This does * all required to destroy GLSV(except to unregister from AMF) * * Arguments : invocation - This parameter designated a particular * invocation of this callback function. The * invoke process return invocation when it * responds to the Avilability Management * FrameWork using the saAmfResponse() * function. * compName - A pointer to the name of the component * whose readiness stae the Availability * Management Framework is setting. * * Return Values : None * * Notes : At present we are just support a simple liveness check. *****************************************************************************/ static void immd_amf_comp_terminate_callback(SaInvocationT invocation, const SaNameT *compName) { IMMD_CB *cb = immd_cb; SaAisErrorT saErr = SA_AIS_OK; LOG_IN("IMMD - AMF Component Termination Callback Invoked, exiting..."); saAmfResponse(cb->amf_hdl, invocation, saErr); immd_mds_unregister(cb); /* unreg with mbcp also ?? */ sleep(1); LOG_NO("Received AMF component terminate callback, exiting"); exit(0); }
/** * Function to set poll fdlist * * @param fd events * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ uint32_t dtm_internode_set_poll_fdlist(int fd, uint16_t events) { int i = 0; for (i = 0; i < nfds; i++) { if (fd == fds[i].fd) { fds[i].events = fds[i].events | events; LOG_IN("event set success, in the poll fd list"); return NCSCC_RC_SUCCESS; } } LOG_ER("Unable to set the event in the poll list"); return NCSCC_RC_FAILURE; }
/**************************************************************************** * Name : amf_quiesced_state_handler * * Description : This function is called upon receving an Quiesced state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the IMMD control block. *****************************************************************************/ static SaAisErrorT amf_quiesced_state_handler(IMMD_CB *cb, SaInvocationT invocation) { LOG_IN("AMF HA QUIESCED request"); /* ** Change the MDS VDSET role to Quiesced. Wait for MDS callback with type ** MDS_CALLBACK_QUIESCED_ACK. Then change MBCSv role. Don't change ** cb->ha_state now. */ cb->mds_role = V_DEST_RL_QUIESCED; immd_mds_change_role(cb); cb->amf_invocation = invocation; cb->is_quiesced_set = true; TRACE_LEAVE(); return SA_AIS_OK; }
uint32_t fm_send_node_down_to_mbx(FM_CB *cb, uint32_t node_id) { FM_EVT *fm_evt = NULL; uint32_t rc = NCSCC_RC_SUCCESS; fm_evt = m_MMGR_ALLOC_FM_EVT; if (NULL == fm_evt) { syslog(LOG_INFO, "fm_mds_rcv_evt: fm_evt allocation FAILED."); return NCSCC_RC_FAILURE; } rc = fm_fill_mds_evt_post_fm_mbx(cb, fm_evt, node_id, FM_EVT_NODE_DOWN); if (rc == NCSCC_RC_FAILURE) { m_MMGR_FREE_FM_EVT(fm_evt); fm_evt = NULL; LOG_IN("node down event post to mailbox failed"); } return rc; }
/**************************************************************************** * Name : eds_process_mbx * * Description : This is the function which process the IPC mail box of * EDS * * Arguments : mbx - This is the mail box pointer on which EDS is * going to block. * * Return Values : None. * * Notes : None. *****************************************************************************/ static void eds_process_mbx(SYSF_MBX *mbx) { EDSV_EDS_EVT *evt = NULL; evt = (EDSV_EDS_EVT *)m_NCS_IPC_NON_BLK_RECEIVE(mbx, evt); if (evt != NULL) { if ((evt->evt_type >= EDSV_EDS_EVT_BASE) && (evt->evt_type < EDSV_EDS_EVT_MAX)) { /* This event belongs to EDS main event dispatcher */ eds_process_evt(evt); } else { /* Free the event */ LOG_IN("Unsupported event type in mailbox"); eds_evt_destroy(evt); } } return; }
static void fm_send_svc_down_to_mbx(FM_CB *cb, uint32_t node_id, NCSMDS_SVC_ID svc_id) { FM_EVT *fm_evt = NULL; uint32_t rc = NCSCC_RC_SUCCESS; fm_evt = m_MMGR_ALLOC_FM_EVT; if (NULL == fm_evt) { syslog(LOG_INFO, "fm_mds_rcv_evt: fm_evt allocation FAILED."); return; } fm_evt->svc_id = svc_id; rc = fm_fill_mds_evt_post_fm_mbx(cb, fm_evt, node_id, FM_EVT_SVC_DOWN); if (rc == NCSCC_RC_FAILURE) { m_MMGR_FREE_FM_EVT(fm_evt); LOG_IN("service down event post to mailbox failed"); fm_evt = NULL; } return; }
/****************************************************************************\ * Function: avsv_mbcsv_process_err_ind * * Purpose: AVSV MBCSV process error indication. * * Input: arg - MBCSV callback argument pointer. * * Returns: NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. * * NOTES: * * \**************************************************************************/ static uns32 avsv_mbcsv_process_err_ind(AVD_CL_CB *cb, NCS_MBCSV_CB_ARG *arg) { switch (arg->info.error.i_code) { case NCS_MBCSV_COLD_SYNC_TMR_EXP: /* The first cold sync request seems to be ignored so don't log */ TRACE("mbcsv cold sync tmr exp"); break; case NCS_MBCSV_WARM_SYNC_TMR_EXP: LOG_WA("mbcsv warm sync tmr exp"); break; case NCS_MBCSV_DATA_RSP_CMPLT_TMR_EXP: LOG_WA("mbcsv data rsp cmplt tmr exp"); break; case NCS_MBCSV_COLD_SYNC_CMPL_TMR_EXP: LOG_WA("mbcsv cold sync cmpl tmr exp"); break; case NCS_MBCSV_WARM_SYNC_CMPL_TMR_EXP: LOG_WA("mbcsv warm sync cmpl tmr exp"); break; case NCS_MBCSV_DATA_RESP_TERMINATED: LOG_WA("mbcsv data rsp term"); break; case NCS_MBCSV_COLD_SYNC_RESP_TERMINATED: LOG_WA("mbcsv cold sync rsp term"); break; case NCS_MBCSV_WARM_SYNC_RESP_TERMINATED: LOG_WA("mbcsv warm sync rsp term"); break; default: LOG_IN("mbcsv unknown ecode %u", arg->info.error.i_code); break; } return NCSCC_RC_SUCCESS; }
/****************************************************************************************************************** * Name :glsv_gld_mbcsv_chgrole * * Description : To assign role for a component * Arguments : GLSV_GLD_CB - cb pointer * * Return Values : Success / Error * * Notes : This API is use for setting the role. Role Standby - initiate Cold Sync Request if it finds Active Role Active - send ckpt data to multiple standby peers *********************************************************************************************************************/ uint32_t glsv_gld_mbcsv_chgrole(GLSV_GLD_CB *gld_cb) { NCS_MBCSV_ARG arg; uint32_t rc = NCSCC_RC_SUCCESS; TRACE_ENTER(); memset(&arg, '\0', sizeof(NCS_MBCSV_ARG)); arg.i_op = NCS_MBCSV_OP_CHG_ROLE; arg.i_mbcsv_hdl = gld_cb->mbcsv_handle; arg.info.chg_role.i_ckpt_hdl = gld_cb->o_ckpt_hdl; arg.info.chg_role.i_ha_state = gld_cb->ha_state; /* ha_state is assigned at the time of amf_init where csi_set_callback will assign the state */ LOG_IN("Setting the state HaState as :%d", gld_cb->ha_state); if (ncs_mbcsv_svc(&arg) != SA_AIS_OK) { LOG_ER("GLD mbcsv chgrole failed"); rc = NCSCC_RC_FAILURE; } TRACE_LEAVE(); return rc; }
/**************************************************************************** * Name : eds_proc_retention_time_clr_msg * * Description : This is the function which is called when eds receives a * EDSV_EDA_RETENTION_TIME_CLR message. * * Arguments : msg - Message that was posted to the EDS Mail box. * * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t eds_proc_retention_time_clr_msg(EDS_CB *cb, EDSV_EDS_EVT *evt) { uint32_t rc = NCSCC_RC_SUCCESS, rs = NCSCC_RC_SUCCESS; uint32_t async_rc = NCSCC_RC_SUCCESS; EDSV_MSG msg; EDSV_EDA_RETENTION_TIME_CLR_PARAM *param = &(evt->info.msg.info.api_info.param.rettimeclr); EDS_CKPT_DATA ckpt; TRACE_ENTER2("agent dest: %" PRIx64, evt->fr_dest); /* Lock the EDS_CB */ m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE); rc = eds_clear_retained_event(cb, param->chan_id, param->chan_open_id, param->event_id, false); if (rc != NCSCC_RC_SUCCESS) TRACE("Retained event clear failed"); /* Unlock the EDS_CB */ m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); /* Send response back */ m_EDS_EDSV_CHAN_RETENTION_TMR_CLEAR_SYNC_MSG_FILL(msg, rc) rs = eds_mds_msg_send(cb, &msg, &evt->fr_dest, &evt->mds_ctxt, MDS_SEND_PRIORITY_HIGH); LOG_IN("MDS send to %" PRIx64 " failed for saEvtEventRetentionTimeClear()", evt->fr_dest); if (rs != NCSCC_RC_SUCCESS) if (rc == NCSCC_RC_SUCCESS) { /*Send an async checkpoint update to STANDBY EDS peer */ if (cb->ha_state == SA_AMF_HA_ACTIVE) { memset(&ckpt, 0, sizeof(ckpt)); m_EDSV_FILL_ASYNC_UPDATE_RETEN_CLEAR(ckpt, param) async_rc = send_async_update(cb, &ckpt, NCS_MBCSV_ACT_ADD); if (async_rc != NCSCC_RC_SUCCESS) TRACE("Async Update send failed for retentime clear msg"); } } TRACE_LEAVE(); return rs; }
/****************************************************************************** Name : avnd_evt_avd_role_change_msg Description : This routine takes cares of role change of AvND. Arguments : cb - ptr to the AvND control block. evt - ptr to the AvND event. Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None ******************************************************************************/ uns32 avnd_evt_avd_role_change_evh(AVND_CB *cb, AVND_EVT *evt) { uns32 rc = NCSCC_RC_SUCCESS; AVSV_D2N_ROLE_CHANGE_INFO *info = NULL; V_DEST_RL mds_role; SaAmfHAStateT prev_ha_state; TRACE_ENTER(); /* dont process unless AvD is up */ if (!m_AVND_CB_IS_AVD_UP(cb)){ LOG_IN("AVD is not up yet"); return NCSCC_RC_FAILURE; } info = &evt->info.avd->msg_info.d2n_role_change_info; TRACE("MsgId: %u,NodeId:%u, role rcvd:%u role present:%u",\ info->msg_id, info->node_id, info->role, cb->avail_state_avnd); if ((info->msg_id != 0) && (info->msg_id != (cb->rcv_msg_id + 1))) { rc = NCSCC_RC_FAILURE; LOG_EM("%s Message id mismatch: %u",__FUNCTION__, info->msg_id); return rc; } cb->rcv_msg_id = info->msg_id; prev_ha_state = cb->avail_state_avnd; /* Ignore the duplicate roles. */ if (prev_ha_state == info->role) { return NCSCC_RC_SUCCESS; } if ((SA_AMF_HA_ACTIVE == cb->avail_state_avnd) && (SA_AMF_HA_QUIESCED == info->role)) { TRACE_1("SA_AMF_HA_QUIESCED role received"); if (NCSCC_RC_SUCCESS != (rc = avnd_mds_set_vdest_role(cb, V_DEST_RL_QUIESCED))) { LOG_ER("avnd_mds_set_vdest_role returned failure, role:%u",info->role); return rc; } return rc; } cb->avail_state_avnd = info->role; if (cb->avail_state_avnd == SA_AMF_HA_ACTIVE) { mds_role = V_DEST_RL_ACTIVE; TRACE_1("SA_AMF_HA_ACTIVE role received"); } else { mds_role = V_DEST_RL_STANDBY; TRACE_1("SA_AMF_HA_STANDBY role received"); } if (NCSCC_RC_SUCCESS != (rc = avnd_mds_set_vdest_role(cb, mds_role))) { TRACE_1("avnd_mds_set_vdest_role returned failure"); return rc; } if (NCSCC_RC_SUCCESS != (rc = avnd_set_mbcsv_ckpt_role(cb, info->role))) { LOG_ER("avnd_set_mbcsv_ckpt_role failed"); return rc; } if (cb->avail_state_avnd == SA_AMF_HA_ACTIVE) { /* We might be having some async update messages in the Queue to be processed, now drop all of them. */ avnd_dequeue_async_update_msgs(cb, FALSE); /* Go through timer list and start it. So send an event in mail box */ /* We need to start all the timers, which were running on ACT. */ rc = avnd_ha_state_act_hdlr(cb); if (NCSCC_RC_SUCCESS != rc) { LOG_ER("avnd_ha_state_act_hdlr failed"); } } TRACE_LEAVE(); return rc; }
/****************************************************************************\ PROCEDURE NAME : immd_saf_csi_set_cb DESCRIPTION : This is a SAF callback function which will be called when there is any change in the HA state. ARGUMENTS : invocation - This parameter designated a particular invocation of this callback function. The invoke process return invocation when it responds to the Avilability Management FrameWork using the saAmfResponse() function. compName - A pointer to the name of the component whose readiness stae the Availability Management Framework is setting. haState - The new HA state to be assumeb by the component service instance identified by csiName. csiDescriptor - RETURNS : Nothing. \*****************************************************************************/ static void immd_saf_csi_set_cb(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT new_haState, SaAmfCSIDescriptorT csiDescriptor) { SaAisErrorT error = SA_AIS_OK; SaAmfHAStateT prev_ha_state; bool role_change = true; uint32_t rc = NCSCC_RC_SUCCESS; IMMD_CB *cb = immd_cb; TRACE_ENTER(); prev_ha_state = cb->ha_state; /* Invoke the appropriate state handler routine */ switch (new_haState) { case SA_AMF_HA_ACTIVE: error = amf_active_state_handler(cb, invocation); break; case SA_AMF_HA_STANDBY: error = amf_standby_state_handler(cb, invocation); break; case SA_AMF_HA_QUIESCED: /* switch over */ error = amf_quiesced_state_handler(cb, invocation); break; case SA_AMF_HA_QUIESCING: /* shut down */ error = amf_quiescing_state_handler(cb, invocation); break; default: LOG_WA("invalid state: %d ", new_haState); error = SA_AIS_ERR_FAILED_OPERATION; break; } if (error != SA_AIS_OK) goto response; if (new_haState == SA_AMF_HA_QUIESCED) { /*Note: should we not change state in cb->ha_state here. This is done in immd_mds_quiesced_ack_process */ goto done; } /* Update control block */ cb->ha_state = new_haState; TRACE_5("New-state: %s, prev-state: %s", ha_state_name(new_haState), ha_state_name(prev_ha_state)); /* Handle active to active role change. */ if (prev_ha_state == new_haState) { TRACE_5("No role change!"); /* bug? */ role_change = false; } if (role_change) { if ((rc = immd_mds_change_role(cb)) != NCSCC_RC_SUCCESS) { LOG_WA("immd_mds_change_role FAILED"); error = SA_AIS_ERR_FAILED_OPERATION; goto response; } TRACE_5("Inform MBCSV of HA state change to %s", (new_haState == SA_AMF_HA_ACTIVE) ? "ACTIVE" : "STANDBY"); if (immd_mbcsv_chgrole(cb) != NCSCC_RC_SUCCESS) { LOG_WA("immd_mbcsv_chgrole FAILED"); error = SA_AIS_ERR_FAILED_OPERATION; goto response; } if (new_haState == SA_AMF_HA_ACTIVE) { /* Change of role to active => We may need to elect new coord */ if(immd_cb->m2PbeCanLoad) { LOG_IN("Electing coord in immd_saf_csi_set_cb() to ACTIVE"); immd_proc_elect_coord(cb, true); } immd_db_purge_fevs(cb); } } response: saAmfResponse(cb->amf_hdl, invocation, error); done: TRACE_LEAVE(); }
/**************************************************************************** * Name : plms_amf_CSI_set_callback * * Description : AMF callback function called * when there is any change in the HA state. * * Arguments : invocation - This parameter designated a particular * invocation of this callback function. The * invoke process return invocation when it * responds to the Avilability Management * FrameWork using the saAmfResponse() * function. * compName - A pointer to the name of the component * whose readiness stae the Availability * Management Framework is setting. * haState - The new HA state to be assumeb by the * component service instance identified by * csiName. * csiDescriptor - This will indicate whether or not the * component service instance for * ativeCompName went through quiescing. * * Return Values : None. * * Notes : None. *****************************************************************************/ void plms_amf_CSI_set_callback(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT new_haState, SaAmfCSIDescriptorT csiDescriptor) { PLMS_CB *cb = plms_cb; SaAisErrorT error = SA_AIS_OK; SaAmfHAStateT prev_haState; bool role_change = true; uint32_t rc = NCSCC_RC_SUCCESS; TRACE_ENTER(); m_NCS_LOCK(&cb->cb_lock,NCS_LOCK_WRITE); prev_haState = cb->ha_state; /* Invoke the appropriate state handler routine */ switch (new_haState) { case SA_AMF_HA_ACTIVE: cb->mds_role = V_DEST_RL_ACTIVE; TRACE("MY HA ROLE : AMF ACTIVE\n"); if (prev_haState == SA_AMF_HA_QUIESCED) { plms_proc_quiesced_active_role_change(); } else if (prev_haState == SA_AMF_HA_STANDBY) { plms_proc_standby_active_role_change(); } if(cb->hpi_cfg.hpi_support){ if (cb->hpi_intf_up == false) { TRACE("Got Active role, spawning HSM & HRB"); rc = plms_hsm_hrb_init(); if(NCSCC_RC_FAILURE == rc) { LOG_ER("hsm & hrb initialization failed"); error = SA_AIS_ERR_FAILED_OPERATION; goto response; } cb->hpi_intf_up = true; } if (prev_haState == SA_AMF_HA_STANDBY) { /* Build entity_path_to_entity mapping tree */ rc = plms_build_epath_to_entity_map_tree(); if( NCSCC_RC_SUCCESS != rc ){ LOG_ER("Failed to build entity_path_to_entity mapping tree"); error = SA_AIS_ERR_FAILED_OPERATION; goto response; } } } if( cb->hpi_intf_up ) { TRACE("PLMS sending Active role to HSM"); pthread_mutex_lock(&hsm_ha_state.mutex); hsm_ha_state.state = V_DEST_RL_ACTIVE; pthread_cond_signal(&hsm_ha_state.cond); pthread_mutex_unlock(&hsm_ha_state.mutex); TRACE("PLMS sending Active role to HRB"); pthread_mutex_lock(&hrb_ha_state.mutex); hrb_ha_state.state = SA_AMF_HA_ACTIVE; pthread_cond_signal(&hrb_ha_state.cond); pthread_mutex_unlock(&hrb_ha_state.mutex); } /* PLMC initialize */ if(!cb->hpi_cfg.hpi_support && !cb->plmc_initialized){ TRACE("Initializing PLMC"); rc = plmc_initialize(plms_plmc_connect_cbk, plms_plmc_udp_cbk, plms_plmc_error_cbk); if (rc){ LOG_ER("PLMC initialize failed."); rc = NCSCC_RC_FAILURE; goto response; } TRACE("PLMC initialize success."); cb->plmc_initialized = true; } cb->mds_role = V_DEST_RL_ACTIVE; break; case SA_AMF_HA_STANDBY: cb->mds_role = V_DEST_RL_STANDBY; LOG_IN("MY HA ROLE : AMF STANDBY\n"); TRACE("Send signal to HSM indicating standby state"); pthread_mutex_lock(&hsm_ha_state.mutex); hsm_ha_state.state = SA_AMF_HA_STANDBY; pthread_mutex_unlock(&hsm_ha_state.mutex); TRACE("Send signal to HRB indicating standby state"); pthread_mutex_lock(&hrb_ha_state.mutex); hrb_ha_state.state = SA_AMF_HA_STANDBY; pthread_mutex_unlock(&hrb_ha_state.mutex); SaUint32T (* hsm_func_ptr)() = NULL; if(cb->hpi_cfg.hpi_support){ /* Get the hsm Init func ptr */ hsm_func_ptr = dlsym(cb->hpi_intf_hdl, "plms_hsm_session_close"); if ( NULL == hsm_func_ptr ) { LOG_ER("dlsym() failed to get the hsm_func_ptr,error %s", dlerror()); goto response; } /* Initialize HSM */ rc = (* hsm_func_ptr)(); if ( NCSCC_RC_SUCCESS != rc ) { LOG_ER("plms_session_close failed"); goto response; } } /* PLMC finalize */ if(cb->plmc_initialized){ rc = plmc_destroy(); if (rc){ LOG_ER("PLMC destroy failed."); rc = NCSCC_RC_FAILURE; } cb->plmc_initialized = false; } if (prev_haState == SA_AMF_HA_QUIESCED) { plms_proc_quiesced_standby_role_change(); } break; case SA_AMF_HA_QUIESCED: plms_quiesced_state_handler(invocation); break; case SA_AMF_HA_QUIESCING: plms_quiescing_state_handler(invocation); break; default: LOG_IN("INVALID HA AMF STATE\n"); plms_invalid_state_handler(invocation); } if (new_haState == SA_AMF_HA_QUIESCED) return; /* Update control block */ cb->ha_state = new_haState; if (cb->csi_assigned == false) { cb->csi_assigned = true; /* We shall open checkpoint only once in our life time. currently doing at lib init */ } else if ((new_haState == SA_AMF_HA_ACTIVE) || (new_haState == SA_AMF_HA_STANDBY)) { /* It is a switch over */ /* check if this step is required */ /* cb->ckpt_state = COLD_SYNC_IDLE; */ } if ((prev_haState == SA_AMF_HA_ACTIVE) && (new_haState == SA_AMF_HA_ACTIVE)) { role_change = false; } if ((prev_haState == SA_AMF_HA_STANDBY) && (new_haState == SA_AMF_HA_STANDBY)) { role_change = false; } if (role_change == true) { if ((rc = plms_mds_change_role()) != NCSCC_RC_SUCCESS) { LOG_ER("plms_mds_change_role FAILED"); error = SA_AIS_ERR_FAILED_OPERATION; goto response; } else { if (cb->ha_state == SA_AMF_HA_ACTIVE) { /* FIXME: Is there any overhead to be done on New Active */ // if (plms_imm_declare_implementer(cb->immOiHandle) != SA_AIS_OK) // printf("ClassImplementer Set Failed\n"); } if (cb->ha_state == SA_AMF_HA_STANDBY) { /* FIXME : Do the over head processing needed to be done for standby state */ } } TRACE_5("Inform MBCSV of HA state change to %s", (new_haState == SA_AMF_HA_ACTIVE) ? "ACTIVE" : "STANDBY"); if (plms_mbcsv_chgrole() != NCSCC_RC_SUCCESS) { LOG_ER("Failed to change role"); error = SA_AIS_ERR_FAILED_OPERATION; goto response; } } response: /* Send the response to AMF */ saAmfResponse(cb->amf_hdl, invocation, error); m_NCS_UNLOCK(&cb->cb_lock,NCS_LOCK_WRITE); TRACE_LEAVE(); } /* End of PLMS CSI Set callback */
static uint32_t eds_proc_init_msg(EDS_CB *cb, EDSV_EDS_EVT *evt) { uint32_t rc = SA_AIS_OK; uint32_t async_rc = NCSCC_RC_SUCCESS; uint32_t loop_count = 0; SaVersionT *version = NULL; EDSV_MSG msg; EDS_CKPT_DATA ckpt; TRACE_ENTER2("agent dest: %" PRIx64, evt->fr_dest); /* Validate the version */ version = &(evt->info.msg.info.api_info.param.init.version); if (!m_EDA_VER_IS_VALID(version)) { TRACE_2("Invalid version"); rc = SA_AIS_ERR_VERSION; } /* Check if this EDA is a b03 client, and is on a cluster member node. */ if (m_IS_B03_CLIENT(version)) { TRACE("B.03 client. HA state = %d",cb->ha_state); /* Are we already assigned HA_STATE and is our node DB is populated ? */ if (cb->ha_state != EDS_HA_INIT_STATE) { TRACE("Checking if node is a member"); /* Check if this node is in the cluster */ if (!is_node_a_member(cb, evt->fr_node_id)) { LOG_IN("SA_AIS_ERR_UNAVAILABLE: saEvtInitialize attempted from a non-member node."); rc = SA_AIS_ERR_UNAVAILABLE; } else TRACE("Node is a member, allow initialize"); } } if (rc != SA_AIS_OK) { /* Return a default reg_id */ m_EDS_EDSV_INIT_MSG_FILL(msg, rc, 0) rc = eds_mds_msg_send(cb, &msg, &evt->fr_dest, &evt->mds_ctxt, MDS_SEND_PRIORITY_HIGH); if (rc != NCSCC_RC_SUCCESS) { LOG_ER("MDS send to %" PRIx64 " failed for saEvtInitialize() response", evt->fr_dest); } return (rc); } /* * Allocating new reg_id's this way on the wild chance we wrap * around the MAX_INT value and try to use a value that's still in use * and valid at the begining of the range. This way we'll keep trying * until we find the next open slot. But we'll only try a max of * MAX_REG_RETRIES times before giving up completly and returning an error. * It's highly unlikely we'll ever wrap, but at least we'll handle it. */ #define MAX_REG_RETRIES 100 loop_count = 0; do { loop_count++; /* Allocate a new regID */ if (cb->last_reg_id == INT_MAX) /* Handle integer wrap-around */ { LOG_IN("Integer wrap around for reg_id: %u", cb->last_reg_id); cb->last_reg_id = 0; } cb->last_reg_id++; /* Add this regid to the registration linked list. */ rc = eds_add_reglist_entry(cb, evt->fr_dest, cb->last_reg_id); } while ((rc == NCSCC_RC_FAILURE) && (loop_count < MAX_REG_RETRIES)); /* If we still have a bad status, return failure */ if (rc != NCSCC_RC_SUCCESS) { /* Send response back with error code */ rc = SA_AIS_ERR_LIBRARY; TRACE("SA_AIS_ERR_LIBRARY: for saEvtInitialize request %" PRIx64, evt->fr_dest); m_EDS_EDSV_INIT_MSG_FILL(msg, rc, 0) rc = eds_mds_msg_send(cb, &msg, &evt->fr_dest, &evt->mds_ctxt, MDS_SEND_PRIORITY_HIGH); if (rc != NCSCC_RC_SUCCESS) LOG_ER("MDS send to %" PRIx64 " failed for saEvtInitialize() response", evt->fr_dest); TRACE_LEAVE2("SA_AIS_ERR_LIBRARY"); return (rc); } /* Send response back with assigned reg_id value */ rc = SA_AIS_OK; m_EDS_EDSV_INIT_MSG_FILL(msg, rc, cb->last_reg_id) rc = eds_mds_msg_send(cb, &msg, &evt->fr_dest, &evt->mds_ctxt, MDS_SEND_PRIORITY_HIGH); if (rc != NCSCC_RC_SUCCESS) LOG_ER("MDS send to %" PRIx64 " failed for saEvtInitialize() response", evt->fr_dest); if (cb->ha_state == SA_AMF_HA_ACTIVE) { /*Revisit this */ memset(&ckpt, 0, sizeof(ckpt)); m_EDSV_FILL_ASYNC_UPDATE_REG(ckpt, cb->last_reg_id, evt->fr_dest) async_rc = send_async_update(cb, &ckpt, NCS_MBCSV_ACT_ADD); if (async_rc != NCSCC_RC_SUCCESS) TRACE("Async Update Send failed"); } TRACE_LEAVE(); return rc; }
/**************************************************************************** * Name : amf_quiescing_state_handler * * Description : This function is called upon receving an Quiescing state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the IMMD control block. * *****************************************************************************/ static SaAisErrorT amf_quiescing_state_handler(IMMD_CB *cb, SaInvocationT invocation) { LOG_IN("AMF HA QUIESCING request"); /*anything to close down ? */ return saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, SA_AIS_OK); }
/**************************************************************************** * Name : amf_standby_state_handler * * Description : This function is called upon receving an standby state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the IMMD control block. * *****************************************************************************/ static SaAisErrorT amf_standby_state_handler(IMMD_CB *cb, SaInvocationT invocation) { LOG_IN("AMF HA STANDBY request"); cb->mds_role = V_DEST_RL_STANDBY; return SA_AIS_OK; }
/** * Function to handle node discovery process * * @param args * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ void node_discovery_process(void *arg) { TRACE_ENTER(); int poll_ret = 0; int end_server = false, compress_array = false; int close_conn = false; DTM_INTERNODE_CB *dtms_cb = dtms_gl_cb; int current_size = 0, i, j; /* Data Received */ uint8_t inbuf[DTM_INTERNODE_RECV_BUFFER_SIZE]; uint8_t *data1; /* Used for DATAGRAM decoding */ uint16_t recd_bytes = 0; uint16_t recd_buf_len = 0; int node_info_buffer_len = 0; uint8_t node_info_hrd[NODE_INFO_PKT_SIZE]; char node_ip[INET6_ADDRSTRLEN]; memset(&node_ip, 0, INET6_ADDRSTRLEN); /*************************************************************/ /* Set up the initial bcast or mcast receiver socket */ /*************************************************************/ if (dtms_cb->mcast_flag != true) { if (NCSCC_RC_SUCCESS != dtm_dgram_bcast_listener(dtms_cb)) { LOG_ER("DTM:Set up the initial bcast receiver socket failed"); exit(1); } } else { if (NCSCC_RC_SUCCESS != dtm_dgram_mcast_listener(dtms_cb)) { LOG_ER("DTM:Set up the initial mcast receiver socket failed"); exit(1); } } /*************************************************************/ /* Set up the initial listening socket */ /*************************************************************/ if (NCSCC_RC_SUCCESS != dtm_stream_nonblocking_listener(dtms_cb)) { LOG_ER("DTM: Set up the initial stream nonblocking serv failed"); exit(1); } #if 0 if (add_self_node(dtms_cb) != NCSCC_RC_SUCCESS) { LOG_ER("DTM: add_self_node failed"); exit(1); } #endif /*************************************************************/ /* Initialize the pollfd structure */ /*************************************************************/ memset(fds, 0, sizeof(fds)); /*************************************************************/ /* Set up the initial listening socket */ /*************************************************************/ fds[0].fd = dtms_cb->dgram_sock_rcvr; fds[0].events = POLLIN; /*************************************************************/ /* Set up the initial listening socket */ /*************************************************************/ fds[1].fd = dtms_cb->stream_sock; fds[1].events = POLLIN; fds[2].fd = dtms_cb->mbx_fd; fds[2].events = POLLIN; nfds = 3; /*************************************************************/ /* Set up the initial listening socket */ /*************************************************************/ if (dtm_construct_node_info_hdr(dtms_cb, node_info_hrd, &node_info_buffer_len) != NCSCC_RC_SUCCESS) { LOG_ER("DTM: dtm_construct_node_info_hdr failed"); goto done; } /*************************************************************/ /* Loop waiting for incoming connects or for incoming data */ /* on any of the connected sockets. */ /*************************************************************/ do { /***********************************************************/ /* Call poll() and wait . */ /***********************************************************/ int fd_check = 0; poll_ret = poll(fds, nfds, DTM_TCP_POLL_TIMEOUT); /***********************************************************/ /* Check to see if the poll call failed. */ /***********************************************************/ if (poll_ret < 0) { LOG_ER(" poll() failed"); continue; } /***********************************************************/ /* Check to see if the 3 minute time out expired. */ /***********************************************************/ if (poll_ret == 0) { continue; } /***********************************************************/ /* One or more descriptors are readable. Need to */ /* determine which ones they are. */ /***********************************************************/ current_size = nfds; for (i = 0; i < current_size; i++) { /*********************************************************/ /* Loop through to find the descriptors that returned */ /* POLLIN and determine whether it's the listening */ /* or the active connection. */ /*********************************************************/ if (POLLIN & fds[i].revents) { if (fds[i].fd == dtms_cb->dgram_sock_rcvr) { fd_check++; /* Data Received */ memset(inbuf, 0, DTM_INTERNODE_RECV_BUFFER_SIZE); recd_bytes = 0; recd_buf_len = 0; recd_bytes = dtm_dgram_recvfrom_bmcast(dtms_cb, node_ip, inbuf, sizeof(inbuf)); if (recd_bytes == 0) { LOG_ER("DTM: recd bytes=0 on DGRAM sock"); continue; } data1 = inbuf; /* take care of previous address */ recd_buf_len = ncs_decode_16bit(&data1); if (recd_buf_len == recd_bytes) { int new_sd = -1; new_sd = dtm_process_connect(dtms_cb, node_ip, inbuf, (recd_bytes - 2)); if (new_sd == -1) continue; /*****************************************************/ /* Add the new incoming connection to the */ /* pollfd structure */ /*****************************************************/ LOG_IN("DTM: add New incoming connection to fd : %d\n", new_sd); fds[nfds].fd = new_sd; fds[nfds].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; nfds++; } else { /* Log message that we are dropping the data */ LOG_ER("DTM: BRoadcastLEN-MISMATCH: dropping the data"); } } else if (fds[i].fd == dtms_cb->stream_sock) { int new_sd = -1; uint32_t local_rc = NCSCC_RC_SUCCESS; fd_check++; /*******************************************************/ /* Listening descriptor is readable. */ /*******************************************************/ TRACE(" DTM :Listening socket is readable"); /*******************************************************/ /* Accept all incoming connections that are */ /* queued up on the listening socket before we */ /* loop back and call poll again. */ /*******************************************************/ /* do { */ /*****************************************************/ /* Accept each incoming connection. If */ /* accept fails with EWOULDBLOCK, then we */ /* have accepted all of them. Any other */ /* failure on accept will cause us to end the */ /* serv. */ /*****************************************************/ new_sd = dtm_process_accept(dtms_cb, dtms_cb->stream_sock); if (new_sd < 0) { LOG_ER("DTM: accept() failed"); end_server = true; break; } /*****************************************************/ /* Node info data back to the accept with node info */ /*****************************************************/ local_rc = dtm_comm_socket_send(new_sd, node_info_hrd, node_info_buffer_len); if (local_rc != NCSCC_RC_SUCCESS) { dtm_comm_socket_close(&new_sd); LOG_ER("DTM: send() failed "); break; } /*****************************************************/ /* Add the new incoming connection to the */ /* pollfd structure */ /*****************************************************/ TRACE("DTM :add New incoming connection to fd : %d\n", new_sd); fds[nfds].fd = new_sd; fds[nfds].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; nfds++; /*****************************************************/ /* Loop back up and accept another incoming */ /* connection */ /*****************************************************/ /* } while (new_sd != -1); */ /* accept one at a time */ } else if (fds[i].fd == dtms_cb->mbx_fd) { /* MBX fd messages that need to be sent out from this node */ /* Process the mailbox events */ DTM_SND_MSG_ELEM *msg_elem = NULL; fd_check++; msg_elem = (DTM_SND_MSG_ELEM *) (m_NCS_IPC_NON_BLK_RECEIVE(&dtms_cb->mbx, NULL)); if (NULL == msg_elem) { LOG_ER("DTM: Inter Node Mailbox IPC_NON_BLK_RECEIVE Failed"); continue; } else if (DTM_MBX_ADD_DISTR_TYPE == msg_elem->type) { dtm_internode_add_to_svc_dist_list(msg_elem->info.svc_event.server_type, msg_elem->info.svc_event.server_inst, msg_elem->info.svc_event.pid); free(msg_elem); msg_elem = NULL; } else if (DTM_MBX_DEL_DISTR_TYPE == msg_elem->type) { dtm_internode_del_from_svc_dist_list(msg_elem->info. svc_event.server_type, msg_elem->info. svc_event.server_inst, msg_elem->info.svc_event.pid); free(msg_elem); msg_elem = NULL; } else if (DTM_MBX_DATA_MSG_TYPE == msg_elem->type) { dtm_prepare_data_msg(msg_elem->info.data.buffer, msg_elem->info.data.buff_len); dtm_internode_snd_msg_to_node(msg_elem->info.data.buffer, msg_elem->info.data.buff_len, msg_elem->info.data.dst_nodeid); free(msg_elem); msg_elem = NULL; } else { LOG_ER("DTM Intranode :Invalid evt type from mbx"); free(msg_elem); msg_elem = NULL; } } else { /*********************************************************/ /* This is not the listening socket, therefore an */ /* existing connection must be readable */ /*********************************************************/ fd_check++; dtm_internode_process_poll_rcv_msg(fds[i].fd, &close_conn, node_info_hrd, node_info_buffer_len); } } else if (fds[i].revents & POLLOUT) { fd_check++; dtm_internode_process_pollout(fds[i].fd); } else if (fds[i].revents & POLLHUP) { fd_check++; close_conn = true; } /*******************************************************/ /* If the close_conn flag was turned on, we need */ /* to clean up this active connection. This */ /* clean up process includes removing the */ /* descriptor. */ /*******************************************************/ if (close_conn) { dtm_comm_socket_close(&fds[i].fd); close_conn = false; compress_array = true; } /* End of existing connection is readable */ if (poll_ret == fd_check) { break; } } /***********************************************************/ /* If the compress_array flag was turned on, we need */ /* to squeeze together the array and decrement the number */ /* of file descriptors. We do not need to move back the */ /* events and revents fields because the events will always */ /* be POLLIN in this case, and revents is output. */ /***********************************************************/ if (compress_array) { compress_array = false; for (i = 0; i < nfds; i++) { if (fds[i].fd == -1) { for (j = i; j < nfds; j++) { fds[j].fd = fds[j + 1].fd; } nfds--; } } } } while (end_server == false); /* End of serving running. */ /*************************************************************/ /* Clean up all of the sockets that are open */ /*************************************************************/ done: for (i = 0; i < nfds; i++) { if (fds[i].fd >= 0) dtm_comm_socket_close(&fds[i].fd); } TRACE_LEAVE(); return; }
/****************************************************************************\ * Function: avsv_mbcsv_process_dec_cb * * Purpose: AVSV MBCSV decode call back function. * * Input: arg - MBCSV callback argument pointer. * * Returns: NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. * * NOTES: * * \**************************************************************************/ static uns32 avsv_mbcsv_process_dec_cb(AVD_CL_CB *cb, NCS_MBCSV_CB_ARG *arg) { uns32 status = NCSCC_RC_SUCCESS; switch (arg->info.decode.i_msg_type) { case NCS_MBCSV_MSG_ASYNC_UPDATE: { if ((arg->info.decode.i_peer_version < AVD_MBCSV_SUB_PART_VERSION_3) && (arg->info.decode.i_reo_type >= AVSV_CKPT_AVD_SI_TRANS)) arg->info.decode.i_reo_type ++; /* Decode Async update message */ if (AVD_STBY_IN_SYNC == cb->stby_sync_state) { if (AVSV_SYNC_COMMIT != arg->info.decode.i_reo_type) { /* * Enqueue async update message till sync commit message is * received from the Active. */ avsv_enqueue_async_update_msgs(cb, &arg->info.decode); } else { /* * we have received sync commit message. So process all async * ckpt updates received till now. */ avsv_dequeue_async_update_msgs(cb, TRUE); } } else { /* Nothing is there to decode in this case */ if (AVSV_SYNC_COMMIT == arg->info.decode.i_reo_type) return status; /* * Cold sync is in progress, then drop the async update for which * cold sync response are yet to come. */ if (NCSCC_RC_SUCCESS != avsv_validate_reo_type_in_csync(cb, arg->info.decode.i_reo_type)) { /* Free userbuff and return without decoding */ ncs_reset_uba(&arg->info.decode.i_uba); break; } /* * During cold sync operation or in case of warm sync failure * and standby require to be sync-up, process the async updates as and * when they received. Dont enqueue them. */ if (arg->info.decode.i_reo_type < AVSV_CKPT_MSG_MAX) { status = avsv_dec_ckpt_data_func_list[arg->info.decode.i_reo_type] (cb, &arg->info.decode); } else { LOG_ER("%s: invalid type %u", __FUNCTION__, arg->info.encode.io_reo_type); status = NCSCC_RC_FAILURE; } } } break; case NCS_MBCSV_MSG_COLD_SYNC_REQ: { /* * Decode Cold Sync request message * Nothing is there to decode. */ TRACE("COLD_SYNC_REQ"); if (cb->init_state < AVD_INIT_DONE) { TRACE("invalid init state (%u) for cold sync req", cb->init_state); status = NCSCC_RC_FAILURE; } } break; case NCS_MBCSV_MSG_COLD_SYNC_RESP: case NCS_MBCSV_MSG_COLD_SYNC_RESP_COMPLETE: { if ((arg->info.decode.i_peer_version < AVD_MBCSV_SUB_PART_VERSION_3) && (arg->info.decode.i_reo_type >= AVSV_CKPT_AVD_SI_TRANS)) arg->info.decode.i_reo_type ++; /* Decode Cold Sync Response message */ status = avsv_decode_cold_sync_rsp(cb, &arg->info.decode); if (NCSCC_RC_SUCCESS != status) { LOG_ER("%s: cold sync decode failed %u", __FUNCTION__, status); (void) avd_data_clean_up(cb); status = NCSCC_RC_FAILURE; break; } /* * If we have received cold sync complete message then mark standby * as in sync. */ if ((NCS_MBCSV_MSG_COLD_SYNC_RESP_COMPLETE == arg->info.decode.i_msg_type) && (NCSCC_RC_SUCCESS == status)) { LOG_NO("Cold sync complete!"); cb->stby_sync_state = AVD_STBY_IN_SYNC; } cb->synced_reo_type = arg->info.decode.i_reo_type; } break; case NCS_MBCSV_MSG_WARM_SYNC_REQ: { /* * Decode Warm Sync Request message * Nothing is there to decode. */ TRACE("warm sync req"); } break; case NCS_MBCSV_MSG_WARM_SYNC_RESP: case NCS_MBCSV_MSG_WARM_SYNC_RESP_COMPLETE: { if ((arg->info.decode.i_peer_version < AVD_MBCSV_SUB_PART_VERSION_3) && (arg->info.decode.i_reo_type >= AVSV_CKPT_AVD_SI_TRANS)) arg->info.decode.i_reo_type ++; /* Decode Warm Sync Response message */ status = avsv_decode_warm_sync_rsp(cb, &arg->info.decode); /* If we find mismatch in data or warm sync fails set in_sync to FALSE */ if (NCSCC_RC_FAILURE == status) { LOG_ER("%s: warm sync decode failed %u", __FUNCTION__, status); cb->stby_sync_state = AVD_STBY_OUT_OF_SYNC; } } break; case NCS_MBCSV_MSG_DATA_REQ: { /* Decode Data request message */ status = avsv_decode_data_req(cb, &arg->info.decode); } break; case NCS_MBCSV_MSG_DATA_RESP: case NCS_MBCSV_MSG_DATA_RESP_COMPLETE: { if ((arg->info.decode.i_peer_version < AVD_MBCSV_SUB_PART_VERSION_3) && (arg->info.decode.i_reo_type >= AVSV_CKPT_AVD_SI_TRANS)) arg->info.decode.i_reo_type ++; /* Decode Data response and data response complete message */ status = avsv_decode_data_sync_rsp(cb, &arg->info.decode); if (NCSCC_RC_SUCCESS != status) { LOG_ER("%s: data resp decode failed %u", __FUNCTION__, status); avd_data_clean_up(cb); /* * Now send data request, which will sync Standby with Active. */ if (NCSCC_RC_SUCCESS != avsv_send_data_req(cb)) break; break; } if (NCS_MBCSV_MSG_DATA_RESP_COMPLETE == arg->info.decode.i_msg_type) { cb->stby_sync_state = AVD_STBY_IN_SYNC; LOG_IN("Standby in sync"); } } break; default: LOG_ER("%s: invalid msg type %u", __FUNCTION__, arg->info.decode.i_msg_type); status = NCSCC_RC_FAILURE; break; } return status; }