/******************************************************************************
  Name          : avnd_nodeid_mdsdest_rec_add
 
  Description   : This routine adds NODE_ID to MDS_DEST record for a particular
                  AvND.
 
  Arguments     : cb  - ptr to the AvND control block.
                  mds_dest - Mds dest of AvND coming up.
 
  Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
 
  Notes         : None
******************************************************************************/
uns32 avnd_nodeid_mdsdest_rec_add(AVND_CB *cb, MDS_DEST mds_dest)
{
	AVND_NODEID_TO_MDSDEST_MAP *rec = NULL;
	NODE_ID node_id = 0;
	uns32 res = NCSCC_RC_SUCCESS;

	node_id = m_NCS_NODE_ID_FROM_MDS_DEST(mds_dest);

	rec = (AVND_NODEID_TO_MDSDEST_MAP *)ncs_patricia_tree_get(&cb->nodeid_mdsdest_db, (uns8 *)&(node_id));
	if (rec != NULL) {
		LOG_ER("nodeid_mdsdest rec already exists, Rec Add Failed: MdsDest:%lld, NodeId:%u",
				    mds_dest, node_id);
		return NCSCC_RC_FAILURE;
	} else {
		rec = malloc(sizeof(AVND_NODEID_TO_MDSDEST_MAP));

		if (rec == NULL) {
			return NCSCC_RC_FAILURE;
		} else {
			rec->node_id = node_id;
			rec->mds_dest = mds_dest;
			rec->tree_node.bit = 0;
			rec->tree_node.key_info = (uns8 *)&(rec->node_id);

			res = ncs_patricia_tree_add(&cb->nodeid_mdsdest_db, &rec->tree_node);

			if (NCSCC_RC_SUCCESS != res) {
				LOG_ER("Couldn't add nodeid_mdsdest rec, patricia add failed:MdsDest:%lld, NodeId:%u",
				     mds_dest, node_id);
				free(rec);
				return res;
			}

		}		/* Else of if(rec == NULL)  */

	}			/* Else of if(rec != NULL)  */

	return res;

}
/****************************************************************************
  Name          : mqa_queue_tree_find_and_add
 
  Description   : This routine adds the new queue to the queue tree
 
  Arguments     : 
                  mqa_cb : pointer to the mqa control block.
                  hdl_id : the handle id.
                  flag   : true/false if true create the new node if node 
                           doesn't exist.FALSE -> search for an existing node.
                 MQA_CLIENT_INFO *client_info : Info about the client.
                 SaMsgQueueOpenFlagsT openFlags : 
                          If flag == true, openFlags is IN parameter.
                          If flag != true, openFlags is ignored.
  Return Values : returns the MQA_QUEUE_INFO node.
 
  Notes         : None
******************************************************************************/
MQA_QUEUE_INFO *mqa_queue_tree_find_and_add(MQA_CB *mqa_cb,
					    SaMsgQueueHandleT hdl_id,
					    bool flag, MQA_CLIENT_INFO *client_info, SaMsgQueueOpenFlagsT openFlags)
{
	MQA_QUEUE_INFO *queue_info = NULL;
	uint32_t rc = NCSCC_RC_SUCCESS;
	TRACE_ENTER();

	/* read lock taken by the caller. */
	queue_info = (MQA_QUEUE_INFO *)ncs_patricia_tree_get(&mqa_cb->mqa_queue_tree, (uint8_t *)&hdl_id);

	if (flag == true) {
		/* create and allocate the memory */
		if (!queue_info) {
			queue_info = (MQA_QUEUE_INFO *)m_MMGR_ALLOC_MQA_QUEUE_INFO;
			if (!queue_info) {
				TRACE_2("Queue database creation failed");
				return NULL;
			}
			memset(queue_info, 0, sizeof(MQA_QUEUE_INFO));
			queue_info->queueHandle = hdl_id;
			queue_info->openFlags = openFlags;
			queue_info->client_info = client_info;
			queue_info->patnode.key_info = (uint8_t *)&queue_info->queueHandle;
			queue_info->msg_get_count = 0;

			if ((rc =
			     ncs_patricia_tree_add(&mqa_cb->mqa_queue_tree,
						   &queue_info->patnode)) != NCSCC_RC_SUCCESS) {
				TRACE_2("Queue database Registration Failed");
				m_MMGR_FREE_MQA_QUEUE_INFO(queue_info);

				return NULL;
			}

		}
	}
	TRACE_LEAVE();
	return queue_info;
}
Exemple #3
0
/****************************************************************************
 * Name          : gld_add_glnd_node
 * Description   : Adds node_details info to the gld_cb and initilizes
                   node_details->rsc_info_tree
 *
 * Arguments     :GLSV_GLD_CB, glnd_mds_dest
 *
 * Return Values :
 *
 * Notes         : None.
 *****************************************************************************/
GLSV_GLD_GLND_DETAILS *gld_add_glnd_node(GLSV_GLD_CB *gld_cb, MDS_DEST glnd_mds_dest)
{
	GLSV_GLD_GLND_DETAILS *node_details;
	NCS_PATRICIA_PARAMS params = { sizeof(uint32_t) };
	TRACE_ENTER2("glnd_mds_dest %" PRIx64, glnd_mds_dest);

	/* Need to add the node details */
	node_details = m_MMGR_ALLOC_GLSV_GLD_GLND_DETAILS;
	if (node_details == NULL) {
		LOG_CR("Node details alloc failed: Error %s", strerror(errno));
		assert(0);
	}
	memset(node_details, 0, sizeof(GLSV_GLD_GLND_DETAILS));

	memcpy(&node_details->dest_id, &glnd_mds_dest, sizeof(MDS_DEST));
	node_details->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(glnd_mds_dest);
	node_details->status = GLND_OPERATIONAL_STATE;

	TRACE("EVT Processing MDS GLND UP: node_id %u", node_details->node_id);

	/* Initialize the pat tree for resource info */
	if ((ncs_patricia_tree_init(&node_details->rsc_info_tree, &params))
	    != NCSCC_RC_SUCCESS) {
		LOG_ER("Patricia tree init failed");
		m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
		node_details = NULL;
		goto end;
	}
	node_details->pat_node.key_info = (uint8_t *)&node_details->node_id;
	if (ncs_patricia_tree_add(&gld_cb->glnd_details, &node_details->pat_node)
	    != NCSCC_RC_SUCCESS) {
		LOG_ER("Patricia tree add failed");
		m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
		node_details = NULL;
		goto end;
	}
 end:
	TRACE_LEAVE2("Node id %u",node_details->node_id);
	return node_details;
}
/****************************************************************************
  Name          : mqa_queue_tree_find_and_add
 
  Description   : This routine adds the new queue to the queue tree
 
  Arguments     : 
                  mqa_cb : pointer to the mqa control block.
                  hdl_id : the handle id.
                  flag   : TRUE/FALSE if TRUE create the new node if node 
                           doesn't exist.FALSE -> search for an existing node.
                 MQA_CLIENT_INFO *client_info : Info about the client.
                 SaMsgQueueOpenFlagsT openFlags : 
                          If flag == TRUE, openFlags is IN parameter.
                          If flag != TRUE, openFlags is ignored.
  Return Values : returns the MQA_QUEUE_INFO node.
 
  Notes         : None
******************************************************************************/
MQA_QUEUE_INFO *mqa_queue_tree_find_and_add(MQA_CB *mqa_cb,
					    SaMsgQueueHandleT hdl_id,
					    NCS_BOOL flag, MQA_CLIENT_INFO *client_info, SaMsgQueueOpenFlagsT openFlags)
{
	MQA_QUEUE_INFO *queue_info = NULL;
	uns32 rc = NCSCC_RC_SUCCESS;
	/* read lock taken by the caller. */
	queue_info = (MQA_QUEUE_INFO *)ncs_patricia_tree_get(&mqa_cb->mqa_queue_tree, (uns8 *)&hdl_id);

	if (flag == TRUE) {
		/* create and allocate the memory */
		if (!queue_info) {
			queue_info = (MQA_QUEUE_INFO *)m_MMGR_ALLOC_MQA_QUEUE_INFO;
			if (!queue_info) {
				m_LOG_MQSV_A(MQA_QUEUE_ALLOC_FAILED, NCSFL_LC_MQSV_INIT, NCSFL_SEV_ERROR, 0, __FILE__,
					     __LINE__);
				return NULL;
			}
			memset(queue_info, 0, sizeof(MQA_QUEUE_INFO));
			queue_info->queueHandle = hdl_id;
			queue_info->openFlags = openFlags;
			queue_info->client_info = client_info;
			queue_info->patnode.key_info = (uns8 *)&queue_info->queueHandle;
			queue_info->msg_get_count = 0;

			if ((rc =
			     ncs_patricia_tree_add(&mqa_cb->mqa_queue_tree,
						   &queue_info->patnode)) != NCSCC_RC_SUCCESS) {
				m_LOG_MQSV_A(MQA_QUEUE_TREE_ADD_FAILED, NCSFL_LC_MQSV_INIT, NCSFL_SEV_ERROR, rc,
					     __FILE__, __LINE__);
				m_MMGR_FREE_MQA_QUEUE_INFO(queue_info);

				return NULL;
			}

		}
	}
	return queue_info;
}
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;
}
Exemple #6
0
/****************************************************************************
  Name          : cpd_ckpt_reploc_node_add
  Description   : This routine adds the new node to ckpt_tree.
  Arguments     : ckpt_tree - Checkpoint Tree.
                  ckpt_node -  checkpoint Node.
  Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
  Notes         : The caller takes the cb lock before calling this function
******************************************************************************/
uns32 cpd_ckpt_reploc_node_add(NCS_PATRICIA_TREE *ckpt_reploc_tree, CPD_CKPT_REPLOC_INFO *ckpt_reploc_node,
                               SaAmfHAStateT ha_state, SaImmOiHandleT immOiHandle)
{
    SaAisErrorT err = SA_AIS_OK;
    SaNameT replica_dn;
    memset(&replica_dn, 0, sizeof(SaNameT));

    /* Add the imm runtime object */
    if (ha_state == SA_AMF_HA_ACTIVE) {
        err = create_runtime_replica_object(ckpt_reploc_node, immOiHandle);
        if (err != SA_AIS_OK) {
            cpd_log(NCSFL_SEV_ERROR, "create_runtime_replica_object failed %u\n", err);
            return NCSCC_RC_FAILURE;
        }
    }
    ckpt_reploc_node->rep_key.ckpt_name.length = m_NCS_OS_HTONS(ckpt_reploc_node->rep_key.ckpt_name.length);
    /* node name is obtained from cluster info which always returns in network order, so no need of the conversion for the node_name length */
    ckpt_reploc_node->rep_key.node_name.length = m_NCS_OS_HTONS(ckpt_reploc_node->rep_key.node_name.length);

    ckpt_reploc_node->patnode.key_info = (uns8 *)&ckpt_reploc_node->rep_key;
    if (ncs_patricia_tree_add(ckpt_reploc_tree, &ckpt_reploc_node->patnode) != NCSCC_RC_SUCCESS) {
        /* m_LOG_CPD_HEADLINE(CPD_CKPT_REPLOC_INFO_ADD_FAILED, NCSFL_SEV_ERROR); */
        /* delete reploc imm runtime object */
        if (ha_state == SA_AMF_HA_ACTIVE) {
            cpd_create_association_class_dn(&ckpt_reploc_node->rep_key.node_name,
                                            &ckpt_reploc_node->rep_key.ckpt_name, "safReplica", &replica_dn);

            if (immutil_saImmOiRtObjectDelete(immOiHandle, &replica_dn) != SA_AIS_OK) {
                cpd_log(NCSFL_SEV_ERROR, "Deleting run time object %s FAILED", replica_dn.value);
                return NCSCC_RC_FAILURE;
            }
            return NCSCC_RC_FAILURE;
        }
    }

    return NCSCC_RC_SUCCESS;
}
Exemple #7
0
/****************************************************************************
  Name          : cpd_cpnd_info_node_add
  Description   : This routine adds the new node to ckpt_tree.
  Arguments     : ckpt_tree - Checkpoint Tree.
                  ckpt_node -  checkpoint Node.
  Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
  Notes         : The caller takes the cb lock before calling this function
******************************************************************************/
uns32 cpd_cpnd_info_node_find_add(NCS_PATRICIA_TREE *cpnd_tree, MDS_DEST *dest,
                                  CPD_CPND_INFO_NODE **cpnd_info_node, NCS_BOOL *add_flag)
{
    /*MDS_DEST key; */
    NODE_ID key;

    memset(&key, 0, sizeof(NODE_ID));
    /* Fill the Key */
    key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest));

    *cpnd_info_node = (CPD_CPND_INFO_NODE *)
                      ncs_patricia_tree_get(cpnd_tree, (uns8 *)&key);
    if ((*cpnd_info_node == NULL) && (*add_flag == TRUE)) {
        *cpnd_info_node = m_MMGR_ALLOC_CPD_CPND_INFO_NODE;
        if (*cpnd_info_node == NULL) {
            m_LOG_CPD_CL(CPD_CPND_INFO_ALLOC_FAILED, CPD_FC_MEMFAIL, NCSFL_SEV_ERROR, __FILE__, __LINE__);
            return NCSCC_RC_FAILURE;
        }
        memset((*cpnd_info_node), '\0', sizeof(CPD_CPND_INFO_NODE));

        /* Store the client_info pointer as msghandle. */
        (*cpnd_info_node)->cpnd_dest = *dest;
        (*cpnd_info_node)->cpnd_key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest));
        /*  (*cpnd_info_node)->patnode.key_info = (uns8*)&(m_NCS_NODE_ID_FROM_MDS_DEST((*cpnd_info_node)->cpnd_dest)); */
        (*cpnd_info_node)->patnode.key_info = (uns8 *)&((*cpnd_info_node)->cpnd_key);

        if (ncs_patricia_tree_add(cpnd_tree, &(*cpnd_info_node)->patnode) != NCSCC_RC_SUCCESS) {
            m_LOG_CPD_FCL(CPD_CPND_INFO_NODE_FAILED, CPD_FC_HDLN, NCSFL_SEV_ERROR, *dest, __FILE__,
                          __LINE__);
            return NCSCC_RC_FAILURE;
        }
        *add_flag = FALSE;
    }

    return NCSCC_RC_SUCCESS;
}
/****************************************************************************\
   PROCEDURE NAME :  mqd_red_db_node_add

   DESCRIPTION    :  This routines adds the Object node into the Tree
                   
   ARGUMENTS      :  pMqd  - MQD Controll block pointer
                     pNode - Nodeinfo Node 

   RETURNS        :  SUCCESS - All went well
                     FAILURE - internal processing didn't like something.
\****************************************************************************/
uns32 mqd_red_db_node_add(MQD_CB *pMqd, MQD_ND_DB_NODE *pNode)
{
	/*m_HTON_SANAMET_LEN(pNode->info.nodeid); */
	pNode->node.key_info = (uns8 *)&pNode->info.nodeid;
	return ncs_patricia_tree_add(&pMqd->node_db, (NCS_PATRICIA_NODE *)&pNode->node);
}	/* End of mqd_red_db_node_add() */
uns32 dta_reg_svc(NCS_BIND_SVC *bind_svc)
{
	DTA_CB *inst = &dta_cb;
	DTSV_MSG msg;
	REG_TBL_ENTRY *svc;
	/*uns32          send_pri; */
	SS_SVC_ID svc_id = bind_svc->svc_id;

	if (inst->created == FALSE) {
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
					  "dta_reg_svc: DTA does not exist. First create DTA before registering your service.",
					  svc_id);
	}

	if ((strlen(bind_svc->svc_name) + 1) > DTSV_SVC_NAME_MAX)
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
					  "dta_reg_svc: Service name supplied in registration is either too long or not properly initialized",
					  svc_id);

	m_DTA_LK(&inst->lock);

	/* Search the patricia tree for exisiting entries */
	/*if ((svc = (REG_TBL_ENTRY *) ncs_find_item(&inst->reg_tbl, 
	   (NCSCONTEXT)&svc_id, dta_match_service)) != NULL) */
	if ((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_reg_svc: Service is already registered with DTSv", svc_id);
	}

	svc = m_MMGR_ALLOC_DTA_REG_TBL;
	if (svc == NULL) {
		m_DTA_UNLK(&inst->lock);
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_reg_svc: Memory allocation failed", svc_id);
	}

	memset(svc, 0, sizeof(REG_TBL_ENTRY));
	svc->svc_id = svc_id;
	svc->log_msg = FALSE;
	svc->enable_log = TRUE;
	/* Restricting bufferring of logs till NOTICE level severity only */
	svc->severity_bit_map = 0xFC;
	svc->category_bit_map = 0xFFFFFFFF;
	svc->version = bind_svc->version;
	strcpy(svc->svc_name, bind_svc->svc_name);

	svc->node.key_info = (uns8 *)&svc->svc_id;

	/* Add to the patricia tree */
	if (ncs_patricia_tree_add(&inst->reg_tbl, (NCS_PATRICIA_NODE *)svc) != NCSCC_RC_SUCCESS) {
		m_MMGR_FREE_DTA_REG_TBL(svc);
		m_DTA_UNLK(&inst->lock);
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE,
					  "dta_reg_svc: Failed to add service registration entry in patricia tree",
					  svc_id);
	}

	/* 
	 * Check whether DTS exist. If DTS does not exist then we will send 
	 * registration information to DTS at later time when DTS comes up. 
	 * For buffering of log messages apply defaults and return success. 
	 */
	if (inst->dts_exist == FALSE) {
		m_DTA_UNLK(&inst->lock);
		return NCSCC_RC_SUCCESS;
	}

	memset(&msg, '\0', sizeof(DTSV_MSG));
	dta_fill_reg_msg(&msg, svc_id, svc->version, svc->svc_name, DTA_REGISTER_SVC);

	m_DTA_UNLK(&inst->lock);

	/* Always register async */
	if (dta_mds_async_send(&msg, inst) != NCSCC_RC_SUCCESS)
		return m_DTA_DBG_SINK_SVC(NCSCC_RC_FAILURE, "dta_reg_svc: MDS async send failed", svc_id);

	return NCSCC_RC_SUCCESS;
}
/****************************************************************************\
 * 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;
}
static void svctype_db_add(AVD_SVC_TYPE *svct)
{
	unsigned int rc = ncs_patricia_tree_add(&svctype_db, &svct->tree_node);
	assert (rc == NCSCC_RC_SUCCESS);
}
/******************************************************************************
  Name          : avnd_internode_comp_add
 
  Description   : This routine adds an internode component in 
                  internode_avail_comp_db.
 
  Arguments     : ptree   - ptr to the patricia tree of data base.
                  name    - ptr to the component name.
                  node id - node id of the component.
                  rc      - out param for operation result
                  pxy_for_ext_comp - Whether this is a proxy for external
                  component.
                  comp_is_proxy - Whether internode component is proxy or
                                  proxied. 1 is for proxy, 0 is for proxied.
 
  Return Values : Pointer to AVND_COMP data structure
 
  Notes         : None
******************************************************************************/
AVND_COMP *avnd_internode_comp_add(NCS_PATRICIA_TREE *ptree, SaNameT *name,
				   NODE_ID node_id, uns32 *rc, NCS_BOOL pxy_for_ext_comp, NCS_BOOL comp_is_proxy)
{
	AVND_COMP *comp = 0;

	*rc = SA_AIS_OK;

	/* verify if this component is already present in the db */
	if (NULL != (comp = m_AVND_COMPDB_REC_GET(*ptree, *name))) {
		/* This is a proxy and already proxying at least one component. 
		   So, no problem. */
		*rc = SA_AIS_ERR_EXIST;
		TRACE_1("avnd_internode_comp_add already exists. %s and NodeId:%u",
				      name->value, node_id);
		return comp;
	}

	/* a fresh comp... */
	comp = calloc(1, sizeof(AVND_COMP));
	if (!comp) {
		*rc = SA_AIS_ERR_NO_MEMORY;
		goto err;
	}

	/* update the comp-name (patricia key) */
	memcpy(&comp->name, name, sizeof(SaNameT));

	comp->pres = SA_AMF_PRESENCE_UNINSTANTIATED;

	if (0 == node_id) {
		/* This means this is an external component. */
		m_AVND_COMP_TYPE_SET_EXT_CLUSTER(comp);
	}

	m_AVND_COMP_TYPE_SET_INTER_NODE(comp);

	if (TRUE == pxy_for_ext_comp) {
		m_AVND_PROXY_FOR_EXT_COMP_SET(comp);
	}

	if (TRUE == comp_is_proxy) {
		m_AVND_COMP_TYPE_PROXY_SET(comp);
	} else if (FALSE == comp_is_proxy) {
		m_AVND_COMP_TYPE_PROXIED_SET(comp);
	}

	comp->node_id = node_id;

	/* initialize proxied list */
	avnd_pxied_list_init(comp);

	/* Add to the patricia tree. */
	comp->tree_node.bit = 0;
	comp->tree_node.key_info = (uns8 *)&comp->name;
	*rc = ncs_patricia_tree_add(ptree, &comp->tree_node);
	if (NCSCC_RC_SUCCESS != *rc) {
		*rc = SA_AIS_ERR_NO_MEMORY;
		goto err;
	}

	TRACE_1("avnd_internode_comp_add:%s nodeid:%u, pxy_for_ext_comp:%u,comp_is_proxy:%u",
			      comp->name.value, node_id, pxy_for_ext_comp, comp_is_proxy);
	return comp;

 err:

	if (comp) {
		avnd_comp_delete(comp);
	}

	LOG_ER("avnd_internode_comp_add failed.%s: NodeId:%u", name->value, node_id);
	return 0;

}
static void cstype_add_to_model(avd_cstype_t *cst)
{
	unsigned int rc = ncs_patricia_tree_add(&cstype_db, &cst->tree_node);
	assert(rc == NCSCC_RC_SUCCESS);
}
/****************************************************************************\
*  Name:          dts_apps_ascii_spec_load                                         * 
*                                                                            *
*  Description:   To load/unload the Application specific ASCII Spec table in DTS *  
*                                                                            *
*  Arguments:     uns8* - Name of the Configuration File                     *
*                 uns32 - what_to_do                                         *
*                          1 - REGISTER the ASCII Spec table                 *
*                          0 - UNREGISTER the ASCII spec table               *
*                                                                            * 
*  Returns:       NCSCC_RC_SUCCESS   - everything is OK                      *
*                 NCSCC_RC_FAILURE   -  failure                              *
\****************************************************************************/
uns32 dts_apps_ascii_spec_load(uns8 *file_name, uns32 what_to_do)
{
	/* get the instruments ready */
	FILE *fp = NULL;
	char lib_name[DTS_MAX_LIBNAME] = { 0 };
	char func_name[DTS_MAX_FUNCNAME] = { 0 };
	int32 nargs = 0;
	uns32 status = NCSCC_RC_SUCCESS;
	uns32 (*reg_unreg_routine) () = NULL;
	char *dl_error = NULL;
	NCS_LIB_REQ_INFO req_info;
	ASCII_SPEC_LIB *lib_entry;
	NCS_OS_DLIB_HDL *lib_hdl = NULL;
	char dbg_str[DTS_MAX_LIB_DBG];

	/* open the file */
	fp = fopen((char *)file_name, "r");
	if (fp == NULL) {
		/* inform that there is no such file, and return */
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_apps_ascii_spec_load: Unable to load the file");
	}

	/* continue till the you reach the end of the file */
	while (((nargs = fscanf(fp, "%s %s", lib_name, func_name)) == 2) && (nargs != EOF)) {
		/* Check if lib is already loaded or not */
		if ((lib_entry =
		     (ASCII_SPEC_LIB *)ncs_patricia_tree_get(&dts_cb.libname_asciispec_tree,
							     (const uns8 *)lib_name)) != NULL) {
			memset(func_name, 0, DTS_MAX_FUNCNAME);
			memset(lib_name, 0, DTS_MAX_LIBNAME);
			continue;
		}

		/* Load the library if REGISTRATION is to be peformed */
		if (what_to_do == 1) {
			lib_hdl = m_NCS_OS_DLIB_LOAD(lib_name, m_NCS_OS_DLIB_ATTR);
			if ((dl_error = m_NCS_OS_DLIB_ERROR()) != NULL) {
				/* log the error returned from dlopen() */
				m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_apps_ascii_spec_load: Unable to load library.");

				dts_log(NCSFL_SEV_ERROR, "\ndts_apps_ascii_spec_load(): m_NCS_OS_DLIB_LOAD() failed: %s\n", lib_name);
				reg_unreg_routine = NULL;
				lib_hdl = NULL;
				memset(func_name, 0, DTS_MAX_FUNCNAME);
				memset(lib_name, 0, DTS_MAX_LIBNAME);
				continue;
			}
		}

		/* load the symbol into DTS Engine process space */
		reg_unreg_routine = m_NCS_OS_DLIB_SYMBOL(lib_hdl, func_name);
		if ((dl_error = m_NCS_OS_DLIB_ERROR()) != NULL) {
			/* log the error returned from dlopen() */
			m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_apps_ascii_spec_load: Unable to load symbol");

			dts_log
			    (NCSFL_SEV_ERROR, "\ndts_apps_ascii_spec_load(): m_NCS_OS_DLIB_SYMBOL()  failed(lib name, func name, error): %s, %s, %s\n",
			     lib_name, func_name, dl_error);

			reg_unreg_routine = NULL;
			lib_hdl = NULL;
			memset(func_name, 0, DTS_MAX_FUNCNAME);
			memset(lib_name, 0, DTS_MAX_LIBNAME);
			continue;
		}

		/* do the INIT/DEINIT now... */
		if (reg_unreg_routine != NULL) {
			memset(&req_info, 0, sizeof(NCS_LIB_REQ_INFO));
			req_info.i_op = NCS_LIB_REQ_CREATE;

			/* do the registration */
			status = (*reg_unreg_routine) (&req_info);
			if (status != NCSCC_RC_SUCCESS) {
				/* log the error */
				sprintf(dbg_str, "ASCII spec registration failed for - %s", lib_name);
				m_LOG_DTS_DBGSTR_NAME(DTS_GLOBAL, dbg_str, 0, 0);
			} else {
				/* log the success, and the function name */
				/* Create patricia tree entry for ascii_spec lib name */
				lib_entry = m_MMGR_ALLOC_DTS_LIBNAME;
				if (lib_entry == NULL) {
					fclose(fp);
					return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
							      "dts_apps_ascii_spec_load: Memory allocation for patricia node failed");
				}
				memset(lib_entry, '\0', sizeof(ASCII_SPEC_LIB));
				strcpy((char *)lib_entry->lib_name, lib_name);
				lib_entry->libname_node.key_info = (uns8 *)lib_entry->lib_name;
				lib_entry->lib_hdl = lib_hdl;
				lib_entry->use_count++;
				/* Add node to patricia tree table */
				if (ncs_patricia_tree_add
				    (&dts_cb.libname_asciispec_tree,
				     (NCS_PATRICIA_NODE *)lib_entry) != NCSCC_RC_SUCCESS) {
					fclose(fp);
					m_MMGR_FREE_DTS_LIBNAME(lib_entry);
					return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
							      "dts_apps_ascii_spec_load: Failed to add node to paticia tree");
				}
			}	/*end of else */
		}
		/*end of if reg_unreg_routine != NULL */
		reg_unreg_routine = NULL;
		lib_hdl = NULL;
		memset(func_name, 0, DTS_MAX_FUNCNAME);
		memset(lib_name, 0, DTS_MAX_LIBNAME);

	}			/* for all the libraries  - end of while */

	if (nargs != EOF) {
		/* log the error */
		m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_apps_ascii_spec_load: Config file is corrupted.");

		/* set the return code */
		status = NCSCC_RC_FAILURE;
	}

	/* close the file */
	fclose(fp);
	return status;
}
/****************************************************************************\
   PROCEDURE NAME :  mqd_db_node_add

   DESCRIPTION    :  This routines adds the Object node into the Tree
                   
   ARGUMENTS      :  pMqd  - MQD Controll block pointer
                     pNode - Object Node 

   RETURNS        :  SUCCESS - All went well
                     FAILURE - internal processing didn't like something.
\****************************************************************************/
uns32 mqd_db_node_add(MQD_CB *pMqd, MQD_OBJ_NODE *pNode)
{
	/*m_HTON_SANAMET_LEN(pNode->oinfo.name.length); */
	pNode->node.key_info = (uns8 *)&pNode->oinfo.name;
	return ncs_patricia_tree_add(&pMqd->qdb, (NCS_PATRICIA_NODE *)&pNode->node);
}	/* End of mqd_db_node_add() */