- When AMFD got IMM BAD_HANDLE, it will try to finalize current OI and reinit new OI, it make some callbacks are removed without execution. Try to dispatch OI before finalize it to reinit. - After reinit OI, check node db to find out node which is not exist in IMM (in case ccb apply delete node miss execution) then cleanup SU/COMP relate to the node and delete the node. --- src/amf/amfd/imm.cc | 4 +++ src/amf/amfd/node.cc | 80 ++++++++++++++++++++-------------------------------- src/amf/amfd/node.h | 1 + src/amf/amfd/su.cc | 79 +++++++++++++++++++++++---------------------------- 4 files changed, 72 insertions(+), 92 deletions(-)
diff --git a/src/amf/amfd/imm.cc b/src/amf/amfd/imm.cc index 82d2b13..1b14383 100644 --- a/src/amf/amfd/imm.cc +++ b/src/amf/amfd/imm.cc @@ -41,6 +41,7 @@ #include "amf/common/amf_defs.h" #include "amf/amfd/imm.h" #include "amf/amfd/cluster.h" +#include "amf/amfd/node.h" #include "amf/amfd/app.h" #include "amf/amfd/sgtype.h" #include "amf/amfd/sg.h" @@ -2132,6 +2133,8 @@ static void *avd_imm_reinit_bg_thread(void *_cb) { immutilWrapperProfile.errorsAreFatal = 0; + /* Try to dispatch imm cb if any, e.g: apply cb, before finalize OI */ + (void)saImmOiDispatch(avd_cb->immOiHandle, SA_DISPATCH_ALL); while (++no_of_retries < MAX_NO_RETRIES) { (void)saImmOiFinalize(avd_cb->immOiHandle); @@ -2167,6 +2170,7 @@ static void *avd_imm_reinit_bg_thread(void *_cb) { osaf_mutex_unlock_ordie(&imm_reinit_mutex); exit(EXIT_FAILURE); } + avd_check_nodes_after_renit_imm(); } else { /* become applier and re-read the config */ rc = avd_imm_applier_set(); diff --git a/src/amf/amfd/node.cc b/src/amf/amfd/node.cc index 201f1fc..b6ebcc8 100644 --- a/src/amf/amfd/node.cc +++ b/src/amf/amfd/node.cc @@ -25,6 +25,7 @@ #include "amf/amfd/amfd.h" #include "amf/amfd/cluster.h" #include "amf/amfd/imm.h" +#include "amf/amfd/util.h" #include <algorithm> AmfDb<std::string, AVD_AVND> *node_name_db = 0; /* SaNameT index */ @@ -153,57 +154,23 @@ AVD_AVND *avd_node_new(const std::string &dn) { void avd_node_delete(AVD_AVND *node) { TRACE_ENTER(); osafassert(node->pg_csi_list.n_nodes == 0); - if (node->node_info.nodeId) avd_node_delete_nodeid(node); - /* Check if the SUs and related objects are still left. This can - happen on Standby Amfd when it has just read the configuration - and before it becomes applier, Act Amfd deletes SUs. Those SUs - will be left out at Standby Amfd. Though this could be rare.*/ - if (avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) { - if (node->list_of_su.empty() != true) { - std::set<std::string> su_list; - std::set<std::string> comp_list; - for (const auto &su : node->list_of_su) su_list.insert(su->name); - for (std::set<std::string>::const_iterator iter = su_list.begin(); - iter != su_list.end(); ++iter) { - AVD_SU *su = su_db->find(*iter); - TRACE("Standby Amfd, su '%s' not deleted", su->name.c_str()); - for (const auto &comp : su->list_of_comp) - comp_list.insert(Amf::to_string(&comp->comp_info.name)); - for (std::set<std::string>::const_iterator iter1 = comp_list.begin(); - iter1 != comp_list.end(); ++iter1) { - AVD_COMP *comp = comp_db->find(*iter1); - TRACE("Standby Amfd, comp '%s' not deleted", - osaf_extended_name_borrow(&comp->comp_info.name)); - - std::map<std::string, AVD_COMPCS_TYPE *>::iterator it = - compcstype_db->begin(); - while (it != compcstype_db->end()) { - AVD_COMPCS_TYPE *compcstype = it->second; - if (compcstype->comp == comp) { - TRACE("Standby Amfd, compcstype '%s' not deleted", - compcstype->name.c_str()); - it = compcstype_db->erase(it); - delete compcstype; - } else - ++it; - } + if (node->node_info.nodeId) { + avd_node_delete_nodeid(node); + } - /* Delete the Comp. */ - struct CcbUtilOperationData opdata; - osaf_extended_name_alloc( - osaf_extended_name_borrow(&comp->comp_info.name), - &opdata.objectName); - comp_ccb_apply_delete_hdlr(&opdata); - } - comp_list.clear(); - /* Delete the SU. */ - struct CcbUtilOperationData opdata; - opdata.userData = su; - su_ccb_apply_delete_hdlr(&opdata); - } - su_list.clear(); - } + std::set<std::string> su_list; + for (const auto &su : node->list_of_ncs_su) su_list.insert(su->name); + for (const auto &su : node->list_of_su) su_list.insert(su->name); + for (std::set<std::string>::const_iterator iter = su_list.begin(); + iter != su_list.end(); ++iter) { + AVD_SU *su = su_db->find(*iter); + LOG_WA("su '%s' not deleted, delete it", su->name.c_str()); + struct CcbUtilOperationData opdata; + opdata.userData = su; + su_ccb_apply_delete_hdlr(&opdata); } + su_list.clear(); + m_AVSV_SEND_CKPT_UPDT_ASYNC_RMV(avd_cb, node, AVSV_CKPT_AVD_NODE_CONFIG); node_name_db->erase(node->name); delete node; @@ -1678,3 +1645,18 @@ bool AVD_AVND::is_campaign_set_for_all_sus() const { return false; } } + +void avd_check_nodes_after_renit_imm() { + TRACE_ENTER(); + + AmfDb<std::string, AVD_AVND>::iterator it; + for (it = node_name_db->begin(); it != node_name_db->end(); it++) + { + if (object_exist_in_imm(it->first) == false) { + LOG_WA("Remove node %s after reinit IMM", it->first.c_str()); + node_ccb_apply_delete_hdlr(it->second); + } + } + + TRACE_LEAVE(); +} \ No newline at end of file diff --git a/src/amf/amfd/node.h b/src/amf/amfd/node.h index e64bf8c..9fe9f19 100644 --- a/src/amf/amfd/node.h +++ b/src/amf/amfd/node.h @@ -240,5 +240,6 @@ extern bool are_all_ngs_in_unlocked_state(const AVD_AVND *node); extern bool any_ng_in_locked_in_state(const AVD_AVND *node); void avd_ng_restore_headless_states(AVD_CL_CB *cb, struct avd_su_si_rel_tag *susi); +void avd_check_nodes_after_renit_imm(); #endif // AMF_AMFD_NODE_H_ diff --git a/src/amf/amfd/su.cc b/src/amf/amfd/su.cc index c3609d8..a79cc14 100644 --- a/src/amf/amfd/su.cc +++ b/src/amf/amfd/su.cc @@ -2024,54 +2024,43 @@ void su_ccb_apply_delete_hdlr(struct CcbUtilOperationData *opdata) { TRACE_ENTER2("'%s'", su->name.c_str()); - if (avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) { - /* Check if the comp and related objects are still left. This can - happen on Standby Amfd when it has just read the configuration - and before it becomes applier, Act Amfd deletes Comps. Those Comps - will be left out at Standby Amfd. Though this could be rare.*/ - std::set<std::string> comp_list; - for (const auto &comp : su->list_of_comp) - comp_list.insert(Amf::to_string(&comp->comp_info.name)); - for (std::set<std::string>::const_iterator iter1 = comp_list.begin(); - iter1 != comp_list.end(); ++iter1) { - AVD_COMP *comp = comp_db->find(*iter1); - - // Create a tmp database of compcstype. - std::set<std::string> compcstype_list; - for (const auto &value : *compcstype_db) { - AVD_COMPCS_TYPE *compcstype = value.second; - compcstype_list.insert(compcstype->name); - } - TRACE("Standby Amfd, comp '%s' not deleted", - osaf_extended_name_borrow(&comp->comp_info.name)); - - for (std::set<std::string>::const_iterator iter1 = - compcstype_list.begin(); - iter1 != compcstype_list.end(); ++iter1) { - AVD_COMPCS_TYPE *compcstype = compcstype_db->find(*iter1); - if (compcstype->comp == comp) { - TRACE("Standby Amfd, compcstype '%s' not deleted", - compcstype->name.c_str()); - compcstype_db->erase(compcstype->name); - delete compcstype; - } + std::set<std::string> comp_list; + for (const auto &comp : su->list_of_comp) + comp_list.insert(Amf::to_string(&comp->comp_info.name)); + for (std::set<std::string>::const_iterator iter1 = comp_list.begin(); + iter1 != comp_list.end(); ++iter1) { + AVD_COMP *comp = comp_db->find(*iter1); + + // Create a tmp database of compcstype. + std::set<std::string> compcstype_list; + for (const auto &value : *compcstype_db) { + AVD_COMPCS_TYPE *compcstype = value.second; + compcstype_list.insert(compcstype->name); + } + LOG_WA("comp '%s' not deleted, delete it", + osaf_extended_name_borrow(&comp->comp_info.name)); + + for (std::set<std::string>::const_iterator iter1 = + compcstype_list.begin(); + iter1 != compcstype_list.end(); ++iter1) { + AVD_COMPCS_TYPE *compcstype = compcstype_db->find(*iter1); + if (compcstype->comp == comp) { + LOG_WA("compcstype '%s' not deleted, delete it", + compcstype->name.c_str()); + compcstype_db->erase(compcstype->name); + delete compcstype; } - compcstype_list.clear(); - /* Delete the Comp. */ - struct CcbUtilOperationData opdata; - osaf_extended_name_alloc(osaf_extended_name_borrow(&comp->comp_info.name), - &opdata.objectName); - comp_ccb_apply_delete_hdlr(&opdata); } - comp_list.clear(); - - su->remove_from_model(); - delete su; - goto done; + compcstype_list.clear(); + /* Delete the Comp. */ + struct CcbUtilOperationData opdata; + osaf_extended_name_alloc(osaf_extended_name_borrow(&comp->comp_info.name), + &opdata.objectName); + comp_ccb_apply_delete_hdlr(&opdata); } + comp_list.clear(); su_node_ptr = su->get_node_ptr(); - if ((su_node_ptr->node_state == AVD_AVND_STATE_PRESENT) || (su_node_ptr->node_state == AVD_AVND_STATE_NO_CONFIG) || (su_node_ptr->node_state == AVD_AVND_STATE_NCS_INIT)) { @@ -2089,6 +2078,10 @@ void su_ccb_apply_delete_hdlr(struct CcbUtilOperationData *opdata) { su->remove_from_model(); delete su; + if (avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) { + goto done; + } + if (AVD_SG_FSM_STABLE == sg->sg_fsm_state) { /*if su of uneqal rank has been delete and all SUs are of same rank then do screening for SI Distribution. */ -- 2.7.4 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel