Hi Alex, ack code review only, a few minor comments below/Thanks HansN On 2019-07-18 21:04, Jones, Alex wrote: Allow saAmfRank of SaAmfSIRankedSU to be changed at runtime --- src/amf/amfd/si.cc | 103 +++++++++++++++++++++++++++++++++++++ src/amf/amfd/si.h | 3 ++ src/amf/amfd/siass.cc | 38 ++++++++++++++ src/amf/amfd/sirankedsu.cc | 73 +++++++++++++++++++++++++- src/amf/amfd/util.cc | 30 ++++++++++- 5 files changed, 243 insertions(+), 4 deletions(-)
diff --git a/src/amf/amfd/si.cc b/src/amf/amfd/si.cc index b308e14a9..3f0a8bf51 100644 --- a/src/amf/amfd/si.cc +++ b/src/amf/amfd/si.cc @@ -255,6 +255,109 @@ void AVD_SI::remove_rankedsu(const std::string &suname) { TRACE_LEAVE(); } +/** + * @brief Update order of sisu list with new rank. + * + * @param suname + * @param saAmfRank + */ +void AVD_SI::update_sisu_rank(const std::string& suname, uint32_t newRank) { + TRACE_ENTER(); + + do { + // if there is only one entry nothing really to do + if (!list_of_sisu || !list_of_sisu->si_next) + break; + + // first find the su, and remove it from the linked list [HansN] AVD_SU_SI_REL *matched_susi{nullptr}; (also some more places below) + AVD_SU_SI_REL *matched_susi(0); + + for (AVD_SU_SI_REL *susi(list_of_sisu), *prev(0); [HansN] perhaps, for (AVD_SU_SI_REL *susi = list_of_sisu, *prev = nullptr; or for (AVD_SU_SI_REL *susi{list_of_sisu}, *prev{nullptr} ? + susi; + prev = susi, susi = susi->si_next) { + if (suname == susi->su->name) { + matched_susi = susi; + if (prev) + prev->si_next = susi->si_next; + else + list_of_sisu = susi->si_next; + break; + } + } + + osafassert(matched_susi); + + // now reinsert it at the correct place + AVD_SU_SI_REL *prev(nullptr); + + for (AVD_SU_SI_REL *curr_susi(list_of_sisu); + curr_susi; + prev = curr_susi, curr_susi = curr_susi->si_next) { + if (curr_susi->is_per_si == true) { + if (false == matched_susi->is_per_si) continue; + + AVD_SUS_PER_SI_RANK *i_su_rank_rec(0); + + /* determine the su_rank rec for this rec */ + for (const auto &value : *sirankedsu_db) { + i_su_rank_rec = value.second; + if (i_su_rank_rec->indx.si_name.compare(name) != 0) continue; + AVD_SU *curr_su(su_db->find(i_su_rank_rec->su_name)); + if (curr_su == curr_susi->su) break; + } + + osafassert(i_su_rank_rec); + + if (newRank <= i_su_rank_rec->indx.su_rank) break; + } else { + if (true == matched_susi->is_per_si) break; + + if (newRank <= curr_susi->su->saAmfSURank) break; + } + } + + if (prev) { + matched_susi->si_next = prev->si_next; + prev->si_next = matched_susi; + } else { + matched_susi->si_next = list_of_sisu; + list_of_sisu = matched_susi; + } + + // update PG rank + for (AVD_SU_SI_REL *curr_susi(matched_susi->si->list_of_sisu); + curr_susi; + curr_susi = curr_susi->si_next) { + if (curr_susi->state == SA_AMF_HA_STANDBY) + avd_pg_susi_chg_prc(avd_cb, curr_susi); + } + } while (false); + + TRACE_LEAVE(); +} + +uint32_t AVD_SI::get_sisu_rank(const std::string& suname) const { + uint32_t rank(0); + + TRACE_ENTER2("%s", suname.c_str()); + + for (const AVD_SU_SI_REL *susi(list_of_sisu); susi; susi = susi->si_next) { + TRACE("su: %s si: %s state: %i", + susi->su->name.c_str(), + susi->si->name.c_str(), + susi->state); + if (susi->state == SA_AMF_HA_STANDBY) + rank++; + + if (suname == susi->su->name) + break; + } + + TRACE_LEAVE(); + + return rank; +} + void AVD_SI::remove_csi(AVD_CSI *csi) { osafassert(csi->si == this); /* remove CSI from the SI */ diff --git a/src/amf/amfd/si.h b/src/amf/amfd/si.h index 3b93e56b1..0db8dde13 100644 --- a/src/amf/amfd/si.h +++ b/src/amf/amfd/si.h @@ -128,6 +128,9 @@ class AVD_SI { void add_rankedsu(const std::string &suname, uint32_t saAmfRank); void remove_rankedsu(const std::string &suname); + void update_sisu_rank(const std::string& suname, uint32_t saAmfRank); + + uint32_t get_sisu_rank(const std::string& suname) const; void set_si_switch(AVD_CL_CB *cb, const SaToggleState state); diff --git a/src/amf/amfd/siass.cc b/src/amf/amfd/siass.cc index 8a2d2175e..8895af3b4 100644 --- a/src/amf/amfd/siass.cc +++ b/src/amf/amfd/siass.cc @@ -616,6 +616,21 @@ done: avd_gen_su_ha_state_changed_ntf(cb, su_si); } + /* + * If we are adding an entry which is not the last we need to send PG updates + * for rank. + */ + if (su_si->si_next) { + for (AVD_SU_SI_REL *curr_susi(si->list_of_sisu); + curr_susi; + curr_susi = curr_susi->si_next) { + // skip this one since a pg update will sent for it already + if (su_si == curr_susi || curr_susi->state != SA_AMF_HA_STANDBY) continue; + + avd_pg_susi_chg_prc(avd_cb, curr_susi); + } + } + TRACE_LEAVE(); return su_si; } @@ -742,13 +757,36 @@ uint32_t avd_susi_delete(AVD_CL_CB *cb, AVD_SU_SI_REL *susi, bool ckpt) { susi->su_next = nullptr; } + bool sendPgUpdate(false); + /* now delete it from the SI list */ if (p_si_su == nullptr) { susi->si->list_of_sisu = susi->si_next; susi->si_next = nullptr; + + if (susi->si->list_of_sisu) + sendPgUpdate = true; } else { p_si_su->si_next = susi->si_next; susi->si_next = nullptr; + + if (p_si_su->si_next) + sendPgUpdate = true; + } + + /* + * If we are removing an entry which is not the last we need to send PG + * updates for rank. + */ + if (sendPgUpdate) { + for (AVD_SU_SI_REL *curr_susi(susi->si->list_of_sisu); + curr_susi; + curr_susi = curr_susi->si_next) { + // skip this one since a pg update will sent for it already + if (susi == curr_susi || curr_susi->state != SA_AMF_HA_STANDBY) continue; + + avd_pg_susi_chg_prc(avd_cb, curr_susi); + } } if (ckpt == false) { diff --git a/src/amf/amfd/sirankedsu.cc b/src/amf/amfd/sirankedsu.cc index 64cde49f5..0b1005eb7 100644 --- a/src/amf/amfd/sirankedsu.cc +++ b/src/amf/amfd/sirankedsu.cc @@ -338,6 +338,38 @@ static void sirankedsu_ccb_apply_cb(CcbUtilOperationData_t *opdata) { &opdata->objectName, opdata->param.create.attrValues); avd_sirankedsu_db_add(avd_sirankedsu); + break; + case CCBUTIL_MODIFY: + if (opdata->userData == nullptr && avd_cb->is_active () == false) + break; + osafassert(opdata->userData != nullptr); + + avd_sirankedsu = static_cast<AVD_SUS_PER_SI_RANK *>(opdata->userData); + + for (int i(0); opdata->param.modify.attrMods[i]; i++) { + const SaImmAttrModificationT_2 *attr_mod( + opdata->param.modify.attrMods[i]); + + if (!strcmp(attr_mod->modAttr.attrName, "saAmfRank")) { + AVD_SI *avd_si(avd_si_get(avd_sirankedsu->indx.si_name)); + + // remove and readd the ranked su + avd_si->remove_rankedsu(avd_sirankedsu->su_name); + + TRACE("saAmfRank modified from '%u' to '%u'", + avd_sirankedsu->indx.su_rank, + *((SaUint32T *)attr_mod->modAttr.attrValues[0])); + avd_sirankedsu->indx.su_rank = + *((SaUint32T *)attr_mod->modAttr.attrValues[0]); + + avd_si->add_rankedsu(avd_sirankedsu->su_name, + avd_sirankedsu->indx.su_rank); + + // update any runtime rankings + avd_si->update_sisu_rank(avd_sirankedsu->su_name, + avd_sirankedsu->indx.su_rank); + } + } break; case CCBUTIL_DELETE: if (opdata->userData == nullptr && avd_cb->is_active () == false) { @@ -357,6 +389,44 @@ static void sirankedsu_ccb_apply_cb(CcbUtilOperationData_t *opdata) { TRACE_LEAVE(); } +static SaAisErrorT ccb_completed_modify_hdlr(CcbUtilOperationData_t *opdata) { + TRACE_ENTER2("'%s'", osaf_extended_name_borrow(&opdata->objectName)); + + SaAisErrorT rc(SA_AIS_OK); + + do { + std::string su_name, si_name; + + avd_susi_namet_init(Amf::to_string(&opdata->objectName), su_name, si_name); + + bool found(false); + + AVD_SUS_PER_SI_RANK *su_rank_rec(0); + + /* determine if the su is ranked per si */ + for (const auto &value : *sirankedsu_db) { + su_rank_rec = value.second; + + if (su_rank_rec->indx.si_name.compare(si_name) == 0 && + su_rank_rec->su_name.compare(su_name) == 0) { + found = true; + break; + } + } + + if (false == found) { + LOG_ER("'%s' not found", osaf_extended_name_borrow(&opdata->objectName)); + rc = SA_AIS_ERR_FAILED_OPERATION; + break; + } + + opdata->userData = su_rank_rec; + } while (false); + + TRACE_LEAVE(); + return rc; +} + static int avd_sirankedsu_ccb_complete_delete_hdlr( CcbUtilOperationData_t *opdata) { AVD_SI *si = nullptr; @@ -424,8 +494,7 @@ static SaAisErrorT sirankedsu_ccb_completed_cb(CcbUtilOperationData_t *opdata) { rc = SA_AIS_OK; break; case CCBUTIL_MODIFY: - report_ccb_validation_error( - opdata, "Modification of SaAmfSIRankedSU not supported"); + rc = ccb_completed_modify_hdlr(opdata); break; case CCBUTIL_DELETE: { if (avd_sirankedsu_ccb_complete_delete_hdlr(opdata)) rc = SA_AIS_OK; diff --git a/src/amf/amfd/util.cc b/src/amf/amfd/util.cc index 0dc3e99e3..70b7233b8 100644 --- a/src/amf/amfd/util.cc +++ b/src/amf/amfd/util.cc @@ -948,6 +948,30 @@ uint32_t avd_snd_susi_msg(AVD_CL_CB *cb, AVD_SU *su, AVD_SU_SI_REL *susi, } } + if (susi_msg->msg_info.d2n_su_si_assign.ha_state == SA_AMF_HA_STANDBY) { + // fill in standby descriptor info + for (const AVD_SU_SI_REL *curr_susi(l_compcsi->susi->si->list_of_sisu); + curr_susi; + curr_susi = curr_susi->si_next) { + if (curr_susi->state == SA_AMF_HA_ACTIVE) { + for (const AVD_COMP_CSI_REL *comp_csi(curr_susi->list_of_csicomp); + comp_csi; + comp_csi = comp_csi->susi_csicomp_next) { + if (comp_csi->csi == l_compcsi->csi) { + osaf_extended_name_alloc( + osaf_extended_name_borrow(&comp_csi->comp->comp_info.name), + &compcsi_info->active_comp_name); + break; + } + } + break; + } + } + + compcsi_info->stdby_rank = + l_compcsi->csi->si->get_sisu_rank(l_compcsi->susi->su->name); + } + compcsi_info->next = susi_msg->msg_info.d2n_su_si_assign.list; susi_msg->msg_info.d2n_su_si_assign.list = compcsi_info; susi_msg->msg_info.d2n_su_si_assign.num_assigns++; @@ -1016,7 +1040,8 @@ static uint32_t avd_prep_pg_mem_list( osaf_extended_name_borrow(&curr->comp->comp_info.name), &comp_name); mem_list->notification[i].member.compName = comp_name; mem_list->notification[i].member.haState = curr->susi->state; - mem_list->notification[i].member.rank = curr->comp->su->saAmfSURank; + mem_list->notification[i].member.rank = + curr->susi->si->get_sisu_rank(curr->comp->su->name); mem_list->notification[i].change = SA_AMF_PROTECTION_GROUP_NO_CHANGE; mem_list->numberOfItems++; } /* for */ @@ -1140,7 +1165,8 @@ uint32_t avd_snd_pg_upd_msg(AVD_CL_CB *cb, AVD_AVND *node, osaf_extended_name_borrow(&comp_csi->comp->comp_info.name), &comp_name); pg_msg_info->mem.member.compName = comp_name; pg_msg_info->mem.member.haState = comp_csi->susi->state; - pg_msg_info->mem.member.rank = comp_csi->comp->su->saAmfSURank; + pg_msg_info->mem.member.rank = + comp_csi->susi->si->get_sisu_rank(comp_csi->comp->su->name); pg_msg_info->mem.change = change; } else { osaf_extended_name_alloc(csi_name.c_str(), &temp_csi_name); -- 2.20.1 ________________________________ Notice: This e-mail together with any attachments may contain information of Ribbon Communications Inc. that is confidential and/or proprietary for the sole use of the intended recipient. Any review, disclosure, reliance or distribution by others or forwarding without express permission is strictly prohibited. If you are not the intended recipient, please notify the sender immediately and then delete all copies, including any attachments. ________________________________ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel