Hi Minh,
        Please find comment inlined with [Nagu].

Thanks
-Nagu

> -----Original Message-----
> From: Minh Chau [mailto:[email protected]]
> Sent: 20 June 2017 07:11
> To: [email protected]; [email protected];
> [email protected]; [email protected]
> Cc: [email protected]; Minh Chau
> Subject: [PATCH 1/1] amfd: Avoid to create duplicated 2N ACTIVE SUSI for
> absent assignment V2 [#2477]
> 
> In large cluster, the IMM sync calls mostly take no effect  when both SCs
> abruptly go down, thus amfd may leaves the susi assignments in amfnd and
> IMM in unexpected states.
> 
> The scenario is same as #2416, but in #2477 amfd can also see 2 ACTIVE
> assignments of 2 SUs for the same 2N SI. That leads to osafassert(), causes
> node reboot, and the same osafassert() repeatedly happens after node
> comes up.
> 
> Patch refactors the creation of absent assignment by adding new function
> avd_susi_validate_absent_assignment(), and adds a check to avoid creating 2
> ACTIVE assignments for one SI. Also, a fix
> avnd_diq_rec_check_buffered_msg() is needed in this scenario
> ---
>  src/amf/amfd/siass.cc | 127 ++++++++++++++++++++++++++++++++----------
> --------
>  src/amf/amfd/susi.h   |   4 +-
>  src/amf/amfnd/di.cc   |   6 ++-
>  3 files changed, 89 insertions(+), 48 deletions(-)
> 
> diff --git a/src/amf/amfd/siass.cc b/src/amf/amfd/siass.cc index
> 6a13836f9..d14d279dc 100644
> --- a/src/amf/amfd/siass.cc
> +++ b/src/amf/amfd/siass.cc
> @@ -218,13 +218,20 @@ void
> avd_susi_read_headless_cached_rta(AVD_CL_CB *cb) {
>          std::string(strstr(osaf_extended_name_borrow(&dn), "safSi"));
>      assert(si_name.empty() == false);
>      AVD_SI *si = si_db->find(si_name);
> -    osafassert(si);
> +    if (si == nullptr) {
> +      LOG_ER("SI:'%s' does not exist in AMF's sidb", si_name.c_str());
> +      continue;
> +    }
[Nagu]: If we have SUSI in Imm DB, then SI should exist. Did you get any 
scenario which hits this.

>      SaNameT su_name;
>      avsv_sanamet_init_from_association_dn(&dn, &su_name, "safSu",
>                                            si->name.c_str());
>      AVD_SU *su = su_db->find(Amf::to_string(&su_name));
> +    if (su == nullptr) {
> +      LOG_ER("SU:'%s' does not exist in AMF's sudb",
> +          Amf::to_string(&su_name).c_str());
> +      continue;
> +    }
>      osaf_extended_name_free(&su_name);
> -    osafassert(su);
[Nagu]: If we have SUSI in Imm DB, then SU should exist. Did you get any 
scenario which hits this.

>      susi = avd_su_susi_find(cb, su, si->name);
>      rc = immutil_getAttr("osafAmfSISUFsmState", attributes, 0,
> &imm_susi_fsm);
>      osafassert(rc == SA_AIS_OK);
> @@ -232,10 +239,11 @@ void
> avd_susi_read_headless_cached_rta(AVD_CL_CB *cb) {
>      osafassert(rc == SA_AIS_OK);
> 
>      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);
> +      TRACE("Check present SUSI:'%s', old(imm) fsm state: %d,"
> +          "new(sync) fsm state: %d", Amf::to_string(&dn).c_str(),
> +          imm_susi_fsm, susi->fsm);
> 
> -      if (avd_susi_validate_headless_cached_rta(susi, imm_ha_state,
> +      if (avd_susi_validate_present_assignment(susi, imm_ha_state,
>                                                  imm_susi_fsm) == false) {
>          continue;
>        }
> @@ -279,38 +287,29 @@ void
> avd_susi_read_headless_cached_rta(AVD_CL_CB *cb) {
>        if (susi->su->su_on_node->admin_ng == nullptr)
>          avd_ng_restore_headless_states(cb, susi);
>      } else {  // For ABSENT SUSI
> -      if (su->sg_of_su->sg_ncs_spec == false &&
> -          su->sg_of_su->sg_redundancy_model !=
> SA_AMF_NO_REDUNDANCY_MODEL &&
> -          su->sg_of_su->sg_redundancy_model !=
> -              SA_AMF_N_WAY_ACTIVE_REDUNDANCY_MODEL &&
> -          (su->sg_of_su->any_assignment_in_progress() == true ||
> -           su->sg_of_su->any_assignment_assigned() == true)) {
> -        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(Amf::to_string(&dn));
> -        }
> -      } else {
> +      TRACE("Check absent SUSI, ha_state:'%u', fsm_state:'%u'",
> imm_ha_state,
> +            imm_susi_fsm);
> +      if (avd_susi_validate_absent_assignment(su, si,
> +          imm_ha_state, imm_susi_fsm) == false) {
>          avd_saImmOiRtObjectDelete(Amf::to_string(&dn));
> +        continue;
> +      }
> +      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);
> +        }
>        }
>      }
>    }
> @@ -321,13 +320,58 @@ done:
>    TRACE_LEAVE();
>  }

[Nagu]: I find below function and above changes are just refactoring. It is not 
making any logic change, please confirm?

>  /**
> + * Validate the creation of absent assignment
> + * @param su: The SU associated with absent assignment
> + * @param si: The SI associated with absent assignment
> + * @return: true of valid, false otherwise  */ bool
> +avd_susi_validate_absent_assignment(AVD_SU *su, AVD_SI *si,
> +    SaAmfHAStateT imm_ha_state, AVD_SU_SI_STATE imm_fsm_state) {
> +  bool valid = false;
> +  TRACE_ENTER();
> +  // Must be application sg
> +  if (su->sg_of_su->sg_ncs_spec == true) goto done;
> +  // skip for removing SUSI assignment
> +  if (imm_fsm_state == AVD_SU_SI_STATE_UNASGN) goto done;
> +  // Must have present SUSI assignment
> +  if (su->sg_of_su->any_assignment_in_progress() == false &&
> +      su->sg_of_su->any_assignment_assigned() == false) {
> +    goto done;
> +  }
> +  // Support: 2N, NoRed, NwayActive. Not support: NpM, Nway
> +  if (su->sg_of_su->sg_redundancy_model ==
> SA_AMF_NPM_REDUNDANCY_MODEL ||
> +      su->sg_of_su->sg_redundancy_model ==
> SA_AMF_N_WAY_REDUNDANCY_MODEL) {
> +    LOG_WA("Unsupported SG Redundancy model(%d) for SC Absence",
> +        su->sg_of_su->sg_redundancy_model);
> +  }
> +  // Skip for NoRed and NWayActive
> +  if (su->sg_of_su->sg_redundancy_model ==
> SA_AMF_NO_REDUNDANCY_MODEL ||
> +        su->sg_of_su->sg_redundancy_model ==
> +            SA_AMF_N_WAY_ACTIVE_REDUNDANCY_MODEL) {
> +      goto done;
> +  }
> +  // No need to create absent SUSI assignment for the 2N SI that
> +already has
> +  // ACTIVE SUSI
> +  if (su->sg_of_su->sg_redundancy_model ==
> SA_AMF_2N_REDUNDANCY_MODEL) {
> +    if (si->list_of_sisu != nullptr &&
> +        si->list_of_sisu->state == SA_AMF_HA_ACTIVE &&
> +        imm_ha_state == SA_AMF_HA_ACTIVE)
> +      goto done;
> +  }
> +
> +  valid = true;
> +done:
> +  TRACE_LEAVE();
> +  return valid;
> +}
> +/**
>   * Validate cached RTA read from IMM
>   * @param present_susi
>   * @param ha_fr_imm: Ha state of @present_susi read from IMM
>   * @param fsm_fr_imm: Fsm state of @present susi read from IMM
>   * @return: true of valid, false otherwise
>   */
> -bool avd_susi_validate_headless_cached_rta(AVD_SU_SI_REL
> *present_susi,
> +bool avd_susi_validate_present_assignment(AVD_SU_SI_REL *present_susi,
>                                             SaAmfHAStateT ha_fr_imm,
>                                             AVD_SU_SI_STATE fsm_fr_imm) {
>    std::string dn = present_susi->si->name + "," + present_susi->su->name;
> @@ -335,15 +379,8 @@ bool
> avd_susi_validate_headless_cached_rta(AVD_SU_SI_REL *present_susi,
>    bool valid = true;
>    // rule 1: valid ha state
>    if (ha_fr_imm != present_susi->state) {
> -    if (ha_fr_imm == SA_AMF_HA_QUIESCING || ha_fr_imm ==
> SA_AMF_HA_QUIESCED) {
> -      // That's fine
> -      ;
> -    } else {
> -      LOG_ER("SISU:'%s', old(imm) ha state: %d, new(sync) ha state: %d",
> +      LOG_WA("SISU:'%s', old(imm) ha state: %d, new(sync) ha state:
> + %d",
>               dn.c_str(), ha_fr_imm, present_susi->state);
> -      valid = false;
> -      goto done;
> -    }
>    }

[Nagu]: This change will allow the present susi to go ahead in function and 
will not mark valid as false.
                This means that avd_susi_validate_present_assignment will 
return true. So, how this change is helping
                In solving the problem, please explain.

>    // rule 2: if ha_fr_imm is QUIESCING, one of relevant entities must
>    // have adminState is SHUTTINGDOWN, otherwise re-adjust if possible diff
> --git a/src/amf/amfd/susi.h b/src/amf/amfd/susi.h index
> 94bd04033..5d925baae 100644
> --- a/src/amf/amfd/susi.h
> +++ b/src/amf/amfd/susi.h
> @@ -143,9 +143,11 @@ AVD_SU_SI_REL *avd_susi_create(
> AVD_SU_SI_REL *avd_susi_find(AVD_CL_CB *cb, const std::string
> &su_name,
>                               const std::string &si_name);  void
> avd_susi_update_fsm(AVD_SU_SI_REL *susi, AVD_SU_SI_STATE
> new_fsm_state); -bool
> avd_susi_validate_headless_cached_rta(AVD_SU_SI_REL *present_susi,
> +bool avd_susi_validate_present_assignment(AVD_SU_SI_REL *present_susi,
>                                             SaAmfHAStateT ha_fr_imm,
>                                             AVD_SU_SI_STATE fsm_fr_imm);
> +bool avd_susi_validate_absent_assignment(AVD_SU *su, AVD_SI *si,
> +    SaAmfHAStateT imm_ha_state, AVD_SU_SI_STATE imm_fsm_state);
>  void avd_susi_read_headless_cached_rta(AVD_CL_CB *cb);  extern void
> avd_susi_update(AVD_SU_SI_REL *susi, SaAmfHAStateT ha_state);
> 

[Nagu]: Below logic change has no comment, not sure how this is related to the 
issue.

> diff --git a/src/amf/amfnd/di.cc b/src/amf/amfnd/di.cc index
> 6f0a76cda..0da907566 100644
> --- a/src/amf/amfnd/di.cc
> +++ b/src/amf/amfnd/di.cc
> @@ -1290,6 +1290,7 @@ void avnd_di_msg_ack_process(AVND_CB *cb,
> uint32_t mid) {  void avnd_diq_rec_check_buffered_msg(AVND_CB *cb) {
>    if ((cb->dnd_list.head != nullptr)) {
>      AVND_DND_MSG_LIST *rec = 0;
> +    AVND_DND_MSG_LIST *tail = cb->dnd_list.tail;
>      bool found = true;
>      while (found) {
>        found = false;
> @@ -1318,7 +1319,7 @@ void
> avnd_diq_rec_check_buffered_msg(AVND_CB *cb) {
>                  rec->msg.info.avd->msg_info.n2d_su_si_assign.msg_id);
>            }
>            m_AVND_DIQ_REC_PUSH(cb, rec);
> -          break;
> +          if (tail == cb->dnd_list.tail) break;
>          } else if (rec->msg.info.avd->msg_type ==
>                AVSV_N2D_OPERATION_STATE_MSG) {
>            if (rec->msg.info.avd->msg_info.n2d_opr_state.msg_id != 0) { @@ -
> 1337,11 +1338,12 @@ void avnd_diq_rec_check_buffered_msg(AVND_CB
> *cb) {
>                      .raw);
>            }
>            m_AVND_DIQ_REC_PUSH(cb, rec);
> -          break;
> +          if (tail == cb->dnd_list.tail) break;
>          } else {
>            // delete other messages for now
>            avnd_diq_rec_del(cb, rec);
>            rec = cb->dnd_list.head;
> +          tail = cb->dnd_list.tail;
>          }
>        }
>      }
> --
> 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

Reply via email to