osaf/services/saf/amf/amfd/cluster.cc     |   7 +++-
 osaf/services/saf/amf/amfd/include/sg.h   |   2 +
 osaf/services/saf/amf/amfd/include/susi.h |   1 +
 osaf/services/saf/amf/amfd/ndfsm.cc       |   6 ++-
 osaf/services/saf/amf/amfd/sg.cc          |  42 +++++++++++++++++++++++++
 osaf/services/saf/amf/amfd/sg_2n_fsm.cc   |  13 +++++--
 osaf/services/saf/amf/amfd/sgproc.cc      |  28 +++++++++++++---
 osaf/services/saf/amf/amfd/siass.cc       |  52 ++++++++++++++++++++++++++----
 osaf/services/saf/amf/amfd/su.cc          |  19 +++++++---
 9 files changed, 144 insertions(+), 26 deletions(-)


When a payload restarts or is powered off during headless, the SUSI
assignments in this payload were removed, that shall break down the HA
characteristic of SUSI assignments after headless.

This patch treats the SUSI assignments removed during headless as ABSENT
SUSI, and reuse node_fail() to perform a failover on SU having ABSENT
SUSIs, in order that the HA of SUSI assignments shall become STABLE, which
means no QUIESCED/QUIESCING SUSI, etc... Inside node_fail(), any su_si
assignments event on ABSENT SUSI toward AMFND likes modification, deletion
will ignored.

diff --git a/osaf/services/saf/amf/amfd/cluster.cc 
b/osaf/services/saf/amf/amfd/cluster.cc
--- a/osaf/services/saf/amf/amfd/cluster.cc
+++ b/osaf/services/saf/amf/amfd/cluster.cc
@@ -84,7 +84,12 @@ void avd_cluster_tmr_init_evh(AVD_CL_CB 
                }
 
                if (i_sg->any_assignment_in_progress() == false) {
-                       i_sg->set_fsm_state(AVD_SG_FSM_STABLE);
+                       if (i_sg->any_assignment_absent() == false) {
+                               i_sg->set_fsm_state(AVD_SG_FSM_STABLE);
+                       } else {
+                               // failover with ABSENT SUSI, which had already 
been removed during headless
+                               i_sg->failover_absent_assignment();
+                       }
                }
 
                if (i_sg->sg_fsm_state == AVD_SG_FSM_STABLE)
diff --git a/osaf/services/saf/amf/amfd/include/sg.h 
b/osaf/services/saf/amf/amfd/include/sg.h
--- a/osaf/services/saf/amf/amfd/include/sg.h
+++ b/osaf/services/saf/amf/amfd/include/sg.h
@@ -415,6 +415,8 @@ public:
        bool is_sg_serviceable_outside_ng(const AVD_AMF_NG *ng);
        SaAisErrorT check_sg_stability();
        bool any_assignment_in_progress();
+       bool any_assignment_absent();
+       void failover_absent_assignment();
        bool ng_using_saAmfSGAdminState;
        
        uint32_t term_su_list_in_reverse();
diff --git a/osaf/services/saf/amf/amfd/include/susi.h 
b/osaf/services/saf/amf/amfd/include/susi.h
--- a/osaf/services/saf/amf/amfd/include/susi.h
+++ b/osaf/services/saf/amf/amfd/include/susi.h
@@ -70,6 +70,7 @@ typedef struct avd_su_si_rel_tag {
        SaBoolT csi_add_rem;
        SaNameT comp_name;
        SaNameT csi_name;
+       bool absent;
 } AVD_SU_SI_REL;
 
 /* SusperSiRank table index structure */
diff --git a/osaf/services/saf/amf/amfd/ndfsm.cc 
b/osaf/services/saf/amf/amfd/ndfsm.cc
--- a/osaf/services/saf/amf/amfd/ndfsm.cc
+++ b/osaf/services/saf/amf/amfd/ndfsm.cc
@@ -125,12 +125,14 @@ void avd_process_state_info_queue(AVD_CL
                }
        }
 
-       // Read cached rta from Imm
+       // Read cached rta from Imm, the order of calling
+       // below functions is IMPORTANT.
        // Reading sg must be after reading susi
+       // Cleanup compcsi must be after reading sg
        if (found_state_info == true) {
-               avd_compcsi_cleanup_imm_object(cb);
                avd_susi_read_headless_cached_rta(cb);
                avd_sg_read_headless_cached_rta(cb);
+               avd_compcsi_cleanup_imm_object(cb);
                avd_su_read_headless_cached_rta(cb);
        }
 done:
diff --git a/osaf/services/saf/amf/amfd/sg.cc b/osaf/services/saf/amf/amfd/sg.cc
--- a/osaf/services/saf/amf/amfd/sg.cc
+++ b/osaf/services/saf/amf/amfd/sg.cc
@@ -2133,6 +2133,23 @@ void avd_sg_read_headless_cached_rta(AVD
                                        }
                                }
                        }
+
+                       // Move fsm state of absent SUSI to 
AVD_SU_SI_STATE_ABSENT
+                       for (const auto& su : sg->list_of_su) {
+                               for (AVD_SU_SI_REL *susi = su->list_of_susi; 
susi;
+                                               susi = susi->su_next) {
+                                       TRACE("SUSI:'%s,%s', fsm:'%d'", 
Amf::to_string(&susi->su->name).c_str(),
+                                                       
Amf::to_string(&susi->si->name).c_str(), susi->fsm);
+                                       if (susi->absent == true) {
+                                               avd_susi_update_fsm(susi, 
AVD_SU_SI_STATE_ABSENT);
+                                               //Checkpoint to add this SUSI 
only after absent SUSI fsm
+                                               //moves to 
AVD_SU_SI_STATE_ABSENT, so var @absent is safe
+                                               //at standby side
+                                               
m_AVSV_SEND_CKPT_UPDT_ASYNC_ADD(cb, susi, AVSV_CKPT_AVD_SI_ASS);
+                                               susi->absent = false;
+                                       }
+                               }
+                       }
                }
        }
 
@@ -2142,6 +2159,31 @@ done:
     TRACE_LEAVE();
 }
 
+void AVD_SG::failover_absent_assignment() {
+
+       TRACE_ENTER2("SG:'%s'", Amf::to_string(&name).c_str());
+       for (const auto& su : list_of_su) {
+               if (su->any_susi_fsm_in(AVD_SU_SI_STATE_ABSENT)){
+                       node_fail(avd_cb, su);
+                       break;
+               }
+       }
+       TRACE_LEAVE();
+}
+
+bool AVD_SG::any_assignment_absent() {
+       bool pending = false;
+       TRACE_ENTER2("SG:'%s'", Amf::to_string(&name).c_str());
+       for (const auto& su : list_of_su) {
+               if (su->any_susi_fsm_in(AVD_SU_SI_STATE_ABSENT)){
+                       pending = true;
+                       break;
+               }
+       }
+       TRACE_LEAVE();
+       return pending;
+}
+
 bool AVD_SG::any_assignment_in_progress() {
        bool pending = false;
        TRACE_ENTER2("SG:'%s'", Amf::to_string(&name).c_str());
diff --git a/osaf/services/saf/amf/amfd/sg_2n_fsm.cc 
b/osaf/services/saf/amf/amfd/sg_2n_fsm.cc
--- a/osaf/services/saf/amf/amfd/sg_2n_fsm.cc
+++ b/osaf/services/saf/amf/amfd/sg_2n_fsm.cc
@@ -75,6 +75,7 @@ static void complete_siswap(AVD_SU *su, 
 AVD_SU_SI_STATE avd_su_fsm_state_determine(AVD_SU *su) {
        AVD_SU_SI_REL *temp_susi;
        bool assigning_flag = false, assigned_flag = false, modify_flag = 
false, unassingned_flag = false;
+       bool absent_flag = false;
        AVD_SU_SI_STATE fsm_state = AVD_SU_SI_STATE_ABSENT;
 
        TRACE_ENTER2("SU '%s'", su->name.value);
@@ -98,16 +99,20 @@ AVD_SU_SI_STATE avd_su_fsm_state_determi
                } else if (AVD_SU_SI_STATE_ASGND == temp_susi->fsm) {
                        assigned_flag =  true;
                        TRACE("Assigned su'%s', si'%s'", 
temp_susi->su->name.value, temp_susi->si->name.value);
+               } else if (AVD_SU_SI_STATE_ABSENT == temp_susi->fsm) {
+                       absent_flag =  true;
+                       TRACE("Absent su'%s', si'%s'", 
temp_susi->su->name.value, temp_susi->si->name.value);
                } else {
                        osafassert(0);
                }
                temp_susi = temp_susi->su_next;
        }
 
-       TRACE("assigning_flag'%u', unassingned_flag'%u', assigned_flag'%u', 
modify_flag'%u'", assigning_flag, 
-                       unassingned_flag, assigned_flag, modify_flag);
-
-       if (true == modify_flag) {
+       TRACE("assigning_flag'%u', unassingned_flag'%u', assigned_flag'%u', 
modify_flag'%u', absent_flag'%u'",
+                       assigning_flag, unassingned_flag, assigned_flag, 
modify_flag, absent_flag);
+       if (absent_flag == true) {
+               fsm_state = AVD_SU_SI_STATE_ABSENT;
+       } else if (true == modify_flag) {
                /* Rule 1. => If any one of the SUSI is Mod, then SU will be 
said to be modified. The other SUSI can 
                   be in assigning/assigned state in transition.*/
                fsm_state = AVD_SU_SI_STATE_MODIFY;
diff --git a/osaf/services/saf/amf/amfd/sgproc.cc 
b/osaf/services/saf/amf/amfd/sgproc.cc
--- a/osaf/services/saf/amf/amfd/sgproc.cc
+++ b/osaf/services/saf/amf/amfd/sgproc.cc
@@ -709,8 +709,9 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb
                        (cluster_su_instantiation_done(cb, su) == true)) {
                avd_stop_tmr(cb, &cb->amf_init_tmr);
 
-               if (su->sg_of_su->any_assignment_in_progress() == false) {
-                       su->sg_of_su->sg_fsm_state = AVD_SG_FSM_STABLE;
+               if (su->sg_of_su->any_assignment_in_progress() == false &&
+                       su->sg_of_su->any_assignment_absent() == false) {
+                       su->sg_of_su->set_fsm_state(AVD_SG_FSM_STABLE);
                }
                cluster_startup_expiry_event_generate(cb);
        }
@@ -872,8 +873,9 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb
                /* if the SU is NCS SU, mark the SU readiness state as in 
service and call
                 * the SG FSM.
                 */
-               if (su->sg_of_su->any_assignment_in_progress() == false) {
-                       su->sg_of_su->sg_fsm_state = AVD_SG_FSM_STABLE;
+               if (su->sg_of_su->any_assignment_in_progress() == false &&
+                       su->sg_of_su->any_assignment_absent() == false) {
+                       su->sg_of_su->set_fsm_state(AVD_SG_FSM_STABLE);
                }
                if (su->sg_of_su->sg_ncs_spec == true) {
                        if (su->saAmfSUAdminState == SA_AMF_ADMIN_UNLOCKED) { 
@@ -1583,7 +1585,9 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb,
        /* Free the messages */
        avsv_dnd_msg_free(n2d_msg);
        evt->info.avnd_msg = nullptr;
-
+       if (su != nullptr && su->sg_of_su->any_assignment_absent() == true) {
+               su->sg_of_su->failover_absent_assignment();
+       }
  done:
        TRACE_LEAVE();
 }
@@ -2189,7 +2193,7 @@ uint32_t avd_sg_su_oper_list_del(AVD_CL_
        TRACE_ENTER2("'%s'", su->name.value);
 
        if (su_oper_list.empty() == true) {
-               LOG_ER("%s: su_oper_list empty", __FUNCTION__);
+               LOG_WA("%s: su_oper_list empty", __FUNCTION__);
                goto done;
        }
        
@@ -2244,6 +2248,12 @@ uint32_t avd_sg_su_si_mod_snd(AVD_CL_CB 
 
        TRACE_ENTER2("'%s', state %u", su->name.value, state);
 
+       // No action on ABSENT SUSI
+       if (su->any_susi_fsm_in(AVD_SU_SI_STATE_ABSENT)) {
+               rc = NCSCC_RC_SUCCESS;
+               goto done;
+       }
+
        /* change the state for all assignments to the specified state. */
        i_susi = su->list_of_susi;
        while (i_susi != AVD_SU_SI_REL_NULL) {
@@ -2353,6 +2363,12 @@ uint32_t avd_sg_su_si_del_snd(AVD_CL_CB 
 
        TRACE_ENTER2("'%s'", su->name.value);
 
+       // No action on ABSENT SUSI
+       if (su->any_susi_fsm_in(AVD_SU_SI_STATE_ABSENT)) {
+               rc = NCSCC_RC_SUCCESS;
+               goto done;
+       }
+
        /* change the state for all assignments to the specified state. */
        i_susi = su->list_of_susi;
        while (i_susi != AVD_SU_SI_REL_NULL) {
diff --git a/osaf/services/saf/amf/amfd/siass.cc 
b/osaf/services/saf/amf/amfd/siass.cc
--- a/osaf/services/saf/amf/amfd/siass.cc
+++ b/osaf/services/saf/amf/amfd/siass.cc
@@ -150,6 +150,10 @@ void avd_susi_update_fsm(AVD_SU_SI_REL *
                if (avd_cb->scs_absence_max_duration > 0) {
                        avd_saImmOiRtObjectUpdate(&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(&dn, 
const_cast<SaImmAttrNameT>("saAmfSISUHAState"),
+                               SA_IMM_ATTR_SAUINT32T, &susi->state);
                }
     }
     TRACE_LEAVE();
@@ -168,7 +172,9 @@ void avd_susi_read_headless_cached_rta(A
        SaNameT dn, su_name, si_name;
        const SaImmAttrValuesT_2 **attributes;
        AVD_SU_SI_REL *susi = nullptr;
+       AVD_SU_SI_REL *absent_susi = nullptr;
        AVD_SU_SI_STATE imm_susi_fsm;
+       SaAmfHAStateT imm_ha_state;
        const char *className = "SaAmfSIAssignment";
        const SaImmAttrNameT siass_attributes[] = {
                const_cast<SaImmAttrNameT>("safSISU"),
@@ -209,7 +215,7 @@ void avd_susi_read_headless_cached_rta(A
                rc = immutil_getAttr("osafAmfSISUFsmState", attributes, 0, 
&imm_susi_fsm);
                osafassert(rc == SA_AIS_OK);
 
-               if (susi) {
+               if (susi) { // FOR PRESENT SUSI found in AMFND(s)
                        TRACE("SISU:'%s', old(imm) fsm state: %d, new(sync) fsm 
state: %d",
                                Amf::to_string(&dn).c_str(), imm_susi_fsm, 
susi->fsm);
 
@@ -226,6 +232,7 @@ void avd_susi_read_headless_cached_rta(A
                        // headless period.
                        susi->fsm = imm_susi_fsm;
 #endif
+                       //Checkpoint to add this SUSI
                        m_AVSV_SEND_CKPT_UPDT_ASYNC_ADD(avd_cb, susi, 
AVSV_CKPT_AVD_SI_ASS);
                        // restore assignment counter
                        if (susi->fsm == AVD_SU_SI_STATE_ASGN || susi->fsm == 
AVD_SU_SI_STATE_ASGND ||
@@ -246,10 +253,33 @@ void avd_susi_read_headless_cached_rta(A
                                }
                        }
 
-               } else {
-                       // This susi does not exist after headless, but it's 
still in IMM
-                       // delete it for now
-                       avd_saImmOiRtObjectDelete(&dn);
+               } else { // For ABSENT SUSI
+                       if (su->sg_of_su->sg_ncs_spec == false) {
+                               rc = immutil_getAttr("saAmfSISUHAState", 
attributes, 0, &imm_ha_state);
+                               osafassert(rc == SA_AIS_OK);
+                               TRACE("Absent SUSI, ha_state:'%u', 
fsm_state:'%u'", imm_ha_state, imm_susi_fsm);
+                               if (imm_susi_fsm != AVD_SU_SI_STATE_UNASGN) {
+                                       absent_susi = avd_susi_create(avd_cb, 
si, su, imm_ha_state, false, AVSV_SUSI_ACT_BASE);
+                                       // Restore the fsm of this absent SUSI, 
which is used to determine
+                                       // whether a SU should be added in SG's 
SUOperationList
+                                       // Memorize it in temporary var @absent
+                                       // The fsm of this SUSI will be changed 
to AVD_SU_SI_STATE_ABSENT
+                                       // after restoring SUOperationList
+                                       absent_susi->fsm = imm_susi_fsm;
+                                       absent_susi->absent = true;
+                                       if (absent_susi->si->saAmfSIAdminState 
== SA_AMF_ADMIN_LOCKED ||
+                                               
absent_susi->si->saAmfSIAdminState == SA_AMF_ADMIN_SHUTTING_DOWN) {
+                                               if (absent_susi->fsm == 
AVD_SU_SI_STATE_MODIFY &&
+                                                       (absent_susi->state == 
SA_AMF_HA_QUIESCED || absent_susi->state == SA_AMF_HA_QUIESCING)) {
+                                                               
m_AVD_SET_SG_ADMIN_SI(cb, si);
+                                               }
+                                       }
+                               } else {
+                                       avd_saImmOiRtObjectDelete(&dn);
+                               }
+                       } else {
+                               avd_saImmOiRtObjectDelete(&dn);
+                       }
                }
        }
 
@@ -647,7 +677,11 @@ uint32_t avd_susi_mod_send(AVD_SU_SI_REL
        uint32_t rc = NCSCC_RC_SUCCESS;
 
        TRACE_ENTER2("SI '%s', SU '%s' ha_state:%d", susi->si->name.value, 
susi->su->name.value, ha_state);
-
+       // No action on ABSENT SUSI
+       if (susi->fsm == AVD_SU_SI_STATE_ABSENT) {
+               rc = NCSCC_RC_SUCCESS;
+               goto done;
+       }
        old_state = susi->state;
        old_fsm_state = susi->fsm;
        susi->state = ha_state;
@@ -688,7 +722,11 @@ uint32_t avd_susi_del_send(AVD_SU_SI_REL
        uint32_t rc = NCSCC_RC_SUCCESS;
 
        TRACE_ENTER2("SI '%s', SU '%s' ", susi->si->name.value, 
susi->su->name.value);
-
+       // No action on ABSENT SUSI
+       if (susi->fsm == AVD_SU_SI_STATE_ABSENT) {
+               rc = NCSCC_RC_SUCCESS;
+               goto done;
+       }
        old_fsm_state = susi->fsm;
        avd_susi_update_fsm(susi, AVD_SU_SI_STATE_UNASGN);
        avd_snd_susi_msg(avd_cb, susi->su, susi, AVSV_SUSI_ACT_DEL, false, 
nullptr);
diff --git a/osaf/services/saf/amf/amfd/su.cc b/osaf/services/saf/amf/amfd/su.cc
--- a/osaf/services/saf/amf/amfd/su.cc
+++ b/osaf/services/saf/amf/amfd/su.cc
@@ -787,12 +787,17 @@ void AVD_SU::set_oper_state(SaAmfOperati
  * @param readiness_state
  */
 void AVD_SU::set_readiness_state(SaAmfReadinessStateT readiness_state) {
-       if (saAmfSuReadinessState == readiness_state)
+       TRACE_ENTER2("'%s' current:'%s' -> new:'%s'", name.value,
+                       avd_readiness_state_name[saAmfSuReadinessState],
+                       avd_readiness_state_name[readiness_state]);
+
+       if (saAmfSuReadinessState == readiness_state) {
+               TRACE_LEAVE();
                return;
+       }
 
        osafassert(readiness_state <= SA_AMF_READINESS_STOPPING);
-       TRACE_ENTER2("'%s' %s", name.value,
-               avd_readiness_state_name[readiness_state]);
+
        saflog(LOG_NOTICE, amfSvcUsrName, "%s ReadinessState %s => %s",
                name.value,
                avd_readiness_state_name[saAmfSuReadinessState],
@@ -2360,14 +2365,16 @@ void AVD_SU::complete_admin_op(SaAisErro
  */
 bool AVD_SU::any_susi_fsm_in(uint32_t check_fsm)
 {
-       TRACE_ENTER2("SU:'%s'", Amf::to_string(&name).c_str());
+       TRACE_ENTER2("SU:'%s', check_fsm:'%d'",
+                       Amf::to_string(&name).c_str(), check_fsm);
        bool rc = false;
        for (AVD_SU_SI_REL *susi = list_of_susi; susi && rc == false;
                        susi = susi->su_next) {
+               TRACE("SUSI:'%s,%s', fsm:'%d'", 
Amf::to_string(&susi->su->name).c_str(),
+                               Amf::to_string(&susi->si->name).c_str(), 
susi->fsm);
                if (susi->fsm == check_fsm) {
                        rc = true;
-                       TRACE("SUSI:'%s,%s', fsm:'%d'", 
Amf::to_string(&susi->su->name).c_str(),
-                                       
Amf::to_string(&susi->si->name).c_str(), susi->fsm);
+                       TRACE("Found");
                }
        }
        TRACE_LEAVE();

------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to