/**************************************************************************** Name : eda_hdl_cbk_dispatch_one Description : This routine dispatches one pending callback. Arguments : cb - ptr to the EDA control block hdl_rec - ptr to the handle record Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None ******************************************************************************/ static uns32 eda_hdl_cbk_dispatch_one(EDA_CB *cb, EDA_CLIENT_HDL_REC *hdl_rec) { EDSV_MSG *cbk_msg = NULL; uns32 rc = SA_AIS_OK; /* Nonblk receive to obtain the message from priority queue */ while (NULL != (cbk_msg = (EDSV_MSG *) m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, cbk_msg))) { if (cbk_msg->info.cbk_info.type == EDSV_EDS_DELIVER_EVENT) { if (eda_find_subsc_validity(cb, cbk_msg) == NCSCC_RC_SUCCESS) { /* process the callback list record */ eda_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec->reg_cbk); eda_msg_destroy(cbk_msg); break; } eda_msg_destroy(cbk_msg); } else { /* process the callback list record */ eda_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec->reg_cbk); eda_msg_destroy(cbk_msg); break; } } return rc; }
/*************************************************************************** @brief : Dipatch all. Read all the msgs from the MBX. @param[in] : client_info - Client for which dispatch is called. @return : SA_AIS_OK. *****************************************************************************/ SaAisErrorT smfa_dispatch_cbk_all(SMFA_CLIENT_INFO *client_info) { SMF_EVT *msg; TRACE_ENTER(); while(NULL != (msg = (SMF_EVT *) m_NCS_IPC_NON_BLK_RECEIVE(&client_info->cbk_mbx,NULL))){ /* You have reached this far means, everything is fine. 1. Client is not yet finalized. 2. Cbk is also registered. So you can call the cbk without any pre-requisite check. */ if (SMF_CLBK_EVT != msg->evt_type){ LOG_ER("SMFA: Wrong evt is posted to client MBX. evt_type: %d",msg->evt_type); free(msg); continue; } client_info->reg_cbk.saSmfCampaignCallback(client_info->client_hdl, msg->evt.cbk_evt.inv_id, msg->evt.cbk_evt.scope_id, &msg->evt.cbk_evt.object_name, msg->evt.cbk_evt.camp_phase, &msg->evt.cbk_evt.cbk_label, msg->evt.cbk_evt.params); smfa_evt_free(msg); } TRACE_LEAVE(); return SA_AIS_OK; }
/**************************************************************************** Name : ava_hdl_cbk_dispatch_one Description : This routine dispatches one pending callback. Arguments : cb - ptr to the AvA control block hdl_rec - ptr to the handle record Return Values : SA_AIS_OK/SA_AIS_ERR_<CODE> Notes : None. ******************************************************************************/ uint32_t ava_hdl_cbk_dispatch_one(AVA_CB **cb, AVA_HDL_REC **hdl_rec) { AVA_PEND_RESP *list_resp = &(*hdl_rec)->pend_resp; AVA_PEND_CBK_REC *rec = 0; uint32_t hdl = (*hdl_rec)->hdl; SaAmfCallbacksT reg_cbk; uint32_t rc = SA_AIS_OK; TRACE_ENTER(); memset(®_cbk, 0, sizeof(SaAmfCallbacksT)); memcpy(®_cbk, &(*hdl_rec)->reg_cbk, sizeof(SaAmfCallbacksT)); /* pop the rec from the mailbox queue */ rec = (AVA_PEND_CBK_REC *)m_NCS_IPC_NON_BLK_RECEIVE(&(*hdl_rec)->callbk_mbx, NULL); if (rec) { if (rec->cbk_info->type != AVSV_AMF_PG_TRACK) { /* push this record into pending response list */ m_AVA_HDL_PEND_RESP_PUSH(list_resp, (AVA_PEND_RESP_REC *)rec); m_AVA_HDL_CBK_REC_IN_DISPATCH_SET(rec); } /* release the cb lock & return the hdls to the hdl-mngr */ m_NCS_UNLOCK(&(*cb)->lock, NCS_LOCK_WRITE); ncshm_give_hdl(hdl); /* process the callback list record */ ava_hdl_cbk_rec_prc(rec->cbk_info, ®_cbk); m_NCS_LOCK(&(*cb)->lock, NCS_LOCK_WRITE); if (0 == (*hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_AVA, hdl))) { /* hdl is already finalized */ ava_hdl_cbk_rec_del(rec); TRACE_LEAVE2("Handle is already finalized"); return rc; } /* if we are done with this rec, free it */ if ((rec->cbk_info->type != AVSV_AMF_PG_TRACK) && m_AVA_HDL_IS_CBK_RESP_DONE(rec)) { m_AVA_HDL_PEND_RESP_POP(list_resp, rec, rec->cbk_info->inv); ava_hdl_cbk_rec_del(rec); } else if (rec->cbk_info->type == AVSV_AMF_PG_TRACK) { /* PG Track cbk do not have any response */ ava_hdl_cbk_rec_del(rec); } else { m_AVA_HDL_CBK_REC_IN_DISPATCH_RESET(rec); } } else TRACE_3("No record to process the dispatch()"); TRACE_LEAVE(); return rc; }
/**************************************************************************** * Name : gld_process_mbx * * Description : This is the function which process the IPC mail box of * GLD * * Arguments : mbx - This is the mail box pointer on which IfD/IfND is * going to block. * * Return Values : None. * * Notes : None. *****************************************************************************/ void gld_process_mbx(SYSF_MBX *mbx) { GLSV_GLD_EVT *evt = GLSV_GLD_EVT_NULL; while (GLSV_GLD_EVT_NULL != (evt = (GLSV_GLD_EVT *)m_NCS_IPC_NON_BLK_RECEIVE(mbx, evt))) { if ((evt->evt_type >= GLSV_GLD_EVT_BASE) && (evt->evt_type < GLSV_GLD_EVT_MAX)) { /* This event belongs to GLD */ gld_process_evt(evt); } else { m_LOG_GLD_HEADLINE(GLD_UNKNOWN_EVT_RCVD, NCSFL_SEV_ERROR, __FILE__, __LINE__, 0); m_MMGR_FREE_GLSV_GLD_EVT(evt); } } return; }
/**************************************************************************** Name : ntfa_hdl_cbk_dispatch_one Description : This routine dispatches one pending callback. Arguments : cb - ptr to the NTFA control block hdl_rec - ptr to the handle record Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None ******************************************************************************/ static SaAisErrorT ntfa_hdl_cbk_dispatch_one(ntfa_cb_t *cb, ntfa_client_hdl_rec_t *hdl_rec) { ntfsv_msg_t *cbk_msg; SaAisErrorT rc = SA_AIS_OK; TRACE_ENTER(); /* Nonblk receive to obtain the message from priority queue */ while (NULL != (cbk_msg = (ntfsv_msg_t *) m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, cbk_msg))) { rc = ntfa_hdl_cbk_rec_prc(cb, cbk_msg, hdl_rec); ntfa_msg_destroy(cbk_msg); break; } TRACE_LEAVE(); return rc; }
/**************************************************************************** Name : ntfa_hdl_cbk_dispatch_all Description : This routine dispatches all the pending callbacks. Arguments : cb - ptr to the NTFA control block hdl_rec - ptr to the handle record Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None ******************************************************************************/ static uns32 ntfa_hdl_cbk_dispatch_all(ntfa_cb_t *cb, ntfa_client_hdl_rec_t *hdl_rec) { ntfsv_msg_t *cbk_msg; uns32 rc = SA_AIS_OK; /* Recv all the cbk notifications from the queue & process them */ do { if (NULL == (cbk_msg = (ntfsv_msg_t *)m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, cbk_msg))) break; rc = ntfa_hdl_cbk_rec_prc(cb, cbk_msg, hdl_rec); /* now that we are done with this rec, free the resources */ ntfa_msg_destroy(cbk_msg); } while (1); return rc; }
/**************************************************************************** * Name : glnd_process_mbx * * Description : This is the function which process the IPC mail box of * GLND. * * Arguments : mbx - This is the mail box pointer on which IfD/IfND is * going to block. * * Return Values : None. * * Notes : None. *****************************************************************************/ void glnd_process_mbx(GLND_CB *cb, SYSF_MBX *mbx) { GLSV_GLND_EVT *evt = NULL; TRACE_ENTER(); while ((evt = (GLSV_GLND_EVT *)m_NCS_IPC_NON_BLK_RECEIVE(mbx, evt))) { if ((evt->type >= GLSV_GLND_EVT_BASE) && (evt->type < GLSV_GLND_EVT_MAX)) { /* process mail box */ glnd_process_evt((NCSCONTEXT)cb, evt); } else { TRACE_1("Unknown glnd evt rcvd: event_type %d", evt->type); m_MMGR_FREE_GLND_EVT(evt); } } TRACE_LEAVE(); return; }
/**************************************************************************** * 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; }
/*************************************************************************** * Name : plms_hrb * * * Description : This thread forwards the HPI request sent from PLM to HPID * This thread is spawned by PLM main task.It receives requests * from PLM main thread through MDS and invokes appropriate * HPI call * * Arguments : * Return Values : *****************************************************************************/ static void *plms_hrb(void) { PLMS_HRB_CB *cb = hrb_cb; PLMS_HPI_REQ *hpi_req = NULL; NCS_SEL_OBJ mbx_fd = m_NCS_IPC_GET_SEL_OBJ(&cb->mbx); TRACE_ENTER(); /* Wait on condition variable for the HA role from PLMS main thread */ pthread_mutex_lock(&hrb_ha_state.mutex); if(hrb_ha_state.state != SA_AMF_HA_ACTIVE){ TRACE("hrb waiting on cond variable for Active state"); pthread_cond_wait(&hrb_ha_state.cond,&hrb_ha_state.mutex); } pthread_mutex_unlock(&hrb_ha_state.mutex); while (osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(mbx_fd), -1) != -1) { /* process the Mail box */ /* Process messages delivered on mailbox */ while(NULL != (hpi_req = (PLMS_HPI_REQ *)m_NCS_IPC_NON_BLK_RECEIVE(&cb->mbx,hpi_req))){ /*Process the received message*/ hrb_process_hpi_req(hpi_req); if(hpi_req->entity_path) free(hpi_req->entity_path); free(hpi_req); } if(hrb_ha_state.state != SA_AMF_HA_ACTIVE){ /* Wait on condition variable for the HA role from PLMS main thread */ LOG_NO("HRB:Received Standby state, thread going \ to block till Active state is set"); pthread_mutex_lock(&hrb_ha_state.mutex); if(hrb_ha_state.state != SA_AMF_HA_ACTIVE){ TRACE("hrb waiting on cond variable for \ Active state"); pthread_cond_wait(&hrb_ha_state.cond, &hrb_ha_state.mutex); } pthread_mutex_unlock(&hrb_ha_state.mutex); }
/**************************************************************************** * Name : smfd_process_mbx * * Description : This is the function which process the IPC mail box of * SMFD * * Arguments : mbx - This is the mail box pointer on which SMFD is * going to block. * * Return Values : None. * * Notes : None. *****************************************************************************/ void smfd_process_mbx(SYSF_MBX * mbx) { SMFSV_EVT *evt = (SMFSV_EVT *) m_NCS_IPC_NON_BLK_RECEIVE(mbx, evt); if (evt != NULL) { if (evt->type != SMFSV_EVT_TYPE_SMFD) { LOG_ER("SMFD received wrong event type %d", evt->type); goto err; } switch (evt->info.smfd.type) { case SMFD_EVT_MDS_INFO: { proc_mds_info(smfd_cb, evt); break; } case SMFD_EVT_CMD_RSP: { /* The CMD RSP is always received synchronized so skip it here */ break; } case SMFD_EVT_CBK_RSP: { proc_callback_rsp(smfd_cb, evt); break; } case SMFD_EVT_QUIESCED_ACK: { proc_quiesced_ack(smfd_cb, evt); break; } default: { LOG_ER("SMFND received unknown event %d", evt->info.smfnd.type); break; } } } err: smfsv_evt_destroy(evt); }
/**************************************************************************** Name : eda_hdl_cbk_dispatch_all Description : This routine dispatches all the pending callbacks. Arguments : cb - ptr to the EDA control block hdl_rec - ptr to the handle record Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None ******************************************************************************/ static uns32 eda_hdl_cbk_dispatch_all(EDA_CB *cb, EDA_CLIENT_HDL_REC *hdl_rec) { EDSV_MSG *cbk_msg = NULL; uns32 rc = SA_AIS_OK; /* Recv all the cbk notifications from the queue & process them */ do { if (NULL == (cbk_msg = (EDSV_MSG *)m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, cbk_msg))) break; if (cbk_msg->info.cbk_info.type == EDSV_EDS_DELIVER_EVENT) { if (eda_find_subsc_validity(cb, cbk_msg) == NCSCC_RC_SUCCESS) { /* process the callback list record */ eda_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec->reg_cbk); } } else { /* process the callback list record */ eda_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec->reg_cbk); } /* now that we are done with this rec, free the resources */ eda_msg_destroy(cbk_msg); } while (1); return rc; }
/***************************************************************************** PROCEDURE NAME: main DESCRIPTION: Main routine for FM *****************************************************************************/ int main(int argc, char *argv[]) { NCS_SEL_OBJ mbx_sel_obj, pipe_sel_obj, highest_sel_obj; NCS_SEL_OBJ amf_sel_obj = {0, 0}; NCS_SEL_OBJ_SET sel_obj_set; FM_EVT *fm_mbx_evt = NULL; daemonize(argc, argv); if (fm_agents_startup() != NCSCC_RC_SUCCESS) { /* notify the NID */ fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_agents_startup_failed; } /* Allocate memory for FM_CB. */ fm_cb = m_MMGR_ALLOC_FM_CB; if (NULL == fm_cb) { /* notify the NID */ syslog(LOG_ERR, "CB Allocation failed."); fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_agents_startup_failed; } memset(fm_cb, 0, sizeof(FM_CB)); /* Create CB handle */ gl_fm_hdl = ncshm_create_hdl(NCS_HM_POOL_ID_COMMON, NCS_SERVICE_ID_GFM, (NCSCONTEXT)fm_cb); /* Take CB handle */ ncshm_take_hdl(NCS_SERVICE_ID_GFM, gl_fm_hdl); if (fm_get_args(fm_cb) != NCSCC_RC_SUCCESS) { /* notify the NID */ fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_get_args_failed; } /* Create MBX. */ if (m_NCS_IPC_CREATE(&fm_cb->mbx) != NCSCC_RC_SUCCESS) { syslog(LOG_ERR, "m_NCS_IPC_CREATE() failed."); fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_get_args_failed; } /* Attach MBX */ if (m_NCS_IPC_ATTACH(&fm_cb->mbx) != NCSCC_RC_SUCCESS) { syslog(LOG_ERR, "m_NCS_IPC_ATTACH() failed."); fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_mbx_attach_failure; } /* MDS initialization */ if (fm_mds_init(fm_cb) != NCSCC_RC_SUCCESS) { fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_mds_init_failed; } /* RDA initialization */ if (fm_rda_init(fm_cb) != NCSCC_RC_SUCCESS) { fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_rda_init_failed; } /* Open FM pipe for receiving AMF up intimation */ if (fm_amf_open(&fm_cb->fm_amf_cb) != NCSCC_RC_SUCCESS) { fm_nid_notify((uns32)NCSCC_RC_FAILURE); goto fm_hpl_lib_init_failed; } /* Get mailbox selection object */ mbx_sel_obj = m_NCS_IPC_GET_SEL_OBJ(&fm_cb->mbx); /* Get pipe selection object */ m_SET_FD_IN_SEL_OBJ(fm_cb->fm_amf_cb.pipe_fd, pipe_sel_obj); /* Give CB hdl */ ncshm_give_hdl(gl_fm_hdl); /* notify the NID */ fm_nid_notify(NCSCC_RC_SUCCESS); /* clear selection object set */ m_NCS_SEL_OBJ_ZERO(&sel_obj_set); /* Set only one pipe eelection object in set */ m_NCS_SEL_OBJ_SET(pipe_sel_obj, &sel_obj_set); highest_sel_obj = pipe_sel_obj; /* Wait for pipe selection object */ if (m_NCS_SEL_OBJ_SELECT(highest_sel_obj, &sel_obj_set, NULL, NULL, NULL) != -1) { /* following if will be true only first time */ if (m_NCS_SEL_OBJ_ISSET(pipe_sel_obj, &sel_obj_set)) { /* Take handle */ ncshm_take_hdl(NCS_SERVICE_ID_GFM, gl_fm_hdl); /* Process the message received on pipe */ if (fm_amf_pipe_process_msg(&fm_cb->fm_amf_cb) != NCSCC_RC_SUCCESS) goto done; /* Get amf selection object */ m_SET_FD_IN_SEL_OBJ(fm_cb->fm_amf_cb.amf_fd, amf_sel_obj); /* Release handle */ ncshm_give_hdl(gl_fm_hdl); } } /* clear selection object set */ m_NCS_SEL_OBJ_ZERO(&sel_obj_set); m_NCS_SEL_OBJ_SET(amf_sel_obj, &sel_obj_set); m_NCS_SEL_OBJ_SET(mbx_sel_obj, &sel_obj_set); highest_sel_obj = m_GET_HIGHER_SEL_OBJ(amf_sel_obj, mbx_sel_obj); /* Wait infinitely on */ while ((m_NCS_SEL_OBJ_SELECT(highest_sel_obj, &sel_obj_set, NULL, NULL, NULL) != -1)) { if (m_NCS_SEL_OBJ_ISSET(mbx_sel_obj, &sel_obj_set)) { /* Take handle */ ncshm_take_hdl(NCS_SERVICE_ID_GFM, gl_fm_hdl); fm_mbx_evt = (FM_EVT *)m_NCS_IPC_NON_BLK_RECEIVE(&fm_cb->mbx, msg); if (fm_mbx_evt) { fm_mbx_msg_handler(fm_cb, fm_mbx_evt); } /* Release handle */ ncshm_give_hdl(gl_fm_hdl); } if (m_NCS_SEL_OBJ_ISSET(amf_sel_obj, &sel_obj_set)) { /* Take handle */ ncshm_take_hdl(NCS_SERVICE_ID_GFM, gl_fm_hdl); /* Process the message received on amf selection object */ fm_amf_process_msg(&fm_cb->fm_amf_cb); /* Release handle */ ncshm_give_hdl(gl_fm_hdl); } m_NCS_SEL_OBJ_SET(amf_sel_obj, &sel_obj_set); m_NCS_SEL_OBJ_SET(mbx_sel_obj, &sel_obj_set); highest_sel_obj = m_GET_HIGHER_SEL_OBJ(amf_sel_obj, mbx_sel_obj); } fm_amf_close(&fm_cb->fm_amf_cb); fm_hpl_lib_init_failed: fm_rda_finalize(fm_cb); fm_rda_init_failed: fm_mds_finalize(fm_cb); fm_mds_init_failed: m_NCS_IPC_DETACH(&fm_cb->mbx, NULL, NULL); fm_mbx_attach_failure: m_NCS_IPC_RELEASE(&fm_cb->mbx, NULL); fm_get_args_failed: ncshm_destroy_hdl(NCS_SERVICE_ID_GFM, gl_fm_hdl); gl_fm_hdl = 0; m_MMGR_FREE_FM_CB(fm_cb); fm_agents_startup_failed: fm_agents_shutdown(); done: return 1; }
/** * Function to handle the intranode processing * * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ static void dtm_intranode_processing(void) { TRACE_ENTER(); while (1) { int poll_ret_val = 0, j = 0; for (j = 0; j < dtm_intranode_max_fd; j++) pfd_list[j] = dtm_intranode_pfd[j]; poll_ret_val = poll(pfd_list, dtm_intranode_max_fd, DTM_INTRANODE_POLL_TIMEOUT); if (poll_ret_val > 0) { int num_fd_checked = 0, i = 0; for (i = 0; i < dtm_intranode_max_fd; i++) { if (pfd_list[i].revents & POLLIN) { num_fd_checked++; if (pfd_list[i].fd == dtm_intranode_cb->server_sockfd) { /* Read indication on server listening socket */ /* Accept the incoming connection */ dtm_intranode_process_incoming_conn(); } else if (pfd_list[i].fd == dtm_intranode_cb->mbx_fd) { /* Message process from internode */ DTM_RCV_MSG_ELEM *msg_elem = NULL; msg_elem = (DTM_RCV_MSG_ELEM *) (m_NCS_IPC_NON_BLK_RECEIVE(&dtm_intranode_cb->mbx, NULL)); if (NULL == msg_elem) { LOG_ER("DTM : Intra Node Mailbox IPC_NON_BLK_RECEIVE Failed"); continue; } else if (DTM_MBX_UP_TYPE == msg_elem->type) { dtm_process_internode_service_up_msg(msg_elem->info.svc_event. buffer, msg_elem->info.svc_event. len, msg_elem->info.svc_event. node_id); free(msg_elem->info.svc_event.buffer); } else if (DTM_MBX_DOWN_TYPE == msg_elem->type) { dtm_process_internode_service_down_msg(msg_elem->info.svc_event. buffer, msg_elem->info.svc_event. len, msg_elem->info.svc_event. node_id); free(msg_elem->info.svc_event.buffer); } else if (DTM_MBX_NODE_UP_TYPE == msg_elem->type) { TRACE("DTM: node_ip:%s, node_id:%u i_addr_family:%d ", msg_elem->info.node.node_ip, msg_elem->info.node.node_id, msg_elem->info.node.i_addr_family); dtm_intranode_process_node_up(msg_elem->info.node.node_id, msg_elem->info.node.node_name, msg_elem->info.node.node_ip, msg_elem->info.node.i_addr_family, msg_elem->info.node.mbx); } else if (DTM_MBX_NODE_DOWN_TYPE == msg_elem->type) { TRACE("DTM: node_ip:%s, node_id:%u i_addr_family:%d ", msg_elem->info.node.node_ip, msg_elem->info.node.node_id, msg_elem->info.node.i_addr_family); dtm_intranode_process_node_down(msg_elem->info.node.node_id); } else if (DTM_MBX_MSG_TYPE == msg_elem->type) { dtm_process_rcv_internode_data_msg(msg_elem->info.data.buffer, msg_elem->info.data.dst_pid, msg_elem->info.data.len); } else { LOG_ER("DTM: Intranode :Invalid evt type from mbx"); } free(msg_elem); } else { /* Data to be received on accepted connections */ dtm_intranode_process_poll_rcv_msg(pfd_list[i].fd); } } else if (pfd_list[i].revents & POLLOUT) { num_fd_checked++; dtm_intranode_process_pollout(pfd_list[i].fd); } else if (pfd_list[i].revents & POLLHUP) { num_fd_checked++; TRACE("DTM_INTRA: Socket close: %d err :%s", pfd_list[i].fd, strerror(errno)); dtm_intranode_process_pid_down(pfd_list[i].fd); dtm_intranode_del_poll_fdlist(pfd_list[i].fd); } if (num_fd_checked == poll_ret_val) { /* No more FD's to be checked */ break; } } } } /* While loop */ TRACE_LEAVE(); }
/**************************************************************************** Name : saClmClusterTrackStop Description : This fuction requests CLM to stop tracking the changes in the cluster membership. Arguments : hdl - CLM handle Return Values : Refer to SAI-AIS specification for various return values. Notes : None. ******************************************************************************/ SaAisErrorT saClmClusterTrackStop(SaClmHandleT clmHandle) { clma_client_hdl_rec_t *hdl_rec; CLMSV_MSG msg, *o_msg = NULL; SaAisErrorT rc = SA_AIS_OK; CLMSV_MSG *cbk_msg; CLMSV_MSG *async_cbk_msg = NULL, *process = NULL; uns32 mds_rc; TRACE_ENTER(); /* retrieve hdl rec */ hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_CLMA, clmHandle); if (hdl_rec == NULL) { TRACE("ncshm_take_hdl failed"); rc = SA_AIS_ERR_BAD_HANDLE; goto done; } /* Check Whether CLMS is up or not */ if (!clma_cb.clms_up) { TRACE("CLMS down"); rc = SA_AIS_ERR_TRY_AGAIN; goto done_give_hdl; } if((hdl_rec->is_configured == FALSE) && (!clma_validate_version(hdl_rec->version))) { TRACE("Node is unconfigured"); rc = SA_AIS_ERR_UNAVAILABLE; goto done_give_hdl; } /** populate & send the finalize message ** and make sure the finalize from the server ** end returned before deleting the local records. **/ memset(&msg, 0, sizeof(CLMSV_MSG)); msg.evt_type = CLMSV_CLMA_TO_CLMS_API_MSG; msg.info.api_info.type = CLMSV_TRACK_STOP_REQ; msg.info.api_info.param.track_stop.client_id = hdl_rec->clms_client_id; mds_rc = clma_mds_msg_sync_send(&clma_cb, &msg, &o_msg, CLMS_WAIT_TIME); switch (mds_rc) { case NCSCC_RC_SUCCESS: break; case NCSCC_RC_REQ_TIMOUT: rc = SA_AIS_ERR_TIMEOUT; TRACE("clma_mds_msg_sync_send FAILED: %u", rc); goto done_give_hdl; default: TRACE("clma_mds_msg_sync_send FAILED: %u", rc); rc = SA_AIS_ERR_NO_RESOURCES; goto done_give_hdl; } if (o_msg != NULL) { rc = o_msg->info.api_resp_info.rc; clma_msg_destroy(o_msg); /*need to do */ } else rc = SA_AIS_ERR_NO_RESOURCES; if (rc == SA_AIS_OK) { do { if (NULL == (cbk_msg = (CLMSV_MSG *) m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, cbk_msg))) break; if (cbk_msg->info.cbk_info.type == CLMSV_TRACK_CBK) { TRACE_2("Dropping Track Callback %d", cbk_msg->info.cbk_info.type); clma_msg_destroy(cbk_msg); } else if (cbk_msg->info.cbk_info.type == CLMSV_NODE_ASYNC_GET_CBK) { clma_add_to_async_cbk_msg_list(&async_cbk_msg, cbk_msg); } else { TRACE("Dropping unsupported callback type %d", cbk_msg->info.cbk_info.type); clma_msg_destroy(cbk_msg); } } while (1); process = async_cbk_msg; while (process) { /* IPC send is making next as NULL in process pointer */ /* process the message */ async_cbk_msg = async_cbk_msg->next; rc = clma_clms_msg_proc(&clma_cb, process, MDS_SEND_PRIORITY_MEDIUM); if (rc != NCSCC_RC_SUCCESS) { TRACE_2("From TrackStop clma_clms_msg_proc returned: %d", rc); } process = async_cbk_msg; /*async_cbk_msg->next = NULL; async_cbk_msg = process; */ } } done_give_hdl: ncshm_give_hdl(clmHandle); done: TRACE_LEAVE(); return rc; }
/** * 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; }
/**************************************************************************** Name : glsv_gla_callback_queue_read Description : This routine is used to read from the queue for the callbacks Arguments : gla_cb - pointer to the gla control block handle - handle id of the client Return Values : pointer to the callback Notes : None ******************************************************************************/ GLSV_GLA_CALLBACK_INFO *glsv_gla_callback_queue_read(GLA_CLIENT_INFO *client_info) { /* remove it to the queue */ return (GLSV_GLA_CALLBACK_INFO *)m_NCS_IPC_NON_BLK_RECEIVE(&client_info->callbk_mbx, NULL); }