If 2N application has each SU hosted on each node and SC Absence feature
is enabled, the event of abruptly stopping both SCs will generate assignment
failover. At this moment, IMM calls to create/delete assignment object are
queued up and executed periodically. Therefore, when both SC are going down,
the assignment from AMFND and IMM are pretty unconsistent.
The patch makes IMM calls to create and delete assignment objects as synced
call. Firstly active AMFD will try to execute IMM calls, if the calls fail
then those calls will be queued.
---
src/amf/amfd/imm.cc | 79 ++++++++++++++++++++++++++++++++++++++++++++-------
src/amf/amfd/imm.h | 5 +++-
src/amf/amfd/siass.cc | 15 ++++++----
3 files changed, 82 insertions(+), 17 deletions(-)
diff --git a/src/amf/amfd/imm.cc b/src/amf/amfd/imm.cc
index dd842d9e1..ae2a43f96 100644
--- a/src/amf/amfd/imm.cc
+++ b/src/amf/amfd/imm.cc
@@ -1703,24 +1703,28 @@ SaAisErrorT avd_saImmOiRtObjectUpdate_sync(
const std::string &dn, SaImmAttrNameT attributeName,
SaImmValueTypeT attrValueType, void *value,
SaImmAttrModificationTypeT modifyType) {
- SaAisErrorT rc;
+ SaAisErrorT rc = SA_AIS_OK;
SaImmAttrModificationT_2 attrMod;
const SaImmAttrModificationT_2 *attrMods[] = {&attrMod, nullptr};
SaImmAttrValueT attrValues[] = {value};
const std::string attribute_name(attributeName);
TRACE_ENTER2("'%s' %s", dn.c_str(), attributeName);
+ if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE) {
- attrMod.modType = modifyType;
- attrMod.modAttr.attrName = attributeName;
- attrMod.modAttr.attrValuesNumber = 1;
- attrMod.modAttr.attrValueType = attrValueType;
- attrMod.modAttr.attrValues = attrValues;
+ attrMod.modType = modifyType;
+ attrMod.modAttr.attrName = attributeName;
+ attrMod.modAttr.attrValuesNumber = 1;
+ attrMod.modAttr.attrValueType = attrValueType;
+ attrMod.modAttr.attrValues = attrValues;
- rc = saImmOiRtObjectUpdate_o3(avd_cb->immOiHandle, dn.c_str(), attrMods);
- if (rc != SA_AIS_OK) {
- LOG_WA("saImmOiRtObjectUpdate of '%s' %s failed with %u", dn.c_str(),
- attributeName, rc);
+ rc = saImmOiRtObjectUpdate_o3(avd_cb->immOiHandle, dn.c_str(), attrMods);
+ if (rc != SA_AIS_OK)
+ LOG_WA("saImmOiRtObjectUpdate of '%s' %s failed with %u", dn.c_str(),
+ attributeName, rc);
+ }
+
+ if (rc != SA_AIS_OK || avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) {
// Now it will be updated through job queue.
avd_saImmOiRtObjectUpdate(dn, attribute_name, attrValueType, value);
}
@@ -1860,6 +1864,39 @@ void avd_saImmOiRtObjectUpdate(const std::string &dn,
}
/**
+ * Create IMM object, blocking call at active AMFD. If fails, move this create
+ * job to queue and to be executed later
+ * @param className
+ * @param parentName
+ * @param attrValues
+ */
+void avd_saImmOiRtObjectCreate_sync(const std::string &className,
+ const std::string &parentName,
+ const SaImmAttrValuesT_2 **attrValues) {
+ TRACE_ENTER2("%s %s", className.c_str(), parentName.c_str());
+
+ SaAisErrorT rc = SA_AIS_OK;
+
+ if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE) {
+ const SaNameTWrapper parent_name(parentName);
+ rc = saImmOiRtObjectCreate_2(avd_cb->immOiHandle,
+ const_cast<SaImmClassNameT>(className.c_str()),
+ parent_name, attrValues);
+ if (rc != SA_AIS_OK) {
+ LOG_WA("saImmOiRtObjectCreate_2 of className:'%s', parentName:'%s',"
+ " failed with %u", className.c_str(), parentName.c_str(), rc);
+ }
+ }
+
+ if (rc != SA_AIS_OK || avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) {
+ // Now it will be updated through job queue.
+ avd_saImmOiRtObjectCreate(className, parentName, attrValues);
+ }
+
+ TRACE_LEAVE();
+}
+
+/**
* Queue an IM object create to be executed later, non blocking
* @param className
* @param parentName
@@ -1887,6 +1924,28 @@ void avd_saImmOiRtObjectCreate(const std::string
&className,
}
/**
+ * Delete IMM object, blocking call at active AMFD. If fails, move this delete
+ * job to queue and to be executed later
+ * @param dn
+ */
+void avd_saImmOiRtObjectDelete_sync(const std::string &dn) {
+ TRACE_ENTER2("%s", dn.c_str());
+ SaAisErrorT rc = SA_AIS_OK;
+
+ if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE) {
+ rc = saImmOiRtObjectDelete_o3(avd_cb->immOiHandle, dn.c_str());
+ if (rc != SA_AIS_OK) {
+ LOG_WA("saImmOiRtObjectDelete_o3 of '%s' failed with %u", dn.c_str(),
rc);
+ }
+ }
+ if (rc != SA_AIS_OK || avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) {
+ // Now it will be updated through job queue.
+ avd_saImmOiRtObjectDelete(dn);
+ }
+ TRACE_LEAVE();
+}
+
+/**
* Queue an IM object delete to be executed later, non blocking
* @param dn
*/
diff --git a/src/amf/amfd/imm.h b/src/amf/amfd/imm.h
index 79e5a54f3..535ee7241 100644
--- a/src/amf/amfd/imm.h
+++ b/src/amf/amfd/imm.h
@@ -222,8 +222,11 @@ extern void avd_saImmOiRtObjectUpdate(const std::string
&dn,
extern void avd_saImmOiRtObjectCreate(const std::string &lassName,
const std::string &parentName,
const SaImmAttrValuesT_2 **attrValues);
+extern void avd_saImmOiRtObjectCreate_sync(const std::string &lassName,
+ const std::string &parentName,
+ const SaImmAttrValuesT_2 **attrValues);
extern void avd_saImmOiRtObjectDelete(const std::string &objectName);
-
+extern void avd_saImmOiRtObjectDelete_sync(const std::string &objectName);
extern void avd_imm_reinit_bg(void);
extern void avd_saImmOiAdminOperationResult(SaImmOiHandleT immOiHandle,
SaInvocationT invocation,
diff --git a/src/amf/amfd/siass.cc b/src/amf/amfd/siass.cc
index 88564b46c..7e61e7746 100644
--- a/src/amf/amfd/siass.cc
+++ b/src/amf/amfd/siass.cc
@@ -82,7 +82,8 @@ static void avd_create_susi_in_imm(AVD_SU_SI_REL *susi) {
const SaNameTWrapper su(susi->su->name);
avsv_create_association_class_dn(su, nullptr, "safSISU", &dn);
- avd_saImmOiRtObjectCreate("SaAmfSIAssignment", susi->si->name, attrValues);
+ avd_saImmOiRtObjectCreate_sync("SaAmfSIAssignment", susi->si->name,
+ attrValues);
osaf_extended_name_free(&dn);
}
@@ -98,7 +99,7 @@ static void avd_delete_siassignment_from_imm(const
std::string &si_dn,
const SaNameTWrapper si(si_dn);
const SaNameTWrapper su(su_dn);
avsv_create_association_class_dn(su, si, "safSISU", &dn);
- avd_saImmOiRtObjectDelete(Amf::to_string(&dn));
+ avd_saImmOiRtObjectDelete_sync(Amf::to_string(&dn));
osaf_extended_name_free(&dn);
}
@@ -123,7 +124,8 @@ void avd_susi_update(AVD_SU_SI_REL *susi, SaAmfHAStateT
ha_state) {
avd_ha_state[ha_state], susi->su->name.c_str(),
susi->si->name.c_str());
- avd_saImmOiRtObjectUpdate(Amf::to_string(&dn), "saAmfSISUHAState",
+ avd_saImmOiRtObjectUpdate_sync(Amf::to_string(&dn),
+ const_cast<SaImmAttrNameT>("saAmfSISUHAState"),
SA_IMM_ATTR_SAUINT32T, &ha_state);
osaf_extended_name_free(&dn);
@@ -134,7 +136,8 @@ void avd_susi_update(AVD_SU_SI_REL *susi, SaAmfHAStateT
ha_state) {
avsv_create_association_class_dn(&compcsi->comp->comp_info.name, csi_name,
"safCSIComp", &dn);
- avd_saImmOiRtObjectUpdate(Amf::to_string(&dn), "saAmfCSICompHAState",
+ avd_saImmOiRtObjectUpdate_sync(Amf::to_string(&dn),
+ const_cast<SaImmAttrNameT>("saAmfCSICompHAState"),
SA_IMM_ATTR_SAUINT32T, &ha_state);
osaf_extended_name_free(&dn);
@@ -156,14 +159,14 @@ void avd_susi_update_fsm(AVD_SU_SI_REL *susi,
AVD_SU_SI_STATE new_fsm_state) {
if (susi->fsm != new_fsm_state) {
susi->fsm = new_fsm_state;
if (avd_cb->scs_absence_max_duration > 0) {
- avd_saImmOiRtObjectUpdate(
+ avd_saImmOiRtObjectUpdate_sync(
Amf::to_string(&dn),
const_cast<SaImmAttrNameT>("osafAmfSISUFsmState"),
SA_IMM_ATTR_SAUINT32T, &susi->fsm);
// Need to write to IMM HA state, otherwise the ABSENT SUSI read from IMM
// will have wrong HA state, which lead to incorrect failover of ABSENT
// SUSI
- avd_saImmOiRtObjectUpdate(Amf::to_string(&dn),
+ avd_saImmOiRtObjectUpdate_sync(Amf::to_string(&dn),
const_cast<SaImmAttrNameT>("saAmfSISUHAState"),
SA_IMM_ATTR_SAUINT32T, &susi->state);
}
--
2.11.0
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel