bool sysfTmrCreate(void) { NCS_PATRICIA_PARAMS pat_param; uint32_t rc = NCSCC_RC_SUCCESS; if (ncs_tmr_create_done == false) ncs_tmr_create_done = true; else return true; /* Empty Timer Service control block. */ memset(&gl_tcb, '\0', sizeof(SYSF_TMR_CB)); /* put local persistent guard in start state */ ncslpg_create(&gl_tcb.persist); /* Initialize the locks */ m_NCS_LOCK_INIT(&gl_tcb.safe.enter_lock); m_NCS_LOCK_INIT(&gl_tcb.safe.free_lock); memset((void *)&pat_param, 0, sizeof(NCS_PATRICIA_PARAMS)); pat_param.key_size = sizeof(uint64_t); rc = ncs_patricia_tree_init(&gl_tcb.tmr_pat_tree, &pat_param); if (rc != NCSCC_RC_SUCCESS) { return NCSCC_RC_FAILURE; } rc = m_NCS_SEL_OBJ_CREATE(&gl_tcb.sel_obj); if (rc != NCSCC_RC_SUCCESS) { ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); return NCSCC_RC_FAILURE; } tmr_destroying = false; /* create expiry thread */ int policy = SCHED_RR; /*root defaults */ int max_prio = sched_get_priority_max(policy); int min_prio = sched_get_priority_min(policy); int prio_val = ((max_prio - min_prio) * 0.87); if (m_NCS_TASK_CREATE((NCS_OS_CB)ncs_tmr_wait, 0, (char *)"OSAF_TMR", prio_val, policy, NCS_TMR_STACKSIZE, &gl_tcb.p_tsk_hdl) != NCSCC_RC_SUCCESS) { ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); m_NCS_SEL_OBJ_DESTROY(&gl_tcb.sel_obj); return false; } if (m_NCS_TASK_START(gl_tcb.p_tsk_hdl) != NCSCC_RC_SUCCESS) { m_NCS_TASK_RELEASE(gl_tcb.p_tsk_hdl); ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); m_NCS_SEL_OBJ_DESTROY(&gl_tcb.sel_obj); return false; } return true; }
NCS_BOOL sysfTmrCreate(void) { NCS_PATRICIA_PARAMS pat_param; uns32 rc = NCSCC_RC_SUCCESS; if (ncs_tmr_create_done == FALSE) ncs_tmr_create_done = TRUE; else return TRUE; /* Empty Timer Service control block. */ memset(&gl_tcb, '\0', sizeof(SYSF_TMR_CB)); /* put local persistent guard in start state */ ncslpg_create(&gl_tcb.persist); /* Initialize the locks */ m_NCS_LOCK_INIT(&gl_tcb.safe.enter_lock); m_NCS_LOCK_INIT(&gl_tcb.safe.free_lock); memset((void *)&pat_param, 0, sizeof(NCS_PATRICIA_PARAMS)); pat_param.key_size = sizeof(uns64); rc = ncs_patricia_tree_init(&gl_tcb.tmr_pat_tree, &pat_param); if (rc != NCSCC_RC_SUCCESS) { return NCSCC_RC_FAILURE; } rc = m_NCS_SEL_OBJ_CREATE(&gl_tcb.sel_obj); if (rc != NCSCC_RC_SUCCESS) { ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); return NCSCC_RC_FAILURE; } tmr_destroying = FALSE; /* create expiry thread */ if (m_NCS_TASK_CREATE((NCS_OS_CB)ncs_tmr_wait, 0, NCS_TMR_TASKNAME, NCS_TMR_PRIORITY, NCS_TMR_STACKSIZE, &gl_tcb.p_tsk_hdl) != NCSCC_RC_SUCCESS) { ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); m_NCS_SEL_OBJ_DESTROY(gl_tcb.sel_obj); return FALSE; } if (m_NCS_TASK_START(gl_tcb.p_tsk_hdl) != NCSCC_RC_SUCCESS) { m_NCS_TASK_RELEASE(gl_tcb.p_tsk_hdl); ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); m_NCS_SEL_OBJ_DESTROY(gl_tcb.sel_obj); return FALSE; } return TRUE; }
/***********************************************************************//** * @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 : 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; }
/******************************************************************** 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) { NCS_SEL_OBJ_SET set; uns32 timeout = 3000; m_NCS_LOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE); if (cb->is_mqnd_up) { m_LOG_MQSV_A(MQA_MQND_ALREADY_UP, NCSFL_LC_MQSV_INIT, NCSFL_SEV_INFO, 1, __FILE__, __LINE__); 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 */ m_NCS_SEL_OBJ_ZERO(&set); m_NCS_SEL_OBJ_SET(cb->mqnd_sync_sel, &set); m_NCS_SEL_OBJ_SELECT(cb->mqnd_sync_sel, &set, 0, 0, &timeout); /* 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); m_LOG_MQSV_A(MQA_SYNC_WITH_MQND_UP, NCSFL_LC_MQSV_INIT, NCSFL_SEV_INFO, 1, __FILE__, __LINE__); return; }
/** * * * @return unsigned int */ static unsigned int ntfa_create(void) { unsigned int timeout = 3000; NCS_SEL_OBJ_SET set; unsigned int rc = NCSCC_RC_SUCCESS; /* create and init sel obj for mds sync */ m_NCS_SEL_OBJ_CREATE(&ntfa_cb.ntfs_sync_sel); m_NCS_SEL_OBJ_ZERO(&set); m_NCS_SEL_OBJ_SET(ntfa_cb.ntfs_sync_sel, &set); pthread_mutex_lock(&ntfa_cb.cb_lock); ntfa_cb.ntfs_sync_awaited = 1; pthread_mutex_unlock(&ntfa_cb.cb_lock); /* register with MDS */ if ((NCSCC_RC_SUCCESS != (rc = ntfa_mds_init(&ntfa_cb)))) { rc = NCSCC_RC_FAILURE; goto error; } /* Block and wait for indication from MDS meaning NTFS is up */ m_NCS_SEL_OBJ_SELECT(ntfa_cb.ntfs_sync_sel, &set, 0, 0, &timeout); pthread_mutex_lock(&ntfa_cb.cb_lock); ntfa_cb.ntfs_sync_awaited = 0; pthread_mutex_unlock(&ntfa_cb.cb_lock); /* No longer needed */ m_NCS_SEL_OBJ_DESTROY(ntfa_cb.ntfs_sync_sel); /* TODO: fix env variable */ ntfa_cb.ntf_var_data_limit = NTFA_VARIABLE_DATA_LIMIT; return rc; error: /* delete the ntfa init instances */ ntfa_hdl_list_del(&ntfa_cb.client_list); return rc; }
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; }
/**************************************************************************** Name : ava_create Description : This routine creates & initializes the AvA control block. Arguments : create_info - ptr to the create info Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None ******************************************************************************/ uns32 ava_create(NCS_LIB_CREATE *create_info) { AVA_CB *cb = 0; NCS_SEL_OBJ_SET set; uns32 rc = NCSCC_RC_SUCCESS, timeout = 300; EDU_ERR err; TRACE_ENTER(); /* allocate AvA cb */ if (!(cb = calloc(1, sizeof(AVA_CB)))) { LOG_ER("AVA Create: Calloc failed"); rc = NCSCC_RC_FAILURE; goto error; } /* fetch the comp name from the env variable */ if (getenv("SA_AMF_COMPONENT_NAME")) { if (strlen(getenv("SA_AMF_COMPONENT_NAME")) < SA_MAX_NAME_LENGTH) { strcpy((char *)cb->comp_name.value, getenv("SA_AMF_COMPONENT_NAME")); cb->comp_name.length = (uns16)strlen((char *)cb->comp_name.value); m_AVA_FLAG_SET(cb, AVA_FLAG_COMP_NAME); TRACE("Component name = %s",cb->comp_name.value); } else { TRACE_2("Length of SA_AMF_COMPONENT_NAME exceeds SA_MAX_NAME_LENGTH bytes"); rc = NCSCC_RC_FAILURE; goto error; } } /* assign the AvA pool-id (used by hdl-mngr) */ cb->pool_id = NCS_HM_POOL_ID_COMMON; /* create the association with hdl-mngr */ if (!(cb->cb_hdl = ncshm_create_hdl(cb->pool_id, NCS_SERVICE_ID_AVA, (NCSCONTEXT)cb))) { LOG_ER("Unable to create handle for control block"); rc = NCSCC_RC_FAILURE; goto error; } TRACE("Created handle for the control block"); /* initialize the AvA cb lock */ m_NCS_LOCK_INIT(&cb->lock); TRACE("Initialized the AVA control block lock"); /* EDU initialisation */ m_NCS_EDU_HDL_INIT(&cb->edu_hdl); TRACE("EDU Initialization success"); rc = m_NCS_EDU_COMPILE_EDP(&cb->edu_hdl, avsv_edp_nda_msg, &err); if (rc != NCSCC_RC_SUCCESS) { TRACE_4("EDU Compilation failed"); goto error; } /* create the sel obj (for mds sync) */ m_NCS_SEL_OBJ_CREATE(&cb->sel_obj); /* initialize the hdl db */ if (NCSCC_RC_SUCCESS != ava_hdl_init(&cb->hdl_db)) { TRACE_4("AVA Handles DB initialization failed"); rc = NCSCC_RC_FAILURE; goto error; } TRACE("AVA Handles DB created successfully"); m_NCS_SEL_OBJ_ZERO(&set); m_NCS_SEL_OBJ_SET(cb->sel_obj, &set); m_AVA_FLAG_SET(cb, AVA_FLAG_FD_VALID); /* register with MDS */ if ((NCSCC_RC_SUCCESS != ava_mds_reg(cb))) { LOG_ER("AVA MDS Registration failed"); rc = NCSCC_RC_FAILURE; goto error; } TRACE("AVA MDS Registration success"); TRACE_1("Waiting on select till AMF Node Director is up"); /* block until mds detects avnd */ m_NCS_SEL_OBJ_SELECT(cb->sel_obj, &set, 0, 0, &timeout); /* reset the fd validity flag */ m_NCS_LOCK(&cb->lock, NCS_LOCK_WRITE); m_AVA_FLAG_RESET(cb, AVA_FLAG_FD_VALID); m_NCS_UNLOCK(&cb->lock, NCS_LOCK_WRITE); /* This sel obj is no more used */ m_NCS_SEL_OBJ_DESTROY(cb->sel_obj); /* everything went off well.. store the cb hdl in the global variable */ gl_ava_hdl = cb->cb_hdl; TRACE_LEAVE(); return rc; error: if (cb) { /* remove the association with hdl-mngr */ if (cb->cb_hdl) ncshm_destroy_hdl(NCS_SERVICE_ID_AVA, cb->cb_hdl); /* delete the hdl db */ ava_hdl_del(cb); /* Flush the edu hdl */ m_NCS_EDU_HDL_FLUSH(&cb->edu_hdl); /* destroy the lock */ m_NCS_LOCK_DESTROY(&cb->lock); /* free the control block */ free(cb); } TRACE_LEAVE(); return rc; }
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; }