/******************************************************************** * Name : cpd_cpnd_dest_replace * * Description : To replace the old Dest info with the new Dest info when ND goes down * * Arguments : CPD_CKPT_REF_INFO - ckpt reference info , CPSV_MDS_INFO - mds info * * Return Values: Success / Error * ********************************************************************************/ static uns32 cpd_cpnd_dest_replace(CPD_CB *cb, CPD_CKPT_REF_INFO *cref_info, CPSV_MDS_INFO *mds_info) { CPD_CKPT_INFO_NODE *cp_node = NULL; CPD_NODE_REF_INFO *nref_info = NULL; uns32 rc = NCSCC_RC_SUCCESS; while (cref_info) { cp_node = cref_info->ckpt_node; if (m_CPND_NODE_ID_CMP (m_NCS_NODE_ID_FROM_MDS_DEST(cp_node->active_dest), m_NCS_NODE_ID_FROM_MDS_DEST(mds_info->dest))) { cp_node->active_dest = mds_info->dest; } nref_info = cp_node->node_list; while (nref_info) { if (m_CPND_NODE_ID_CMP (m_NCS_NODE_ID_FROM_MDS_DEST(nref_info->dest), m_NCS_NODE_ID_FROM_MDS_DEST(mds_info->dest))) { nref_info->dest = mds_info->dest; } nref_info = nref_info->next; } cref_info = cref_info->next; } return rc; }
/****************************************************************************\ PROCEDURE NAME : mqd_nd_status_evt_process DESCRIPTION : This routine process the MQND status event. ARGUMENTS : pMqd - MQD Control block pointer nd_info - ND information RETURNS : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE \*****************************************************************************/ static uns32 mqd_nd_status_evt_process(MQD_CB *pMqd, MQD_ND_STATUS_INFO *nd_info) { uns32 rc = NCSCC_RC_SUCCESS; void *ptr = 0; MQD_ND_DB_NODE *pNdNode = 0; SaTimeT timeout = m_NCS_CONVERT_SATIME_TO_TEN_MILLI_SEC(MQD_ND_EXPIRY_TIME_STANDBY); NODE_ID node_id = 0; MQD_A2S_MSG msg; TRACE("MQND status:MDS EVT :processing %d", m_NCS_NODE_ID_FROM_MDS_DEST(nd_info->dest)); /* Process MQND Related events */ if (nd_info->is_up == FALSE) { pNdNode = m_MMGR_ALLOC_MQD_ND_DB_NODE; if (pNdNode == NULL) { rc = NCSCC_RC_FAILURE; m_LOG_MQSV_D(MQD_MEMORY_ALLOC_FAIL, NCSFL_LC_MQSV_INIT, NCSFL_SEV_ERROR, rc, __FILE__, __LINE__); return rc; } memset(pNdNode, 0, sizeof(MQD_ND_DB_NODE)); pNdNode->info.nodeid = m_NCS_NODE_ID_FROM_MDS_DEST(nd_info->dest); pNdNode->info.is_restarted = FALSE; pNdNode->info.timer.type = MQD_ND_TMR_TYPE_EXPIRY; pNdNode->info.timer.tmr_id = 0; pNdNode->info.timer.nodeid = pNdNode->info.nodeid; pNdNode->info.timer.uarg = pMqd->hdl; pNdNode->info.timer.is_active = FALSE; mqd_red_db_node_add(pMqd, pNdNode); mqd_tmr_start(&pNdNode->info.timer, timeout); if (pMqd->ha_state == SA_AMF_HA_ACTIVE) mqd_nd_down_update_info(pMqd, nd_info->dest); TRACE("MDS DOWN PROCESSED ON %d DONE", pMqd->ha_state); } else { node_id = m_NCS_NODE_ID_FROM_MDS_DEST(nd_info->dest); pNdNode = (MQD_ND_DB_NODE *)ncs_patricia_tree_get(&pMqd->node_db, (uns8 *)&node_id); if (pNdNode) { mqd_tmr_stop(&pNdNode->info.timer); pNdNode->info.is_restarted = TRUE; pNdNode->info.dest = nd_info->dest; if (pMqd->ha_state == SA_AMF_HA_ACTIVE) { mqd_red_db_node_del(pMqd, pNdNode); mqd_nd_restart_update_dest_info(pMqd, nd_info->dest); /* Send an async update event to standby MQD */ memset(&msg, 0, sizeof(MQD_A2S_MSG)); msg.type = MQD_A2S_MSG_TYPE_MQND_STATEVT; msg.info.nd_stat_evt.nodeid = m_NCS_NODE_ID_FROM_MDS_DEST(nd_info->dest); msg.info.nd_stat_evt.is_restarting = nd_info->is_up; msg.info.nd_stat_evt.downtime = nd_info->event_time; ptr = &(msg.info.nd_stat_evt); mqd_a2s_async_update(pMqd, MQD_A2S_MSG_TYPE_MQND_STATEVT, (void *)(&msg.info.nd_stat_evt)); } } TRACE("MDS UP PROCESSED ON %d DONE", pMqd->ha_state); } return rc; }
/**************************************************************************** Name : immd_immnd_info_node_find_add Description : This routine adds the new node to immnd_tree. Arguments : immnd_tree - IMMND Tree. immnd_info_node - IMMND Node. Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE *****************************************************************************/ uns32 immd_immnd_info_node_find_add(NCS_PATRICIA_TREE *immnd_tree, MDS_DEST *dest, IMMD_IMMND_INFO_NODE **immnd_info_node, NCS_BOOL *add_flag) { NODE_ID key; memset(&key, 0, sizeof(NODE_ID)); /* Fill the Key */ key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest)); *immnd_info_node = (IMMD_IMMND_INFO_NODE *) ncs_patricia_tree_get(immnd_tree, (uns8 *)&key); if ((*immnd_info_node == NULL) && (*add_flag == TRUE)) { *immnd_info_node = calloc(1, sizeof(IMMD_IMMND_INFO_NODE)); if (*immnd_info_node == NULL) { LOG_ER("IMMD - calloc returned NULL"); return NCSCC_RC_FAILURE; } (*immnd_info_node)->immnd_dest = *dest; (*immnd_info_node)->immnd_key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest)); (*immnd_info_node)->patnode.key_info = (uns8 *)&((*immnd_info_node)->immnd_key); if (ncs_patricia_tree_add(immnd_tree, &(*immnd_info_node)->patnode) != NCSCC_RC_SUCCESS) { LOG_ER("ncs_patricia_tree_add FAILED"); free(*immnd_info_node); *immnd_info_node = NULL; return NCSCC_RC_FAILURE; } *add_flag = FALSE; } return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_rsc_set_orphan * * Description : Instruction from the GLND to set the orphan flag * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t gld_rsc_set_orphan(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details; uint32_t node_id; uint32_t rc = NCSCC_RC_FAILURE; TRACE_ENTER(); node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); 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) { LOG_ER("Event from unknown glnd: node_id %u", node_id); goto end; } TRACE("EVT Processing set orphan: node_id %u ", node_details->node_id); if (gld_rsc_ref_set_orphan (node_details, evt->info.rsc_details.rsc_id, evt->info.rsc_details.orphan, evt->info.rsc_details.lck_mode) == NCSCC_RC_SUCCESS) { /* Checkpoint rsc_details */ glsv_gld_a2s_ckpt_rsc_details(gld_cb, evt->evt_type, evt->info.rsc_details, node_details->dest_id, evt->info.rsc_details.lcl_ref_cnt); rc = NCSCC_RC_SUCCESS; } end: TRACE_LEAVE(); return rc; }
/**************************************************************************** * 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(uns32) }; /* Need to add the node details */ node_details = m_MMGR_ALLOC_GLSV_GLD_GLND_DETAILS; if (node_details == NULL) { m_LOG_GLD_MEMFAIL(GLD_NODE_DETAILS_ALLOC_FAILED, __FILE__, __LINE__); return NULL; } 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; m_LOG_GLD_EVT(GLD_EVT_MDS_GLND_UP, NCSFL_SEV_NOTICE, __FILE__, __LINE__, 0, node_details->node_id); /* Initialize the pat tree for resource info */ if ((ncs_patricia_tree_init(&node_details->rsc_info_tree, ¶ms)) != NCSCC_RC_SUCCESS) { m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_INIT_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__, 0); m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details); return NULL; } node_details->pat_node.key_info = (uns8 *)&node_details->node_id; if (ncs_patricia_tree_add(&gld_cb->glnd_details, &node_details->pat_node) != NCSCC_RC_SUCCESS) { m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_ADD_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__, 0); m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details); return NULL; } return node_details; }
/**************************************************************************** Name : avnd_snd_shutdown_app_su_msg Description : This routine sends the response to AVD for shutdown application SUs msg. Arguments : cb - ptr to the AvND control block Return Values : None. Notes : MARK the node_state as shutting down before invoking this function so we have the context what to do when we get the event "last step of termination". ******************************************************************************/ void avnd_snd_shutdown_app_su_msg(AVND_CB *cb) { AVND_MSG msg; uns32 rc = NCSCC_RC_SUCCESS; memset(&msg, 0, sizeof(AVND_MSG)); msg.info.avd = calloc(1, sizeof(AVSV_DND_MSG)); if (!msg.info.avd) { rc = NCSCC_RC_FAILURE; goto done; } msg.type = AVND_MSG_AVD; msg.info.avd->msg_type = AVSV_N2D_SHUTDOWN_APP_SU_MSG; msg.info.avd->msg_info.n2d_shutdown_app_su.msg_id = ++(cb->snd_msg_id); msg.info.avd->msg_info.n2d_shutdown_app_su.node_id = m_NCS_NODE_ID_FROM_MDS_DEST(cb->avnd_dest); rc = avnd_di_msg_send(cb, &msg); if (NCSCC_RC_SUCCESS == rc) msg.info.avd = 0; /* free the contents of avnd message */ avnd_msg_content_free(cb, &msg); done: return; }
/**************************************************************************** Name : avnd_evt_mds_avd_up Description : This routine processes the AvD up event from MDS. It sends the node-up message to AvD. it also starts AvD supervision we are on a controller and the up event is for our node. Arguments : cb - ptr to the AvND control block evt - ptr to the AvND event Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : None. ******************************************************************************/ uns32 avnd_evt_mds_avd_up_evh(AVND_CB *cb, AVND_EVT *evt) { TRACE_ENTER2("%llx", evt->info.mds.mds_dest); /* Validate whether this is a ADEST or VDEST */ if (m_MDS_DEST_IS_AN_ADEST(evt->info.mds.mds_dest)) { NCS_NODE_ID node_id, my_node_id = ncs_get_node_id(); node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.mds.mds_dest); if ((node_id == my_node_id) && (cb->type == AVSV_AVND_CARD_SYS_CON)) { TRACE("Starting hb supervision of local avd"); avnd_stop_tmr(cb, &cb->hb_duration_tmr); avnd_start_tmr(cb, &cb->hb_duration_tmr, AVND_TMR_HB_DURATION, cb->hb_duration, 0); } } else { /* Avd is already UP, reboot the node */ if (m_AVND_CB_IS_AVD_UP(cb)) { opensaf_reboot(avnd_cb->node_info.nodeId, (char *)avnd_cb->node_info.executionEnvironment.value, "AVD already up"); goto done; } m_AVND_CB_AVD_UP_SET(cb); /* store the AVD MDS address */ cb->avd_dest = evt->info.mds.mds_dest; avnd_send_node_up_msg(); } done: TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
/****************************************************************************** Name : avnd_nodeid_mdsdest_rec_del Description : This routine delete 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_del(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 doesn't exist, Rec del failed: MdsDest:%lld NodeId:%u", mds_dest, node_id); return NCSCC_RC_FAILURE; } else { res = ncs_patricia_tree_del(&cb->nodeid_mdsdest_db, &rec->tree_node); if (NCSCC_RC_SUCCESS != res) { LOG_ER("Couldn't del nodeid_mdsdest rec, patricia del failed: MdsDest:%lld,NodeId:%u, res%u", mds_dest, node_id, res); return res; } } /* Else of if(rec == NULL) */ free(rec); return res; }
/**************************************************************************** * Name : gld_rsc_set_orphan * * Description : Instruction from the GLND to set the orphan flag * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uns32 gld_rsc_set_orphan(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details; uns32 node_id; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); 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) { m_LOG_GLD_HEADLINE(GLD_UNKNOWN_GLND_EVT, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id); return NCSCC_RC_FAILURE; } m_LOG_GLD_EVT(GLD_EVT_SET_ORPHAN, NCSFL_SEV_INFO, __FILE__, __LINE__, 0, node_details->node_id); if (gld_rsc_ref_set_orphan (node_details, evt->info.rsc_details.rsc_id, evt->info.rsc_details.orphan, evt->info.rsc_details.lck_mode) == NCSCC_RC_SUCCESS) { /* Checkpoint rsc_details */ glsv_gld_a2s_ckpt_rsc_details(gld_cb, evt->evt_type, evt->info.rsc_details, node_details->dest_id, evt->info.rsc_details.lcl_ref_cnt); return NCSCC_RC_SUCCESS; } else return NCSCC_RC_FAILURE; }
/****************************************************************************\ PROCEDURE NAME : mqd_timer_expiry_evt_process DESCRIPTION : This routine process the comp specific message. ARGUMENTS : pMqd - MQD Control block pointer nodeid - NODE ID RETURNS : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE \*****************************************************************************/ uns32 mqd_timer_expiry_evt_process(MQD_CB *pMqd, NODE_ID *nodeid) { MQD_ND_DB_NODE *pNdNode = 0; MQD_OBJ_NODE *pNode = 0; MQD_A2S_MSG msg; uns32 rc = NCSCC_RC_SUCCESS; m_LOG_MQSV_D(MQD_TMR_EXPIRED, NCSFL_LC_TIMER, NCSFL_SEV_NOTICE, NCS_PTR_TO_UNS32_CAST(nodeid), __FILE__, __LINE__); pNdNode = (MQD_ND_DB_NODE *)ncs_patricia_tree_get(&pMqd->node_db, (uns8 *)nodeid); /* We need to scan the entire database and remove the track inforamtion * pertaining to the user */ if (pNdNode == NULL) { rc = NCSCC_RC_FAILURE; return rc; } if (pMqd->ha_state == SA_AMF_HA_ACTIVE) { if (pNdNode->info.timer.tmr_id != TMR_T_NULL) { m_NCS_TMR_DESTROY(pNdNode->info.timer.tmr_id); pNdNode->info.timer.tmr_id = TMR_T_NULL; } pNode = (MQD_OBJ_NODE *)ncs_patricia_tree_getnext(&pMqd->qdb, (uns8 *)0); while (pNode) { ASAPi_DEREG_INFO dereg; SaNameT name; memset(&dereg, 0, sizeof(ASAPi_DEREG_INFO)); name = pNode->oinfo.name; if (m_NCS_NODE_ID_FROM_MDS_DEST(pNode->oinfo.info.q.dest) == pNdNode->info.nodeid) { dereg.objtype = ASAPi_OBJ_QUEUE; dereg.queue = pNode->oinfo.name; rc = mqd_asapi_dereg_hdlr(pMqd, &dereg, NULL); } pNode = (MQD_OBJ_NODE *)ncs_patricia_tree_getnext(&pMqd->qdb, (uns8 *)&name); } /* Send an async Update to the standby */ memset(&msg, 0, sizeof(MQD_A2S_MSG)); msg.type = MQD_A2S_MSG_TYPE_MQND_TIMER_EXPEVT; msg.info.nd_tmr_exp_evt.nodeid = pNdNode->info.nodeid; /* Send async update to the standby for MQD redundancy */ mqd_a2s_async_update(pMqd, MQD_A2S_MSG_TYPE_MQND_TIMER_EXPEVT, (void *)(&msg.info.nd_tmr_exp_evt)); if (pNdNode) mqd_red_db_node_del(pMqd, pNdNode); TRACE("MQND TMR EXPIRY PROCESSED ON ACTIVE"); } else if (pMqd->ha_state == SA_AMF_HA_STANDBY) { pNdNode->info.timer.is_expired = TRUE; TRACE("MQND TMR EXPIRY PROCESSED ON STANDBY"); } return rc; } /* End of mqd_timer_expiry_evt_process() */
NCS_PHY_SLOT_ID mqsv_get_phy_slot_id(MDS_DEST dest) { NCS_PHY_SLOT_ID phy_slot; NCS_SUB_SLOT_ID sub_slot; m_NCS_GET_PHYINFO_FROM_NODE_ID(m_NCS_NODE_ID_FROM_MDS_DEST(dest), NULL, &phy_slot, &sub_slot); return ((sub_slot * NCS_SUB_SLOT_MAX) + phy_slot); }
/***************************************************************************** Name : immd_get_slot_and_subslot_id_from_mds_dest Description : To get the physical slot & subslot unique id from the mds_dest Arguments : *****************************************************************************/ uns32 immd_get_slot_and_subslot_id_from_mds_dest(MDS_DEST dest) { NCS_PHY_SLOT_ID phy_slot; NCS_SUB_SLOT_ID sub_slot; m_NCS_GET_PHYINFO_FROM_NODE_ID(m_NCS_NODE_ID_FROM_MDS_DEST(dest), NULL, &phy_slot, &sub_slot); return ((sub_slot * NCS_SUB_SLOT_MAX) + (phy_slot)); }
/**************************************************************************** * Name : cpnd_down_process * * Description : This function is invoked when cpnd is down * * Arguments : CPSV_MDS_INFO - mds_info , CPD_CPND_INFO_NODE - cpnd info * * Return Values : Success / Error * * Notes: 1. Start the Retention timer * 2. If that ND contains Active Replica , then send RESTART event to other NDs * 3. If that ND does not contain Active Replica, send REP_DEL event to other NDs * ***************************************************************************/ static uns32 cpnd_down_process(CPD_CB *cb, CPSV_MDS_INFO *mds_info, CPD_CPND_INFO_NODE *cpnd_info) { CPD_CKPT_REF_INFO *cref_info; CPSV_EVT send_evt; uns32 proc_rc = NCSCC_RC_SUCCESS; cpnd_info->cpnd_ret_timer.type = CPD_TMR_TYPE_CPND_RETENTION; cpnd_info->cpnd_ret_timer.info.cpnd_dest = mds_info->dest; cpd_tmr_start(&cpnd_info->cpnd_ret_timer, CPD_CPND_DOWN_RETENTION_TIME); cref_info = cpnd_info->ckpt_ref_list; while (cref_info) { if (m_CPD_IS_LOCAL_NODE (m_NCS_NODE_ID_FROM_MDS_DEST(cref_info->ckpt_node->active_dest), m_NCS_NODE_ID_FROM_MDS_DEST(cpnd_info->cpnd_ret_timer.info.cpnd_dest))) { memset(&send_evt, 0, sizeof(CPSV_EVT)); send_evt.type = CPSV_EVT_TYPE_CPND; send_evt.info.cpnd.type = CPSV_D2ND_RESTART; send_evt.info.cpnd.info.cpnd_restart.ckpt_id = cref_info->ckpt_node->ckpt_id; proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND); /* send this event to Standby also */ /* cpd_a2s_ckpt_dest_down(cb,cref_info->ckpt_node,&mds_info->dest); */ memset(&send_evt, 0, sizeof(CPSV_EVT)); send_evt.type = CPSV_EVT_TYPE_CPA; send_evt.info.cpa.type = CPA_EVT_D2A_NDRESTART; send_evt.info.cpa.info.ackpt_info.ckpt_id = cref_info->ckpt_node->ckpt_id; proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPA); } else { memset(&send_evt, 0, sizeof(CPSV_EVT)); send_evt.type = CPSV_EVT_TYPE_CPND; send_evt.info.cpnd.type = CPND_EVT_D2ND_CKPT_REP_DEL; send_evt.info.cpnd.info.ckpt_del.ckpt_id = cref_info->ckpt_node->ckpt_id; send_evt.info.cpnd.info.ckpt_del.mds_dest = cpnd_info->cpnd_ret_timer.info.cpnd_dest; proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND); m_LOG_CPD_FFCL(CPD_REP_DEL_SUCCESS, CPD_FC_DB, NCSFL_SEV_INFO, cref_info->ckpt_node->ckpt_id, cpnd_info->cpnd_ret_timer.info.cpnd_dest, __FILE__, __LINE__); } cref_info = cref_info->next; } return proc_rc; }
/**************************************************************************** * Name : glsv_gld_standby_rsc_close * * Description : This is the function is invoked when a rsc_close event is * is sent from avtive GLD to standby GLD. This function will * remove references to * to this resource from the mentioned node. If the resource * is not referred any longer then the data structures are freed * up. * * Arguments : async_evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t glsv_gld_standby_rsc_close(GLSV_GLD_A2S_CKPT_EVT *async_evt) { GLSV_GLD_CB *gld_cb; GLSV_GLD_GLND_DETAILS *node_details; GLSV_GLD_GLND_RSC_REF *glnd_rsc; bool orphan_flag; uint32_t node_id; uint32_t rc = NCSCC_RC_FAILURE; TRACE_ENTER(); if (async_evt == NULL) goto end; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(async_evt->info.rsc_details.mdest_id); if ((gld_cb = (NCSCONTEXT)ncshm_take_hdl(NCS_SERVICE_ID_GLD, gl_gld_hdl)) == NULL) { LOG_ER("Handle take failed"); goto end; } orphan_flag = async_evt->info.rsc_details.orphan; /* 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) { LOG_ER("Patricia tree get failed: node_id %u", node_id); goto error; } glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree, (uint8_t *)&async_evt->info.rsc_details.rsc_id); if (glnd_rsc == NULL) { LOG_ER("Patricia tree get failed"); goto error; } glnd_rsc->rsc_info->saf_rsc_no_of_users = glnd_rsc->rsc_info->saf_rsc_no_of_users - 1; if (async_evt->info.rsc_details.lcl_ref_cnt == 0) gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag); TRACE_1("GLD a2s evt rsc close success: rsc_id %u node_id %u", async_evt->info.rsc_details.rsc_id, node_id); ncshm_give_hdl(gld_cb->my_hdl); rc = NCSCC_RC_SUCCESS; goto end; error: LOG_ER("GLD a2s evt rsc close failed: rsc_id %u node_id %u", async_evt->info.rsc_details.rsc_id, node_id); ncshm_give_hdl(gld_cb->my_hdl); end: TRACE_LEAVE(); return rc; }
/**************************************************************************** * Name : gld_mds_glnd_down * * Description : MDS indicated that a glnd has gone down * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t gld_mds_glnd_down(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details = NULL; GLSV_GLD_RSC_INFO *rsc_info; uint32_t node_id; uint32_t rc = NCSCC_RC_FAILURE; TRACE_ENTER2("mds identification %u",gld_cb->my_dest_id ); node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.glnd_mds_info.mds_dest_id); if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)) goto end; memcpy(&evt->fr_dest_id, &evt->info.glnd_mds_info.mds_dest_id, sizeof(MDS_DEST) ); if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) == NULL) { TRACE_1("Resource details is empty for glnd on node_id %u ", node_id); rc = NCSCC_RC_SUCCESS; goto end; } node_details->status = GLND_RESTART_STATE; TRACE("EVT Processing MDS GLND DOWN: node_id %u", node_details->node_id); memcpy(&node_details->restart_timer.mdest_id, &node_details->dest_id, sizeof(MDS_DEST)); /* Start GLSV_GLD_GLND_RESTART_TIMEOUT timer */ gld_start_tmr(gld_cb, &node_details->restart_timer, GLD_TMR_NODE_RESTART_TIMEOUT, GLD_NODE_RESTART_TIMEOUT, 0); /* Check whether this node is master for any resource, if yes send the status to all the non master nodes */ if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) { /* Check whether this node is master for any resource, if yes send the status to all the non master nodes */ rsc_info = gld_cb->rsc_info; while (rsc_info != NULL) { if (rsc_info->node_list) { if (rsc_info->node_list->node_id == node_details->node_id) gld_snd_master_status(gld_cb, rsc_info, GLND_RESOURCE_MASTER_RESTARTED); } rsc_info = rsc_info->next; } /* If this node is non master for any resource, then send node status to the master */ gld_process_send_non_master_status(gld_cb, node_details, GLND_RESTART_STATE); } end: TRACE_LEAVE2("Return value: %u", rc); return rc; }
/***************************************************************************** PROCEDURE NAME : gld_process_tmr_node_restart_wait_timeout DESCRIPTION : ARGUMENTS :gld_cb - ptr to the GLD control block evt - ptr to the event. RETURNS :NCSCC_RC_FAILURE/NCSCC_RC_SUCCESS NOTES : None *****************************************************************************/ static uint32_t gld_process_tmr_node_restart_wait_timeout(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details; GLSV_GLD_GLND_RSC_REF *glnd_rsc; SaLckResourceIdT rsc_id; uint32_t node_id; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.tmr.mdest_id); TRACE_ENTER2("Node restart wait timer expired: node_id %u", node_id); if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) == NULL) { LOG_ER("Evenr from unknown glnd: node_id %u", node_id); return NCSCC_RC_FAILURE; } if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) { /* checkpoint node_details */ glsv_gld_a2s_ckpt_node_details(gld_cb, node_details->dest_id, GLSV_GLD_EVT_GLND_DOWN); /* If this node is non master for any resource, then send node status to the master */ gld_process_send_non_master_status(gld_cb, node_details, GLND_DOWN_STATE); /* 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, glnd_rsc->rsc_info->can_orphan); 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; } } /* 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); } } else { node_details->status = GLND_DOWN_STATE; } return NCSCC_RC_SUCCESS; }
/***************************************************************************** PROCEDURE NAME : gld_process_tmr_node_restart_wait_timeout DESCRIPTION : ARGUMENTS :gld_cb - ptr to the GLD control block evt - ptr to the event. RETURNS :NCSCC_RC_FAILURE/NCSCC_RC_SUCCESS NOTES : None *****************************************************************************/ static uns32 gld_process_tmr_node_restart_wait_timeout(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details; GLSV_GLD_GLND_RSC_REF *glnd_rsc; SaLckResourceIdT rsc_id; uns32 node_id; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.tmr.mdest_id); m_LOG_GLD_HEADLINE(GLD_ND_RESTART_WAIT_TMR_EXP, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id); if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uns8 *)&node_id)) == NULL) { m_LOG_GLD_HEADLINE(GLD_UNKNOWN_GLND_EVT, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id); return NCSCC_RC_FAILURE; } if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) { /* checkpoint node_details */ glsv_gld_a2s_ckpt_node_details(gld_cb, node_details->dest_id, GLSV_GLD_EVT_GLND_DOWN); /* If this node is non master for any resource, then send node status to the master */ gld_process_send_non_master_status(gld_cb, node_details, GLND_DOWN_STATE); /* 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, (uns8 *)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, glnd_rsc->rsc_info->can_orphan); glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uns8 *)&rsc_id); if (glnd_rsc) rsc_id = glnd_rsc->rsc_id; } } /* 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); } } else { node_details->status = GLND_DOWN_STATE; } return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : glsv_gld_glnd_operational * * 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_glnd_operational(GLSV_GLD_A2S_CKPT_EVT *async_evt) { GLSV_GLD_CB *gld_cb = NULL; GLSV_GLD_GLND_DETAILS *node_details = NULL; GLSV_GLD_RSC_INFO *rsc_info = NULL; GLSV_NODE_LIST *node_list = NULL; 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; } if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) != NULL) { memcpy(&node_details->dest_id, &async_evt->info.glnd_mds_info.mdest_id, sizeof(MDS_DEST)); /* Cancel the restart timer if started */ gld_stop_tmr(&node_details->restart_timer); node_details->status = GLND_OPERATIONAL_STATE; rsc_info = gld_cb->rsc_info; while (rsc_info != NULL) { node_list = rsc_info->node_list; while (node_list != NULL) { if (node_list->node_id == node_id) { memcpy(&node_list->dest_id, &async_evt->info.glnd_mds_info.mdest_id, sizeof(MDS_DEST)); } node_list = node_list->next; } rsc_info = rsc_info->next; } } ncshm_give_hdl(gld_cb->my_hdl); end: TRACE_LEAVE(); return rc; }
/**************************************************************************** Name : cpd_cpnd_info_node_get Description : This routine finds the CPND Info node. Arguments : ckpt_map_tree - Ckpt Tree. ckpt_name - Checkpoint Name Return Values : ckpt_map_node - Checkpoint Node NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : The caller takes the cb lock before calling this function ******************************************************************************/ uns32 cpd_cpnd_info_node_get(NCS_PATRICIA_TREE *cpnd_tree, MDS_DEST *dest, CPD_CPND_INFO_NODE **cpnd_info_node) { 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); return NCSCC_RC_SUCCESS; }
/**************************************************************************** Name : immd_immnd_info_node_get Description : This routine finds the IMMND Info node. Arguments : immnd_tree - IMMND Tree. dest - MDS_DEST Return Values : immnd_info_node - IMMND Node NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE *****************************************************************************/ uns32 immd_immnd_info_node_get(NCS_PATRICIA_TREE *immnd_tree, MDS_DEST *dest, IMMD_IMMND_INFO_NODE **immnd_info_node) { NODE_ID key; memset(&key, 0, sizeof(NODE_ID)); /* Fill the Key */ key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest)); *immnd_info_node = (IMMD_IMMND_INFO_NODE *) ncs_patricia_tree_get(immnd_tree, (uns8 *)&key); return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_mds_glnd_down * * Description : MDS indicated that a glnd has gone down * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uns32 gld_mds_glnd_down(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details = NULL; NCS_BOOL orphan_flag; GLSV_GLD_RSC_INFO *rsc_info; uns32 node_id; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.glnd_mds_info.mds_dest_id); if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)) return NCSCC_RC_FAILURE; orphan_flag = evt->info.rsc_details.orphan; memcpy(&evt->fr_dest_id, &evt->info.glnd_mds_info.mds_dest_id, sizeof(MDS_DEST) ); if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uns8 *)&node_id)) == NULL) { m_LOG_GLD_HEADLINE(GLD_UNKNOWN_GLND_EVT, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id); return NCSCC_RC_SUCCESS; } node_details->status = GLND_RESTART_STATE; m_LOG_GLD_EVT(GLD_EVT_MDS_GLND_DOWN, NCSFL_SEV_NOTICE, __FILE__, __LINE__, 0, node_details->node_id); memcpy(&node_details->restart_timer.mdest_id, &node_details->dest_id, sizeof(MDS_DEST)); /* Start GLSV_GLD_GLND_RESTART_TIMEOUT timer */ gld_start_tmr(gld_cb, &node_details->restart_timer, GLD_TMR_NODE_RESTART_TIMEOUT, GLD_NODE_RESTART_TIMEOUT, 0); /* Check whether this node is master for any resource, if yes send the status to all the non master nodes */ if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) { /* Check whether this node is master for any resource, if yes send the status to all the non master nodes */ rsc_info = gld_cb->rsc_info; while (rsc_info != NULL) { if (rsc_info->node_list) { if (rsc_info->node_list->node_id == node_details->node_id) gld_snd_master_status(gld_cb, rsc_info, GLND_RESOURCE_MASTER_RESTARTED); } rsc_info = rsc_info->next; } /* If this node is non master for any resource, then send node status to the master */ gld_process_send_non_master_status(gld_cb, node_details, GLND_RESTART_STATE); } return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_rsc_close * * Description : This is the function is invoked when a rsc_close event is * is sent from a GLND. This function will remove references to * to this resource from the mentioned node. If the resource * is not referred any longer then the data structures are freed * up. * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t gld_rsc_close(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details; GLSV_GLD_GLND_RSC_REF *glnd_rsc; bool orphan_flag; uint32_t node_id; uint32_t rc = NCSCC_RC_SUCCESS; TRACE_ENTER2("component name %s", gld_cb->comp_name.value); node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)){ rc = NCSCC_RC_FAILURE; goto end; } orphan_flag = evt->info.rsc_details.orphan; /* 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) { LOG_ER("Event from unknown glnd: node_id %u ", node_id); rc = NCSCC_RC_FAILURE; goto end; } glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree, (uint8_t *)&evt->info.rsc_details.rsc_id); if ((glnd_rsc == NULL) || (glnd_rsc->rsc_info == NULL)) { LOG_ER("Rsc operation for unopened rsc: rsc_id %u node_id %u ", evt->info.rsc_details.rsc_id, node_details->node_id); goto end; } TRACE("EVT Processing rsc close rsc_id %u node_id %u", glnd_rsc->rsc_info->rsc_id, node_details->node_id); 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; /*Checkkpoint resource close event */ glsv_gld_a2s_ckpt_rsc_details(gld_cb, evt->evt_type, evt->info.rsc_details, node_details->dest_id, evt->info.rsc_details.lcl_ref_cnt); if (evt->info.rsc_details.lcl_ref_cnt == 0) gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag); end: TRACE_LEAVE2("Return value %u", rc); return rc; }
/**************************************************************************** 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; }
/**************************************************************************** Name : immd_immnd_info_node_add Description : This routine adds the new node to immnd_tree. Arguments : immnd_tree - IMMND Tree. immnd_node - IMMND Node. Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : The caller takes the cb lock before calling this function *****************************************************************************/ #if 0 /*CURRENTLY NOT CALLED */ uns32 immd_immnd_info_node_add(NCS_PATRICIA_TREE *immnd_tree, IMMD_IMMND_INFO_NODE *immnd_info_node) { /* Store the client_info pointer as msghandle. */ NODE_ID key; key = m_NCS_NODE_ID_FROM_MDS_DEST(immnd_info_node->immnd_dest); immnd_info_node->patnode.key_info = (uns8 *)&key; if (ncs_patricia_tree_add(immnd_tree, &immnd_info_node->patnode) != NCSCC_RC_SUCCESS) { LOG_ER("IMMD - ncs_patricia_tree_add failed"); return NCSCC_RC_FAILURE; } return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_glnd_operational * * Description : * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t gld_glnd_operational(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details = NULL; GLSV_GLD_RSC_INFO *rsc_info = NULL; uint32_t node_id; GLSV_NODE_LIST *node_list = NULL; TRACE_ENTER(); node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); /* Find if the node details are already available */ if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) != NULL) { memcpy(&node_details->dest_id, &evt->fr_dest_id, sizeof(MDS_DEST)); /* Cancel the restart timer if started */ gld_stop_tmr(&node_details->restart_timer); node_details->status = GLND_OPERATIONAL_STATE; rsc_info = gld_cb->rsc_info; while (rsc_info != NULL) { node_list = rsc_info->node_list; while (node_list != NULL) { if (node_list->node_id == node_id) { memcpy(&node_list->dest_id, &evt->fr_dest_id, sizeof(MDS_DEST)); } node_list = node_list->next; } rsc_info = rsc_info->next; } glsv_gld_a2s_ckpt_node_details(gld_cb, node_details->dest_id, GLSV_GLD_EVT_GLND_OPERATIONAL); rsc_info = gld_cb->rsc_info; while (rsc_info != NULL) { if (rsc_info->node_list->node_id == node_details->node_id) gld_snd_master_status(gld_cb, rsc_info, GLND_RESOURCE_MASTER_OPERATIONAL); rsc_info = rsc_info->next; } /* If this node is non master for any resource, then send node status to the master */ gld_process_send_non_master_status(gld_cb, node_details, GLND_OPERATIONAL_STATE); } /*Send resource-master information to GLND */ gld_send_res_master_info(gld_cb, node_details, evt->fr_dest_id); TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_rsc_close * * Description : This is the function is invoked when a rsc_close event is * is sent from a GLND. This function will remove references to * to this resource from the mentioned node. If the resource * is not referred any longer then the data structures are freed * up. * * Arguments : evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uns32 gld_rsc_close(GLSV_GLD_EVT *evt) { GLSV_GLD_CB *gld_cb = evt->gld_cb; GLSV_GLD_GLND_DETAILS *node_details; GLSV_GLD_GLND_RSC_REF *glnd_rsc; NCS_BOOL orphan_flag; uns32 node_id; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id); if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)) return NCSCC_RC_FAILURE; orphan_flag = evt->info.rsc_details.orphan; /* 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) { m_LOG_GLD_HEADLINE(GLD_UNKNOWN_GLND_EVT, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id); return NCSCC_RC_FAILURE; } glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree, (uns8 *)&evt->info.rsc_details.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__, "", evt->info.rsc_details.rsc_id, node_details->node_id); return NCSCC_RC_SUCCESS; } m_LOG_GLD_EVT(GLD_EVT_RSC_CLOSE, NCSFL_SEV_INFO, __FILE__, __LINE__, glnd_rsc->rsc_info->rsc_id, node_details->node_id); 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; /*Checkkpoint resource close event */ glsv_gld_a2s_ckpt_rsc_details(gld_cb, evt->evt_type, evt->info.rsc_details, node_details->dest_id, evt->info.rsc_details.lcl_ref_cnt); if (evt->info.rsc_details.lcl_ref_cnt == 0) gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag); return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : gld_dump_cb * * Description : This is the function dumps the contents of the control block. * * Arguments : gld_cb - Pointer to the control block * * Return Values : None. * * Notes : None. *****************************************************************************/ void gld_dump_cb() { GLSV_GLD_CB *gld_cb = NULL; GLSV_GLD_GLND_DETAILS *node_details; MDS_DEST mds_dest_id; GLSV_GLD_RSC_INFO *rsc_info; SaLckResourceIdT rsc_id = 0; uns32 node_id = 0; gld_cb = (NCSCONTEXT)ncshm_take_hdl(NCS_SERVICE_ID_GLD, gl_gld_hdl); if (!gld_cb) { m_LOG_GLD_HEADLINE(GLD_TAKE_HANDLE_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__, 0); return; } memset(&mds_dest_id, 0, sizeof(MDS_DEST)); TRACE("************ GLD CB info *************** "); /* print Amf Info */ TRACE("AMF HA state : %d ", gld_cb->ha_state); /* print the Node details */ TRACE("GLND info :"); while ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_getnext(&gld_cb->glnd_details, (uns8 *)&node_id))) { node_id = node_details->node_id; TRACE("Node Id - :%d ", node_details->node_id); } /* print the Resource details */ while ((rsc_info = (GLSV_GLD_RSC_INFO *)ncs_patricia_tree_getnext(&gld_cb->rsc_info_id, (uns8 *)&rsc_id))) { GLSV_NODE_LIST *list; rsc_id = rsc_info->rsc_id; TRACE("Resource Id - : %d Resource Name - %.10s ", (uns32)rsc_info->rsc_id, rsc_info->lck_name.value); TRACE("Can Orphan - %d Mode - %d ", rsc_info->can_orphan, (uns32)rsc_info->orphan_lck_mode); list = rsc_info->node_list; TRACE("List of Nodes :"); while (list != NULL) { TRACE("%d ", m_NCS_NODE_ID_FROM_MDS_DEST(list->dest_id)); list = list->next; } } ncshm_give_hdl(gl_gld_hdl); TRACE("************************************************** "); }
/**************************************************************************** * Name : glsv_gld_standby_rsc_set_orphan * * Description : Instruction from the GLND to set the orphan flag * * Arguments : async_evt - Event structure * * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE * * Notes : None. *****************************************************************************/ static uint32_t glsv_gld_standby_rsc_set_orphan(GLSV_GLD_A2S_CKPT_EVT *async_evt) { GLSV_GLD_CB *gld_cb; GLSV_GLD_GLND_DETAILS *node_details; uint32_t node_id; uint32_t rc = NCSCC_RC_FAILURE; TRACE_ENTER(); if (async_evt == NULL) goto end; node_id = m_NCS_NODE_ID_FROM_MDS_DEST(async_evt->info.rsc_details.mdest_id); if ((gld_cb = (NCSCONTEXT)ncshm_take_hdl(NCS_SERVICE_ID_GLD, gl_gld_hdl)) == NULL) { LOG_ER("Handle take failed"); 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) { LOG_ER("Patricia tree get failed: node_id %u", node_id); goto error; } if (gld_rsc_ref_set_orphan(node_details, async_evt->info.rsc_details.rsc_id, async_evt->info.rsc_details.orphan, async_evt->info.rsc_details.lck_mode) == NCSCC_RC_SUCCESS) { TRACE_1("GLD a2s evt set orphan success: rsc_id %u node_id %u", async_evt->info.rsc_details.rsc_id, node_id); ncshm_give_hdl(gld_cb->my_hdl); rc = NCSCC_RC_SUCCESS; goto end; } else goto error; error: LOG_ER("GLD a2s evt set orphan failed: rsc_id %u node_id %u", async_evt->info.rsc_details.rsc_id, node_id); ncshm_give_hdl(gld_cb->my_hdl); end: TRACE_LEAVE(); return rc; }
/**************************************************************************** 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_add(NCS_PATRICIA_TREE *cpnd_tree, CPD_CPND_INFO_NODE *cpnd_info_node) { /* Store the client_info pointer as msghandle. */ NODE_ID key; key = m_NCS_NODE_ID_FROM_MDS_DEST(cpnd_info_node->cpnd_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 *)&key; if (ncs_patricia_tree_add(cpnd_tree, &cpnd_info_node->patnode) != NCSCC_RC_SUCCESS) { m_LOG_CPD_CL(CPD_CPND_INFO_NODE_FAILED, CPD_FC_HDLN, NCSFL_SEV_ERROR, __FILE__, __LINE__); return NCSCC_RC_FAILURE; } return NCSCC_RC_SUCCESS; }
/**************************************************************************** Name : immd_immnd_info_node_getnext Description : This routine finds the IMMND Info node. Arguments : immnd_tree - IMMND Tree. dest - MDS_DEST Return Values : immnd_info_node - IMMND Node NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE Notes : The caller takes the cb lock before calling this function *****************************************************************************/ void immd_immnd_info_node_getnext(NCS_PATRICIA_TREE *immnd_tree, MDS_DEST *dest, IMMD_IMMND_INFO_NODE **immnd_info_node) { NODE_ID key; memset(&key, 0, sizeof(NODE_ID)); /* Fill the Key */ if (dest) { key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest)); *immnd_info_node = (IMMD_IMMND_INFO_NODE *) ncs_patricia_tree_getnext(immnd_tree, (uns8 *)&key); } else *immnd_info_node = (IMMD_IMMND_INFO_NODE *) ncs_patricia_tree_getnext(immnd_tree, (uns8 *)NULL); return; }