/***********************************************************************//** * @brief This function is for PLMA to sync with PLMS when it gets * MDS callback. * * @return Returns nothing. ***************************************************************************/ void plma_sync_with_plms() { PLMA_CB *cb = plma_ctrlblk; TRACE_ENTER(); m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE); if (cb->plms_svc_up) { TRACE("Plms is up"); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); return; } cb->plms_sync_awaited = true; m_NCS_SEL_OBJ_CREATE(&cb->sel_obj); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); /** Await indication from MDS saying PLMS is up */ osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(cb->sel_obj), 30000); /* Destroy the sync - object */ m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE); cb->plms_sync_awaited = false; m_NCS_SEL_OBJ_DESTROY(cb->sel_obj); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE); TRACE_LEAVE(); return; }
/******************************************************************** Name : cpa_sync_with_cpnd Description : This is for CPA to sync with CPND when it gets MDS callback **********************************************************************/ void cpa_sync_with_cpnd(CPA_CB *cb) { m_NCS_LOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE); if (cb->is_cpnd_up) { m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE); return; } cb->cpnd_sync_awaited = true; m_NCS_SEL_OBJ_CREATE(&cb->cpnd_sync_sel); m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE); /* Await indication from MDS saying CPND is up */ osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(cb->cpnd_sync_sel), 30000); /* Destroy the sync - object */ m_NCS_LOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE); cb->cpnd_sync_awaited = false; m_NCS_SEL_OBJ_DESTROY(&cb->cpnd_sync_sel); m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE); return; }
/******************************************************************** Name : mqa_sync_with_mqnd Description : This is for MQA to sync with MQND when it gets MDS callback **********************************************************************/ static void mqa_sync_with_mqnd(MQA_CB *cb) { TRACE_ENTER(); m_NCS_LOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE); if (cb->is_mqnd_up) { TRACE_1("MQND is already up with the MQA"); m_NCS_UNLOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE); return; } cb->mqnd_sync_awaited = true; m_NCS_SEL_OBJ_CREATE(&cb->mqnd_sync_sel); m_NCS_UNLOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE); /* Await indication from MDS saying MQND is up */ osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(cb->mqnd_sync_sel), 30000); /* Destroy the sync - object */ m_NCS_LOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE); cb->mqnd_sync_awaited = false; m_NCS_SEL_OBJ_DESTROY(cb->mqnd_sync_sel); m_NCS_UNLOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE); TRACE_1("MQND synced up with the MQA"); TRACE_LEAVE(); return; }
/** * This function initializes the DTMS_CB including the Patricia trees * * @param dtms_cb * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ uns32 dtm_cb_init(DTM_INTERNODE_CB * dtms_cb) { NCS_PATRICIA_PARAMS nodeid_param; NCS_PATRICIA_PARAMS comm_socket_param; NCS_PATRICIA_PARAMS ipaddr_param; TRACE_ENTER(); memset(&nodeid_param, 0, sizeof(NCS_PATRICIA_PARAMS)); memset(&comm_socket_param, 0, sizeof(NCS_PATRICIA_PARAMS)); memset(&ipaddr_param, 0, sizeof(NCS_PATRICIA_PARAMS)); nodeid_param.key_size = sizeof(uns32); comm_socket_param.key_size = sizeof(uns32); ipaddr_param.key_size = IPV6_ADDR_UNS8_CNT; /* Initialize patricia tree for nodeid list */ if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtms_cb->nodeid_tree, &nodeid_param)) { LOG_ER("DTM: ncs_patricia_tree_init FAILED"); return NCSCC_RC_FAILURE; } /* Initialize comm_socket patricia tree */ if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtms_cb->comm_sock_tree, &comm_socket_param)) { LOG_ER("DTM:ncs_patricia_tree_init FAILED"); return NCSCC_RC_FAILURE; } /* Initialize comm_socket patricia tree */ if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtms_cb->ip_addr_tree, &ipaddr_param)) { LOG_ER("DTM:ncs_patricia_tree_init FAILED"); return NCSCC_RC_FAILURE; } if (m_NCS_IPC_CREATE(&dtms_cb->mbx) != NCSCC_RC_SUCCESS) { /* Mail box creation failed */ LOG_ER("DTM:IPC create FAILED"); return NCSCC_RC_FAILURE; } else { NCS_SEL_OBJ obj; if (NCSCC_RC_SUCCESS != m_NCS_IPC_ATTACH(&dtms_cb->mbx)) { m_NCS_IPC_RELEASE(&dtms_cb->mbx, NULL); LOG_ER("DTM: Internode Mailbox Attach failed"); return NCSCC_RC_FAILURE; } obj = m_NCS_IPC_GET_SEL_OBJ(&dtms_cb->mbx); /* retreive the corresponding fd for mailbox and fill it in cb */ dtms_cb->mbx_fd = m_GET_FD_FROM_SEL_OBJ(obj); /* extract and fill value needs to be extracted */ } TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
/*************************************************************************** * 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 : saClmSelectionObjectGet Description : This function creates & returns the operating system handle associated with the CLM Handle. Arguments : clmHandle - CLM handle selectionObject - ptr to the selection object Return Values : Refer to SAI-AIS specification for various return values. Notes : None. ******************************************************************************/ SaAisErrorT saClmSelectionObjectGet(SaClmHandleT clmHandle, SaSelectionObjectT *selectionObject) { SaAisErrorT rc = SA_AIS_OK; clma_client_hdl_rec_t *hdl_rec; NCS_SEL_OBJ sel_obj; TRACE_ENTER(); if (selectionObject == NULL) { TRACE("selectionObject is NULL"); rc = SA_AIS_ERR_INVALID_PARAM; goto done; } /* 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; } 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; } /* Obtain the selection object from the IPC queue */ sel_obj = m_NCS_IPC_GET_SEL_OBJ(&hdl_rec->mbx); /* everything's fine.. pass the sel fd to the appl */ *selectionObject = (SaSelectionObjectT)m_GET_FD_FROM_SEL_OBJ(sel_obj); done_give_hdl: /* return hdl rec */ ncshm_give_hdl(clmHandle); done: TRACE_LEAVE(); return rc; }
/*************************************************************************** @brief : saSmfSelectionObjectGet. If this api is called twice, same sel obj will be returned. @param[in] : smfHandle - Handle returned by successful intialize. @param[out] : selectionObject - Will have a valid sel obj in successful return of the api. @return : SA_AIS_OK if successful otherwise appropiate err code. *****************************************************************************/ SaAisErrorT saSmfSelectionObjectGet( SaSmfHandleT smfHandle, SaSelectionObjectT *selectionObject) { SMFA_CB *cb = &_smfa_cb; SMFA_CLIENT_INFO *client_info; TRACE_ENTER2("SMFA: Handle: %llu.",smfHandle); if (NULL == selectionObject){ LOG_ER("SMFA: selectionObject is NULL."); TRACE_LEAVE(); return SA_AIS_ERR_INVALID_PARAM; } /* To check if finalize is already called.*/ if (cb->is_finalized){ LOG_ER("SMFA: Already finalized, Bad handle: %llu.",smfHandle); TRACE_LEAVE(); return SA_AIS_ERR_BAD_HANDLE; } if (NCSCC_RC_SUCCESS != m_NCS_LOCK(&cb->cb_lock,NCS_LOCK_READ)){ LOG_ER("SMFA: Cb lock acquire FAILED."); TRACE_LEAVE(); return SA_AIS_ERR_NO_RESOURCES; } /* Get the client info structure for the handle.*/ client_info = smfa_client_info_get(smfHandle); if (NULL == client_info){ LOG_ER("SMFA: Could not retrieve client info, Bad handle: %llu",smfHandle); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_READ); TRACE_LEAVE(); return SA_AIS_ERR_BAD_HANDLE; } *selectionObject = (SaSelectionObjectT)m_GET_FD_FROM_SEL_OBJ( m_NCS_IPC_GET_SEL_OBJ(&client_info->cbk_mbx)); m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_READ); TRACE_LEAVE(); return SA_AIS_OK; }
static uint32_t dtm_intranode_create_pid_info(int fd) { DTM_INTRANODE_PID_INFO *pid_node = NULL; TRACE_ENTER(); if (NULL == (pid_node = calloc(1, sizeof(DTM_INTRANODE_PID_INFO)))) { TRACE("\nMemory allocation failed for DTM_INTRANODE_PID_INFO"); return NCSCC_RC_FAILURE; } pid_node->accepted_fd = fd; pid_node->pid = 0; /* Yet to be filled from the PID Message which is yet to come */ pid_node->node_id = m_NCS_GET_NODE_ID; pid_node->fd_node.key_info = (uint8_t *)&pid_node->accepted_fd; if (m_NCS_IPC_CREATE(&pid_node->mbx) != NCSCC_RC_SUCCESS) { /* Mail box creation failed */ TRACE("Mailbox creation failed,dtm_accept msg"); free(pid_node); return NCSCC_RC_FAILURE; } else { NCS_SEL_OBJ obj; /* Code added for attaching the mailbox */ if (NCSCC_RC_SUCCESS != m_NCS_IPC_ATTACH(&pid_node->mbx)) { TRACE("\nMailbox attach failed,dtm_intranode_process_pid_msg"); m_NCS_IPC_RELEASE(&pid_node->mbx, NULL); free(pid_node); return NCSCC_RC_FAILURE; } obj = m_NCS_IPC_GET_SEL_OBJ(&pid_node->mbx); /* retreive the corresponding fd for mailbox */ pid_node->mbx_fd = m_GET_FD_FROM_SEL_OBJ(obj); /* extract and fill value needs to be extracted */ } ncs_patricia_tree_add(&dtm_intranode_cb->dtm_intranode_fd_list, (NCS_PATRICIA_NODE *)&pid_node->fd_node); TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
bool sysfTmrDestroy(void) { SYSF_TMR *tmr; SYSF_TMR *free_tmr; SYSF_TMR_PAT_NODE *tmp = NULL; /* There is only ever one timer per instance */ m_NCS_LOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); gl_tcb.safe.dmy_free.next = NULL; m_NCS_UNLOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* Create selection object */ m_NCS_SEL_OBJ_CREATE(&tmr_destroy_syn_obj); tmr_destroying = true; m_NCS_SEL_OBJ_IND(&gl_tcb.sel_obj); /* Unlock the lock */ m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* critical region END */ /* Wait on Poll object */ osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(tmr_destroy_syn_obj), 20000); m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); tmr = &gl_tcb.safe.dmy_keep; while (tmr->keep != NULL) { free_tmr = tmr->keep; tmr->keep = tmr->keep->keep; m_NCS_MEM_FREE(free_tmr, NCS_MEM_REGION_PERSISTENT, NCS_SERVICE_ID_LEAP_TMR, 0); } while ((tmp = (SYSF_TMR_PAT_NODE *)ncs_patricia_tree_getnext(&gl_tcb.tmr_pat_tree, (uint8_t *)0)) != NULL) { ncs_patricia_tree_del(&gl_tcb.tmr_pat_tree, (NCS_PATRICIA_NODE *)tmp); m_NCS_MEM_FREE(tmp, NCS_MEM_REGION_PERSISTENT, NCS_SERVICE_ID_LEAP_TMR, 0); } ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); m_NCS_SEL_OBJ_DESTROY(&gl_tcb.sel_obj); /* Stop the dedicated thread that runs out of ncs_tmr_wait() */ m_NCS_TASK_RELEASE(gl_tcb.p_tsk_hdl); tmr_destroying = false; m_NCS_SEL_OBJ_DESTROY(&tmr_destroy_syn_obj); m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* critical region END */ /* don't destroy the lock (but remember that you could!). * m_NCS_LOCK_DESTROY (&l_tcb.lock); */ m_NCS_LOCK_DESTROY(&gl_tcb.safe.enter_lock); m_NCS_LOCK_DESTROY(&gl_tcb.safe.free_lock); ncs_tmr_create_done = false; return true; }
/**************************************************************************** * Function Name: ncs_tmr_wait * * Purpose: Goto counting semephore and block until tmr_pulse is felt. This * means the actual expiry task no longer services the sysfTmrExpiry * function any more. This should eliminate timer drift. * ****************************************************************************/ static uint32_t ncs_tmr_wait(void) { unsigned rc; int inds_rmvd; uint64_t next_delay = 0; struct timeval tv = { 0xffffff, 0 }; struct timespec ts_current = { 0, 0 }; struct timespec ts; struct pollfd set; if (clock_gettime(CLOCK_MONOTONIC, &ts_start)) { perror("clock_gettime with MONOTONIC Failed \n"); return NCSCC_RC_FAILURE; } ts_current = ts_start; while (true) { set.fd = m_GET_FD_FROM_SEL_OBJ(gl_tcb.sel_obj); set.events = POLLIN; osaf_timeval_to_timespec(&tv, &ts); rc = osaf_ppoll(&set, 1, next_delay != 0 ? &ts : NULL, NULL); m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); if (rc == 1) { if (set.revents != POLLIN) osaf_abort(set.revents); /* if select returned because of indication on sel_obj from sysfTmrDestroy */ if (tmr_destroying == true) { /* Raise An indication */ m_NCS_SEL_OBJ_IND(&tmr_destroy_syn_obj); m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); return NCSCC_RC_SUCCESS; } gl_tcb.msg_count--; if (gl_tcb.msg_count == 0) { inds_rmvd = m_NCS_SEL_OBJ_RMV_IND(&gl_tcb.sel_obj, true, true); if (inds_rmvd <= 0) { if (inds_rmvd != -1) { /* The object has not been destroyed and it has no indication raised on it inspite of msg_count being non-zero. */ m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* The mbox must have been destroyed */ return NCSCC_RC_FAILURE; } } } rc = ncs_tmr_engine(&tv, &next_delay); if (rc == NCSCC_RC_FAILURE) { m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); return NCSCC_RC_FAILURE; } m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); ts_current.tv_sec = ts_current.tv_nsec = 0; if (clock_gettime(CLOCK_MONOTONIC, &ts_current)) { perror("clock_gettime with MONOTONIC Failed \n"); return NCSCC_RC_FAILURE; } } return NCSCC_RC_SUCCESS; }
/** * Function to init the intranode processing * * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ uint32_t dtm_intra_processing_init(char *node_ip, DTM_IP_ADDR_TYPE i_addr_family) { int servlen, size = DTM_INTRANODE_SOCK_SIZE; /* For socket fd and server len */ struct sockaddr_un serv_addr; /* For Unix Sock address */ char server_ux_name[255]; NCS_PATRICIA_PARAMS pat_tree_params; struct sockaddr_in serveraddr; struct sockaddr_in6 serveraddr6; int flags; TRACE_ENTER(); /* UNIX is default transport for intranode */ dtm_socket_domain = AF_UNIX; if (NULL == (dtm_intranode_cb = calloc(1, sizeof(DTM_INTRANODE_CB)))) { LOG_ER("DTM: Memory allocation failed for dtm_intranode_cb"); return NCSCC_RC_FAILURE; } dtm_intranode_cb->sock_domain = dtm_socket_domain; /* Open a socket, If socket opens to fail return Error */ dtm_intranode_cb->server_sockfd = socket(dtm_socket_domain, SOCK_STREAM, 0); if (dtm_intranode_cb->server_sockfd < 0) { LOG_ER("DTM: Socket creation failed err :%s ", strerror(errno)); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } /*Make the socket Non-Blocking for accepting */ if ((flags = fcntl(dtm_intranode_cb->server_sockfd, F_GETFL, NULL)) < 0) { LOG_ER("DTM :fcntl(F_SETFL, O_NONBLOCK) err :%s ", strerror(errno)); return false; } flags |= O_NONBLOCK; if(fcntl(dtm_intranode_cb->server_sockfd, F_SETFL, flags) < 0) { /*Non-Blocking Options hasnt been set, what shall we do now */ LOG_ER("DTM: Socket NON Block set failed err :%s ", strerror(errno)); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } /* Increase the socket buffer size */ if (setsockopt(dtm_intranode_cb->server_sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) != 0) { LOG_ER("DTM: Unable to set the SO_RCVBUF err :%s ", strerror(errno)); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } if (setsockopt(dtm_intranode_cb->server_sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) != 0) { LOG_ER("DTM: Unable to set the SO_SNDBUF err :%s ", strerror(errno)); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } dtm_intranode_cb->nodeid = m_NCS_GET_NODE_ID; bzero((char *)&serv_addr, sizeof(serv_addr)); if (dtm_socket_domain == AF_UNIX) { #define UX_SOCK_NAME_PREFIX PKGLOCALSTATEDIR "/osaf_dtm_intra_server" sprintf(server_ux_name, "%s", UX_SOCK_NAME_PREFIX); serv_addr.sun_family = AF_UNIX; strcpy(serv_addr.sun_path, server_ux_name); unlink(serv_addr.sun_path); servlen = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family); /* Bind the created socket here with the address NODEID, * if bind fails return error by the closing the * created socket*/ if (bind(dtm_intranode_cb->server_sockfd, (struct sockaddr *)&serv_addr, servlen) < 0) { LOG_ER("DTM: Bind failed err :%s ", strerror(errno)); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } if (chmod(UX_SOCK_NAME_PREFIX, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) < 0) { LOG_ER("chmod %s failed - %s", UX_SOCK_NAME_PREFIX, strerror(errno)); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } } else { if (dtm_socket_domain == AF_INET) { memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(DTM_INTRA_SERVER_PORT); serveraddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (bind(dtm_intranode_cb->server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr) ) < 0) { LOG_ER("DTM: Bind failed err :%s ", strerror(errno)); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } } else { memset(&serveraddr6, 0, sizeof(serveraddr6)); serveraddr6.sin6_family = AF_INET6; serveraddr.sin_port = htons(DTM_INTRA_SERVER_PORT); inet_pton(AF_INET6, "localhost", &serveraddr6.sin6_addr); if (bind(dtm_intranode_cb->server_sockfd, (struct sockaddr *)&serveraddr6, sizeof(serveraddr6) ) < 0) { LOG_ER("DTM_INTRA: Bind failed"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } } } listen(dtm_intranode_cb->server_sockfd, 20); memset(&pat_tree_params, 0, sizeof(pat_tree_params)); pat_tree_params.key_size = sizeof(uint32_t); if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtm_intranode_cb->dtm_intranode_pid_list, &pat_tree_params)) { LOG_ER("DTM: ncs_patricia_tree_init failed for dtm_intranode_pid_list"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } pat_tree_params.key_size = sizeof(int); if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtm_intranode_cb->dtm_intranode_fd_list, &pat_tree_params)) { LOG_ER("DTM: ncs_patricia_tree_init failed for dtm_intranode_pid_list"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } pat_tree_params.key_size = sizeof(uint32_t); if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtm_intranode_cb->dtm_svc_subscr_list, &pat_tree_params)) { LOG_ER("DTM: ncs_patricia_tree_init failed for dtm_intranode_pid_list"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } pat_tree_params.key_size = sizeof(uint32_t); if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&dtm_intranode_cb->dtm_svc_install_list, &pat_tree_params)) { LOG_ER("DTM: ncs_patricia_tree_init failed for dtm_intranode_pid_list"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } dtm_intranode_add_self_node_to_node_db(dtm_intranode_cb->nodeid, node_ip, i_addr_family); if (m_NCS_IPC_CREATE(&dtm_intranode_cb->mbx) != NCSCC_RC_SUCCESS) { /* Mail box creation failed */ LOG_ER("DTM : Intranode Mailbox Creation failed"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } else { NCS_SEL_OBJ obj; /* Code added for attaching the mailbox, to eliminate the DBG Print at sysf_ipc.c: 640 */ if (NCSCC_RC_SUCCESS != m_NCS_IPC_ATTACH(&dtm_intranode_cb->mbx)) { m_NCS_IPC_RELEASE(&dtm_intranode_cb->mbx, NULL); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); LOG_ER("DTM: Intranode Mailbox Attach failed"); return NCSCC_RC_FAILURE; } obj = m_NCS_IPC_GET_SEL_OBJ(&dtm_intranode_cb->mbx); /* retreive the corresponding fd for mailbox and fill it in cb */ dtm_intranode_cb->mbx_fd = m_GET_FD_FROM_SEL_OBJ(obj); /* extract and fill value needs to be extracted */ } dtm_intranode_add_poll_fdlist(dtm_intranode_cb->server_sockfd, POLLIN); dtm_intranode_add_poll_fdlist(dtm_intranode_cb->mbx_fd, POLLIN); if (dtm_intranode_create_rcv_task(dtm_intranode_cb->task_hdl) != NCSCC_RC_SUCCESS) { LOG_ER("MDS:MDTM: Receive Task Creation Failed in MDTM_INIT\n"); close(dtm_intranode_cb->server_sockfd); free(dtm_intranode_cb); return NCSCC_RC_FAILURE; } TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
uint32_t mds_lib_req(NCS_LIB_REQ_INFO *req) { char *p_field = NULL; uint32_t node_id = 0, cluster_id, mds_tipc_ref = 0; /* this mds tipc ref is random num part of the TIPC id */ uint32_t status = NCSCC_RC_SUCCESS; NCS_SEL_OBJ destroy_ack_obj; char *ptr; switch (req->i_op) { case NCS_LIB_REQ_CREATE: mds_mutex_init_once(); osaf_mutex_lock_ordie(&gl_mds_library_mutex); if (gl_mds_mcm_cb != NULL) { syslog(LOG_ERR, "MDS_LIB_CREATE : MDS is already initialized"); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return NCSCC_RC_FAILURE; } /* Initialize mcm database */ mds_mcm_init(); /* Extract parameters from req and fill adest and pcon_id */ /* Get Node_id */ p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "NODE_ID="); if (p_field != NULL) { if (sscanf(p_field + strlen("NODE_ID="), "%d", &node_id) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in NODE_ID argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } /* Get Cluster_id */ p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "CLUSTER_ID="); if (p_field != NULL) { if (sscanf(p_field + strlen("CLUSTER_ID="), "%d", &cluster_id) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in CLUSTER_ID argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } /* Get tipc_mcast_enabled */ if ((ptr = getenv("MDS_TIPC_MCAST_ENABLED")) != NULL) { tipc_mcast_enabled = atoi(ptr); if (tipc_mcast_enabled != false) tipc_mcast_enabled = true; m_MDS_LOG_DBG("MDS_TIPC_MCAST_ENABLED: %d Set argument \n",tipc_mcast_enabled); } /* to use cluster id in mds prefix? */ /* Get gl_mds_log_level */ /* setting MDS_LOG_LEVEL from environment variable if given */ if ((ptr = getenv("MDS_LOG_LEVEL")) != NULL) { gl_mds_log_level = atoi(ptr); } else { p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "MDS_LOG_LEVEL="); if (p_field != NULL) { if (sscanf(p_field + strlen("MDS_LOG_LEVEL="), "%d", &gl_mds_log_level) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in MDS_LOG_LEVEL argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } } /* gl_mds_log_level consistency check */ if (gl_mds_log_level > 5 || gl_mds_log_level < 1) { /* gl_mds_log_level specified is outside range so reset to Default = 3 */ gl_mds_log_level = 3; } /* Get gl_mds_checksum */ /* setting MDS_CHECKSUM from environment variable if given */ if ((ptr = getenv("MDS_CHECKSUM")) != NULL) { gl_mds_checksum = atoi(ptr); } else { p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "MDS_CHECKSUM="); if (p_field != NULL) { if (sscanf(p_field + strlen("MDS_CHECKSUM="), "%d", &gl_mds_checksum) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in MDS_CHECKSUM argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } } /* gl_mds_checksum consistency check */ if (gl_mds_checksum != 1) { /* gl_mds_checksum specified is not 1 so reset to 0 */ gl_mds_checksum = 0; } /*****************************/ /* Timer value Configuration */ /*****************************/ /* Get Subscription timer value */ p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "SUBSCRIPTION_TMR_VAL="); if (p_field != NULL) { if (sscanf(p_field + strlen("SUBSCRIPTION_TMR_VAL="), "%d", &MDS_SUBSCRIPTION_TMR_VAL) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in SUBSCRIPTION_TMR_VAL argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } /* Get Await Active timer value */ p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "AWAIT_ACTIVE_TMR_VAL="); if (p_field != NULL) { if (sscanf(p_field + strlen("AWAIT_ACTIVE_TMR_VAL="), "%d", &MDS_AWAIT_ACTIVE_TMR_VAL) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in AWAIT_ACTIVE_TMR_VAL argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } /* Get Quiesced timer value */ p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "QUIESCED_TMR_VAL="); if (p_field != NULL) { if (sscanf(p_field + strlen("QUIESCED_TMR_VAL="), "%d", &MDS_QUIESCED_TMR_VAL) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in QUIESCED_TMR_VAL argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } /* Get Reassembly timer value */ p_field = NULL; p_field = (char *)ncs_util_search_argv_list(req->info.create.argc, req->info.create.argv, "REASSEMBLE_TMR_VAL="); if (p_field != NULL) { if (sscanf(p_field + strlen("REASSEMBLE_TMR_VAL="), "%d", &MDTM_REASSEMBLE_TMR_VAL) != 1) { syslog(LOG_ERR, "MDS_LIB_CREATE : Problem in REASSEMBLE_TMR_VAL argument\n"); mds_mcm_destroy(); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE); } } mds_init_transport(); /* Invoke MDTM-INIT. */ status = mds_mdtm_init(node_id, &mds_tipc_ref); if (status != NCSCC_RC_SUCCESS) { /* todo cleanup */ return NCSCC_RC_FAILURE; } gl_mds_mcm_cb->adest = m_MDS_GET_ADEST_FROM_NODE_ID_AND_PROCESS_ID(node_id, mds_tipc_ref); get_adest_details(gl_mds_mcm_cb->adest, gl_mds_mcm_cb->adest_details); /* Initialize logging */ { char buff[50], pref[50]; snprintf(buff, sizeof(buff), PKGLOGDIR "/mds.log"); memset(pref, 0 ,sizeof(pref)); mds_log_init(buff, pref); } osaf_mutex_unlock_ordie(&gl_mds_library_mutex); break; case NCS_LIB_REQ_DESTROY: /* STEP 1: Invoke MDTM-Destroy. */ /* mds_mdtm_destroy (); */ /* STEP 2: Destroy MCM-CB; */ /* ncs_patricia_tree_destroy(&gl_mds_mcm_cb->vdest_list); */ /* m_MMGR_FREE_MDS_CB(gl_mds_mcm_cb); */ m_NCS_SEL_OBJ_CREATE(&destroy_ack_obj); /* Post a dummy message to MDS thread to guarantee that it wakes up (and thereby sees the destroy_ind) */ if (mds_destroy_event(destroy_ack_obj) == NCSCC_RC_FAILURE) { m_NCS_SEL_OBJ_DESTROY(&destroy_ack_obj); return NCSCC_RC_FAILURE; } /* Wait for indication from MDS thread that it is ok to kill it */ osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(destroy_ack_obj), 70000); /* 70 seconds */ m_MDS_LOG_DBG("LIB_DESTROY:Destroy ack from MDS thread in 70 s"); /* Take the lock before killing the thread */ osaf_mutex_lock_ordie(&gl_mds_library_mutex); /* Now two things have happened (1) MDS thread has acked the destroy-event. So it will do no further things beyound MDS unlock (2) We have obtained MDS-Lock. So, even the un-lock by MDS thead is completed Now we can proceed with the systematic destruction of MDS internal Data */ /* Free the objects related to destroy-indication. The destroy mailbox event will be automatically freed by MDS processing or during MDS mailbox destruction. Since we will be destroying the MDS-thread, the following selection-object can no longer be accessed. Hence, it is safe and correct to destroy it now */ m_NCS_SEL_OBJ_DESTROY(&destroy_ack_obj); memset(&destroy_ack_obj, 0, sizeof(destroy_ack_obj)); /* Destroy info */ /* Sanity check */ if (gl_mds_mcm_cb == NULL) { syslog(LOG_ERR, "MDS_LIB_DESTROY : MDS is already Destroyed"); osaf_mutex_unlock_ordie(&gl_mds_library_mutex); return NCSCC_RC_FAILURE; } status = mds_mdtm_destroy(); if (status != NCSCC_RC_SUCCESS) { /* todo anything? */ } status = mds_mcm_destroy(); if (status != NCSCC_RC_SUCCESS) { /* todo anything? */ } /* Just Unlock the lock, Lock is never destroyed */ osaf_mutex_unlock_ordie(&gl_mds_library_mutex); break; default: break; } return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : glnd_main_process * * Description : This is the function which is given as a input to the * GLND task. * * Arguments : mbx - This is the mail box pointer on which GLND is * going to block. * * Return Values : None. * * Notes : None. *****************************************************************************/ void glnd_main_process(SYSF_MBX *mbx) { NCS_SEL_OBJ mbx_fd = m_NCS_IPC_GET_SEL_OBJ(mbx); GLND_CB *glnd_cb = NULL; TRACE_ENTER(); SaAmfHandleT amf_hdl; SaSelectionObjectT amf_sel_obj; SaAisErrorT amf_error; struct pollfd sel[NUM_FD]; int term_fd; /* take the handle */ glnd_cb = (GLND_CB *)m_GLND_TAKE_GLND_CB; if (!glnd_cb) { LOG_ER("GLND cb take handle failed"); goto end; } amf_hdl = glnd_cb->amf_hdl; /*giveup the handle */ m_GLND_GIVEUP_GLND_CB; amf_error = saAmfSelectionObjectGet(amf_hdl, &amf_sel_obj); if (amf_error != SA_AIS_OK) { LOG_ER("GLND amf get sel obj error"); goto end; } daemon_sigterm_install(&term_fd); sel[FD_TERM].fd = term_fd; sel[FD_TERM].events = POLLIN; sel[FD_AMF].fd = amf_sel_obj; sel[FD_AMF].events = POLLIN; sel[FD_MBX].fd = m_GET_FD_FROM_SEL_OBJ(mbx_fd); sel[FD_MBX].events = POLLIN; while (osaf_poll(&sel[0], NUM_FD, -1) > 0) { if (sel[FD_TERM].revents & POLLIN) { daemon_exit(); } if (((sel[FD_AMF].revents | sel[FD_MBX].revents) & (POLLERR | POLLHUP | POLLNVAL)) != 0) { LOG_ER("GLND poll() failure: %hd %hd", sel[FD_AMF].revents, sel[FD_MBX].revents); TRACE_LEAVE(); return; } /* process all the AMF messages */ if (sel[FD_AMF].revents & POLLIN) { /* dispatch all the AMF pending function */ amf_error = saAmfDispatch(amf_hdl, SA_DISPATCH_ALL); if (amf_error != SA_AIS_OK) { TRACE_2("GLND amf dispatch failure"); } } /* process the GLND Mail box */ if (sel[FD_MBX].revents & POLLIN) { glnd_cb = (GLND_CB *)m_GLND_TAKE_GLND_CB; if (glnd_cb) { /* now got the IPC mail box event */ glnd_process_mbx(glnd_cb, mbx); m_GLND_GIVEUP_GLND_CB; /* giveup the handle */ } else break; } } TRACE("DANGER: Exiting the Select loop of GLND"); end: TRACE_LEAVE(); return; }