- 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. */