Beispiel #1
0
/* signal from AMF, time to register with AMF */
void dts_amf_sigusr1_handler(int i_sig_num)
{
	DTS_CB *inst = &dts_cb;
	/* ignore the signal */
	signal(SIGUSR1, SIG_IGN);

	/* Just raise an indication on the selection object here */
	m_NCS_SEL_OBJ_IND(inst->sighdlr_sel_obj);

	/*if (NCSCC_RC_SUCCESS != dts_amf_init(inst))
	   {
	   return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_amf_sigusr1_handler: AMF Initialization failed.");
	   }

	   inst->amf_init = TRUE; */

}
Beispiel #2
0
/****************************************************************************
  Name          : lga_mds_svc_evt
 
  Description   : This is a callback routine that is invoked to inform LGA 
                  of MDS events. LGA had subscribed to these events during
                  through MDS subscription.
 
  Arguments     : pointer to struct ncsmds_callback_info
 
  Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
 
  Notes         : None.
******************************************************************************/
static uint32_t lga_mds_svc_evt(struct ncsmds_callback_info *mds_cb_info)
{
	TRACE_2("LGA Rcvd MDS subscribe evt from svc %d \n", mds_cb_info->info.svc_evt.i_svc_id);

	switch (mds_cb_info->info.svc_evt.i_change) {
	case NCSMDS_NO_ACTIVE:
	case NCSMDS_DOWN:
		if (mds_cb_info->info.svc_evt.i_svc_id == NCSMDS_SVC_ID_LGS) {
		/** TBD what to do if LGS goes down
                 ** Hold on to the subscription if possible
                 ** to send them out if LGS comes back up
                 **/
			TRACE("LGS down");
			pthread_mutex_lock(&lga_cb.cb_lock);
			memset(&lga_cb.lgs_mds_dest, 0, sizeof(MDS_DEST));
			lga_cb.lgs_up = 0;
			pthread_mutex_unlock(&lga_cb.cb_lock);
		}
		break;
	case NCSMDS_NEW_ACTIVE:
	case NCSMDS_UP:
		switch (mds_cb_info->info.svc_evt.i_svc_id) {
		case NCSMDS_SVC_ID_LGS:
		    /** Store the MDS DEST of the LGS 
                     **/
			TRACE_2("MSG from LGS NCSMDS_NEW_ACTIVE/UP");
			pthread_mutex_lock(&lga_cb.cb_lock);
			lga_cb.lgs_mds_dest = mds_cb_info->info.svc_evt.i_dest;
			lga_cb.lgs_up = 1;
			if (lga_cb.lgs_sync_awaited) {
				/* signal waiting thread */
				m_NCS_SEL_OBJ_IND(lga_cb.lgs_sync_sel);
			}
			pthread_mutex_unlock(&lga_cb.cb_lock);
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return NCSCC_RC_SUCCESS;
}
Beispiel #3
0
/***********************************************************************//**
* @brief	PLMA is informed when MDS events occur that he has 
*		subscribed to
*
* @param[in]	svc_evt - MDS Svc evt info.
*
* @return	NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
***************************************************************************/
static uint32_t plma_mds_svc_evt(MDS_CALLBACK_SVC_EVENT_INFO *svc_evt)
{
	uint32_t    rc = NCSCC_RC_SUCCESS;
	PLMA_CB *plma_cb = plma_ctrlblk;
	
	TRACE_ENTER();
	
	if (svc_evt->i_svc_id != NCSMDS_SVC_ID_PLMS) {
		return NCSCC_RC_SUCCESS;
	}
	switch(svc_evt->i_change)
        {
		case NCSMDS_RED_UP:
			break;
		case NCSMDS_NEW_ACTIVE:
			TRACE_5("Received NCSMDS_NEW_ACTIVE for PLMS");
		case NCSMDS_UP:
			TRACE_5("Received MDSUP EVT for PLMS");
                        m_NCS_LOCK(&plma_cb->cb_lock, NCS_LOCK_WRITE);
			plma_cb->plms_mdest_id = svc_evt->i_dest;
			plma_cb->plms_svc_up = true;
			if (plma_cb->plms_sync_awaited == true) {
				m_NCS_SEL_OBJ_IND(plma_cb->sel_obj);
			}
                        m_NCS_UNLOCK(&plma_cb->cb_lock, NCS_LOCK_WRITE);
			break;
		case NCSMDS_NO_ACTIVE:
			TRACE_5("Received NCSMDS_NO_ACTIVE for PLMS");
		case NCSMDS_DOWN:
			TRACE_5("Received MDSDOWN EVT for PLMS");
			plma_cb->plms_mdest_id = 0;
			plma_cb->plms_svc_up = false;
			break;
		default:
			TRACE_5("Received unknown event");
			break;
	}
	
	TRACE_LEAVE();
	
	return rc;
}
Beispiel #4
0
/****************************************************************************
 * Function Name: sysfTmrStart
 *
 * Purpose: Take the passed Timer traits and engage/register with TmrSvc
 *
 ****************************************************************************/
tmr_t ncs_tmr_start(tmr_t tid, uint32_t tmrDelay,	/* timer period in number of 10ms units */
		    TMR_CALLBACK tmrCB, void *tmrUarg, char *file, uint32_t line)
{
	SYSF_TMR *tmr;
	SYSF_TMR *new_tmr;
	uint64_t scaled;
	uint64_t temp_key_value;
	uint32_t rc = NCSCC_RC_SUCCESS;

	if (((tmr = (SYSF_TMR *)tid) == NULL) || (tmr_destroying == true))	/* NULL tmrs are no good! */
		return NULL;

	TMR_DBG_ASSERT_ISA(tmr->dbg);	/* confirm that its TMR memory */

	TMR_DBG_ASSERT_STATE(tmr, (TMR_STATE_DORMANT | TMR_STATE_CREATE));

	if (ncslpg_take(&gl_tcb.persist) == false)	/* guarentee persistence */
		return NULL;

	if (TMR_TEST_STATE(tmr, TMR_STATE_DORMANT)) {	/* If client is re-using timer */
		m_NCS_TMR_CREATE(new_tmr, tmrDelay, tmrCB, tmrUarg);	/* get a new one */
		if (new_tmr == NULL) {
			ncslpg_give(&gl_tcb.persist, 0);
			return NULL;
		}

		TMR_SET_STATE(tmr, TMR_STATE_DESTROY);	/* TmrSvc ignores 'old' one */
		tmr = new_tmr;
	}
	scaled = (tmrDelay * 10 / NCS_MILLISECONDS_PER_TICK) + 1 + (get_time_elapsed_in_ticks(&ts_start));

	/* Lock the enter wheel in the safe area */
	m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

	/* Do some up front initialization as if all will go well */
	tmr->tmrCB = tmrCB;
	tmr->tmrUarg = tmrUarg;
	TMR_SET_STATE(tmr, TMR_STATE_START);

	tmr->next = NULL;
	m_NCS_OS_HTONLL_P(&temp_key_value, scaled);
	tmr->key = temp_key_value;

	rc = ncs_tmr_add_pat_node(tmr);
	if (rc == NCSCC_RC_FAILURE) {
		/* Free the timer created */
		m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
		return NULL;
	}
#if ENABLE_SYSLOG_TMR_STATS
	gl_tcb.stats.cnt++;
	if (gl_tcb.stats.cnt == 1) {
		syslog(LOG_INFO, "At least one timer started\n");
	}
#endif
	if (gl_tcb.msg_count == 0) {
		/* There are no messages queued, we shall raise an indication
		   on the "sel_obj".  */
		if (m_NCS_SEL_OBJ_IND(&gl_tcb.sel_obj) != NCSCC_RC_SUCCESS) {
			/* We would never reach here! */
			m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
			m_LEAP_DBG_SINK_VOID;
			return NULL;
		}
	}
	gl_tcb.msg_count++;

	/*
	   1)Take Lock
	   2)Caliculate the key value based on (A+1)+T
	   T is Timer ticks elapsed  and A is ticks 
	   ncs_tmr_add_pat_node(root_node,tmr,(A+1)+T,)
	   3)See whether patricia Node is already present in patricia Tree with the 
	   caliculated Key 
	   If not present 
	   Create patricia Node and add it the patricia tree 
	   If present
	   Add the tmr data structure to the double linked list as FIFO.
	   i.e adds at the last of the double linked list.
	   4) Raise an indication on the selection object.
	   if (write(i_ind_obj.raise_obj, "A", 1) != 1)
	   return NCSCC_RC_FAILURE;
	 */

	TMR_STAT_STARTS(gl_tcb.stats);

	m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
	TMR_DBG_SET(tmr->dbg, file, line);

	ncslpg_give(&gl_tcb.persist, 0);

	return tmr;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/****************************************************************************
 * Function Name: ncs_tmr_wait
 *
 * Purpose: Goto counting semephore and block until tmr_pulse is felt. This
 *          means the actual expiry task no longer services the sysfTmrExpiry
 *          function any more. This should eliminate timer drift.
 *
 ****************************************************************************/
static uint32_t ncs_tmr_wait(void)
{

	unsigned rc;
	int inds_rmvd;

	uint64_t next_delay = 0;

	struct timeval tv = { 0xffffff, 0 };
	struct timespec ts_current = { 0, 0 };
	struct timespec ts;
	struct pollfd set;

	if (clock_gettime(CLOCK_MONOTONIC, &ts_start)) {
		perror("clock_gettime with MONOTONIC Failed \n");
		return NCSCC_RC_FAILURE;
	}

	ts_current = ts_start;

	while (true) {
		set.fd = m_GET_FD_FROM_SEL_OBJ(gl_tcb.sel_obj);
		set.events = POLLIN;
		osaf_timeval_to_timespec(&tv, &ts);
		rc = osaf_ppoll(&set, 1, next_delay != 0 ? &ts : NULL, NULL);
		m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

		if (rc == 1) {
			if (set.revents != POLLIN) osaf_abort(set.revents);

			/* if select returned because of indication on sel_obj from sysfTmrDestroy */
			if (tmr_destroying == true) {
				/* Raise An indication */
				m_NCS_SEL_OBJ_IND(&tmr_destroy_syn_obj);
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				return NCSCC_RC_SUCCESS;
			}

			gl_tcb.msg_count--;

			if (gl_tcb.msg_count == 0) {
				inds_rmvd = m_NCS_SEL_OBJ_RMV_IND(&gl_tcb.sel_obj, true, true);
				if (inds_rmvd <= 0) {
					if (inds_rmvd != -1) {
						/* The object has not been destroyed and it has no indication
						   raised on it inspite of msg_count being non-zero.
						 */
						m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
						return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
					}

					m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

					/* The mbox must have been destroyed */
					return NCSCC_RC_FAILURE;
				}
			}
		}

		rc = ncs_tmr_engine(&tv, &next_delay);
		if (rc == NCSCC_RC_FAILURE) {
			m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
			return NCSCC_RC_FAILURE;
		}

		m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
		ts_current.tv_sec = ts_current.tv_nsec = 0;

		if (clock_gettime(CLOCK_MONOTONIC, &ts_current)) {
			perror("clock_gettime with MONOTONIC Failed \n");
			return NCSCC_RC_FAILURE;
		}
	}

	return NCSCC_RC_SUCCESS;
}
Beispiel #7
0
/****************************************************************************
 * 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;
}
Beispiel #8
0
static uns32 mqa_mds_svc_evt(MQA_CB *cb, MDS_CALLBACK_SVC_EVENT_INFO *svc_evt)
{
	uns32 to_dest_slotid, o_msg_fmt_ver;

	/* TBD: The MQND and MQD restarts are to be implemented post April release */
	switch (svc_evt->i_change) {
	case NCSMDS_DOWN:
		switch (svc_evt->i_svc_id) {
		case NCSMDS_SVC_ID_MQND:

			cb->ver_mqnd[mqsv_get_phy_slot_id(svc_evt->i_dest)] = 0;

			m_LOG_MQSV_A(MQA_MQND_DOWN, NCSFL_LC_MQSV_INIT, NCSFL_SEV_NOTICE,
				     m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest), __FILE__, __LINE__);
			if (m_NCS_NODE_ID_FROM_MDS_DEST(cb->mqa_mds_dest) ==
			    m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest)) {
				cb->is_mqnd_up = FALSE;
			}
			break;
		case NCSMDS_SVC_ID_MQD:
			cb->is_mqd_up = FALSE;
			m_LOG_MQSV_A(MQA_MQD_DOWN, NCSFL_LC_MQSV_INIT, NCSFL_SEV_NOTICE, 0, __FILE__, __LINE__);
			break;

		default:
			break;
		}

		break;
	case NCSMDS_UP:
		switch (svc_evt->i_svc_id) {
		case NCSMDS_SVC_ID_MQND:
			to_dest_slotid = mqsv_get_phy_slot_id(svc_evt->i_dest);
			cb->ver_mqnd[to_dest_slotid] = svc_evt->i_rem_svc_pvt_ver;

			o_msg_fmt_ver = m_NCS_ENC_MSG_FMT_GET(svc_evt->i_rem_svc_pvt_ver,
							      MQA_WRT_MQND_SUBPART_VER_AT_MIN_MSG_FMT,
							      MQA_WRT_MQND_SUBPART_VER_AT_MAX_MSG_FMT,
							      mqa_mqnd_msg_fmt_table);

			if (!o_msg_fmt_ver)
				/*Log informing the existence of Non compatible MQND version, Slot id being logged */
				m_LOG_MQSV_A(MQA_MSG_FRMT_VER_INVALID, NCSFL_LC_MQSV_INIT,
					     NCSFL_SEV_ERROR, to_dest_slotid, __FILE__, __LINE__);

			if (m_NCS_NODE_ID_FROM_MDS_DEST(cb->mqa_mds_dest) ==
			    m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest)) {
				m_NCS_LOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE);

				cb->mqnd_mds_dest = svc_evt->i_dest;
				cb->is_mqnd_up = TRUE;

				if (cb->mqnd_sync_awaited == TRUE) {
					m_NCS_SEL_OBJ_IND(cb->mqnd_sync_sel);
				}

				m_NCS_UNLOCK(&cb->mqnd_sync_lock, NCS_LOCK_WRITE);
			}
			m_LOG_MQSV_A(MQA_MQND_UP, NCSFL_LC_MQSV_INIT, NCSFL_SEV_NOTICE,
				     m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest), __FILE__, __LINE__);
			break;

		case NCSMDS_SVC_ID_MQD:
			m_NCS_LOCK(&cb->mqd_sync_lock, NCS_LOCK_WRITE);

			to_dest_slotid = mqsv_get_phy_slot_id(svc_evt->i_dest);

			o_msg_fmt_ver = m_NCS_ENC_MSG_FMT_GET(svc_evt->i_rem_svc_pvt_ver,
							      MQA_WRT_MQD_SUBPART_VER_AT_MIN_MSG_FMT,
							      MQA_WRT_MQD_SUBPART_VER_AT_MAX_MSG_FMT,
							      mqa_mqd_msg_fmt_table);

			if (!o_msg_fmt_ver)
				/*Log informing the existence of Non compatible MQD version, Slot id being logged */
				m_LOG_MQSV_A(MQA_MSG_FRMT_VER_INVALID, NCSFL_LC_MQSV_INIT,
					     NCSFL_SEV_ERROR, to_dest_slotid, __FILE__, __LINE__);

			cb->mqd_mds_dest = svc_evt->i_dest;
			cb->is_mqd_up = TRUE;

			if (cb->mqd_sync_awaited == TRUE) {
				m_NCS_SEL_OBJ_IND(cb->mqd_sync_sel);
			}
			m_LOG_MQSV_A(MQA_MQD_UP, NCSFL_LC_MQSV_INIT, NCSFL_SEV_NOTICE, 0, __FILE__, __LINE__);

			m_NCS_UNLOCK(&cb->mqd_sync_lock, NCS_LOCK_WRITE);
			break;

		default:
			break;
		}
		break;
	default:
		break;
	}

	return NCSCC_RC_SUCCESS;
}
Beispiel #9
0
static uint32_t cpa_mds_svc_evt(CPA_CB *cb, MDS_CALLBACK_SVC_EVENT_INFO *svc_evt)
{
    SaCkptCheckpointHandleT  prev_ckpt_id=0;
    CPA_GLOBAL_CKPT_NODE *gc_node = NULL;
    uint32_t proc_rc = 0, i = 0, no_of_nodes = 0;
    uint32_t counter=cb->gbl_ckpt_tree.n_nodes;
    CPSV_EVT send_evt;
    CPSV_REF_CNT   ref_cnt_array[100];
	
	TRACE_ENTER2("EventType = %d, service id = %d",svc_evt->i_change, svc_evt->i_svc_id);

	/* TBD: The CPND and CPD restarts are to be implemented post April release */
	switch (svc_evt->i_change) {
	case NCSMDS_DOWN:
		switch (svc_evt->i_svc_id) {
		case NCSMDS_SVC_ID_CPND:
			if (m_NCS_GET_NODE_ID == m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest)) {
				m_NCS_LOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
				cb->is_cpnd_up = false;
				m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
			}
			break;
		default:
			break;
		}

		break;
	case NCSMDS_UP:
		switch (svc_evt->i_svc_id) {
		case NCSMDS_SVC_ID_CPND:

			/* get the node_id and compare with the node_id of the mdest */
			if (m_NCS_GET_NODE_ID == m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest)) {
				m_NCS_LOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
				cb->is_cpnd_up = true;
				cb->cpnd_mds_dest = svc_evt->i_dest;
				if (cb->cpnd_sync_awaited == true) {
					m_NCS_SEL_OBJ_IND(cb->cpnd_sync_sel);
				}
		
           /* Get the First Node */
           gc_node = (CPA_GLOBAL_CKPT_NODE *)ncs_patricia_tree_getnext(&cb->gbl_ckpt_tree,
                                           (uint8_t*)&prev_ckpt_id);
           if(gc_node) 
           {
            for(i=0;i<counter;i++) 
             {
                prev_ckpt_id = gc_node->gbl_ckpt_hdl;
                if(gc_node->ref_cnt > 1)
                {
              	  ref_cnt_array[no_of_nodes].ckpt_ref_cnt= gc_node->ref_cnt - 1;
              	  ref_cnt_array[no_of_nodes].ckpt_id = gc_node->gbl_ckpt_hdl;
                  no_of_nodes++;
                }
                gc_node = (CPA_GLOBAL_CKPT_NODE *)ncs_patricia_tree_getnext(&cb->gbl_ckpt_tree,
                                                        (uint8_t*)&prev_ckpt_id);
             }  

               memset(&send_evt, 0, sizeof(CPSV_EVT));
               send_evt.type = CPSV_EVT_TYPE_CPND;
               send_evt.info.cpnd.type = CPND_EVT_A2ND_CKPT_REFCNTSET;
               memcpy(send_evt.info.cpnd.info.refCntsetReq.ref_cnt_array,ref_cnt_array,no_of_nodes*sizeof(CPSV_REF_CNT));
           
               send_evt.info.cpnd.info.refCntsetReq.no_of_nodes = no_of_nodes;
         
               proc_rc = cpa_mds_msg_send(cb->cpa_mds_hdl,&cb->cpnd_mds_dest,&send_evt,NCSMDS_SVC_ID_CPND);
    
               switch (proc_rc)
               {
                 case NCSCC_RC_SUCCESS:
                      break;
                 case NCSCC_RC_REQ_TIMOUT:
			TRACE_4("cpa api failed for active ckpt info bcase :MDS with return value:%d for mds dest :%"PRIu64,
				proc_rc ,cb->cpnd_mds_dest);
			break;
                 default:
			TRACE_4("cpa api failed for active ckpt info bcase:MDS with return value:%d for mds dest:%"PRIu64,
				proc_rc ,cb->cpnd_mds_dest);
			break;
               }
           } 

	   /* loop  the Lcl Checkpoint Details */
	   TRACE("Number of nodes in Lcl CKPT Tree:  %d", cb->lcl_ckpt_tree.n_nodes);
	   SaCkptCheckpointHandleT  prev_ckpt_id=0;
	   CPA_LOCAL_CKPT_NODE *lc_node;
	   CPSV_EVT evt;
	   /* Get the First Node */
	   lc_node = (CPA_LOCAL_CKPT_NODE *)ncs_patricia_tree_getnext(&cb->lcl_ckpt_tree,
			   (uint8_t *)&prev_ckpt_id);
	   while (lc_node) {
		   prev_ckpt_id = lc_node->lcl_ckpt_hdl;

		   /* Populate & Send the Open Event to CPND */
		   memset(&evt, 0, sizeof(CPSV_EVT));
		   evt.type = CPSV_EVT_TYPE_CPND;
		   evt.info.cpnd.type = CPND_EVT_A2ND_CKPT_LIST_UPDATE;
		   evt.info.cpnd.info.ckptListUpdate.client_hdl = lc_node->cl_hdl; 
		   evt.info.cpnd.info.ckptListUpdate.ckpt_name = lc_node->ckpt_name ;

		   proc_rc = cpa_mds_msg_send(cb->cpa_mds_hdl, &cb->cpnd_mds_dest, &evt, NCSMDS_SVC_ID_CPND);

		   TRACE("------------------------------------------------------");
		   TRACE(" Lcl CKPT Hdl:  = %d", (uint32_t)lc_node->lcl_ckpt_hdl);
		   TRACE(" Client CKPT Hdl:  = %d", (uint32_t)lc_node->cl_hdl);
		   TRACE(" Global CKPT Hdl:  = %d", (uint32_t)lc_node->gbl_ckpt_hdl);
		   TRACE(" Open Flags:  = %d", (uint32_t)lc_node->open_flags);
		   if (lc_node->async_req_tmr.is_active)
			   TRACE("Timer Type %d is active", lc_node->async_req_tmr.type);
		   else
			   TRACE(" Timer is not active");

		   TRACE(" End of Local CKPT Info");
		   TRACE("------------------------------------------------------");

		   lc_node = (CPA_LOCAL_CKPT_NODE *)ncs_patricia_tree_getnext(&cb->lcl_ckpt_tree,
				   (uint8_t *)&prev_ckpt_id);
	   }
	   TRACE(" End of Local CKPT nodes information ");
	   m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
         }
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
	TRACE_LEAVE();
	return NCSCC_RC_SUCCESS;
}
Beispiel #10
0
static uns32 cpa_mds_svc_evt(CPA_CB *cb, MDS_CALLBACK_SVC_EVENT_INFO *svc_evt)
{
    SaCkptCheckpointHandleT  prev_ckpt_id=0;
    CPA_GLOBAL_CKPT_NODE *gc_node = NULL;
    uns32 proc_rc = 0, i = 0, no_of_nodes = 0;
    uns32 counter=cb->gbl_ckpt_tree.n_nodes;
    CPSV_EVT send_evt;
    CPSV_REF_CNT   ref_cnt_array[100];

	/* TBD: The CPND and CPD restarts are to be implemented post April release */
	switch (svc_evt->i_change) {
	case NCSMDS_DOWN:
		switch (svc_evt->i_svc_id) {
		case NCSMDS_SVC_ID_CPND:
			if (m_NCS_GET_NODE_ID == m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest)) {
				m_NCS_LOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
				cb->is_cpnd_up = FALSE;
				m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
			}
			break;
		default:
			break;
		}

		break;
	case NCSMDS_UP:
		switch (svc_evt->i_svc_id) {
		case NCSMDS_SVC_ID_CPND:

			/* get the node_id and compare with the node_id of the mdest */
			if (m_NCS_GET_NODE_ID == m_NCS_NODE_ID_FROM_MDS_DEST(svc_evt->i_dest)) {
				m_NCS_LOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
				cb->is_cpnd_up = TRUE;
				cb->cpnd_mds_dest = svc_evt->i_dest;
				if (cb->cpnd_sync_awaited == TRUE) {
					m_NCS_SEL_OBJ_IND(cb->cpnd_sync_sel);
				}
				m_NCS_UNLOCK(&cb->cpnd_sync_lock, NCS_LOCK_WRITE);
           /* Get the First Node */
           gc_node = (CPA_GLOBAL_CKPT_NODE *)ncs_patricia_tree_getnext(&cb->gbl_ckpt_tree,
                                           (uns8*)&prev_ckpt_id);
           if(gc_node) 
           {
            for(i=0;i<counter;i++) 
             {
                prev_ckpt_id = gc_node->gbl_ckpt_hdl;
                if(gc_node->ref_cnt > 1)
                {
              	  ref_cnt_array[no_of_nodes].ckpt_ref_cnt= gc_node->ref_cnt - 1;
              	  ref_cnt_array[no_of_nodes].ckpt_id = gc_node->gbl_ckpt_hdl;
                  no_of_nodes++;
                }
                gc_node = (CPA_GLOBAL_CKPT_NODE *)ncs_patricia_tree_getnext(&cb->gbl_ckpt_tree,
                                                        (uns8*)&prev_ckpt_id);
             }  

               memset(&send_evt, 0, sizeof(CPSV_EVT));
               send_evt.type = CPSV_EVT_TYPE_CPND;
               send_evt.info.cpnd.type = CPND_EVT_A2ND_CKPT_REFCNTSET;
               memcpy(send_evt.info.cpnd.info.refCntsetReq.ref_cnt_array,ref_cnt_array,no_of_nodes*sizeof(CPSV_REF_CNT));
           
               send_evt.info.cpnd.info.refCntsetReq.no_of_nodes = no_of_nodes;
         
               proc_rc = cpa_mds_msg_send(cb->cpa_mds_hdl,&cb->cpnd_mds_dest,&send_evt,NCSMDS_SVC_ID_CPND);
    
               switch (proc_rc)
               {
                 case NCSCC_RC_SUCCESS:
                      break;
                 case NCSCC_RC_REQ_TIMOUT:
                      m_LOG_CPA_CCLLFF(CPA_API_FAILED, NCSFL_LC_CKPT_MGMT, NCSFL_SEV_ERROR,
                                               "active_ckpt_info_bcast :MDS", __FILE__ ,__LINE__, proc_rc ,0, cb->cpnd_mds_dest);
                      break;
                 default:
                      m_LOG_CPA_CCLLFF(CPA_API_FAILED, NCSFL_LC_CKPT_MGMT, NCSFL_SEV_ERROR,
                                                "active_ckpt_info_bcast:MDS", __FILE__ ,__LINE__, proc_rc ,0, cb->cpnd_mds_dest);
                      break;
               }
           } 
         }
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return NCSCC_RC_SUCCESS;
}
Beispiel #11
0
/****************************************************************************
 * Function Name: ncs_tmr_wait
 *
 * Purpose: Goto counting semephore and block until tmr_pulse is felt. This
 *          means the actual expiry task no longer services the sysfTmrExpiry
 *          function any more. This should eliminate timer drift.
 *
 ****************************************************************************/
static uns32 ncs_tmr_wait(void)
{

	int rc = 0;
	int inds_rmvd;
	int save_errno = 0;

	uns64 next_delay = 0;

	NCS_SEL_OBJ mbx_fd = gl_tcb.sel_obj;
	NCS_SEL_OBJ highest_sel_obj;
	NCS_SEL_OBJ_SET all_sel_obj;
	struct timeval tv = { 0xffffff, 0 };
	struct timespec ts_current = { 0, 0 };

	m_NCS_SEL_OBJ_ZERO(&all_sel_obj);
	highest_sel_obj = mbx_fd;

	if (clock_gettime(CLOCK_MONOTONIC, &ts_start)) {
		perror("clock_gettime with MONOTONIC Failed \n");
		return NCSCC_RC_FAILURE;
	}

	ts_current = ts_start;

	while (TRUE) {
 select_sleep:
		m_NCS_SEL_OBJ_SET(mbx_fd, &all_sel_obj);
		rc = select(highest_sel_obj.rmv_obj + 1, &all_sel_obj, NULL, NULL, &tv);
		save_errno = errno;
		m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

		if (rc < 0) {
			if (save_errno != EINTR)
				assert(0);

			if (ncs_tmr_select_intr_process(&tv, &ts_current, next_delay) == NCSCC_RC_SUCCESS) {
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				goto select_sleep;
			} else {
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				return NCSCC_RC_FAILURE;
			}
		} else if (rc == 1) {
			/* if select returned because of indication on sel_obj from sysfTmrDestroy */
			if (tmr_destroying == TRUE) {
				/* Raise An indication */
				m_NCS_SEL_OBJ_IND(tmr_destroy_syn_obj);
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				return NCSCC_RC_SUCCESS;
			}

			gl_tcb.msg_count--;

			if (gl_tcb.msg_count == 0) {
				inds_rmvd = m_NCS_SEL_OBJ_RMV_IND(gl_tcb.sel_obj, TRUE, TRUE);
				if (inds_rmvd <= 0) {
					if (inds_rmvd != -1) {
						/* The object has not been destroyed and it has no indication
						   raised on it inspite of msg_count being non-zero.
						 */
						m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
						return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
					}

					m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

					/* The mbox must have been destroyed */
					return NCSCC_RC_FAILURE;
				}
			}
		}

		rc = ncs_tmr_engine(&tv, &next_delay);
		if (rc == NCSCC_RC_FAILURE) {
			m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
			return NCSCC_RC_FAILURE;
		}

		m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
		ts_current.tv_sec = ts_current.tv_nsec = 0;

		if (clock_gettime(CLOCK_MONOTONIC, &ts_current)) {
			perror("clock_gettime with MONOTONIC Failed \n");
			return NCSCC_RC_FAILURE;
		}
	}

	return NCSCC_RC_SUCCESS;
}