/************************************************************************************ * Name : cpd_a2s_ckpt_create * Description : This routine will update the CPD_MBCSV_MSG (message) which has * to be sent to Standby for checkpoint create Async Update * Input Values : CPD_CB , CPD_CKPT_INFO_NODE - CPD checkpoint node * Return Values : SA_AIS_OK if success else return appropriate error * * Notes : The information present in the ckpt_node is copied into cpd_msg(which has to be sent to Standby ) **************************************************************************************************************/ uint32_t cpd_a2s_ckpt_create(CPD_CB *cb, CPD_CKPT_INFO_NODE *ckpt_node) { CPD_MBCSV_MSG cpd_msg; SaAisErrorT rc = SA_AIS_OK; uint32_t count = 0; TRACE_ENTER(); memset(&cpd_msg, '\0', sizeof(CPD_MBCSV_MSG)); cpd_msg.type = CPD_A2S_MSG_CKPT_CREATE; cpd_msg.info.ckpt_create.ckpt_name = ckpt_node->ckpt_name; cpd_msg.info.ckpt_create.ckpt_id = ckpt_node->ckpt_id; cpd_msg.info.ckpt_create.ckpt_attrib = ckpt_node->attributes; cpd_msg.info.ckpt_create.is_unlink_set = ckpt_node->is_unlink_set; cpd_msg.info.ckpt_create.create_time = ckpt_node->create_time; cpd_msg.info.ckpt_create.num_users = ckpt_node->num_users; cpd_msg.info.ckpt_create.num_readers = ckpt_node->num_readers; cpd_msg.info.ckpt_create.num_writers = ckpt_node->num_writers; cpd_msg.info.ckpt_create.num_sections = ckpt_node->num_sections; cpd_msg.info.ckpt_create.is_active_exists = ckpt_node->is_active_exists; if (cpd_msg.info.ckpt_create.is_active_exists) cpd_msg.info.ckpt_create.active_dest = ckpt_node->active_dest; if (ckpt_node->dest_cnt) { CPD_NODE_REF_INFO *node_list = ckpt_node->node_list; cpd_msg.info.ckpt_create.dest_cnt = ckpt_node->dest_cnt; cpd_msg.info.ckpt_create.dest_list = m_MMGR_ALLOC_CPSV_CPND_DEST_INFO(ckpt_node->dest_cnt); if (cpd_msg.info.ckpt_create.dest_list == NULL) { LOG_CR("cpd cpnd dest info memory allocation failed"); rc = SA_AIS_ERR_NO_MEMORY; goto end; } else { memset(cpd_msg.info.ckpt_create.dest_list, '\0', (sizeof(CPSV_CPND_DEST_INFO) * ckpt_node->dest_cnt)); for (count = 0; count < ckpt_node->dest_cnt; count++) { cpd_msg.info.ckpt_create.dest_list[count].dest = node_list->dest; node_list = node_list->next; } } } /* send it to MBCSv */ rc = cpd_mbcsv_async_update(cb, &cpd_msg); if (rc != SA_AIS_OK) TRACE_4("cpd A2S ckpt create async failed for ckptid :%llx",ckpt_node->ckpt_id); else TRACE_1("cpd A2S ckpt create async success for ckptid :%llx",ckpt_node->ckpt_id); if (cpd_msg.info.ckpt_create.dest_list) m_MMGR_FREE_CPSV_CPND_DEST_INFO(cpd_msg.info.ckpt_create.dest_list); end: TRACE_LEAVE(); return rc; }
/***************************************************************************** * Name : cpnd_up_process * * Description : This function is invoked when the ND is up * * Arguments : CPSV_MDS_INFO - mds info , CPD_CPND_INFO_NODE - cpnd info * * Return Values : Success / Error * * Notes : 1. Send the Restart Done event to other ND's if ND having Active replica is up 2. Send a REP_ADD event if ND not having Active Replica is up *****************************************************************************/ static uns32 cpnd_up_process(CPD_CB *cb, CPSV_MDS_INFO *mds_info, CPD_CPND_INFO_NODE *cpnd_info) { CPD_CKPT_REF_INFO *cref_info = NULL, *cpd_ckpt_info = NULL; CPSV_EVT send_evt; uns32 proc_rc = NCSCC_RC_SUCCESS; uns32 i = 0; cpnd_info->cpnd_ret_timer.type = CPD_TMR_TYPE_CPND_RETENTION; cpnd_info->cpnd_ret_timer.info.cpnd_dest = mds_info->dest; cpd_tmr_stop(&cpnd_info->cpnd_ret_timer); cref_info = cpnd_info->ckpt_ref_list; cpd_ckpt_info = cpnd_info->ckpt_ref_list; if (cref_info) cpd_cpnd_dest_replace(cb, cref_info, mds_info); while (cref_info) { memset(&send_evt, 0, sizeof(CPSV_EVT)); /* If the Node contains Active Replica, then send RESTART_DONE event */ 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))) { send_evt.type = CPSV_EVT_TYPE_CPND; send_evt.info.cpnd.type = CPSV_D2ND_RESTART_DONE; send_evt.info.cpnd.info.cpnd_restart_done.ckpt_id = cref_info->ckpt_node->ckpt_id; send_evt.info.cpnd.info.cpnd_restart_done.mds_dest = cpnd_info->cpnd_ret_timer.info.cpnd_dest; send_evt.info.cpnd.info.cpnd_restart_done.dest_cnt = cref_info->ckpt_node->dest_cnt; send_evt.info.cpnd.info.cpnd_restart_done.active_dest = cref_info->ckpt_node->active_dest; send_evt.info.cpnd.info.cpnd_restart_done.attributes = cref_info->ckpt_node->attributes; send_evt.info.cpnd.info.cpnd_restart_done.ckpt_flags = cref_info->ckpt_node->ckpt_flags; if (send_evt.info.cpnd.info.cpnd_restart_done.dest_cnt) { CPD_NODE_REF_INFO *node_list = cref_info->ckpt_node->node_list; send_evt.info.cpnd.info.cpnd_restart_done.dest_list = m_MMGR_ALLOC_CPSV_CPND_DEST_INFO(cref_info->ckpt_node->dest_cnt); if (!send_evt.info.cpnd.info.cpnd_restart_done.dest_list) { /* No memory, don't know what to do, setting dest_cnt to zero & continue */ m_LOG_CPD_CL(CPD_CPND_DEST_INFO_ALLOC_FAILED, CPD_FC_MEMFAIL, NCSFL_SEV_ERROR, __FILE__, __LINE__); send_evt.info.cpnd.info.cpnd_restart_done.dest_cnt = 0; } for (i = 0; i < send_evt.info.cpnd.info.cpnd_restart_done.dest_cnt; i++) { send_evt.info.cpnd.info.cpnd_restart_done.dest_list[i].dest = node_list->dest; node_list = node_list->next; } } proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND); if (send_evt.info.cpnd.info.cpnd_restart_done.dest_list) { m_MMGR_FREE_CPSV_CPND_DEST_INFO(send_evt.info.cpnd.info.cpnd_restart_done.dest_list); send_evt.info.cpnd.info.cpnd_restart_done.dest_list = NULL; send_evt.info.cpnd.info.cpnd_restart_done.dest_cnt = 0; } /*To broadcast the active MDS_DEST info of ckpt to all CPA's */ memset(&send_evt, 0, sizeof(CPSV_EVT)); send_evt.type = CPSV_EVT_TYPE_CPA; send_evt.info.cpa.type = CPA_EVT_D2A_ACT_CKPT_INFO_BCAST_SEND; send_evt.info.cpa.info.ackpt_info.ckpt_id = cref_info->ckpt_node->ckpt_id; send_evt.info.cpa.info.ackpt_info.mds_dest = cref_info->ckpt_node->active_dest; proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPA); } else { /* else just send the ND which has the active replica */ send_evt.type = CPSV_EVT_TYPE_CPND; send_evt.info.cpnd.type = CPND_EVT_D2ND_CKPT_REP_ADD; send_evt.info.cpnd.info.ckpt_add.ckpt_id = cref_info->ckpt_node->ckpt_id; send_evt.info.cpnd.info.ckpt_add.mds_dest = cpnd_info->cpnd_ret_timer.info.cpnd_dest; send_evt.info.cpnd.info.ckpt_add.dest_cnt = cref_info->ckpt_node->dest_cnt; send_evt.info.cpnd.info.ckpt_add.active_dest = cref_info->ckpt_node->active_dest; send_evt.info.cpnd.info.ckpt_add.attributes = cref_info->ckpt_node->attributes; send_evt.info.cpnd.info.ckpt_add.is_cpnd_restart = TRUE; send_evt.info.cpnd.info.ckpt_add.ckpt_flags = cref_info->ckpt_node->ckpt_flags; if (send_evt.info.cpnd.info.ckpt_add.dest_cnt) { CPD_NODE_REF_INFO *node_list = cref_info->ckpt_node->node_list; send_evt.info.cpnd.info.ckpt_add.dest_list = m_MMGR_ALLOC_CPSV_CPND_DEST_INFO(cref_info->ckpt_node->dest_cnt); if (!send_evt.info.cpnd.info.ckpt_add.dest_list) { /* No memory, don't know what to do, setting dest_cnt to zero & continue */ m_LOG_CPD_CL(CPD_CPND_DEST_INFO_ALLOC_FAILED, CPD_FC_MEMFAIL, NCSFL_SEV_ERROR, __FILE__, __LINE__); send_evt.info.cpnd.info.ckpt_add.dest_cnt = 0; } for (i = 0; i < send_evt.info.cpnd.info.ckpt_add.dest_cnt; i++) { send_evt.info.cpnd.info.ckpt_add.dest_list[i].dest = node_list->dest; node_list = node_list->next; } } proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND); m_LOG_CPD_FFCL(CPD_REP_ADD_SUCCESS, CPD_FC_DB, NCSFL_SEV_INFO, cref_info->ckpt_node->ckpt_id, cpnd_info->cpnd_ret_timer.info.cpnd_dest, __FILE__, __LINE__); if (send_evt.info.cpnd.info.ckpt_add.dest_list) { m_MMGR_FREE_CPSV_CPND_DEST_INFO(send_evt.info.cpnd.info.ckpt_add.dest_list); send_evt.info.cpnd.info.ckpt_add.dest_list = NULL; send_evt.info.cpnd.info.ckpt_add.dest_cnt = 0; } } cref_info = cref_info->next; } return proc_rc; }
/**************************************************************************** * Name : cpd_evt_proc_ckpt_create * * Description : Function to process the CPD_EVT_ND2D_CKPT_CREATE event * from CPD. * * Arguments : CPD_CB *cb - CPD CB pointer * CPSV_EVT *evt - Received Event structure * * Return Values : NCSCC_RC_SUCCESS/Error. * * Notes : None. *****************************************************************************/ static uns32 cpd_evt_proc_ckpt_create(CPD_CB *cb, CPD_EVT *evt, CPSV_SEND_INFO *sinfo) { CPSV_EVT send_evt; SaAisErrorT rc = SA_AIS_OK; uns32 proc_rc = NCSCC_RC_SUCCESS; CPD_CKPT_INFO_NODE *ckpt_node = 0; CPD_CKPT_MAP_INFO *map_info = NULL; CPSV_ND2D_CKPT_CREATE *ckpt_create = &evt->info.ckpt_create; NCS_BOOL is_first_rep = FALSE, is_new_noncol = FALSE; cpd_ckpt_map_node_get(&cb->ckpt_map_tree, &ckpt_create->ckpt_name, &map_info); if (map_info) { /* ckpt_create->ckpt_name.length = m_NCS_OS_NTOHS(ckpt_create->ckpt_name.length); */ if (m_CPA_VER_IS_ABOVE_B_1_1(&ckpt_create->client_version)) { if ((ckpt_create->ckpt_flags & SA_CKPT_CHECKPOINT_CREATE) && (!m_COMPARE_CREATE_ATTR(&ckpt_create->attributes, &map_info->attributes))) { m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_NOTICE, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); rc = SA_AIS_ERR_EXIST; goto send_rsp; } } else { if ((ckpt_create->ckpt_flags & SA_CKPT_CHECKPOINT_CREATE) && (!m_COMPARE_CREATE_ATTR_B_1_1(&ckpt_create->attributes, &map_info->attributes))) { m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_NOTICE, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); rc = SA_AIS_ERR_EXIST; goto send_rsp; } } } else { SaCkptCheckpointCreationAttributesT ckpt_local_attrib; memset(&ckpt_local_attrib, 0, sizeof(SaCkptCheckpointCreationAttributesT)); /* ckpt_create->ckpt_name.length = m_NCS_OS_NTOHS(ckpt_create->ckpt_name.length); */ is_first_rep = TRUE; if (m_CPA_VER_IS_ABOVE_B_1_1(&ckpt_create->client_version)) { if (!(ckpt_create->ckpt_flags & SA_CKPT_CHECKPOINT_CREATE) && (m_COMPARE_CREATE_ATTR(&ckpt_create->attributes, &ckpt_local_attrib))) { m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_ERROR, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); rc = SA_AIS_ERR_NOT_EXIST; goto send_rsp; } } else { if (!(ckpt_create->ckpt_flags & SA_CKPT_CHECKPOINT_CREATE) && (m_COMPARE_CREATE_ATTR_B_1_1(&ckpt_create->attributes, &ckpt_local_attrib))) { m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_ERROR, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); rc = SA_AIS_ERR_NOT_EXIST; goto send_rsp; } } } /* Add/Update the entries in ckpt DB, ckpt_map DB, ckpt_node DB */ proc_rc = cpd_ckpt_db_entry_update(cb, &sinfo->dest, ckpt_create, &ckpt_node, &map_info); if (proc_rc == NCSCC_RC_OUT_OF_MEM) { /*m_LOG_CPD_CFCL(CPD_DB_ADD_FAILED,CPD_FC_DB,NCSFL_SEV_ERROR,ckpt_create->ckpt_name.value,sinfo->dest,__FILE__,__LINE__); */ m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_ERROR, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); rc = SA_AIS_ERR_NO_MEMORY; goto send_rsp; } else if (proc_rc != NCSCC_RC_SUCCESS) { m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_ERROR, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); rc = SA_AIS_ERR_LIBRARY; goto send_rsp; } if (ckpt_create->ckpt_flags & SA_CKPT_CHECKPOINT_READ) ckpt_node->num_readers++; if (ckpt_create->ckpt_flags & SA_CKPT_CHECKPOINT_WRITE) ckpt_node->num_writers++; ckpt_node->num_users++; cb->is_db_upd = TRUE; /* Redundancy A2S This is for async update */ /* Only for 1st replica we send the entire info , for later openings we send dest_add */ if (is_first_rep) { cpd_a2s_ckpt_create(cb, ckpt_node); cpd_a2s_ckpt_usr_info(cb, ckpt_node); } /* Send the dest info to the Standby SCXB This is for async update */ if (is_first_rep == FALSE) { cpd_a2s_ckpt_dest_add(cb, ckpt_node, &sinfo->dest); cpd_a2s_ckpt_usr_info(cb, ckpt_node); } /* Non-colocated processing */ if ((is_first_rep == TRUE) && (!(map_info->attributes.creationFlags & SA_CKPT_CHECKPOINT_COLLOCATED))) { /* Policy is to create the replic on both active & standby SCXB's CPND Right now replica is created only on the active (local) SCXB */ /* if(cb->is_loc_cpnd_up && (cpd_get_slot_sub_id_from_mds_dest(sinfo->dest) != ckpt_node->ckpt_on_scxb1)) */ if (cb->is_loc_cpnd_up && (!m_CPND_IS_ON_SCXB(cb->cpd_self_id, cpd_get_slot_sub_id_from_mds_dest(sinfo->dest)))) { proc_rc = cpd_noncolloc_ckpt_rep_create(cb, &cb->loc_cpnd_dest, ckpt_node, map_info); if (proc_rc == NCSCC_RC_SUCCESS) m_LOG_CPD_CFCL(CPD_NON_COLOC_CKPT_CREATE_SUCCESS, CPD_FC_HDLN, NCSFL_SEV_INFO, ckpt_create->ckpt_name.value, cb->loc_cpnd_dest, __FILE__, __LINE__); else m_LOG_CPD_CFCL(CPD_NON_COLOC_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_NOTICE, ckpt_create->ckpt_name.value, cb->loc_cpnd_dest, __FILE__, __LINE__); } /* if(cb->is_rem_cpnd_up && (cpd_get_slot_sub_id_from_mds_dest(sinfo->dest) != ckpt_node->ckpt_on_scxb2)) */ if (cb->is_rem_cpnd_up && (!m_CPND_IS_ON_SCXB(cb->cpd_remote_id, cpd_get_slot_sub_id_from_mds_dest(sinfo->dest)))) { proc_rc = cpd_noncolloc_ckpt_rep_create(cb, &cb->rem_cpnd_dest, ckpt_node, map_info); if (proc_rc == NCSCC_RC_SUCCESS) m_LOG_CPD_CFCL(CPD_NON_COLOC_CKPT_CREATE_SUCCESS, CPD_FC_HDLN, NCSFL_SEV_INFO, ckpt_create->ckpt_name.value, cb->rem_cpnd_dest, __FILE__, __LINE__); else m_LOG_CPD_CFCL(CPD_NON_COLOC_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_NOTICE, ckpt_create->ckpt_name.value, cb->rem_cpnd_dest, __FILE__, __LINE__); } /* ND on SCXB has created the same checkpoint, so is_new_noncol must be made to true */ is_new_noncol = TRUE; } send_rsp: /* Send the response to the creater of this ckpt */ /* Populate & Send the Open Event to CPND */ memset(&send_evt, 0, sizeof(CPSV_EVT)); send_evt.type = CPSV_EVT_TYPE_CPND; send_evt.info.cpnd.type = CPND_EVT_D2ND_CKPT_INFO; send_evt.info.cpnd.info.ckpt_info.error = rc; if (rc == SA_AIS_OK) { send_evt.info.cpnd.info.ckpt_info.ckpt_id = ckpt_node->ckpt_id; send_evt.info.cpnd.info.ckpt_info.is_active_exists = ckpt_node->is_active_exists; send_evt.info.cpnd.info.ckpt_info.attributes = map_info->attributes; if (send_evt.info.cpnd.info.ckpt_info.is_active_exists) send_evt.info.cpnd.info.ckpt_info.active_dest = ckpt_node->active_dest; if (map_info->attributes.creationFlags & SA_CKPT_CHECKPOINT_COLLOCATED) send_evt.info.cpnd.info.ckpt_info.ckpt_rep_create = TRUE; else { if (is_first_rep) send_evt.info.cpnd.info.ckpt_info.ckpt_rep_create = TRUE; else send_evt.info.cpnd.info.ckpt_info.ckpt_rep_create = FALSE; } if (ckpt_node->dest_cnt) { CPD_NODE_REF_INFO *node_list = ckpt_node->node_list; uns32 i = 0; send_evt.info.cpnd.info.ckpt_info.dest_cnt = ckpt_node->dest_cnt; send_evt.info.cpnd.info.ckpt_info.dest_list = m_MMGR_ALLOC_CPSV_CPND_DEST_INFO(ckpt_node->dest_cnt); if (send_evt.info.cpnd.info.ckpt_info.dest_list == NULL) { send_evt.info.cpnd.info.ckpt_info.error = SA_AIS_ERR_NO_MEMORY; rc = SA_AIS_ERR_NO_MEMORY; m_LOG_CPD_CL(CPD_CPND_DEST_INFO_ALLOC_FAILED, CPD_FC_MEMFAIL, NCSFL_SEV_ERROR, __FILE__, __LINE__); proc_rc = NCSCC_RC_OUT_OF_MEM; } else { memset(send_evt.info.cpnd.info.ckpt_info.dest_list, 0, (sizeof(CPSV_CPND_DEST_INFO) * ckpt_node->dest_cnt)); for (i = 0; i < ckpt_node->dest_cnt; i++) { send_evt.info.cpnd.info.ckpt_info.dest_list[i].dest = node_list->dest; node_list = node_list->next; } } } } proc_rc = cpd_mds_send_rsp(cb, sinfo, &send_evt); if (send_evt.info.cpnd.info.ckpt_info.dest_list) m_MMGR_FREE_CPSV_CPND_DEST_INFO(send_evt.info.cpnd.info.ckpt_info.dest_list); if (proc_rc != NCSCC_RC_SUCCESS) m_LOG_CPD_CFCL(CPD_CKPT_CREATE_FAILURE, CPD_FC_HDLN, NCSFL_SEV_ERROR, ckpt_create->ckpt_name.value, sinfo->dest, __FILE__, __LINE__); if ((proc_rc != NCSCC_RC_SUCCESS) || (rc != SA_AIS_OK)) return proc_rc; /* Ckpt info successfully updated at CPD, send it to all CPNDs */ /* Broadcast the ckpt add info to all the CPNDs, only the relevent CPNDs will process this message */ if ((is_first_rep == FALSE) || (is_new_noncol == TRUE)) { memset(&send_evt, 0, sizeof(CPSV_EVT)); send_evt.type = CPSV_EVT_TYPE_CPND; send_evt.info.cpnd.type = CPND_EVT_D2ND_CKPT_REP_ADD; send_evt.info.cpnd.info.ckpt_add.ckpt_id = ckpt_node->ckpt_id; send_evt.info.cpnd.info.ckpt_add.mds_dest = sinfo->dest; send_evt.info.cpnd.info.ckpt_add.is_cpnd_restart = FALSE; proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND); m_LOG_CPD_FFCL(CPD_REP_ADD_SUCCESS, CPD_FC_DB, NCSFL_SEV_INFO, map_info->ckpt_id, sinfo->dest, __FILE__, __LINE__); } if (is_first_rep) m_LOG_CPD_CFFCL(CPD_CKPT_CREATE_SUCCESS, CPD_FC_HDLN, NCSFL_SEV_INFO, map_info->ckpt_name.value, sinfo->dest, map_info->ckpt_id, __FILE__, __LINE__); else m_LOG_CPD_FFCL(CPD_CKPT_CREATE_SUCCESS, CPD_FC_HDLN, NCSFL_SEV_INFO, sinfo->dest, map_info->ckpt_id, __FILE__, __LINE__); return proc_rc; }