/**************************************************************************** Name : mqa_queue_tree_delete_node Description : This routine adds the deletes the queue from the queue tree Arguments : queue_info - pointer to the queue node. Return Values : NCSCC_RC_FAILURE/NCSCC_RC_SUCCESS Notes : None ******************************************************************************/ uns32 mqa_queue_tree_delete_node(MQA_CB *mqa_cb, SaMsgQueueHandleT hdl_id) { MQA_QUEUE_INFO *queue_info = NULL; uns32 rc = NCSCC_RC_SUCCESS; queue_info = (MQA_QUEUE_INFO *)ncs_patricia_tree_get(&mqa_cb->mqa_queue_tree, (uns8 *)&hdl_id); if (!queue_info) { return NCSCC_RC_FAILURE; } /* delete from the tree */ if ((rc = ncs_patricia_tree_del(&mqa_cb->mqa_queue_tree, &queue_info->patnode)) != NCSCC_RC_SUCCESS) m_LOG_MQSV_A(MQA_QUEUE_TREE_DEL_FAILED, NCSFL_LC_MQSV_INIT, NCSFL_SEV_ERROR, rc, __FILE__, __LINE__); if (queue_info->task_handle != 0) { /* m_NCS_TASK_STOP(queue_info->task_handle); m_NCS_TASK_RELEASE(queue_info->task_handle); */ } /* free the mem */ m_MMGR_FREE_MQA_QUEUE_INFO(queue_info); return NCSCC_RC_SUCCESS; }
/**************************************************************************** Name : avnd_pgdb_rec_del Description : This routine deletes a PG record from the PG database. Arguments : cb - ptr to the AvND control block csi_name - ptr to the csi-name Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None. ******************************************************************************/ uns32 avnd_pgdb_rec_del(AVND_CB *cb, SaNameT *csi_name) { AVND_PG *pg = 0; uns32 rc = NCSCC_RC_SUCCESS; /* get the pg record */ pg = m_AVND_PGDB_REC_GET(cb->pgdb, *csi_name); if (!pg) { rc = AVND_ERR_NO_PG; goto err; } /* delete the mem-list */ avnd_pgdb_mem_rec_del_all(cb, pg); /* delete the track-list */ avnd_pgdb_trk_rec_del_all(cb, pg); /* remove from the patricia tree */ rc = ncs_patricia_tree_del(&cb->pgdb, &pg->tree_node); if (NCSCC_RC_SUCCESS != rc) { rc = AVND_ERR_TREE; goto err; } TRACE("PG DB record deleted: CSI = %s",csi_name->value); /* free the memory */ free(pg); return rc; err: LOG_CR("PG DB record deletion failed: CSI = %s",csi_name->value); return rc; }
/**************************************************************************** Name : mqa_track_tree_find_and_del Description : This routine deletes a new group track element to the client tree. Arguments : client_info : pointer to the mqa client. group : the group name to delete from track list. Return Values : returns status of deletion, TRUE if deleted, FALSE otherwise Notes : The caller takes the cb lock before calling this function ******************************************************************************/ NCS_BOOL mqa_track_tree_find_and_del(MQA_CLIENT_INFO *client_info, SaNameT *group) { MQA_TRACK_INFO *track_info = NULL; uns32 rc = NCSCC_RC_SUCCESS; track_info = (MQA_TRACK_INFO *)ncs_patricia_tree_get(&client_info->mqa_track_tree, (uns8 *)group->value); if (!track_info) return FALSE; if ((rc = ncs_patricia_tree_del(&client_info->mqa_track_tree, &track_info->patnode)) != NCSCC_RC_SUCCESS) { m_LOG_MQSV_A(MQA_TRACK_TREE_DEL_FAILED, NCSFL_LC_MQSV_INIT, NCSFL_SEV_ERROR, rc, __FILE__, __LINE__); if (track_info->notificationBuffer.notification) m_MMGR_FREE_MQA_TRACK_BUFFER_INFO(track_info->notificationBuffer.notification); m_MMGR_FREE_MQA_TRACK_INFO(track_info); return FALSE; } if (track_info->notificationBuffer.notification) m_MMGR_FREE_MQA_TRACK_BUFFER_INFO(track_info->notificationBuffer.notification); m_MMGR_FREE_MQA_TRACK_INFO(track_info); return TRUE; }
/**************************************************************************** * Name : dts_set_dta_up_down * * Description : Function marks DTA as up or down on receiving the up down * event from the DTA. * * Arguments : node_id - Node ID of the node where DTA resides. * adest - DTA destination address. * up_down - Flag indicating whether DTA is up or down. * * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. * * Notes : None. *****************************************************************************/ void dts_set_dta_up_down(NODE_ID node_id, MDS_DEST adest, NCS_BOOL up_down) { DTS_CB *inst = &dts_cb; SVC_KEY key, nt_key; DTS_SVC_REG_TBL *svc; DTA_DEST_LIST *dta, *dta_ptr; SVC_ENTRY *svc_entry; /*MDS_DEST dta_key; */ OP_DEVICE *dev; /* Network order key added */ nt_key.node = m_NCS_OS_HTONL(node_id); nt_key.ss_svc_id = 0; /* Check if node with node_id already exists. If it doesn't, return */ if ((svc = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&inst->svc_tbl, (const uns8 *)&nt_key)) == NULL) { m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_set_dta_up_down: No svc node exists in patricia tree"); return; } if ((dta = (DTA_DEST_LIST *)ncs_patricia_tree_get(&inst->dta_list, (const uns8 *)&adest)) != NULL) { /* Adjust the pointer to DTA with the offset */ dta = (DTA_DEST_LIST *)((long)dta - DTA_DEST_LIST_OFFSET); dta->dta_up = up_down; if (up_down == FALSE) { m_LOG_DTS_EVT(DTS_EV_DTA_DOWN, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta->dta_addr), (uns32)(dta->dta_addr)); /* go through the svc_list of DTA removing DTA frm all those svcs */ svc_entry = dta->svc_list; while (svc_entry != NULL) { svc = svc_entry->svc; if (svc == NULL) { svc_entry = svc_entry->next_in_dta_entry; continue; } key = svc->my_key; if ((dta_ptr = (DTA_DEST_LIST *)dts_find_dta(svc, &dta->dta_addr)) != NULL) { /* Remove dta entry frm svc->v_cd_list */ if ((dta_ptr = (DTA_DEST_LIST *)dts_dequeue_dta(svc, dta_ptr)) == NULL) { m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_set_dta_up_down: Unable to remove dta entry frm svc->v_cd_list"); break; } m_LOG_DTS_EVT(DTS_EV_SVC_DTA_RMV, svc->my_key.ss_svc_id, svc->my_key.node, (uns32)(dta_ptr->dta_addr)); /* Versioning support - Remove spec entry corresponding to the * DTA from svc's spec_list. * Note: Even when spec's use_count becomes 0 don't call unload * of library here. Unload will be called only in case of * service unregister. */ if (dts_del_spec_frm_svc(svc, adest, NULL) != NCSCC_RC_SUCCESS) m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_set_dta_up_down: Unable to remove spec entry"); /* Point to the next svc in DTA svc_list */ svc_entry = svc_entry->next_in_dta_entry; /*Remove svc entry frm dta->svc_list */ if ((svc = (DTS_SVC_REG_TBL *)dts_del_svc_frm_dta(dta_ptr, svc)) == NULL) { m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_set_dta_up_down: Unable to remove svc from dta->svc_list"); break; } m_LOG_DTS_EVT(DTS_EV_DTA_SVC_RMV, svc->my_key.ss_svc_id, svc->my_key.node, (uns32)(dta_ptr->dta_addr)); if (svc->dta_count == 0) { dts_circular_buffer_free(&svc->device.cir_buffer); dev = &svc->device; /* Cleanup the DTS_FILE_LIST datastructure for svc */ m_DTS_FREE_FILE_LIST(dev); if ((TRUE == svc->device.file_open) && (svc->device.svc_fh != NULL)) { fclose(svc->device.svc_fh); svc->device.svc_fh = NULL; svc->device.file_open = FALSE; svc->device.new_file = TRUE; svc->device.cur_file_size = 0; } /* Cleanup the console devices associated with the node */ m_DTS_RMV_ALL_CONS(dev); ncs_patricia_tree_del(&inst->svc_tbl, (NCS_PATRICIA_NODE *)svc); m_LOG_DTS_EVT(DTS_EV_SVC_DEREG_SUCCESSFUL, key.ss_svc_id, key.node, (uns32)(dta_ptr->dta_addr)); if (NULL != svc) m_MMGR_FREE_SVC_REG_TBL(svc); } } /*end of if */ else { m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_set_dta_up_down: dta entry missing in svc->v_cd_list"); /* hop to the next service */ svc_entry = svc_entry->next_in_dta_entry; } } /* end of while */ /*At the end of while loop svc_list shud point to NULL */ dta->svc_list = NULL; if (ncs_patricia_tree_del(&inst->dta_list, (NCS_PATRICIA_NODE *)&dta->node) != NCSCC_RC_SUCCESS) { m_LOG_DTS_EVT(DTS_EV_DTA_DEST_RMV_FAIL, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta->dta_addr), (uns32)(dta->dta_addr)); m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_set_dta_up_down: Unable to remove DTA entry frm patricia tree"); return; } m_LOG_DTS_EVT(DTS_EV_DTA_DEST_RMV_SUCC, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta->dta_addr), (uns32)(dta->dta_addr)); /* Send Async update (REMOVE) for DTA_DEST_LIST */ m_DTSV_SEND_CKPT_UPDT_ASYNC(inst, NCS_MBCSV_ACT_RMV, (MBCSV_REO_HDL)(long)dta, DTSV_CKPT_DTA_DEST_LIST_CONFIG); if (NULL != dta) m_MMGR_FREE_VCARD_TBL(dta); } /* end of up_down == FALSE */ else if ((TRUE == up_down) && (TRUE == dta->updt_req)) { /* send filter config msg for all svcs for this dta */ m_LOG_DTS_EVT(DTS_EV_DTA_UP, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta->dta_addr), (uns32)(dta->dta_addr)); svc_entry = dta->svc_list; while (svc_entry != NULL) { dts_send_filter_config_msg(inst, svc_entry->svc, dta); dta->updt_req = FALSE; svc_entry = svc_entry->next_in_dta_entry; } } } /* end of if dta = ncs_patricia_tree_get() */ else { /*Nothing to do */ } }
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: sysfTmrExpiry * * Purpose: Service all timers that live in this expiry bucket * ****************************************************************************/ static bool sysfTmrExpiry(SYSF_TMR_PAT_NODE *tmp) { SYSF_TMR *now_tmr; SYSF_TMR dead_inst; SYSF_TMR *dead_tmr = &dead_inst; SYSF_TMR *start_dead = &dead_inst; /* get these guys one behind to start as well */ dead_tmr->next = NULL; /* Confirm and secure tmr service is/will persist */ if (ncslpg_take(&gl_tcb.persist) == false) return false; /* going or gone away.. Lets leave */ if (tmr_destroying == true) { /* Raise An indication */ m_NCS_SEL_OBJ_IND(&tmr_destroy_syn_obj); /*If thread canceled here, It had no effect on timer thread destroy */ ncslpg_give(&gl_tcb.persist, 0); /* returns true if thread is going to be destroyed otherwise return false(normal flow) */ return true; } TMR_DBG_TICK(gl_tcb); dead_tmr->next = tmp->tmr_list_start; TMR_SET_CNT(gl_tcb.stats); while (dead_tmr->next != NULL) { /* process old and new */ now_tmr = dead_tmr->next; TMR_INC_CNT(gl_tcb.stats); /* SMM states CREATE, EXPIRED, illegal assert */ if ((TMR_TEST_STATE(now_tmr, TMR_STATE_DORMANT)) || (TMR_TEST_STATE(now_tmr, TMR_STATE_DESTROY))) { TMR_STAT_CANCELLED(gl_tcb.stats); TMR_STAT_ADD_FREE(gl_tcb.stats); TMR_STAT_FREE_HWM(gl_tcb.stats); TMR_DBG_STAMP(now_tmr, gl_tcb.tick); dead_tmr = now_tmr; /* move on to next one */ } else { TMR_SET_STATE(now_tmr, TMR_STATE_DORMANT); /* mark it dormant */ TMR_STAT_EXPIRY(gl_tcb.stats); TMR_STAT_ADD_FREE(gl_tcb.stats); TMR_STAT_FREE_HWM(gl_tcb.stats); TMR_DBG_STAMP(now_tmr, gl_tcb.tick); /* EXPIRY HAPPENS RIGHT HERE !!.................................. */ if (now_tmr->tmrCB != ((TMR_CALLBACK)0x0ffffff)) { #if ENABLE_SYSLOG_TMR_STATS gl_tcb.stats.cnt--; if (gl_tcb.stats.cnt == 0) { syslog(LOG_INFO, "NO Timers Active in Expiry PID %u \n", getpid()); } #endif now_tmr->tmrCB(now_tmr->tmrUarg); /* OK this is it! Expire ! */ } dead_tmr = now_tmr; /* move on to next one */ } } TMR_STAT_RING_HWM(gl_tcb.stats); /* Now replenish the free pool */ if (start_dead->next != NULL) { m_NCS_LOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); /* critical region START */ dead_tmr->next = gl_tcb.safe.dmy_free.next; /* append old free list to end of that */ gl_tcb.safe.dmy_free.next = start_dead->next; /* put start of collected dead in front */ m_NCS_UNLOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); /* critical region END */ } 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); ncslpg_give(&gl_tcb.persist, 0); return false; }
/****************************************************************************\ PROCEDURE NAME : mqd_red_db_node_del DESCRIPTION : This routines deletes the Object node from the Tree, and free's all the resources. ARGUMENTS : pMqd - MQD Controll block pointer pNode - Object Node RETURNS : none \****************************************************************************/ void mqd_red_db_node_del(MQD_CB *pMqd, MQD_ND_DB_NODE *pNode) { /* Remove the object node from the tree */ ncs_patricia_tree_del(&pMqd->node_db, (NCS_PATRICIA_NODE *)&pNode->node); m_MMGR_FREE_MQD_ND_DB_NODE(pNode); } /* End of mqd_db_node_del() */
uns32 dta_dereg_svc(SS_SVC_ID svc_id) { DTA_CB *inst = &dta_cb; REG_TBL_ENTRY *rmv_svc; DTSV_MSG *msg; uns32 send_pri; if (inst->created == FALSE) { return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_dereg_svc: DTA does not exist. First create DTA before de-registering your service.", svc_id); } m_DTA_LK(&inst->lock); /* If DTS is deregistering from DTS means that DTS is going down, * So don't send any registration message to DTS */ if (NCS_SERVICE_ID_DTSV == svc_id) { if ((rmv_svc = (REG_TBL_ENTRY *)ncs_patricia_tree_get(&inst->reg_tbl, (const uns8 *)&svc_id)) == NULL) { m_DTA_UNLK(&inst->lock); return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_dereg_svc: Specified service registration entry doesn't exist in patricia tree", svc_id); } /* Remove entry from the Patricia tree */ ncs_patricia_tree_del(&inst->reg_tbl, (NCS_PATRICIA_NODE *)rmv_svc); m_MMGR_FREE_DTA_REG_TBL(rmv_svc); m_DTA_UNLK(&inst->lock); return NCSCC_RC_SUCCESS; } if ((rmv_svc = (REG_TBL_ENTRY *)ncs_patricia_tree_get(&inst->reg_tbl, (const uns8 *)&svc_id)) == NULL) { m_DTA_UNLK(&inst->lock); return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_dereg_svc: Specified service registration entry doesn't exist in patricia tree", svc_id); } /* Remove entry from the Patricia tree */ ncs_patricia_tree_del(&inst->reg_tbl, (NCS_PATRICIA_NODE *)rmv_svc); if (inst->dts_exist == FALSE) { if (0 != rmv_svc) m_MMGR_FREE_DTA_REG_TBL(rmv_svc); m_DTA_UNLK(&inst->lock); return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_dereg_svc: DTS does not exist, de-registration request is not sent to DTS.", svc_id); } msg = m_MMGR_ALLOC_DTSV_MSG; if (msg == NULL) { if (0 != rmv_svc) m_MMGR_FREE_DTA_REG_TBL(rmv_svc); m_DTA_UNLK(&inst->lock); return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_dereg_svc: Mem allocation failed, de-registration request is not sent to DTS.", svc_id); } memset(msg, '\0', sizeof(DTSV_MSG)); dta_fill_reg_msg(msg, svc_id, rmv_svc->version, rmv_svc->svc_name, DTA_UNREGISTER_SVC); if (0 != rmv_svc) m_MMGR_FREE_DTA_REG_TBL(rmv_svc); m_DTA_UNLK(&inst->lock); /* Smik - Don't send msg to MDS but to DTA msgbox */ send_pri = NCS_IPC_PRIORITY_LOW; if (m_DTA_SND_MSG(&gl_dta_mbx, msg, send_pri) != NCSCC_RC_SUCCESS) { m_MMGR_FREE_DTSV_MSG(msg); /*if (dta_mds_async_send(&msg, inst) != NCSCC_RC_SUCCESS) */ return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_dereg_svc: send to DTA msgbox failed", svc_id); } return NCSCC_RC_SUCCESS; }
/***************************************************************************** * * PROCEDURE NAME: dta_svc_destroy * * DESCRIPTION: Destroy an instance of DTA. Withdraw from MDS and free * this DTA_CB and tend to other resource recovery issues. * * Arguments : destroy : Information require for destroy. * * RETURNS: SUCCESS - all went well. * FAILURE - something went wrong. Turn on m_DTA_DBG_SINK() * for details. * *****************************************************************************/ uns32 dta_svc_destroy(NCSDTA_DESTROY *destroy) { DTA_CB *inst = &dta_cb; uns32 retval = NCSCC_RC_SUCCESS; REG_TBL_ENTRY *svc; if (inst->created == FALSE) return m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "dta_svc_destroy: DTA does not exist. First create DTA."); m_DTA_LK(&inst->lock); /* Clear the local datastructures */ while ((svc = (REG_TBL_ENTRY *)ncs_patricia_tree_getnext(&inst->reg_tbl, NULL)) != NULL) { ncs_patricia_tree_del(&inst->reg_tbl, (NCS_PATRICIA_NODE *)svc); m_MMGR_FREE_DTA_REG_TBL(svc); } /*Destroy the patricia tree created */ ncs_patricia_tree_destroy(&inst->reg_tbl); /* Clear the logs buffered in DTA */ { DTA_LOG_BUFFER *list = &dta_cb.log_buffer; DTA_BUFFERED_LOG *buf; uns32 i, count; DTSV_MSG *msg; if ((list == NULL) || (list->num_of_logs == 0)) { /* Don't print anythig, service users don't like DBG SINKs */ } else { count = list->num_of_logs; for (i = 0; i < count; i++) { if (!list->head) { list->tail = NULL; break; } buf = list->head; list->head = list->head->next; msg = buf->buf_msg; if (msg->data.data.msg.log_msg.uba.start != NULL) m_MMGR_FREE_BUFR_LIST(msg->data.data.msg.log_msg.uba.start); m_MMGR_FREE_OCT(msg->data.data.msg.log_msg.hdr.fmat_type); if (0 != msg) m_MMGR_FREE_DTSV_MSG(msg); m_MMGR_FREE_DTA_BUFFERED_LOG(buf); list->num_of_logs--; } /*end of for */ } /*end of else */ } m_DTA_UNLK(&inst->lock); /* Uninstall DTA from MDS */ if (dta_mds_uninstall() != NCSCC_RC_SUCCESS) { retval = m_DTA_DBG_SINK(NCSCC_RC_FAILURE, "dta_svc_destroy: MDS uninstall failed."); } inst->created = FALSE; m_DTA_LK_DLT(&inst->lock); return retval; }
/****************************************************************************\ * Function: dtsv_ckpt_add_rmv_updt_dta_dest * * Purpose: Add new DTA entry if action is ADD, remove node from the tree if * action is to remove and update data if request is to update. * * Input: cb - CB pointer. * avnd - Decoded structur. * action - ADD/RMV/UPDT * key - SVC_KEY of the service associated with DTA being added/updated * * Returns: NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. * * NOTES: ADD will add to the Patricia tree. ADD also modifies svc_reg patricia * tree by adding to svc_reg's v_cd_list. * UPDT is not used. * RMV will remove dta frm patricia tree and modify svc_reg patricia tree * only on DTA going down. * Service de-regs are handled by svc_reg async updates. * * As per this IR param key is not passed in network order \**************************************************************************/ uns32 dtsv_ckpt_add_rmv_updt_dta_dest(DTS_CB *cb, DTA_DEST_LIST *dtadest, NCS_MBCSV_ACT_TYPE action, SVC_KEY key) { uns32 status = NCSCC_RC_SUCCESS; DTA_DEST_LIST *to_reg = NULL, *del_reg = NULL; DTS_SVC_REG_TBL *svc = NULL; OP_DEVICE *device = NULL; MDS_DEST dta_key; SVC_ENTRY *svc_entry = NULL; SVC_KEY svc_key = {0, 0}, nt_key = {0, 0}; if (dtadest == NULL) { return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: DTA_DEST_LIST ptr is NULL"); } dta_key = dtadest->dta_addr; switch (action) { case NCS_MBCSV_ACT_ADD: { SYSF_ASCII_SPECS *spec_entry = NULL; ASCII_SPEC_INDEX spec_key; SPEC_ENTRY *per_dta_svc_spec = NULL; ASCII_SPEC_LIB *lib_hdl = NULL; /* Network order key added */ nt_key.node = m_NCS_OS_HTONL(key.node); nt_key.ss_svc_id = m_NCS_OS_HTONL(key.ss_svc_id); m_DTS_LK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_LOCKED, &cb->lock); /* Find svc entry in svc_tbl patricia tree */ if ((svc = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_REG_NOTFOUND, key.ss_svc_id, key.node, (uns32)dta_key); /*Service should have already been added to patricia tree */ return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: No service entry in Patricia Tree"); /*For cold-sync also, svc_reg cold sync has to happen prior to this */ } /* Check if dta is already present in dta_dest patricia tree */ if ((to_reg = (DTA_DEST_LIST *)ncs_patricia_tree_get(&cb->dta_list, (const uns8 *)&dta_key)) == NULL) { to_reg = m_MMGR_ALLOC_VCARD_TBL; if (to_reg == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Memory allocation failed"); } memset(to_reg, '\0', sizeof(DTA_DEST_LIST)); /* Update the fields of DTA_DEST_LIST */ to_reg->dta_addr = dtadest->dta_addr; to_reg->dta_up = dtadest->dta_up; to_reg->updt_req = dtadest->updt_req; to_reg->dta_num_svcs = 0; /*ncs_create_queue(&to_reg->svc_list); */ to_reg->node.key_info = (uns8 *)&to_reg->dta_addr; to_reg->svc_list = NULL; if (ncs_patricia_tree_add(&cb->dta_list, (NCS_PATRICIA_NODE *)&to_reg->node) != NCSCC_RC_SUCCESS) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_DTA_DEST_ADD_FAIL, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta_key), (uns32)dta_key); if (NULL != to_reg) m_MMGR_FREE_VCARD_TBL(to_reg); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Failed to add DTA list in Patricia tree"); } m_LOG_DTS_EVT(DTS_EV_DTA_DEST_ADD_SUCC, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta_key), (uns32)dta_key); } else { /* Not an error condition - DTA entry might already exist */ /* Adjust the pointer to to_reg with the offset */ to_reg = (DTA_DEST_LIST *)((long)to_reg - DTA_DEST_LIST_OFFSET); /* Also check if dta-svc relationship already exists */ /* If it does then just break frm this case & return */ if (dts_find_dta(svc, &dta_key) != NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return status; } } /* If svc entry found, just add it to the dta */ dts_add_svc_to_dta(to_reg, svc); m_LOG_DTS_EVT(DTS_EV_DTA_SVC_ADD, key.ss_svc_id, key.node, (uns32)dta_key); /* Now add dta into the svc->v_cd_list */ dts_enqueue_dta(svc, to_reg); m_LOG_DTS_EVT(DTS_EV_SVC_DTA_ADD, key.ss_svc_id, key.node, (uns32)dta_key); /* Version support : Call to function to load ASCII_SPEC * library. This function will load all versioning enabled * ASCII_SPEC libraries. */ /* First check whether CB last_spec_loaded has valid svc_name or not * If not, then break else continue to load library */ if (*cb->last_spec_loaded.svc_name == 0) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); break; } lib_hdl = (ASCII_SPEC_LIB *)dts_ascii_spec_load(cb->last_spec_loaded.svc_name, cb->last_spec_loaded.version, 1); /* memset the spec_key first before filling it up */ memset(&spec_key, '\0', sizeof(ASCII_SPEC_INDEX)); spec_key.svc_id = svc->ntwk_key.ss_svc_id; spec_key.ss_ver = cb->last_spec_loaded.version; /*Check if ASCII_SPEC table for this service is already loaded. * If no, read the config file */ if ((spec_entry = (SYSF_ASCII_SPECS *)ncs_patricia_tree_get(&cb->svcid_asciispec_tree, (const uns8 *)&spec_key)) == NULL) { /* If ASCII_SPEC table is versioning enabled, this means * service name & version specified was incorrect. */ dts_log(NCSFL_SEV_ERROR, "\n Service cribbing : %d\n", svc->my_key.ss_svc_id); fflush(stdout); m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: ASCII_SPEC library couldn't be loaded. Check service name & version no. across ASCII_SPEC tables, registration parameters & library name."); } else { /* Add an ASCII_SPEC entry for each service registration. * So any log message will directly index to this entry and * get the relevant spec pointer to use. */ per_dta_svc_spec = m_MMGR_ALLOC_DTS_SVC_SPEC; if (per_dta_svc_spec == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_EVT(DTS_EV_DTA_DEST_ADD_FAIL, 0, m_NCS_NODE_ID_FROM_MDS_DEST(dta_key), (uns32)dta_key); /* Do rest of cleanup, cleaning service regsitration table etc */ return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Memory allocation failed"); } memset(per_dta_svc_spec, '\0', sizeof(SPEC_ENTRY)); per_dta_svc_spec->dta_addr = dta_key; per_dta_svc_spec->spec_struct = spec_entry; per_dta_svc_spec->lib_struct = lib_hdl; strcpy(per_dta_svc_spec->svc_name, cb->last_spec_loaded.svc_name); /* Add to the svc reg tbl's spec list */ per_dta_svc_spec->next_spec_entry = svc->spec_list; /* point next to the rest of list */ svc->spec_list = per_dta_svc_spec; /*Add new struct to start of list */ /* Increment use count */ spec_entry->use_count++; } m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); } break; /* Yet not using UPDT for DTA_DEST_LIST */ case NCS_MBCSV_ACT_UPDATE: { m_DTS_LK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_LOCKED, &cb->lock); if ((to_reg = (DTA_DEST_LIST *)ncs_patricia_tree_get(&cb->dta_list, (const uns8 *)&dta_key)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: NCS_MBCSV_ACT_UPDATE - DTA entry does not exist in Patricia Tree"); } to_reg = (DTA_DEST_LIST *)((long)to_reg - DTA_DEST_LIST_OFFSET); to_reg->dta_addr = dtadest->dta_addr; to_reg->dta_up = dtadest->dta_up; to_reg->updt_req = dtadest->updt_req; m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); } break; case NCS_MBCSV_ACT_RMV: { m_DTS_LK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_LOCKED, &cb->lock); if ((to_reg = (DTA_DEST_LIST *)ncs_patricia_tree_get(&cb->dta_list, (const uns8 *)&dta_key)) != NULL) { to_reg = (DTA_DEST_LIST *)((long)to_reg - DTA_DEST_LIST_OFFSET); svc_entry = to_reg->svc_list; /* Remove dta entry frm the svc->v_cd_lists for all svcs */ while (svc_entry != NULL) { svc = svc_entry->svc; if (svc != NULL) { svc_key = svc->my_key; /* Network order key added */ nt_key = svc->ntwk_key; } if ((svc = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_REG_NOTFOUND, svc_key.ss_svc_id, svc_key.node, (uns32)to_reg->dta_addr); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Service entry not found in Patricia tree"); } /* remove dta from svc->v_cd_list */ if ((del_reg = (DTA_DEST_LIST *)dts_dequeue_dta(svc, to_reg)) == NULL) { m_LOG_DTS_EVT(DTS_EV_SVC_DTA_RMV_FAIL, svc_key.ss_svc_id, svc_key.node, (uns32)to_reg->dta_addr); /* Don't return failure, continue rmeoving service frm dta */ m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Failed to remove dta entry frm svc->v_cd_list"); } else m_LOG_DTS_EVT(DTS_EV_SVC_DTA_RMV, svc_key.ss_svc_id, svc_key.node, (uns32)to_reg->dta_addr); /* Versioning support: Remove spec entry corresponding to the * DTA from svc's spec_list. */ if (dts_del_spec_frm_svc(svc, dta_key, NULL) != NCSCC_RC_SUCCESS) { m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Unable to remove spec entry"); } /*Point to next entry before deleting svc frm svc_list */ svc_entry = svc_entry->next_in_dta_entry; /* remove svc from dta->svc_list */ if ((svc = (DTS_SVC_REG_TBL *)dts_del_svc_frm_dta(to_reg, svc)) == NULL) { m_LOG_DTS_EVT(DTS_EV_DTA_SVC_RMV_FAIL, svc_key.ss_svc_id, svc_key.node, (uns32)to_reg->dta_addr); /* Don't return, continue */ m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_dta_dest: Failed to delete svc from dta->svc_list"); } else m_LOG_DTS_EVT(DTS_EV_DTA_SVC_RMV, svc_key.ss_svc_id, svc_key.node, (uns32)to_reg->dta_addr); /* Check if svc entry is required or not */ if (svc->dta_count == 0) { if (&svc->device.cir_buffer != NULL) dts_circular_buffer_free(&svc->device.cir_buffer); device = &svc->device; m_DTS_FREE_FILE_LIST(device); ncs_patricia_tree_del(&cb->svc_tbl, (NCS_PATRICIA_NODE *)svc); m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_RMVD, svc_key.ss_svc_id, svc_key.node, (uns32)to_reg->dta_addr); if (svc != NULL) m_MMGR_FREE_SVC_REG_TBL(svc); } } /*end of while svc!=NULL */ /* Now delete the dta entry */ if (to_reg->svc_list == NULL) { ncs_patricia_tree_del(&cb->dta_list, (NCS_PATRICIA_NODE *)&to_reg->node); m_LOG_DTS_EVT(DTS_EV_DTA_DEST_RMV_SUCC, 0, m_NCS_NODE_ID_FROM_MDS_DEST(to_reg->dta_addr), (uns32)to_reg->dta_addr); if (NULL != to_reg) m_MMGR_FREE_VCARD_TBL(to_reg); } } else { /* Not an error condition */ } m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); } break; default: /* Log error */ status = NCSCC_RC_FAILURE; } return status; }
/****************************************************************************\ * Function: dtsv_ckpt_add_rmv_updt_svc_reg * * Purpose: Add new entry if action is ADD, remove from the table if * action is to remove and update data if request is to update. * * Input: cb - CB pointer. * svcreg - pointer to SVC REG table structure. * action - ADD/RMV/UPDT * * Returns: NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. * * NOTES: ADD takes care of forming the node entry for DTS_SVC_REG_TBL as well * as forming the individual service node. * ADD just adds svc_reg to DTA Patricia tree. * Hence, DTS_SVC_REG_TBL Async update(ADD) needs to be sent after * modification on the DTA Patricia tree in active DTS. * UPDT takes care of the changes in policy/filtering settings. * DTS_SVC_REG_TBL ADD happens before DTA_DEST_LIST ADD. * DTS_SVC_REG_TBL RMV takes care of removing svc entries from all DTAs * in its v_cd_list. \**************************************************************************/ uns32 dtsv_ckpt_add_rmv_updt_svc_reg(DTS_CB *cb, DTS_SVC_REG_TBL *svcreg, NCS_MBCSV_ACT_TYPE action) { uns32 status = NCSCC_RC_SUCCESS; DTS_SVC_REG_TBL *svc_ptr = NULL, *node_reg_ptr = NULL; DTA_DEST_LIST *to_reg = NULL; SVC_KEY nt_key, key; OP_DEVICE *device = NULL; DTA_ENTRY *dta_entry = NULL; MDS_DEST *vkey = NULL; switch (action) { case NCS_MBCSV_ACT_ADD: { /* * add new SVC_REG entry into pat tree. */ key.node = svcreg->my_key.node; key.ss_svc_id = 0; /* Network order key added */ nt_key.node = m_NCS_OS_HTONL(svcreg->my_key.node); nt_key.ss_svc_id = 0; m_DTS_LK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_LOCKED, &cb->lock); /* Check whether the Node exist in the node registration table * if yes, do nothing else create new entry in table and * fill the datastructure*/ if ((node_reg_ptr = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) == NULL) { node_reg_ptr = m_MMGR_ALLOC_SVC_REG_TBL; if (node_reg_ptr == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg: Memory allocation failed"); } memset(node_reg_ptr, '\0', sizeof(DTS_SVC_REG_TBL)); /* Check for NULL value of svcreg parameter, if not NULL Copy the attributes of the node passed by decoder */ node_reg_ptr->my_key.node = key.node; node_reg_ptr->my_key.ss_svc_id = 0; /* Network order key added */ node_reg_ptr->ntwk_key = nt_key; node_reg_ptr->node.key_info = (uns8 *)&node_reg_ptr->ntwk_key; node_reg_ptr->v_cd_list = NULL; node_reg_ptr->dta_count = 0; node_reg_ptr->my_node = node_reg_ptr; if (svcreg->my_key.ss_svc_id == 0) { /*updt for node entry */ /*cold sync update for node entry, set attributes accordingly */ m_DTS_SET_SVC_REG_TBL(node_reg_ptr, svcreg); } else { /*async update for new svc_reg, so initialize node param */ node_reg_ptr->per_node_logging = NODE_LOGGING; /* Copy attributes of node policy & op device */ node_reg_ptr->svc_policy.enable = NODE_ENABLE; node_reg_ptr->svc_policy.category_bit_map = NODE_CATEGORY_FILTER; node_reg_ptr->svc_policy.severity_bit_map = NODE_SEVERITY_FILTER; node_reg_ptr->svc_policy.log_dev = NODE_LOG_DEV; node_reg_ptr->svc_policy.log_file_size = NODE_LOGFILE_SIZE; node_reg_ptr->svc_policy.file_log_fmt = NODE_FILE_LOG_FMT; node_reg_ptr->svc_policy.cir_buff_size = NODE_CIR_BUFF_SIZE; node_reg_ptr->svc_policy.buff_log_fmt = NODE_BUFF_LOG_FMT; node_reg_ptr->device.new_file = TRUE; node_reg_ptr->device.file_open = FALSE; node_reg_ptr->device.last_rec_id = 0; } /* Add the node to the patricia tree */ if (ncs_patricia_tree_add(&cb->svc_tbl, (NCS_PATRICIA_NODE *)node_reg_ptr) != NCSCC_RC_SUCCESS) { /* Attempt to add node was unsuccessful */ if (NULL != node_reg_ptr) m_MMGR_FREE_SVC_REG_TBL(node_reg_ptr); m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_SVCREG_ADD_FAIL(DTS_EV_SVC_REG_ENT_ADD_FAIL, key.ss_svc_id, key.node, 0); m_LOG_DTS_EVT(DTS_EV_SVC_REG_FAILED, key.ss_svc_id, key.node, 0); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg : Failed to add node registration in Patricia tree"); } m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_ADD, key.ss_svc_id, key.node, 0); } /*end of creating new entry for node */ key.ss_svc_id = svcreg->my_key.ss_svc_id; /* Network order key added */ nt_key.ss_svc_id = m_NCS_OS_HTONL(svcreg->my_key.ss_svc_id); /* Check whether the Service exist in the service registration * table. If yes, then add the DTA v-card in the v-card queue. * If NO then create new entry in the table. Initialize it with * the default.Enqueue the v-card in the v-card table. */ if ((svc_ptr = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) != NULL) { /* Do nothing */ m_LOG_DTS_EVT(DTS_EV_SVC_ALREADY_REG, key.ss_svc_id, key.node, 0); } /* end of if svc_ptr */ else { /* Add to patricia tree; then create link list and add the new * element to it */ svc_ptr = m_MMGR_ALLOC_SVC_REG_TBL; if (svc_ptr == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg : Memory allocation failed"); } memset(svc_ptr, '\0', sizeof(DTS_SVC_REG_TBL)); svc_ptr->my_key.ss_svc_id = key.ss_svc_id; svc_ptr->my_key.node = key.node; /* Network order key added */ svc_ptr->ntwk_key = nt_key; svc_ptr->node.key_info = (uns8 *)&svc_ptr->ntwk_key; svc_ptr->v_cd_list = NULL; svc_ptr->dta_count = 0; svc_ptr->my_node = node_reg_ptr; m_DTS_SET_SVC_REG_TBL(svc_ptr, svcreg); if (ncs_patricia_tree_add(&cb->svc_tbl, (NCS_PATRICIA_NODE *)svc_ptr) != NCSCC_RC_SUCCESS) { /* Attempt to add node was unsuccessful */ if (NULL != svc_ptr) m_MMGR_FREE_SVC_REG_TBL(svc_ptr); m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_SVCREG_ADD_FAIL(DTS_EV_SVC_REG_ENT_ADD_FAIL, key.ss_svc_id, key.node, 0); m_LOG_DTS_EVT(DTS_EV_SVC_REG_FAILED, key.ss_svc_id, key.node, 0); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg : Failed to add service entry in patricia tree"); } m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_ADD, key.ss_svc_id, key.node, 0); svc_ptr->device.last_rec_id = svcreg->device.last_rec_id; m_LOG_DTS_EVT(DTS_EV_SVC_REG_SUCCESSFUL, key.ss_svc_id, key.node, 0); } /*end of else */ m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); } break; case NCS_MBCSV_ACT_UPDATE: { if (NULL != svcreg) { key = svcreg->my_key; /* Network order key added */ nt_key.node = m_NCS_OS_HTONL(key.node); nt_key.ss_svc_id = m_NCS_OS_HTONL(key.ss_svc_id); m_DTS_LK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_LOCKED, &cb->lock); if (svcreg->my_key.ss_svc_id == 0) { /*Node policy change */ /* update the policy for all services in the node */ if ((svc_ptr = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_REG_NOTFOUND, key.ss_svc_id, key.node, 0); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg : Node entry not found in the patricia tree"); } /* Update this node first */ m_DTS_SET_SVC_REG_TBL(svc_ptr, svcreg); m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_UPDT, key.ss_svc_id, key.node, 0); if (cb->cli_bit_map != 0) { while ((svc_ptr != NULL) && (svc_ptr->my_key.node == key.node)) { switch (cb->cli_bit_map) { case osafDtsvNodeMessageLogging_ID: if (svcreg->per_node_logging == FALSE) svc_ptr->device.new_file = TRUE; break; case osafDtsvNodeCategoryBitMap_ID: svc_ptr->svc_policy.category_bit_map = svcreg->svc_policy.category_bit_map; break; case osafDtsvNodeLoggingState_ID: svc_ptr->svc_policy.enable = svcreg->svc_policy.enable; break; case osafDtsvNodeSeverityBitMap_ID: svc_ptr->svc_policy.severity_bit_map = svcreg->svc_policy.severity_bit_map; break; default: /* Do nothing, it should not hit this */ break; } /*end of switch */ nt_key = svc_ptr->ntwk_key; /*m_DTS_SET_SVC_REG_TBL(svc_ptr, svcreg); */ m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_UPDT, key.ss_svc_id, key.node, 0); svc_ptr = (DTS_SVC_REG_TBL *)dts_get_next_svc_entry(&cb->svc_tbl, (SVC_KEY *) &nt_key); } /*end of while */ /* Re-set the cli_bit_map for subsequent policy changes */ cb->cli_bit_map = 0; } /*end of if cli_bit_map */ } else { /*Service policy change */ if ((svc_ptr = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_REG_NOTFOUND, key.ss_svc_id, key.node, 0); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg : Service entry not found in the patricia tree"); } else { m_DTS_SET_SVC_REG_TBL(svc_ptr, svcreg); m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_UPDT, key.ss_svc_id, key.node, 0); } } m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); } else { return NCSCC_RC_FAILURE; } } break; case NCS_MBCSV_ACT_RMV: { SPEC_CKPT spec_info; if (NULL != svcreg) { key.node = svcreg->my_key.node; key.ss_svc_id = svcreg->my_key.ss_svc_id; /* Network order key added */ nt_key.node = m_NCS_OS_HTONL(key.node); nt_key.ss_svc_id = m_NCS_OS_HTONL(key.ss_svc_id); m_DTS_LK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_LOCKED, &cb->lock); if ((svc_ptr = (DTS_SVC_REG_TBL *)ncs_patricia_tree_get(&cb->svc_tbl, (const uns8 *)&nt_key)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_REG_NOTFOUND, key.ss_svc_id, key.node, 0); /* Return Success, since svc is already not present */ return m_DTS_DBG_SINK(NCSCC_RC_SUCCESS, "dtsv_ckpt_add_rmv_updt_svc_reg : Service entry not found in patricia tree"); } /*The DTA to be removed from svc_reg->v_cd_list is stored in * DTS_CB's svc_rmv_mds_dest. * If svc_rmv_mds_dest is 0, then the svc->dta_count should already * be zero else there's an error. * If svc_rmv_mds_dest is not zero, then it is async update for * svc unregister. In this case, remove the DTA with MDS_DEST * the same as cb->svc_rmv_mds_dest from * svc_ptr->v-cd_list, also remove svc entry from dta->svc_list. */ if (cb->svc_rmv_mds_dest == 0) { if (svc_ptr->dta_count == 0) { if (&svc_ptr->device.cir_buffer != NULL) dts_circular_buffer_free(&svc_ptr->device.cir_buffer); device = &svc_ptr->device; /* Cleanup the DTS_FILE_LIST datastructure for svc */ m_DTS_FREE_FILE_LIST(device); ncs_patricia_tree_del(&cb->svc_tbl, (NCS_PATRICIA_NODE *)svc_ptr); m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_RMVD, key.ss_svc_id, key.node, 0); if (NULL != svc_ptr) m_MMGR_FREE_SVC_REG_TBL(svc_ptr); m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return NCSCC_RC_SUCCESS; } else { m_LOG_DTS_EVT(DTS_EV_SVC_DEREG_FAILED, key.ss_svc_id, key.node, 0); m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg: Either MDS_DEST for async update is wrong or database is inconsistent"); } } /*end of if(cb->svc_rmv_mds_dest == 0) */ else { vkey = &cb->svc_rmv_mds_dest; dta_entry = svc_ptr->v_cd_list; /* iterate through v_cd_list to find the dta to be removed */ while (dta_entry != NULL) { to_reg = dta_entry->dta; /* Point to next dta entry before deletion */ dta_entry = dta_entry->next_in_svc_entry; /*Check if the MDS_DEST for the dta to be removed matches */ if (dts_find_reg(vkey, to_reg) == TRUE) { if ((svc_ptr = (DTS_SVC_REG_TBL *)dts_del_svc_frm_dta(to_reg, svc_ptr)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_DTA_SVC_RMV_FAIL, key.ss_svc_id, key.node, (uns32)to_reg->dta_addr); m_LOG_DTS_EVT(DTS_EV_SVC_DEREG_FAILED, key.ss_svc_id, key.node, (uns32)to_reg->dta_addr); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg: Unable to remove svc reg entry from dta's list"); } m_LOG_DTS_EVT(DTS_EV_DTA_SVC_RMV, key.ss_svc_id, key.node, (uns32)to_reg->dta_addr); /* Remove dta entry frm svc_ptr->v_cd_list */ if ((to_reg = (DTA_DEST_LIST *)dts_dequeue_dta(svc_ptr, to_reg)) == NULL) { m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_DTA_RMV_FAIL, key.ss_svc_id, key.node, (uns32)to_reg->dta_addr); m_LOG_DTS_EVT(DTS_EV_SVC_DEREG_FAILED, key.ss_svc_id, key.node, (uns32)to_reg->dta_addr); return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg: Unable to remove adest entry"); } m_LOG_DTS_EVT(DTS_EV_SVC_DTA_RMV, key.ss_svc_id, key.node, (uns32)to_reg->dta_addr); memset(&spec_info, '\0', sizeof(SPEC_CKPT)); /* Versioning support : Remove spec entry corresponding to * the DTA from svc's spec_list. */ if (dts_del_spec_frm_svc(svc_ptr, *vkey, &spec_info) != NCSCC_RC_SUCCESS) { m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dtsv_ckpt_add_rmv_updt_svc_reg: Unable to remove spec entry"); } /* Call function to unload the ASCII_SPEC library if * use_count of the library has become 0. */ dts_ascii_spec_load(spec_info.svc_name, spec_info.version, 0); /* If dta svc queue is empty delete dta frm patricia tree */ if (to_reg->svc_list == NULL) { /*ncs_destroy_queue(&to_reg->svc_list); */ ncs_patricia_tree_del(&cb->dta_list, (NCS_PATRICIA_NODE *) &to_reg->node); m_LOG_DTS_EVT(DTS_EV_DTA_DEST_RMV_SUCC, 0, key.node, (uns32)to_reg->dta_addr); if (NULL != to_reg) m_MMGR_FREE_VCARD_TBL(to_reg); } /*Since the dta is found and deleted exit the while loop */ break; } /*end of if(dts_find_reg() == TRUE) */ } /*end of while */ } /*end of else (cb->svc_rmv_mds_dest == 0) */ /* Do NOT attempt deletion of service entries while * it's still syncing with Active DTS esp. if its still yet to * get the data for DTA LIST. Because until then SVC<->DTA * mapping won't be established. * In that case all services which have dta_count = 0 will be * cleaned at the end of completion of DTA list data-sync. */ if ((cb->in_sync == FALSE) && (cb->cold_sync_done < DTSV_CKPT_DTA_DEST_LIST_CONFIG)) { /* Whatever is needed has been done so return success */ m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_DEREG_SUCCESSFUL, key.ss_svc_id, key.node, 0); return NCSCC_RC_SUCCESS; } /* Delete svc entry when dta_count is zero */ else if (svc_ptr->dta_count == 0) { /* No need of policy handles */ /* Now delete the svc entry from the patricia tree */ /*ncshm_destroy_hdl(NCS_SERVICE_ID_DTSV, svc_ptr->svc_hdl); m_LOG_DTS_EVT(DTS_EV_SVC_POLCY_HDL_DES, key.ss_svc_id, key.node, 0); */ if (&svc_ptr->device.cir_buffer != NULL) dts_circular_buffer_free(&svc_ptr->device.cir_buffer); device = &svc_ptr->device; /* Cleanup the DTS_FILE_LIST datastructure for svc */ m_DTS_FREE_FILE_LIST(device); ncs_patricia_tree_del(&cb->svc_tbl, (NCS_PATRICIA_NODE *)svc_ptr); m_LOG_DTS_EVT(DTS_EV_SVC_REG_ENT_RMVD, key.ss_svc_id, key.node, 0); if (NULL != svc_ptr) m_MMGR_FREE_SVC_REG_TBL(svc_ptr); } m_DTS_UNLK(&cb->lock); m_LOG_DTS_LOCK(DTS_LK_UNLOCKED, &cb->lock); m_LOG_DTS_EVT(DTS_EV_SVC_DEREG_SUCCESSFUL, key.ss_svc_id, key.node, 0); } else { return NCSCC_RC_FAILURE; } } break; default: /* Log error */ return NCSCC_RC_FAILURE; } return status; }
/**************************************************************************** * Name : glsv_gld_mds_glnd_down * * Description : MDS indicated that a glnd has gone down * * Arguments : async_evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t glsv_gld_standby_mds_glnd_down(GLSV_GLD_A2S_CKPT_EVT *async_evt) { GLSV_GLD_CB *gld_cb; GLSV_GLD_GLND_DETAILS *node_details = NULL; GLSV_GLD_GLND_RSC_REF *glnd_rsc = NULL; bool orphan_flag; SaLckResourceIdT rsc_id; uint32_t node_id; uint32_t rc = NCSCC_RC_SUCCESS; TRACE_ENTER(); if (async_evt == NULL) { rc = NCSCC_RC_FAILURE; goto end; } node_id = m_NCS_NODE_ID_FROM_MDS_DEST(async_evt->info.glnd_mds_info.mdest_id); if ((gld_cb = (NCSCONTEXT)ncshm_take_hdl(NCS_SERVICE_ID_GLD, gl_gld_hdl)) == NULL) { LOG_ER("Handle take failed"); rc = NCSCC_RC_FAILURE; goto end; } orphan_flag = async_evt->info.rsc_details.orphan; if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) == NULL) { LOG_ER("Patricia tree get failed: node_id %u", node_id); rc = NCSCC_RC_FAILURE; goto end; } /* Remove the reference to each of the resource referred by this node */ glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uint8_t *)0); if (glnd_rsc) { rsc_id = glnd_rsc->rsc_id; while (glnd_rsc) { gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag); glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uint8_t *)&rsc_id); if (glnd_rsc) rsc_id = glnd_rsc->rsc_id; } } /* Cancel the restart timer if started */ if (node_details->restart_timer.tmr_id != TMR_T_NULL) gld_stop_tmr(&node_details->restart_timer); /* Now delete this node details node */ if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) { LOG_ER("Patricia tree del failed: node_id %u", node_details->node_id); } m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details); ncshm_give_hdl(gld_cb->my_hdl); end: TRACE_LEAVE(); return rc; }
static void svctype_delete(AVD_SVC_TYPE *svc_type) { unsigned int rc = ncs_patricia_tree_del(&svctype_db, &svc_type->tree_node); assert(rc == NCSCC_RC_SUCCESS); free(svc_type); }
/**************************************************************************\ * * ncs_exec_mod_hdlr * * Description: Task to handle the signals. * * Synopsis: * * Call Arguments: * pid - Process ID for which timeout has occurrend. * * Returns: * None. * * Notes: * \**************************************************************************/ void ncs_exec_mod_hdlr(void) { EXEC_MOD_INFO info; uns32 maxsize = sizeof(EXEC_MOD_INFO); int count = 0, ret_val = 0; SYSF_PID_LIST *exec_pid = NULL; int status = -1; int pid = -1; while (1) { while ((ret_val = read(module_cb.read_fd, (((uns8 *)&info) + count), (maxsize - count))) != (maxsize - count)) { if (ret_val <= 0) { if (errno == EBADF) return; perror("ncs_exec_mod_hdlr: read fail:"); continue; } count += ret_val; } /* while */ if (info.type == SYSF_EXEC_INFO_TIME_OUT) { /* printf("Time out signal \n"); */ pid = info.pid; give_exec_mod_cb(info.pid, info.status, info.type); } /* if */ else { repeat_srch_from_beginning: m_NCS_LOCK(&module_cb.tree_lock, NCS_LOCK_WRITE); for (exec_pid = (SYSF_PID_LIST *)ncs_patricia_tree_getnext(&module_cb.pid_list, NULL); exec_pid != NULL; exec_pid = (SYSF_PID_LIST *)ncs_patricia_tree_getnext(&module_cb.pid_list, (const uns8 *)&exec_pid->pid)) { pid = exec_pid->pid; /*printf(" Going to wait on waitpid %d \n", pid); */ if ((pid == waitpid(pid, &status, WNOHANG))) { /* TIMED OUT CHILDS which are terminated by sending SIG CHILD */ if (exec_pid->exec_info_type == SYSF_EXEC_INFO_TIME_OUT) { ncs_patricia_tree_del(&module_cb.pid_list, (NCS_PATRICIA_NODE *)exec_pid); m_MMGR_FREE_PRO_EXC(exec_pid); m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE); } else { info.pid = pid; info.status = status; info.type = SYSF_EXEC_INFO_SIG_CHLD; m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE); give_exec_mod_cb(info.pid, info.status, info.type); } goto repeat_srch_from_beginning; } } /*for */ m_NCS_UNLOCK(&module_cb.tree_lock, NCS_LOCK_WRITE); } /* else */ count = 0; } /* while(1) */ }
/***************************************************************************** PROCEDURE NAME : glnd_client_node_del DESCRIPTION : Deletes the client node from the tree. ARGUMENTS :glnd_cb - ptr to the GLND control block agent_mds_dest - mds dest id for the agent. RETURNS :NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE NOTES : None *****************************************************************************/ uns32 glnd_client_node_del(GLND_CB *glnd_cb, GLND_CLIENT_INFO *client_info) { GLND_CLIENT_LIST_RESOURCE *res_list, *tmp_res_list; GLND_RESOURCE_INFO *res_info; SaLckLockModeT mode; GLSV_GLD_EVT gld_evt; NCS_BOOL orphan = FALSE; /* delete from the tree */ if (ncs_patricia_tree_del(&glnd_cb->glnd_client_tree, &client_info->patnode) != NCSCC_RC_SUCCESS) { m_LOG_GLND_API(GLND_CLIENT_TREE_DEL_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__); return NCSCC_RC_FAILURE; } /* free up all the resource requests */ for (res_list = client_info->res_list; res_list != NULL;) { res_info = res_list->rsc_info; tmp_res_list = res_list; res_list = res_list->next; if (res_info) { glnd_set_orphan_state(glnd_cb, res_info); glnd_client_node_resource_del(glnd_cb, client_info, res_info); if (!res_info->lck_master_info.grant_list) { /* do the re sync of the grant list */ glnd_resource_master_lock_resync_grant_list(glnd_cb, res_info); } if (res_info->lcl_ref_cnt > 0) { memset(&gld_evt, 0, sizeof(GLSV_GLD_EVT)); gld_evt.evt_type = GLSV_GLD_EVT_RSC_CLOSE; gld_evt.info.rsc_details.rsc_id = res_info->resource_id; gld_evt.info.rsc_details.lcl_ref_cnt = res_info->lcl_ref_cnt; glnd_mds_msg_send_gld(glnd_cb, &gld_evt, glnd_cb->gld_mdest_id); res_info->lcl_ref_cnt--; } glnd_restart_resource_info_ckpt_overwrite(glnd_cb, res_info); if (tmp_res_list->open_ref_cnt > 1) { memset(&gld_evt, 0, sizeof(GLSV_GLD_EVT)); gld_evt.evt_type = GLSV_GLD_EVT_RSC_CLOSE; gld_evt.info.rsc_details.rsc_id = res_info->resource_id; gld_evt.info.rsc_details.lcl_ref_cnt = tmp_res_list->open_ref_cnt; glnd_mds_msg_send_gld(glnd_cb, &gld_evt, glnd_cb->gld_mdest_id); } if (res_info->lcl_ref_cnt == 0 && glnd_resource_grant_list_orphan_locks(res_info, &mode) == FALSE) { glnd_resource_node_destroy(glnd_cb, res_info, orphan); } } } /* free up any stale res_requests from this finalized client ... */ while (glnd_cb->res_req_list != NULL) { if (client_info->app_handle_id == glnd_cb->res_req_list->client_handle_id) glnd_resource_req_node_del(glnd_cb, glnd_cb->res_req_list->res_req_hdl_id); } /* free the memory */ m_MMGR_FREE_GLND_CLIENT_INFO(client_info); return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_rsc_open * * Description : This is the function is invoked when a rsc_open event is * is sent from a GLND. This function will assign a resource id * and send the information to the GLND * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uns32 gld_rsc_open(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_RSC_INFO *rsc_info; GLSV_GLD_GLND_DETAILS *node_details; GLSV_NODE_LIST *node_list, **tmp_node_list; GLSV_GLND_EVT glnd_evt; NCSMDS_INFO snd_mds; uns32 res; SaAisErrorT error; uns32 node_id; NCS_BOOL node_first_rsc_open = FALSE; GLSV_GLD_GLND_RSC_REF *glnd_rsc = NULL; NCS_BOOL orphan_flag = FALSE; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); memset(&snd_mds, '\0', sizeof(NCSMDS_INFO)); memset(&glnd_evt, '\0', sizeof(GLSV_GLND_EVT)); if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)) return NCSCC_RC_FAILURE; /* Find if the node details are available */ if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uns8 *)&node_id)) == NULL) { node_first_rsc_open = TRUE; if ((node_details = gld_add_glnd_node(gld_cb, evt->fr_dest_id)) == NULL) return NCSCC_RC_FAILURE; } rsc_info = gld_find_add_rsc_name(gld_cb, &evt->info.rsc_open_info.rsc_name, evt->info.rsc_open_info.rsc_id, evt->info.rsc_open_info.flag, &error); if (rsc_info == NULL) { /* based on the error - pass on the info to the glnd */ glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS; glnd_evt.info.rsc_gld_info.rsc_name = evt->info.rsc_open_info.rsc_name; glnd_evt.info.rsc_gld_info.error = error; snd_mds.i_mds_hdl = gld_cb->mds_handle; snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD; snd_mds.i_op = MDS_SEND; snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt; snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND; snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH; snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND; snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id; res = ncsmds_api(&snd_mds); if (res != NCSCC_RC_SUCCESS) { m_LOG_GLD_SVC_PRVDR(GLD_MDS_SEND_ERROR, NCSFL_SEV_ERROR, __FILE__, __LINE__); } goto err1; } m_LOG_GLD_EVT(GLD_EVT_RSC_OPEN, NCSFL_SEV_INFO, __FILE__, __LINE__, rsc_info->rsc_id, node_details->node_id); gld_rsc_add_node_ref(gld_cb, node_details, rsc_info); /* Now add this node to the list of nodes referring this resource */ node_list = rsc_info->node_list; tmp_node_list = &rsc_info->node_list; while (node_list != NULL) { if (node_list->node_id == node_id) break; tmp_node_list = &node_list->next; node_list = node_list->next; } if (node_list == NULL) { node_list = m_MMGR_ALLOC_GLSV_NODE_LIST; memset(node_list, 0, sizeof(GLSV_NODE_LIST)); node_list->dest_id = node_details->dest_id; node_list->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); *tmp_node_list = node_list; /* Send the details to the glnd */ glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS; glnd_evt.info.rsc_gld_info.master_dest_id = rsc_info->node_list->dest_id; glnd_evt.info.rsc_gld_info.rsc_id = rsc_info->rsc_id; glnd_evt.info.rsc_gld_info.rsc_name = rsc_info->lck_name; glnd_evt.info.rsc_gld_info.can_orphan = rsc_info->can_orphan; glnd_evt.info.rsc_gld_info.orphan_mode = rsc_info->orphan_lck_mode; glnd_evt.info.rsc_gld_info.error = SA_AIS_OK; snd_mds.i_mds_hdl = gld_cb->mds_handle; snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD; snd_mds.i_op = MDS_SEND; snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt; snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND; snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH; snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND; snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id; res = ncsmds_api(&snd_mds); if (res != NCSCC_RC_SUCCESS) { m_LOG_GLD_SVC_PRVDR(GLD_MDS_SEND_ERROR, NCSFL_SEV_ERROR, __FILE__, __LINE__); goto err2; } } /* checkpoint resource */ glsv_gld_a2s_ckpt_resource(gld_cb, &rsc_info->lck_name, rsc_info->rsc_id, evt->fr_dest_id, rsc_info->saf_rsc_creation_time); return NCSCC_RC_SUCCESS; err2: glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree, (uns8 *)&rsc_info->rsc_id); if ((glnd_rsc == NULL) || (glnd_rsc->rsc_info == NULL)) { m_LOG_GLD_LCK_OPER(GLD_OPER_RSC_OPER_ERROR, NCSFL_SEV_ERROR, __FILE__, __LINE__, "", rsc_info->rsc_id, node_details->node_id); return NCSCC_RC_FAILURE; } if (glnd_rsc->rsc_info->saf_rsc_no_of_users > 0) glnd_rsc->rsc_info->saf_rsc_no_of_users = glnd_rsc->rsc_info->saf_rsc_no_of_users - 1; gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag); err1: if (node_first_rsc_open) { /* Now delete this node details node */ if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) { m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_DEL_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__, node_details->node_id); } else { m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details); m_LOG_GLD_HEADLINE(GLD_ACTIVE_RMV_NODE, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id); } } return NCSCC_RC_FAILURE; }
/**************************************************************************** * Name : gld_rsc_open * * Description : This is the function is invoked when a rsc_open event is * is sent from a GLND. This function will assign a resource id * and send the information to the GLND * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t gld_rsc_open(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_RSC_INFO *rsc_info; GLSV_GLD_GLND_DETAILS *node_details; GLSV_NODE_LIST *node_list, **tmp_node_list; GLSV_GLND_EVT glnd_evt; NCSMDS_INFO snd_mds; uint32_t res = NCSCC_RC_FAILURE;; SaAisErrorT error; uint32_t node_id; bool node_first_rsc_open = false; GLSV_GLD_GLND_RSC_REF *glnd_rsc = NULL; bool orphan_flag = false; TRACE_ENTER2("component name %s", gld_cb->comp_name.value); node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); memset(&snd_mds, '\0', sizeof(NCSMDS_INFO)); memset(&glnd_evt, '\0', sizeof(GLSV_GLND_EVT)); if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)) goto end; /* Find if the node details are available */ if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) == NULL) { node_first_rsc_open = true; if ((node_details = gld_add_glnd_node(gld_cb, evt->fr_dest_id)) == NULL) goto end; } rsc_info = gld_find_add_rsc_name(gld_cb, &evt->info.rsc_open_info.rsc_name, evt->info.rsc_open_info.rsc_id, evt->info.rsc_open_info.flag, &error); if (rsc_info == NULL) { /* based on the error - pass on the info to the glnd */ glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS; glnd_evt.info.rsc_gld_info.rsc_name = evt->info.rsc_open_info.rsc_name; glnd_evt.info.rsc_gld_info.error = error; snd_mds.i_mds_hdl = gld_cb->mds_handle; snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD; snd_mds.i_op = MDS_SEND; snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt; snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND; snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH; snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND; snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id; res = ncsmds_api(&snd_mds); if (res != NCSCC_RC_SUCCESS) { LOG_ER("MDS Send failed"); } goto err1; } TRACE_1("EVT Processing rsc open: rsc_id %u node_id %u", rsc_info->rsc_id, node_details->node_id); gld_rsc_add_node_ref(gld_cb, node_details, rsc_info); /* Now add this node to the list of nodes referring this resource */ node_list = rsc_info->node_list; tmp_node_list = &rsc_info->node_list; while (node_list != NULL) { if (node_list->node_id == node_id) break; tmp_node_list = &node_list->next; node_list = node_list->next; } if (node_list == NULL) { node_list = m_MMGR_ALLOC_GLSV_NODE_LIST; memset(node_list, 0, sizeof(GLSV_NODE_LIST)); node_list->dest_id = node_details->dest_id; node_list->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); *tmp_node_list = node_list; /* Send the details to the glnd */ glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS; glnd_evt.info.rsc_gld_info.master_dest_id = rsc_info->node_list->dest_id; glnd_evt.info.rsc_gld_info.rsc_id = rsc_info->rsc_id; glnd_evt.info.rsc_gld_info.rsc_name = rsc_info->lck_name; glnd_evt.info.rsc_gld_info.can_orphan = rsc_info->can_orphan; glnd_evt.info.rsc_gld_info.orphan_mode = rsc_info->orphan_lck_mode; glnd_evt.info.rsc_gld_info.error = SA_AIS_OK; snd_mds.i_mds_hdl = gld_cb->mds_handle; snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD; snd_mds.i_op = MDS_SEND; snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt; snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND; snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH; snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND; snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id; res = ncsmds_api(&snd_mds); if (res != NCSCC_RC_SUCCESS) { LOG_ER("MDS Send failed"); goto err2; } } /* checkpoint resource */ glsv_gld_a2s_ckpt_resource(gld_cb, &rsc_info->lck_name, rsc_info->rsc_id, evt->fr_dest_id, rsc_info->saf_rsc_creation_time); res = NCSCC_RC_SUCCESS; goto end; err2: glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree, (uint8_t *)&rsc_info->rsc_id); if ((glnd_rsc == NULL) || (glnd_rsc->rsc_info == NULL)) { LOG_ER("Rsc operation for unopened rsc: rsc_id %u node_id %u", rsc_info->rsc_id, node_details->node_id); goto end; } if (glnd_rsc->rsc_info->saf_rsc_no_of_users > 0) glnd_rsc->rsc_info->saf_rsc_no_of_users = glnd_rsc->rsc_info->saf_rsc_no_of_users - 1; gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag); err1: if (node_first_rsc_open) { /* Now delete this node details node */ if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) { LOG_ER("Patricia tree del failed: node_id %u ", node_details->node_id); } else { m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details); TRACE("Node getting removed on active: node_id %u", node_id); } } res = NCSCC_RC_FAILURE; end: TRACE_LEAVE2("return value %u", res); return res; }