osaf/libs/common/amf/d2nedu.c | 5 +- osaf/libs/common/amf/include/amf_d2nmsg.h | 4 + osaf/libs/common/amf/include/amf_si_assign.h | 2 +- osaf/services/saf/amf/amfd/cluster.cc | 4 + osaf/services/saf/amf/amfd/csi.cc | 93 ++++++---- osaf/services/saf/amf/amfd/imm.cc | 5 +- osaf/services/saf/amf/amfd/include/csi.h | 3 +- osaf/services/saf/amf/amfd/include/imm.h | 5 +- osaf/services/saf/amf/amfd/include/mds.h | 7 +- osaf/services/saf/amf/amfd/include/proc.h | 4 +- osaf/services/saf/amf/amfd/include/sg.h | 7 +- osaf/services/saf/amf/amfd/include/su.h | 6 +- osaf/services/saf/amf/amfd/include/susi.h | 10 +- osaf/services/saf/amf/amfd/include/util.h | 2 + osaf/services/saf/amf/amfd/mds.cc | 7 +- osaf/services/saf/amf/amfd/ndfsm.cc | 13 +- osaf/services/saf/amf/amfd/role.cc | 6 - osaf/services/saf/amf/amfd/sg.cc | 101 +++++++++++- osaf/services/saf/amf/amfd/sg_2n_fsm.cc | 8 +- osaf/services/saf/amf/amfd/sg_npm_fsm.cc | 2 +- osaf/services/saf/amf/amfd/sg_nwayact_fsm.cc | 2 +- osaf/services/saf/amf/amfd/sgproc.cc | 148 +++++++++------- osaf/services/saf/amf/amfd/siass.cc | 220 +++++++++++++++++------- osaf/services/saf/amf/amfd/su.cc | 103 +++++++++-- osaf/services/saf/amf/amfnd/di.cc | 14 +- osaf/services/saf/amf/amfnd/include/avnd_mds.h | 4 +- osaf/services/saf/amf/amfnd/mds.cc | 6 +- osaf/services/saf/amf/config/amf_classes.xml | 28 +++ 28 files changed, 584 insertions(+), 235 deletions(-)
If there's an admin operation running and at that time cluster goes into headless stage, the normal admin operation sequence is interrupted. Since both SCs are down, the SI assignments at AMFND could be on going or completed during headless period. After headless this admin operation should be continued. This patch series supports the admin operation continuation after headless. To resume the admin operation after headless, the states need to be restored are: SUSI fsm states, SG fsm states, SI Dependency states (not suppported in this patch), SU Switch toggle, and SU operation list in SG at the time cluster goes headless. At this moment, the SG fsm states are set variously in each specific SG models. Also, the rule that a SU to be added in SG's operation list is not consistent. A SU is added to operation list after AMFD sends su_si_assign event on this SU in most of the places. However, there're are some scenarios that a SU is added to the list for other purposes (failover). These difficulties make the state deduction logic hard to implemenent. This patch introduces new RTA states: osafAmfSGSuOperationList, osafAmfSGFsmState, osafAmfSISUFsmState and osafAmfSUSwitch to capture the SU operation list of SG, SG fsm state, SUSI fsm state, and SU Switch of AMFD memory to IMM during AMFD lifetime. When cluster comes back from headless, these RTA will read from IMM to restore states in AMFD's memory. It also adds additional field in state_info (headless synchronization) message which indicates current SUSI fsm states. Both of SUSI fsm states help to validate the new RTA states read from IMM after headless. Example: if IMM SUSI fsm state is ASGN, synced SUSI fsm state is ASGND, then HA state must be ACTIVE or STANDBY. Such validation is indeed neccessary since headless interruption is unplanned and the recovery heavily depends on RTA read from IMM. diff --git a/osaf/libs/common/amf/d2nedu.c b/osaf/libs/common/amf/d2nedu.c --- a/osaf/libs/common/amf/d2nedu.c +++ b/osaf/libs/common/amf/d2nedu.c @@ -865,6 +865,7 @@ uint32_t avsv_edp_sisu_state_info_msg(ED { uint32_t rc = NCSCC_RC_SUCCESS; AVSV_SISU_STATE_MSG *struct_ptr = NULL, **d_ptr = NULL; + uint16_t ver7 = AVSV_AVD_AVND_MSG_FMT_VER_7; EDU_INST_SET avsv_sisu_state_msg_rules[] = { {EDU_START, avsv_edp_sisu_state_info_msg, EDQ_LNKLIST, 0, 0, @@ -876,7 +877,9 @@ uint32_t avsv_edp_sisu_state_info_msg(ED (long)&((AVSV_SISU_STATE_MSG *)0)->safSI, 0, NULL}, {EDU_EXEC, m_NCS_EDP_SAAMFHASTATET, 0, 0, 0, (long)&((AVSV_SISU_STATE_MSG *)0)->saAmfSISUHAState, 0, NULL}, - + {EDU_VER_GE, NULL, 0, 0, 2, 0, 0, (EDU_EXEC_RTINE)((uint16_t *)(&(ver7)))}, + {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, + (long)&((AVSV_SISU_STATE_MSG *)0)->assignmentAct, 0, NULL}, {EDU_TEST_LL_PTR, avsv_edp_sisu_state_info_msg, 0, 0, 0, (long)&((AVSV_SISU_STATE_MSG *)0)->next, 0, NULL}, {EDU_END, 0, 0, 0, 0, 0, 0, NULL}, diff --git a/osaf/libs/common/amf/include/amf_d2nmsg.h b/osaf/libs/common/amf/include/amf_d2nmsg.h --- a/osaf/libs/common/amf/include/amf_d2nmsg.h +++ b/osaf/libs/common/amf/include/amf_d2nmsg.h @@ -50,6 +50,7 @@ extern "C" { #define AVSV_AVD_AVND_MSG_FMT_VER_4 4 #define AVSV_AVD_AVND_MSG_FMT_VER_5 5 #define AVSV_AVD_AVND_MSG_FMT_VER_6 6 +#define AVSV_AVD_AVND_MSG_FMT_VER_7 7 /* Internode/External Components Validation result */ typedef enum { @@ -325,7 +326,9 @@ typedef struct avsv_param_info { * Tese values are mapped to SU_SI fsm states */ typedef enum { AVSV_SUSI_ACT_BASE = 0, + //AVSV_SUSI_ACT_ABSENT = 1, /*AVD_SU_SI_STATE_ABSENT */ AVSV_SUSI_ACT_ASGN = 2, /*AVD_SU_SI_STATE_ASGN */ + AVSV_SUSI_ACT_ASGND = 3, /*AVD_SU_SI_STATE_ASGND */ AVSV_SUSI_ACT_DEL = 4, /* AVD_SU_SI_STATE_UNASGN */ AVSV_SUSI_ACT_MOD = 5, /* AVD_SU_SI_STATE_MODIFY */ } AVSV_SUSI_ACT; @@ -438,6 +441,7 @@ typedef struct avsv_sisu_state_msg_tag { SaNameT safSU; SaNameT safSI; SaAmfHAStateT saAmfSISUHAState; + uint32_t assignmentAct; struct avsv_sisu_state_msg_tag *next; } AVSV_SISU_STATE_MSG; diff --git a/osaf/libs/common/amf/include/amf_si_assign.h b/osaf/libs/common/amf/include/amf_si_assign.h --- a/osaf/libs/common/amf/include/amf_si_assign.h +++ b/osaf/libs/common/amf/include/amf_si_assign.h @@ -26,7 +26,6 @@ #ifndef AMF_SI_ASSIGN_H #define AMF_SI_ASSIGN_H -#include <string> #include <saAmf.h> struct SaAmfSIAssignment { @@ -35,6 +34,7 @@ struct SaAmfSIAssignment { SaNameT si; SaAmfHAStateT saAmfSISUHAState; uint32_t saAmfSISUHAReadinessState; + uint32_t assignmentAct; }; struct SaAmfCSIAssignment { 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 @@ -83,6 +83,10 @@ void avd_cluster_tmr_init_evh(AVD_CL_CB continue; } + if (i_sg->any_assignment_in_progress() == false) { + i_sg->set_fsm_state(AVD_SG_FSM_STABLE); + } + if (i_sg->sg_fsm_state == AVD_SG_FSM_STABLE) i_sg->realign(cb, i_sg); } diff --git a/osaf/services/saf/amf/amfd/csi.cc b/osaf/services/saf/amf/amfd/csi.cc --- a/osaf/services/saf/amf/amfd/csi.cc +++ b/osaf/services/saf/amf/amfd/csi.cc @@ -1411,44 +1411,6 @@ bool are_sponsor_csis_assigned_in_su(AVD } /** - * Clean up COMPCSI objects by searching for SaAmfCSIAssignment instances in IMM - * @return SA_AIS_OK when OK - */ -SaAisErrorT avd_compcsi_cleanup(void) -{ - SaAisErrorT rc; - SaImmSearchHandleT searchHandle; - SaImmSearchParametersT_2 searchParam; - const char *className = "SaAmfCSIAssignment"; - - TRACE_ENTER(); - - searchParam.searchOneAttr.attrName = const_cast<SaImmAttrNameT>("SaImmAttrClassName"); - searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT; - searchParam.searchOneAttr.attrValue = &className; - - if ((rc = immutil_saImmOmSearchInitialize_2(avd_cb->immOmHandle, nullptr, SA_IMM_SUBTREE, - SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_NO_ATTR, &searchParam, - nullptr, &searchHandle)) != SA_AIS_OK) { - LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc); - goto done; - } - - SaNameT csiass_name; - const SaImmAttrValuesT_2 **attributes; - while ((rc = immutil_saImmOmSearchNext_2(searchHandle, &csiass_name, - (SaImmAttrValuesT_2 ***)&attributes)) == SA_AIS_OK) { - avd_saImmOiRtObjectDelete(&csiass_name); - } - - (void)immutil_saImmOmSearchFinalize(searchHandle); - -done: - TRACE_LEAVE(); - return SA_AIS_OK; -} - -/** * Re-create csi assignment and update comp related states, which are * collected after headless * Update relevant runtime attributes @@ -1515,3 +1477,58 @@ SaAisErrorT avd_compcsi_recreate(AVSV_N2 return SA_AIS_OK; } +void avd_compcsi_cleanup_imm_object(AVD_CL_CB *cb) +{ + SaAisErrorT rc; + SaImmSearchHandleT searchHandle; + SaImmSearchParametersT_2 searchParam; + + SaNameT dn, comp_name; + const SaImmAttrValuesT_2 **attributes; + AVD_SU_SI_REL *susi; + + const char *className = "SaAmfCSIAssignment"; + const SaImmAttrNameT siass_attributes[] = { + const_cast<SaImmAttrNameT>("safCSIComp"), + NULL + }; + + TRACE_ENTER(); + + osafassert(cb->scs_absence_max_duration > 0); + + searchParam.searchOneAttr.attrName = const_cast<SaImmAttrNameT>("SaImmAttrClassName"); + searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT; + searchParam.searchOneAttr.attrValue = &className; + + if ((rc = immutil_saImmOmSearchInitialize_2(cb->immOmHandle, NULL, SA_IMM_SUBTREE, + SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR, &searchParam, + siass_attributes, &searchHandle)) != SA_AIS_OK) { + + LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc); + goto done; + } + + while ((rc = immutil_saImmOmSearchNext_2(searchHandle, &dn, + (SaImmAttrValuesT_2 ***)&attributes)) == SA_AIS_OK) { + AVD_SI *si = si_db->find(strstr((char*)dn.value, "safSi")); + osafassert(si); + + AVD_CSI *csi = csi_db->find(strstr((char*)dn.value, "safCsi")); + osafassert(csi); + + avsv_sanamet_init_from_association_dn(&dn, &comp_name, "safComp", (char*)csi->name.value); + AVD_COMP *comp = comp_db->find(Amf::to_string(&comp_name)); + osafassert(comp); + + susi = avd_susi_find(avd_cb, &comp->su->name, &si->name); + if (susi == nullptr || (susi->fsm == AVD_SU_SI_STATE_ABSENT)) { + avd_saImmOiRtObjectDelete(&dn); + } + } + + (void)immutil_saImmOmSearchFinalize(searchHandle); + +done: + TRACE_LEAVE(); +} diff --git a/osaf/services/saf/amf/amfd/imm.cc b/osaf/services/saf/amf/amfd/imm.cc --- a/osaf/services/saf/amf/amfd/imm.cc +++ b/osaf/services/saf/amf/amfd/imm.cc @@ -1588,7 +1588,8 @@ done: * @param value */ SaAisErrorT avd_saImmOiRtObjectUpdate_sync(const SaNameT *dn, SaImmAttrNameT attributeName, - SaImmValueTypeT attrValueType, void *value) + SaImmValueTypeT attrValueType, void *value, + SaImmAttrModificationTypeT modifyType) { SaAisErrorT rc; SaImmAttrModificationT_2 attrMod; @@ -1597,7 +1598,7 @@ SaAisErrorT avd_saImmOiRtObjectUpdate_sy TRACE_ENTER2("'%s' %s", dn->value, attributeName); - attrMod.modType = SA_IMM_ATTR_VALUES_REPLACE; + attrMod.modType = modifyType; attrMod.modAttr.attrName = attributeName; attrMod.modAttr.attrValuesNumber = 1; attrMod.modAttr.attrValueType = attrValueType; diff --git a/osaf/services/saf/amf/amfd/include/csi.h b/osaf/services/saf/amf/amfd/include/csi.h --- a/osaf/services/saf/amf/amfd/include/csi.h +++ b/osaf/services/saf/amf/amfd/include/csi.h @@ -184,7 +184,6 @@ extern AVD_CSI *csi_create(const SaNameT extern bool csi_assignment_validate(AVD_SG *sg); extern SaAisErrorT csi_assign_hdlr(AVD_CSI *csi); extern bool are_sponsor_csis_assigned_in_su(AVD_CSI *dep_csi, AVD_SU *su); -SaAisErrorT avd_compcsi_cleanup(void); SaAisErrorT avd_compcsi_recreate(AVSV_N2D_ND_CSICOMP_STATE_MSG_INFO *info); - +void avd_compcsi_cleanup_imm_object(AVD_CL_CB *cb); #endif diff --git a/osaf/services/saf/amf/amfd/include/imm.h b/osaf/services/saf/amf/amfd/include/imm.h --- a/osaf/services/saf/amf/amfd/include/imm.h +++ b/osaf/services/saf/amf/amfd/include/imm.h @@ -147,10 +147,11 @@ void avd_class_impl_set(const char *clas * @return SaAisErrorT */ SaAisErrorT avd_imm_default_OK_completed_cb(CcbUtilOperationData_t *opdata); +SaAisErrorT avd_saImmOiRtObjectUpdate_sync(const SaNameT *dn, + SaImmAttrNameT attributeName, SaImmValueTypeT attrValueType, void *value, + SaImmAttrModificationTypeT modifyType = SA_IMM_ATTR_VALUES_REPLACE); extern unsigned int avd_imm_config_get(void); -extern SaAisErrorT avd_saImmOiRtObjectUpdate_sync(const SaNameT *dn, - SaImmAttrNameT attributeName, SaImmValueTypeT attrValueType, void *value); extern void avd_saImmOiRtObjectUpdate(const SaNameT* dn, const char *attributeName, SaImmValueTypeT attrValueType, void* value); extern void avd_saImmOiRtObjectCreate(const char *className, diff --git a/osaf/services/saf/amf/amfd/include/mds.h b/osaf/services/saf/amf/amfd/include/mds.h --- a/osaf/services/saf/amf/amfd/include/mds.h +++ b/osaf/services/saf/amf/amfd/include/mds.h @@ -33,13 +33,13 @@ /* In Service upgrade support */ #define AVD_MDS_SUB_PART_VERSION_4 4 -#define AVD_MDS_SUB_PART_VERSION 6 +#define AVD_MDS_SUB_PART_VERSION 7 #define AVD_AVND_SUBPART_VER_MIN 1 -#define AVD_AVND_SUBPART_VER_MAX 6 +#define AVD_AVND_SUBPART_VER_MAX 7 #define AVD_AVD_SUBPART_VER_MIN 1 -#define AVD_AVD_SUBPART_VER_MAX 6 +#define AVD_AVD_SUBPART_VER_MAX 7 /* Message format versions */ #define AVD_AVD_MSG_FMT_VER_1 1 @@ -48,6 +48,7 @@ #define AVD_AVD_MSG_FMT_VER_4 4 #define AVD_AVD_MSG_FMT_VER_5 5 #define AVD_AVD_MSG_FMT_VER_6 6 +#define AVD_AVD_MSG_FMT_VER_7 7 uint32_t avd_mds_set_vdest_role(struct cl_cb_tag *cb, SaAmfHAStateT role); uint32_t avd_mds_init(struct cl_cb_tag *cb); diff --git a/osaf/services/saf/amf/amfd/include/proc.h b/osaf/services/saf/amf/amfd/include/proc.h --- a/osaf/services/saf/amf/amfd/include/proc.h +++ b/osaf/services/saf/amf/amfd/include/proc.h @@ -46,8 +46,8 @@ uint32_t avd_new_assgn_susi(AVD_CL_CB *c void su_try_repair(const AVD_SU *su); void avd_sg_app_node_su_inst_func(AVD_CL_CB *cb, AVD_AVND *avnd); uint32_t avd_sg_app_su_inst_func(AVD_CL_CB *cb, AVD_SG *sg); -uint32_t avd_sg_su_oper_list_add(AVD_CL_CB *cb, AVD_SU *su, bool ckpt); -uint32_t avd_sg_su_oper_list_del(AVD_CL_CB *cb, AVD_SU *su, bool ckpt); +uint32_t avd_sg_su_oper_list_add(AVD_CL_CB *cb, AVD_SU *su, bool ckpt, bool wrt_to_imm = true); +uint32_t avd_sg_su_oper_list_del(AVD_CL_CB *cb, AVD_SU *su, bool ckpt, bool wrt_to_imm = true); uint32_t avd_sg_app_sg_admin_func(AVD_CL_CB *cb, AVD_SG *sg); uint32_t avd_sg_su_si_mod_snd(AVD_CL_CB *cb, AVD_SU *su, SaAmfHAStateT state); uint32_t avd_sg_susi_mod_snd_honouring_si_dependency(AVD_SU *su, SaAmfHAStateT state); 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 @@ -185,7 +185,7 @@ public: */ std::vector<AVD_SU*> list_of_su; AVD_SU* first_su(); - + AVD_SU* get_su_by_name(SaNameT su_name); /* the list of service instances in * this group in the descending order * of the rank. @@ -222,7 +222,7 @@ public: * Set FSM state * @param sg_fsm_state */ - void set_fsm_state(AVD_SG_FSM_STATE sg_fsm_state); + void set_fsm_state(AVD_SG_FSM_STATE sg_fsm_state, bool wrt_to_imm = true); /** * Set adjust state @@ -414,6 +414,7 @@ public: */ bool is_sg_serviceable_outside_ng(const AVD_AMF_NG *ng); SaAisErrorT check_sg_stability(); + bool any_assignment_in_progress(); bool ng_using_saAmfSGAdminState; uint32_t term_su_list_in_reverse(); @@ -575,6 +576,8 @@ private: #define m_AVD_CLEAR_SG_ADMIN_SI(cb,sg) (sg)->clear_admin_si() #define m_AVD_CHK_OPLIST(i_su,flag) (flag) = (i_su)->sg_of_su->in_su_oper_list(i_su) +void avd_sg_read_headless_cached_rta(AVD_CL_CB *cb); + extern void avd_sg_delete(AVD_SG *sg); extern void avd_sg_db_add(AVD_SG *sg); extern void avd_sg_db_remove(AVD_SG *sg); diff --git a/osaf/services/saf/amf/amfd/include/su.h b/osaf/services/saf/amf/amfd/include/su.h --- a/osaf/services/saf/amf/amfd/include/su.h +++ b/osaf/services/saf/amf/amfd/include/su.h @@ -115,7 +115,7 @@ class AVD_SU { void set_all_susis_assigned(void); void set_term_state(bool state); void remove_from_model(); - void set_su_switch(SaToggleState state); + void set_su_switch(SaToggleState state, bool wrt_to_imm = true); AVD_AVND *get_node_ptr(void); bool is_in_service(void); bool is_instantiable(void); @@ -133,8 +133,7 @@ class AVD_SU { void shutdown(SaImmOiHandleT immoi_handle, SaInvocationT invocation); void lock(SaImmOiHandleT immoi_handle, SaInvocationT invocation, SaAmfAdminStateT adm_state); - bool any_susi_fsm_in_unasgn(); - bool any_susi_fsm_in_modify(); + bool any_susi_fsm_in(uint32_t check_fsm); SaAisErrorT check_su_stability(); uint32_t curr_num_standby_sis(); uint32_t curr_num_active_sis(); @@ -174,4 +173,5 @@ extern SaAisErrorT avd_su_config_get(con */ extern void avd_su_constructor(void); extern void su_ccb_apply_delete_hdlr(struct CcbUtilOperationData *opdata); +void avd_su_read_headless_cached_rta(AVD_CL_CB *cb); #endif 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 @@ -39,7 +39,8 @@ #include <ntf.h> typedef enum { - AVD_SU_SI_STATE_ABSENT = 1, + AVD_SU_SI_STATE_BASE = AVSV_SUSI_ACT_BASE, + AVD_SU_SI_STATE_ABSENT, AVD_SU_SI_STATE_ASGN, AVD_SU_SI_STATE_ASGND, AVD_SU_SI_STATE_UNASGN, @@ -136,8 +137,12 @@ extern AmfDb<std::pair<std::string, uint avd_susi_delete(cb,susi,false);\ } -AVD_SU_SI_REL *avd_susi_create(AVD_CL_CB *cb, AVD_SI *si, AVD_SU *su, SaAmfHAStateT state, bool ckpt); +AVD_SU_SI_REL *avd_susi_create(AVD_CL_CB *cb, AVD_SI *si, AVD_SU *su, SaAmfHAStateT state, + bool ckpt, AVSV_SUSI_ACT default_act = AVSV_SUSI_ACT_BASE, + AVD_SU_SI_STATE default_fsm = AVD_SU_SI_STATE_ABSENT); AVD_SU_SI_REL *avd_susi_find(AVD_CL_CB *cb, const SaNameT *su_name, const SaNameT *si_name); +void avd_susi_update_fsm(AVD_SU_SI_REL *susi, AVD_SU_SI_STATE new_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); AVD_SU_SI_REL *avd_su_susi_find(AVD_CL_CB *cb, AVD_SU *su, const SaNameT *si_name); @@ -157,7 +162,6 @@ extern bool si_assignment_state_check(AV extern SaAmfHAStateT avd_su_state_determine(AVD_SU *su); extern AVD_SU_SI_REL *avd_siass_next_susi_to_quiesce(const AVD_SU_SI_REL *susi); extern bool avd_susi_quiesced_canbe_given(const AVD_SU_SI_REL *susi); -SaAisErrorT avd_susi_cleanup(void); SaAisErrorT avd_susi_recreate(AVSV_N2D_ND_SISU_STATE_MSG_INFO*); #endif diff --git a/osaf/services/saf/amf/amfd/include/util.h b/osaf/services/saf/amf/amfd/include/util.h --- a/osaf/services/saf/amf/amfd/include/util.h +++ b/osaf/services/saf/amf/amfd/include/util.h @@ -96,4 +96,6 @@ extern void d2n_msg_free(AVSV_DND_MSG *m extern const char* avd_getparent(const char* dn); extern bool object_exist_in_imm(const SaNameT *dn); extern const char *admin_op_name(SaAmfAdminOperationIdT opid); +void avsv_sanamet_init_from_association_dn(const SaNameT *haystack, SaNameT *dn, + const char *needle, const char *parent); #endif diff --git a/osaf/services/saf/amf/amfd/mds.cc b/osaf/services/saf/amf/amfd/mds.cc --- a/osaf/services/saf/amf/amfd/mds.cc +++ b/osaf/services/saf/amf/amfd/mds.cc @@ -45,13 +45,16 @@ const MDS_CLIENT_MSG_FORMAT_VER avd_avnd_msg_fmt_map_table[] = { AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2, AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4, - AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6 + AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6, + AVSV_AVD_AVND_MSG_FMT_VER_7 }; const MDS_CLIENT_MSG_FORMAT_VER avd_avd_msg_fmt_map_table[] = { AVD_AVD_MSG_FMT_VER_1, AVD_AVD_MSG_FMT_VER_2, AVD_AVD_MSG_FMT_VER_3, AVD_AVD_MSG_FMT_VER_4, - AVD_AVD_MSG_FMT_VER_5, AVD_AVD_MSG_FMT_VER_6}; + AVD_AVD_MSG_FMT_VER_5, AVD_AVD_MSG_FMT_VER_6, + AVD_AVD_MSG_FMT_VER_7 +}; /* fwd decl */ 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 @@ -53,7 +53,7 @@ void avd_process_state_info_queue(AVD_CL AVD_EVT_QUEUE *queue_evt = nullptr; /* Counter for Act Amfnd node up message.*/ static int act_amfnd_node_up_count = 0; - + bool found_state_info = false; TRACE_ENTER(); TRACE("queue_size before processing: %lu", (unsigned long) queue_size); @@ -72,7 +72,7 @@ void avd_process_state_info_queue(AVD_CL AVD_DND_MSG* n2d_msg = queue_evt->evt->info.avnd_msg; TRACE("msg_type: %u", n2d_msg->msg_type); - + found_state_info = true; switch(n2d_msg->msg_type) { case AVSV_N2D_ND_SISU_STATE_INFO_MSG: avd_susi_recreate(&n2d_msg->msg_info.n2d_nd_sisu_state_info); @@ -124,6 +124,15 @@ void avd_process_state_info_queue(AVD_CL } } } + + // Read cached rta from Imm + // Reading sg must be after reading susi + 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_su_read_headless_cached_rta(cb); + } done: TRACE("queue_size after processing: %lu", (unsigned long) cb->evt_queue.size()); TRACE_LEAVE(); diff --git a/osaf/services/saf/amf/amfd/role.cc b/osaf/services/saf/amf/amfd/role.cc --- a/osaf/services/saf/amf/amfd/role.cc +++ b/osaf/services/saf/amf/amfd/role.cc @@ -227,12 +227,6 @@ uint32_t initialize_for_assignment(cl_cb goto done; } - /* in a normal cluster start there will be no assignments object found so - * nothing happens. Used to cleanup cached RTAs after SCs recover after - * being headless. - */ - avd_susi_cleanup(); - avd_compcsi_cleanup(); } else if (ha_state == SA_AMF_HA_STANDBY) { rc = avd_standby_role_initialization(cb); if (rc != NCSCC_RC_SUCCESS) { 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 @@ -1661,7 +1661,7 @@ void AVD_SG::set_admin_state(SaAmfAdminS saflog(LOG_NOTICE, amfSvcUsrName, "%s AdmState %s => %s", name.value, avd_adm_state_name[old_state], avd_adm_state_name[state]); saAmfSGAdminState = state; - avd_saImmOiRtObjectUpdate(&name, + avd_saImmOiRtObjectUpdate(const_cast<SaNameT*>(&name), const_cast<SaImmAttrNameT>("saAmfSGAdminState"), SA_IMM_ATTR_SAUINT32T, &saAmfSGAdminState); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, this, AVSV_CKPT_SG_ADMIN_STATE); @@ -1671,13 +1671,18 @@ void AVD_SG::set_admin_state(SaAmfAdminS TRACE_LEAVE(); } -void AVD_SG::set_fsm_state(AVD_SG_FSM_STATE state) { +void AVD_SG::set_fsm_state(AVD_SG_FSM_STATE state, bool wrt_to_imm) { TRACE_ENTER(); if (sg_fsm_state != state) { TRACE("%s sg_fsm_state %u => %u", name.value, sg_fsm_state, state); sg_fsm_state = state; m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, this, AVSV_CKPT_SG_FSM_STATE); + if (avd_cb->scs_absence_max_duration > 0 && wrt_to_imm) { + avd_saImmOiRtObjectUpdate_sync(const_cast<SaNameT*>(&name), + const_cast<SaImmAttrNameT>("osafAmfSGFsmState"), + SA_IMM_ATTR_SAUINT32T, &sg_fsm_state); + } } if (state == AVD_SG_FSM_STABLE) { @@ -2043,6 +2048,17 @@ AVD_SU* AVD_SG::first_su() } } +AVD_SU* AVD_SG::get_su_by_name(SaNameT su_name) +{ + for (const auto& su : list_of_su) { + if (Amf::to_string(const_cast<SaNameT*>(&su->name)) == + Amf::to_string(const_cast<SaNameT*>(&su_name))) { + return su; + } + } + return nullptr; +} + uint32_t AVD_SG::curr_assigned_sus() const { return (std::count_if (list_of_su.cbegin(), list_of_su.cend(), @@ -2060,3 +2076,84 @@ uint32_t AVD_SG::curr_non_instantiated_s [](AVD_SU *su) -> bool { return ((su->list_of_susi == nullptr) && (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED));})); } + +void avd_sg_read_headless_cached_rta(AVD_CL_CB *cb) +{ + SaAisErrorT rc; + SaImmSearchHandleT searchHandle; + SaImmSearchParametersT_2 searchParam; + + SaNameT sg_dn; + AVD_SG *sg; + unsigned int num_of_values = 0; + const SaImmAttrValuesT_2 **attributes; + AVD_SG_FSM_STATE imm_sg_fsm_state; + const char *className = "SaAmfSG"; + const SaImmAttrNameT searchAttributes[] = { + const_cast<SaImmAttrNameT>("osafAmfSGFsmState"), + const_cast<SaImmAttrNameT>("osafAmfSGSuOperationList"), + NULL + }; + + TRACE_ENTER(); + + osafassert(cb->scs_absence_max_duration > 0); + + searchParam.searchOneAttr.attrName = const_cast<SaImmAttrNameT>("SaImmAttrClassName"); + searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT; + searchParam.searchOneAttr.attrValue = &className; + + if ((rc = immutil_saImmOmSearchInitialize_2(cb->immOmHandle, NULL, SA_IMM_SUBTREE, + SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR, &searchParam, + searchAttributes, &searchHandle)) != SA_AIS_OK) { + + LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc); + goto done; + } + + while ((rc = immutil_saImmOmSearchNext_2(searchHandle, &sg_dn, + (SaImmAttrValuesT_2 ***)&attributes)) == SA_AIS_OK) { + sg = sg_db->find(Amf::to_string(&sg_dn)); + if (sg && sg->sg_ncs_spec == false) { + // Read sg fsm state + rc = immutil_getAttr(const_cast<SaImmAttrNameT>("osafAmfSGFsmState"), + attributes, 0, &imm_sg_fsm_state); + osafassert(rc == SA_AIS_OK); + sg->set_fsm_state(imm_sg_fsm_state, false); + // Read sg operation list + if (immutil_getAttrValuesNumber(const_cast<SaImmAttrNameT>("osafAmfSGSuOperationList"), attributes, &num_of_values) == SA_AIS_OK) { + unsigned int i; + for (i = 0; i < num_of_values; i++) { + const SaNameT *su_name = immutil_getNameAttr(attributes, "osafAmfSGSuOperationList", i); + AVD_SU* op_su = sg->get_su_by_name(*su_name); + if (op_su) { + if (op_su->sg_of_su->any_assignment_in_progress()) { + avd_sg_su_oper_list_add(avd_cb, op_su, false, false); + } + } + } + } + } + } + + (void)immutil_saImmOmSearchFinalize(searchHandle); + +done: + TRACE_LEAVE(); +} + +bool AVD_SG::any_assignment_in_progress() { + 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_ASGN) || + su->any_susi_fsm_in(AVD_SU_SI_STATE_UNASGN) || + su->any_susi_fsm_in(AVD_SU_SI_STATE_MODIFY)){ + pending = true; + break; + } + } + TRACE_LEAVE(); + return pending; +} + 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 @@ -1088,7 +1088,7 @@ uint32_t SG_2N::su_fault_si_oper(AVD_SU * Add the SU to the SU operation list.Change SG fsm to su_oper. */ l_susi->state = SA_AMF_HA_QUIESCED; - l_susi->fsm = AVD_SU_SI_STATE_ASGND; + avd_susi_update_fsm(l_susi, AVD_SU_SI_STATE_ASGND); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, l_susi, AVSV_CKPT_AVD_SI_ASS); avd_gen_su_ha_state_changed_ntf(avd_cb, l_susi); avd_susi_update_assignment_counters(l_susi, AVSV_SUSI_ACT_MOD, SA_AMF_HA_QUIESCING, SA_AMF_HA_QUIESCED); @@ -2958,7 +2958,7 @@ void SG_2N::node_fail_su_oper(AVD_SU *su * *a_susi->su* starts active assignment. */ su->set_su_switch(AVSV_SI_TOGGLE_STABLE); - if (a_susi->su->any_susi_fsm_in_modify() == true) { + if (a_susi->su->any_susi_fsm_in(AVD_SU_SI_STATE_MODIFY) == true) { avd_sg_su_oper_list_add(cb, a_susi->su, false); m_AVD_SET_SG_FSM(cb, (su->sg_of_su), AVD_SG_FSM_SG_REALIGN); } @@ -4034,8 +4034,8 @@ void SG_2N::ng_admin(AVD_SU *su, AVD_AMF if (sg_fsm_state == AVD_SG_FSM_STABLE) { su_admin_down(avd_cb, su, node); //Increment node counter for tracking status of ng operation. - if ((su->any_susi_fsm_in_modify() == true) || - (su->any_susi_fsm_in_unasgn() == true)) { + if ((su->any_susi_fsm_in(AVD_SU_SI_STATE_MODIFY) == true) || + (su->any_susi_fsm_in(AVD_SU_SI_STATE_UNASGN) == true)) { node->su_cnt_admin_oper++; TRACE("node:%s, su_cnt_admin_oper:%u", node->name.value, node->su_cnt_admin_oper); diff --git a/osaf/services/saf/amf/amfd/sg_npm_fsm.cc b/osaf/services/saf/amf/amfd/sg_npm_fsm.cc --- a/osaf/services/saf/amf/amfd/sg_npm_fsm.cc +++ b/osaf/services/saf/amf/amfd/sg_npm_fsm.cc @@ -2066,7 +2066,7 @@ uint32_t SG_NPM::susi_sucss_sg_reln(AVD_ i_susi = su->sg_of_su->admin_si->list_of_sisu; if ((i_susi != AVD_SU_SI_REL_NULL) && (i_susi->fsm != AVD_SU_SI_STATE_UNASGN)) { - i_susi->fsm = AVD_SU_SI_STATE_UNASGN; + avd_susi_update_fsm(i_susi, AVD_SU_SI_STATE_UNASGN); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, i_susi, AVSV_CKPT_AVD_SI_ASS); avd_susi_del_send(i_susi); avd_sg_su_oper_list_add(cb, i_susi->su, false); diff --git a/osaf/services/saf/amf/amfd/sg_nwayact_fsm.cc b/osaf/services/saf/amf/amfd/sg_nwayact_fsm.cc --- a/osaf/services/saf/amf/amfd/sg_nwayact_fsm.cc +++ b/osaf/services/saf/amf/amfd/sg_nwayact_fsm.cc @@ -1953,7 +1953,7 @@ void SG_NACV::ng_admin(AVD_SU *su, AVD_A avd_sg_su_oper_list_add(avd_cb, su, false); su->sg_of_su->set_fsm_state(AVD_SG_FSM_SG_REALIGN); //Increment node counter for tracking status of ng operation. - if (su->any_susi_fsm_in_modify() == true) { + if (su->any_susi_fsm_in(AVD_SU_SI_STATE_MODIFY) == true) { su->su_on_node->su_cnt_admin_oper++; TRACE("node:%s, su_cnt_admin_oper:%u", su->su_on_node->name.value, su->su_on_node->su_cnt_admin_oper); 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 @@ -111,15 +111,13 @@ uint32_t avd_new_assgn_susi(AVD_CL_CB *c * checkpointed dynamically */ osafassert (si->list_of_csi != nullptr); - if ((susi = avd_susi_create(cb, si, su, ha_state, ckpt)) == nullptr) { + if ((susi = avd_susi_create(cb, si, su, ha_state, ckpt, + AVSV_SUSI_ACT_ASGN, AVD_SU_SI_STATE_ASGN)) == nullptr) { LOG_ER("%s: Could not create SUSI '%s' '%s'", __FUNCTION__, su->name.value, si->name.value); goto done; } - susi->fsm = AVD_SU_SI_STATE_ASGN; - susi->state = ha_state; - /* Mark csi to be unassigned to detect duplicate assignment.*/ l_csi = si->list_of_csi; while (l_csi != nullptr) { @@ -710,6 +708,10 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb if ((cb->amf_init_tmr.is_active == true) && (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; + } cluster_startup_expiry_event_generate(cb); } @@ -870,6 +872,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->sg_ncs_spec == true) { if (su->saAmfSUAdminState == SA_AMF_ADMIN_UNLOCKED) { su->set_readiness_state(SA_AMF_READINESS_IN_SERVICE); @@ -1109,7 +1114,7 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb, } if (su->list_of_susi == AVD_SU_SI_REL_NULL) { - LOG_ER("%s: no susis", __FUNCTION__); + LOG_WA("%s: no susis", __FUNCTION__); goto done; } @@ -1169,9 +1174,12 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb, /* Now process the acknowledge message based on * Success or failure. */ + /* + * Continue waiting for all pending assignment from headless to complete + */ if (n2d_msg->msg_info.n2d_su_si_assign.error == NCSCC_RC_SUCCESS) { if (q_flag == false) { - su->sg_of_su->susi_success(cb, su, AVD_SU_SI_REL_NULL, + su->sg_of_su->susi_success(cb, su, AVD_SU_SI_REL_NULL, n2d_msg->msg_info.n2d_su_si_assign.msg_act, n2d_msg->msg_info.n2d_su_si_assign.ha_state); } @@ -1342,7 +1350,7 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb, } if (n2d_msg->msg_info.n2d_su_si_assign.error == NCSCC_RC_SUCCESS) { - susi->fsm = AVD_SU_SI_STATE_ASGND; + avd_susi_update_fsm(susi, AVD_SU_SI_STATE_ASGND); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, susi, AVSV_CKPT_AVD_SI_ASS); /* trigger pg upd */ @@ -1372,7 +1380,7 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb, if (n2d_msg->msg_info.n2d_su_si_assign.error == NCSCC_RC_SUCCESS) { if (n2d_msg->msg_info.n2d_su_si_assign.ha_state == SA_AMF_HA_QUIESCING) { q_flag = true; - susi->fsm = AVD_SU_SI_STATE_ASGND; + avd_susi_update_fsm(susi, AVD_SU_SI_STATE_ASGND); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, susi, AVSV_CKPT_AVD_SI_ASS); } else { if (susi->state == SA_AMF_HA_QUIESCING) { @@ -1383,7 +1391,7 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb, } /* set the assigned in the SUSIs. */ - susi->fsm = AVD_SU_SI_STATE_ASGND; + avd_susi_update_fsm(susi, AVD_SU_SI_STATE_ASGND); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, susi, AVSV_CKPT_AVD_SI_ASS); } @@ -2048,60 +2056,51 @@ void avd_node_down_appl_susi_failover(AV /* If the AvD is in AVD_APP_STATE run through all the application SUs and * reassign all the SUSI assignments for the SG of which the SU is a member */ - - if (cb->init_state == AVD_APP_STATE) { - for (const auto& i_su : avnd->list_of_su) { - - /* Unlike active, quiesced and standby HA states, assignment counters - in quiescing HA state are updated when AMFD receives assignment - response from AMFND. During nodefailover amfd will not receive - assignment response from AMFND. - So if any SU is under going modify operation then update assignment - counters for those SUSIs which are in quiescing state in the SU. - */ - for (AVD_SU_SI_REL *susi = i_su->list_of_susi; susi; susi = susi->su_next) { - if ((susi->fsm == AVD_SU_SI_STATE_MODIFY) && - (susi->state == SA_AMF_HA_QUIESCING)) { - avd_susi_update_assignment_counters(susi, AVSV_SUSI_ACT_MOD, - SA_AMF_HA_QUIESCING, SA_AMF_HA_QUIESCED); - } - else if ((susi->fsm == AVD_SU_SI_STATE_MODIFY) && - (susi->state == SA_AMF_HA_ACTIVE)) { - /* SUSI is undergoing active modification. For active state - saAmfSINumCurrActiveAssignments was increased when active - assignment had been sent. So decrement the count in SI before - deleting the SUSI. */ - susi->si->dec_curr_act_ass(); - } - else if ((susi->fsm == AVD_SU_SI_STATE_MODIFY) && - (susi->state == SA_AMF_HA_STANDBY)) { - /* SUSI is undergoing standby modification. For standby state - saAmfSINumCurrStandbyAssignments was increased when standby - assignment had been sent. So decrement the count in SI before - deleting the SUSI. */ - susi->si->dec_curr_stdby_ass(); - } - - + TRACE("cb->init_state: %d", cb->init_state); + for (const auto& i_su : avnd->list_of_su) { + /* Unlike active, quiesced and standby HA states, assignment counters + in quiescing HA state are updated when AMFD receives assignment + response from AMFND. During nodefailover amfd will not receive + assignment response from AMFND. + So if any SU is under going modify operation then update assignment + counters for those SUSIs which are in quiescing state in the SU. + */ + for (AVD_SU_SI_REL *susi = i_su->list_of_susi; susi; susi = susi->su_next) { + if ((susi->fsm == AVD_SU_SI_STATE_MODIFY) && + (susi->state == SA_AMF_HA_QUIESCING)) { + avd_susi_update_assignment_counters(susi, AVSV_SUSI_ACT_MOD, + SA_AMF_HA_QUIESCING, SA_AMF_HA_QUIESCED); + } + else if ((susi->fsm == AVD_SU_SI_STATE_MODIFY) && + (susi->state == SA_AMF_HA_ACTIVE)) { + /* SUSI is undergoing active modification. For active state + saAmfSINumCurrActiveAssignments was increased when active + assignment had been sent. So decrement the count in SI before + deleting the SUSI. */ + susi->si->dec_curr_act_ass(); + } + else if ((susi->fsm == AVD_SU_SI_STATE_MODIFY) && + (susi->state == SA_AMF_HA_STANDBY)) { + /* SUSI is undergoing standby modification. For standby state + saAmfSINumCurrStandbyAssignments was increased when standby + assignment had been sent. So decrement the count in SI before + deleting the SUSI. */ + susi->si->dec_curr_stdby_ass(); } + } /* Now analyze the service group for the new HA state - * assignments and send the SU SI assign messages - * accordingly. - */ - i_su->sg_of_su->node_fail(cb, i_su); - + * assignments and send the SU SI assign messages + * accordingly. + */ + i_su->sg_of_su->node_fail(cb, i_su); /* Free all the SU SI assignments*/ - i_su->delete_all_susis(); - + i_su->delete_all_susis(); /* Since a SU has gone out of service relook at the SG to - * re instatiate and terminate SUs if needed. - */ - avd_sg_app_su_inst_func(cb, i_su->sg_of_su); - - } /* for (const auto& i_su : avnd->list_of_su) */ - - } + * re instatiate and terminate SUs if needed. + */ + avd_sg_app_su_inst_func(cb, i_su->sg_of_su); + } /* for (const auto& i_su : avnd->list_of_su) */ /* If this node-failover/nodereboot occurs dueing nodegroup operation then check if this leads to completion of operation and try to reply to imm.*/ @@ -2130,7 +2129,7 @@ void avd_node_down_appl_susi_failover(AV * **************************************************************************/ -uint32_t avd_sg_su_oper_list_add(AVD_CL_CB *cb, AVD_SU *su, bool ckpt) +uint32_t avd_sg_su_oper_list_add(AVD_CL_CB *cb, AVD_SU *su, bool ckpt, bool wrt_to_imm) { uint32_t rc = NCSCC_RC_SUCCESS; @@ -2148,8 +2147,15 @@ uint32_t avd_sg_su_oper_list_add(AVD_CL_ su_oper_list.push_back(su); - if (!ckpt) + if (!ckpt) { + // Update to IMM if headless is enabled + if (cb->scs_absence_max_duration > 0 && wrt_to_imm) { + avd_saImmOiRtObjectUpdate_sync(const_cast<SaNameT*>(&su->sg_of_su->name), + const_cast<SaImmAttrNameT>("osafAmfSGSuOperationList"), + SA_IMM_ATTR_SANAMET, &su->name, SA_IMM_ATTR_VALUES_ADD); + } m_AVSV_SEND_CKPT_UPDT_ASYNC_ADD(cb, su, AVSV_CKPT_AVD_SG_OPER_SU); + } done: TRACE_LEAVE(); @@ -2174,7 +2180,7 @@ done: * **************************************************************************/ -uint32_t avd_sg_su_oper_list_del(AVD_CL_CB *cb, AVD_SU *su, bool ckpt) +uint32_t avd_sg_su_oper_list_del(AVD_CL_CB *cb, AVD_SU *su, bool ckpt, bool wrt_to_imm) { uint32_t rc = NCSCC_RC_SUCCESS; std::list<AVD_SU*>& su_oper_list = su->sg_of_su->su_oper_list; @@ -2188,14 +2194,22 @@ uint32_t avd_sg_su_oper_list_del(AVD_CL_ } if (elem == su_oper_list.end()) { - LOG_ER("%s: su not found", __FUNCTION__); + LOG_WA("%s: su not found", __FUNCTION__); rc = NCSCC_RC_FAILURE; goto done; } su_oper_list.erase(elem); - if (!ckpt) + + if (!ckpt) { + // Update to IMM if headless is enabled + if (cb->scs_absence_max_duration > 0 && wrt_to_imm) { + avd_saImmOiRtObjectUpdate_sync(const_cast<SaNameT*>(&su->sg_of_su->name), + const_cast<SaImmAttrNameT>("osafAmfSGSuOperationList"), + SA_IMM_ATTR_SANAMET, &su->name, SA_IMM_ATTR_VALUES_DELETE); + } m_AVSV_SEND_CKPT_UPDT_ASYNC_RMV(cb, su, AVSV_CKPT_AVD_SG_OPER_SU); + } done: TRACE_LEAVE2("rc:%u", rc); @@ -2248,7 +2262,7 @@ uint32_t avd_sg_su_si_mod_snd(AVD_CL_CB old_state = i_susi->fsm; i_susi->state = state; - i_susi->fsm = AVD_SU_SI_STATE_MODIFY; + avd_susi_update_fsm(i_susi, AVD_SU_SI_STATE_MODIFY); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, i_susi, AVSV_CKPT_AVD_SI_ASS); avd_susi_update_assignment_counters(i_susi, AVSV_SUSI_ACT_MOD, old_ha_state, state); @@ -2270,7 +2284,7 @@ uint32_t avd_sg_su_si_mod_snd(AVD_CL_CB } i_susi->state = old_ha_state; - i_susi->fsm = old_state; + avd_susi_update_fsm(i_susi, old_state); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, i_susi, AVSV_CKPT_AVD_SI_ASS); i_susi = i_susi->su_next; } @@ -2344,7 +2358,7 @@ uint32_t avd_sg_su_si_del_snd(AVD_CL_CB while (i_susi != AVD_SU_SI_REL_NULL) { old_state = i_susi->fsm; if (i_susi->fsm != AVD_SU_SI_STATE_UNASGN) { - i_susi->fsm = AVD_SU_SI_STATE_UNASGN; + avd_susi_update_fsm(i_susi, AVD_SU_SI_STATE_UNASGN); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, i_susi, AVSV_CKPT_AVD_SI_ASS); /* Update the assignment counters */ avd_susi_update_assignment_counters(i_susi, AVSV_SUSI_ACT_DEL, static_cast<SaAmfHAStateT>(0), static_cast<SaAmfHAStateT>(0)); @@ -2359,7 +2373,7 @@ uint32_t avd_sg_su_si_del_snd(AVD_CL_CB LOG_ER("%s: avd_snd_susi_msg failed, %s", __FUNCTION__, su->name.value); i_susi = su->list_of_susi; while (i_susi != AVD_SU_SI_REL_NULL) { - i_susi->fsm = old_state; + avd_susi_update_fsm(i_susi, old_state); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(cb, i_susi, AVSV_CKPT_AVD_SI_ASS); i_susi = i_susi->su_next; } 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 @@ -45,15 +45,21 @@ * @param si_dn * @param su_dn */ -static void avd_create_susi_in_imm(SaAmfHAStateT ha_state, - const SaNameT *si_dn, const SaNameT *su_dn) +static void avd_create_susi_in_imm(AVD_SU_SI_REL* susi) { SaNameT dn; SaAmfHAReadinessStateT saAmfSISUHAReadinessState = SA_AMF_HARS_READY_FOR_ASSIGNMENT; + void *arr1[] = { &dn }; - void *arr2[] = { &ha_state }; + void *arr2[] = { &susi->state }; void *arr3[] = { &saAmfSISUHAReadinessState }; + + uint32_t fsm = 0; + if (avd_cb->scs_absence_max_duration > 0) + fsm = susi->fsm; + + void *arr4[] = { &fsm }; const SaImmAttrValuesT_2 attr_safSISU = { const_cast<SaImmAttrNameT>("safSISU"), SA_IMM_ATTR_SANAMET, 1, arr1 @@ -66,15 +72,21 @@ static void avd_create_susi_in_imm(SaAmf const_cast<SaImmAttrNameT>("saAmfSISUHAReadinessState"), SA_IMM_ATTR_SAUINT32T, 1, arr3 }; + const SaImmAttrValuesT_2 attr_osafAmfSISUFsmState = { + const_cast<SaImmAttrNameT>("osafAmfSISUFsmState"), + SA_IMM_ATTR_SAUINT32T, 1, arr4 + }; + const SaImmAttrValuesT_2 *attrValues[] = { &attr_safSISU, &attr_saAmfSISUHAState, &attr_saAmfSISUHAReadinessState, + &attr_osafAmfSISUFsmState, nullptr }; - avsv_create_association_class_dn(su_dn, nullptr, "safSISU", &dn); - avd_saImmOiRtObjectCreate("SaAmfSIAssignment", si_dn, attrValues); + avsv_create_association_class_dn(&susi->su->name, nullptr, "safSISU", &dn); + avd_saImmOiRtObjectCreate("SaAmfSIAssignment", &susi->si->name, attrValues); } /** Delete an SaAmfSIAssignment from IMM @@ -121,6 +133,131 @@ void avd_susi_update(AVD_SU_SI_REL *susi } } +/** + * Update an osafAmfSISUFsmState runtime object in IMM. + * @param susi + * @param new_fsm_state + */ +void avd_susi_update_fsm(AVD_SU_SI_REL *susi, AVD_SU_SI_STATE new_fsm_state) +{ + SaNameT dn; + + avsv_create_association_class_dn(&susi->su->name, &susi->si->name, "safSISU", &dn); + TRACE_ENTER2("SISU:'%s', old fsm state: %d, new fsm state: %d", + dn.value, susi->fsm, new_fsm_state); + if (susi->fsm != new_fsm_state) { + susi->fsm = new_fsm_state; + if (avd_cb->scs_absence_max_duration > 0) { + avd_saImmOiRtObjectUpdate(&dn, const_cast<SaImmAttrNameT>("osafAmfSISUFsmState"), + SA_IMM_ATTR_SAUINT32T, &susi->fsm); + } + } + TRACE_LEAVE(); +} + +/** + * Read an osafAmfSISUFsmState runtime object from IMM. + * @param susi + */ +void avd_susi_read_headless_cached_rta(AVD_CL_CB *cb) +{ + SaAisErrorT rc; + SaImmSearchHandleT searchHandle; + SaImmSearchParametersT_2 searchParam; + + SaNameT dn, su_name, si_name; + const SaImmAttrValuesT_2 **attributes; + AVD_SU_SI_REL *susi = nullptr; + AVD_SU_SI_STATE imm_susi_fsm; + const char *className = "SaAmfSIAssignment"; + const SaImmAttrNameT siass_attributes[] = { + const_cast<SaImmAttrNameT>("safSISU"), + const_cast<SaImmAttrNameT>("saAmfSISUHAState"), + const_cast<SaImmAttrNameT>("osafAmfSISUFsmState"), + NULL + }; + + TRACE_ENTER(); + + osafassert(cb->scs_absence_max_duration > 0); + + searchParam.searchOneAttr.attrName = const_cast<SaImmAttrNameT>("SaImmAttrClassName"); + searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT; + searchParam.searchOneAttr.attrValue = &className; + + if ((rc = immutil_saImmOmSearchInitialize_2(cb->immOmHandle, NULL, SA_IMM_SUBTREE, + SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR, &searchParam, + siass_attributes, &searchHandle)) != SA_AIS_OK) { + + LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc); + goto done; + } + + while ((rc = immutil_saImmOmSearchNext_2(searchHandle, &dn, + (SaImmAttrValuesT_2 ***)&attributes)) == SA_AIS_OK) { + //TODO: to be refined after long DN + si_name.length = sprintf((char*)si_name.value, "%s", + strstr((char*)dn.value, "safSi")); + assert(si_name.length > 0); + AVD_SI *si = si_db->find(Amf::to_string(&si_name)); + osafassert(si); + + avsv_sanamet_init_from_association_dn(&dn, &su_name, "safSu", (char*)si->name.value); + AVD_SU *su = su_db->find(Amf::to_string(&su_name)); + osafassert(su); + susi = avd_su_susi_find(cb, su, &si->name); + rc = immutil_getAttr("osafAmfSISUFsmState", attributes, 0, &imm_susi_fsm); + osafassert(rc == SA_AIS_OK); + + if (susi) { + TRACE("SISU:'%s', old(imm) fsm state: %d, new(sync) fsm state: %d", + Amf::to_string(&dn).c_str(), imm_susi_fsm, susi->fsm); + +#if 1 + // If remove the below line in this #if block, AMFD will use + // the synced fsm state, which is latest. That means, in + // case of CSI completion during headless period, AMFD has to + // self trigger susi_success() in order to continue the admin + // operation. + + // Currently, AMFD uses the fsm state read from IMM, which is + // the last fsm state when AMFD was before headless. This needs + // AMFND to resend susi_resp message if CSI completes during + // headless period. + susi->fsm = imm_susi_fsm; +#endif + 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 || + susi->fsm == AVD_SU_SI_STATE_MODIFY) { + if (susi->state == SA_AMF_HA_ACTIVE || susi->state == SA_AMF_HA_QUIESCING) { + su->inc_curr_act_si(); + susi->si->inc_curr_act_ass(); + } else if (susi->state == SA_AMF_HA_STANDBY) { + su->inc_curr_stdby_si(); + susi->si->inc_curr_stdby_ass(); + } + } + if (susi->si->saAmfSIAdminState == SA_AMF_ADMIN_LOCKED || + susi->si->saAmfSIAdminState == SA_AMF_ADMIN_SHUTTING_DOWN) { + if (susi->fsm == AVD_SU_SI_STATE_MODIFY && + (susi->state == SA_AMF_HA_QUIESCED || susi->state == SA_AMF_HA_QUIESCING)) { + m_AVD_SET_SG_ADMIN_SI(cb, si); + } + } + + } else { + // This susi does not exist after headless, but it's still in IMM + // delete it for now + avd_saImmOiRtObjectDelete(&dn); + } + } + + (void)immutil_saImmOmSearchFinalize(searchHandle); + +done: + TRACE_LEAVE(); +} /***************************************************************************** * Function: avd_susi_create * @@ -138,7 +275,8 @@ void avd_susi_update(AVD_SU_SI_REL *susi * **************************************************************************/ -AVD_SU_SI_REL *avd_susi_create(AVD_CL_CB *cb, AVD_SI *si, AVD_SU *su, SaAmfHAStateT state, bool ckpt) +AVD_SU_SI_REL *avd_susi_create(AVD_CL_CB *cb, AVD_SI *si, AVD_SU *su, SaAmfHAStateT state, + bool ckpt, AVSV_SUSI_ACT default_act, AVD_SU_SI_STATE default_fsm) { AVD_SU_SI_REL *su_si, *p_su_si, *i_su_si; AVD_SU *curr_su = 0; @@ -152,7 +290,7 @@ AVD_SU_SI_REL *avd_susi_create(AVD_CL_CB su_si = new AVD_SU_SI_REL(); su_si->state = state; - su_si->fsm = AVD_SU_SI_STATE_ABSENT; + su_si->fsm = default_fsm; su_si->list_of_csicomp = nullptr; su_si->si = si; su_si->su = su; @@ -243,9 +381,9 @@ AVD_SU_SI_REL *avd_susi_create(AVD_CL_CB done: //ADD susi in imm job queue at both standby and active amfd. if (su_si != nullptr) - avd_create_susi_in_imm(state, &si->name, &su->name); - if ((ckpt == false) && (su_si != nullptr)) { - avd_susi_update_assignment_counters(su_si, AVSV_SUSI_ACT_ASGN, state, state); + avd_create_susi_in_imm(su_si); + if ((ckpt == false) && (su_si != nullptr) && default_act != AVSV_SUSI_ACT_BASE) { + avd_susi_update_assignment_counters(su_si, default_act, state, state); avd_gen_su_ha_state_changed_ntf(cb, su_si); } @@ -513,13 +651,13 @@ uint32_t avd_susi_mod_send(AVD_SU_SI_REL old_state = susi->state; old_fsm_state = susi->fsm; susi->state = ha_state; - susi->fsm = AVD_SU_SI_STATE_MODIFY; + avd_susi_update_fsm(susi, AVD_SU_SI_STATE_MODIFY); rc = avd_snd_susi_msg(avd_cb, susi->su, susi, AVSV_SUSI_ACT_MOD, false, nullptr); if (NCSCC_RC_SUCCESS != rc) { LOG_NO("role modification msg send failed %s:%u: SU:%s SI:%s", __FILE__,__LINE__, susi->su->name.value,susi->si->name.value); susi->state = old_state; - susi->fsm = old_fsm_state; + avd_susi_update_fsm(susi, old_fsm_state); goto done; } /* Update the assignment counters */ @@ -552,19 +690,17 @@ uint32_t avd_susi_del_send(AVD_SU_SI_REL TRACE_ENTER2("SI '%s', SU '%s' ", susi->si->name.value, susi->su->name.value); old_fsm_state = susi->fsm; - susi->fsm = AVD_SU_SI_STATE_UNASGN; - + 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); if (NCSCC_RC_SUCCESS != rc) { LOG_NO("susi del msg snd failed %s:%u: SU:%s SI:%s", __FILE__,__LINE__, susi->su->name.value,susi->si->name.value); - susi->fsm = old_fsm_state; + avd_susi_update_fsm(susi, old_fsm_state); goto done; } /* Update the assignment counters */ avd_susi_update_assignment_counters(susi, AVSV_SUSI_ACT_DEL, static_cast<SaAmfHAStateT>(0), static_cast<SaAmfHAStateT>(0)); - /* Checkpointing has to be done after getting response, will take care subsequently */ m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, susi, AVSV_CKPT_AVD_SI_ASS); @@ -777,44 +913,6 @@ done: } /** - * Clean up SUSI objects by searching for SaAmfSIAssignment instances in IMM - * @return SA_AIS_OK when OK - */ -SaAisErrorT avd_susi_cleanup(void) -{ - SaAisErrorT rc; - SaImmSearchHandleT searchHandle; - SaImmSearchParametersT_2 searchParam; - const char *className = "SaAmfSIAssignment"; - - TRACE_ENTER(); - - searchParam.searchOneAttr.attrName = const_cast<SaImmAttrNameT>("SaImmAttrClassName"); - searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT; - searchParam.searchOneAttr.attrValue = &className; - - if ((rc = immutil_saImmOmSearchInitialize_2(avd_cb->immOmHandle, nullptr, SA_IMM_SUBTREE, - SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_NO_ATTR, &searchParam, - nullptr, &searchHandle)) != SA_AIS_OK) { - LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc); - goto done; - } - - SaNameT siass_name; - const SaImmAttrValuesT_2 **attributes; - while ((rc = immutil_saImmOmSearchNext_2(searchHandle, &siass_name, - (SaImmAttrValuesT_2 ***)&attributes)) == SA_AIS_OK) { - avd_saImmOiRtObjectDelete(&siass_name); - } - - (void)immutil_saImmOmSearchFinalize(searchHandle); - -done: - TRACE_LEAVE(); - return SA_AIS_OK; -} - -/** * Recreates SUSI objects by with information retrieved from node directors. * Update relevant runtime attributes * @return SA_AIS_OK when OK @@ -877,21 +975,17 @@ SaAisErrorT avd_susi_recreate(AVSV_N2D_N susi = avd_su_susi_find(avd_cb, su, &susi_state->safSI); if (susi == nullptr) { - susi = avd_susi_create(avd_cb, si, su, ha_state, false); + susi = avd_susi_create(avd_cb, si, su, ha_state, false, AVSV_SUSI_ACT_BASE); osafassert(susi); } else { avd_susi_ha_state_set(susi, ha_state); } - susi->fsm = AVD_SU_SI_STATE_ASGND; - if (susi->state == SA_AMF_HA_QUIESCING) { - susi->su->inc_curr_act_si(); - susi->si->inc_curr_act_ass(); - } - su->saAmfSUHostedByNode = node->name; - avd_saImmOiRtObjectUpdate(&su->name, "saAmfSUHostedByNode", + susi->fsm = static_cast<AVD_SU_SI_STATE>(susi_state->assignmentAct); + TRACE("synced fsm:%u", susi->fsm); + su->saAmfSUHostedByNode = node->name; + avd_saImmOiRtObjectUpdate(&su->name, "saAmfSUHostedByNode", SA_IMM_ATTR_SANAMET, &su->saAmfSUHostedByNode); - m_AVSV_SEND_CKPT_UPDT_ASYNC_ADD(avd_cb, susi, AVSV_CKPT_AVD_SI_ASS); } 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 @@ -1919,6 +1919,56 @@ done: TRACE_LEAVE(); } +void avd_su_read_headless_cached_rta(AVD_CL_CB *cb) +{ + SaAisErrorT rc; + SaImmSearchHandleT searchHandle; + SaImmSearchParametersT_2 searchParam; + + SaNameT su_dn; + AVD_SU *su; + const SaImmAttrValuesT_2 **attributes; + SaToggleState su_toggle; + const char *className = "SaAmfSU"; + const SaImmAttrNameT searchAttributes[] = { + const_cast<SaImmAttrNameT>("osafAmfSUSwitch"), + NULL + }; + + TRACE_ENTER(); + + osafassert(cb->scs_absence_max_duration > 0); + + searchParam.searchOneAttr.attrName = const_cast<SaImmAttrNameT>("SaImmAttrClassName"); + searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT; + searchParam.searchOneAttr.attrValue = &className; + + if ((rc = immutil_saImmOmSearchInitialize_2(cb->immOmHandle, NULL, SA_IMM_SUBTREE, + SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR, &searchParam, + searchAttributes, &searchHandle)) != SA_AIS_OK) { + + LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc); + goto done; + } + + while ((rc = immutil_saImmOmSearchNext_2(searchHandle, &su_dn, + (SaImmAttrValuesT_2 ***)&attributes)) == SA_AIS_OK) { + su = su_db->find(Amf::to_string(&su_dn)); + if (su && su->sg_of_su->sg_ncs_spec == false) { + // Read sg fsm state + rc = immutil_getAttr(const_cast<SaImmAttrNameT>("osafAmfSUSwitch"), + attributes, 0, &su_toggle); + osafassert(rc == SA_AIS_OK); + su->set_su_switch(su_toggle, false); + } + } + + (void)immutil_saImmOmSearchFinalize(searchHandle); + +done: + TRACE_LEAVE(); +} + static void su_ccb_apply_cb(CcbUtilOperationData_t *opdata) { AVD_SU *su; @@ -2066,7 +2116,7 @@ void AVD_SU::set_all_susis_assigned_quie for (; susi != nullptr; susi = susi->su_next) { if (susi->fsm != AVD_SU_SI_STATE_UNASGN) { susi->state = SA_AMF_HA_QUIESCED; - susi->fsm = AVD_SU_SI_STATE_ASGND; + avd_susi_update_fsm(susi, AVD_SU_SI_STATE_ASGND); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, susi, AVSV_CKPT_AVD_SI_ASS); avd_gen_su_ha_state_changed_ntf(avd_cb, susi); avd_susi_update_assignment_counters(susi, AVSV_SUSI_ACT_MOD, @@ -2085,7 +2135,7 @@ void AVD_SU::set_all_susis_assigned(void for (; susi != nullptr; susi = susi->su_next) { if (susi->fsm != AVD_SU_SI_STATE_UNASGN) { - susi->fsm = AVD_SU_SI_STATE_ASGND; + avd_susi_update_fsm(susi, AVD_SU_SI_STATE_ASGND); m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, susi, AVSV_CKPT_AVD_SI_ASS); avd_pg_susi_chg_prc(avd_cb, susi); } @@ -2100,9 +2150,14 @@ void AVD_SU::set_term_state(bool state) m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, this, AVSV_CKPT_SU_TERM_STATE); } -void AVD_SU::set_su_switch(SaToggleState state) { +void AVD_SU::set_su_switch(SaToggleState state, bool wrt_to_imm) { su_switch = state; TRACE("%s su_switch %u", name.value, su_switch); + if (avd_cb->scs_absence_max_duration > 0 && wrt_to_imm) { + avd_saImmOiRtObjectUpdate_sync(const_cast<SaNameT*>(&name), + const_cast<SaImmAttrNameT>("osafAmfSUSwitch"), + SA_IMM_ATTR_SAUINT32T, &su_switch); + } m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, this, AVSV_CKPT_SU_SWITCH); } @@ -2293,28 +2348,30 @@ void AVD_SU::complete_admin_op(SaAisErro } } /** - * @brief Checks if modification of assignment is sent for any SUSI in SU. - * @result true/false + * @brief Checks if assignment is under specific fsm state + * . If any assignment's fsm is AVD_SU_SI_STATE_UNASGN, + * deletion of assignment has sent to amfnd. + * . If any assignment's fsm is AVD_SU_SI_STATE_MODIFY, + * modification of assignment has sent to amfnd. + * . If any assignment's fsm is AVD_SU_SI_STATE_ASGN, + * creation of assignment has sent to amfnd. + * @param @check_fsm: to-be-check fsm state + * @result true/false */ -bool AVD_SU::any_susi_fsm_in_modify() +bool AVD_SU::any_susi_fsm_in(uint32_t check_fsm) { - for (AVD_SU_SI_REL *susi = list_of_susi; susi; susi = susi->su_next) { - if (susi->fsm == AVD_SU_SI_STATE_MODIFY) - return true; - } - return false; -} -/** - * @brief Checks if deletion of assignment is sent for any SUSI in SU. - * @result true/false - */ -bool AVD_SU::any_susi_fsm_in_unasgn() -{ - for (AVD_SU_SI_REL *susi = list_of_susi; susi; susi = susi->su_next) { - if (susi->fsm == AVD_SU_SI_STATE_UNASGN) - return true; - } - return false; + TRACE_ENTER2("SU:'%s'", Amf::to_string(&name).c_str()); + bool rc = false; + for (AVD_SU_SI_REL *susi = list_of_susi; susi && rc == false; + susi = susi->su_next) { + 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_LEAVE(); + return rc; } /** * @brief Verify if SU is stable for admin operation on any higher diff --git a/osaf/services/saf/amf/amfnd/di.cc b/osaf/services/saf/amf/amfnd/di.cc --- a/osaf/services/saf/amf/amfnd/di.cc +++ b/osaf/services/saf/amf/amfnd/di.cc @@ -284,6 +284,7 @@ void add_sisu_state_info(AVND_MSG *msg, sisu_state->safSU = si_assign->su; sisu_state->safSI = si_assign->si; sisu_state->saAmfSISUHAState = si_assign->saAmfSISUHAState; + sisu_state->assignmentAct = si_assign->assignmentAct; sisu_state->next = msg->info.avd->msg_info.n2d_nd_sisu_state_info.sisu_list; msg->info.avd->msg_info.n2d_nd_sisu_state_info.sisu_list = sisu_state; @@ -1617,7 +1618,6 @@ void avnd_sync_sisu(AVND_CB *cb) su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)0); while (su != nullptr) { TRACE("syncing su: %s", su->name.value); - // attach SISUs for (si = (AVND_SU_SI_REC *)m_NCS_DBLIST_FIND_FIRST(&su->si_list); si != nullptr; @@ -1627,6 +1627,18 @@ void avnd_sync_sisu(AVND_CB *cb) si_assignment.si = si->name; si_assignment.saAmfSISUHAState = si->curr_state; + if (m_AVND_SU_SI_CURR_ASSIGN_STATE_IS_ASSIGNED(si)) { + si_assignment.assignmentAct = static_cast<uint32_t>(AVSV_SUSI_ACT_ASGND); + } else if (m_AVND_SU_SI_CURR_ASSIGN_STATE_IS_ASSIGNING(si)) { + if (si->prv_state) { + si_assignment.assignmentAct = static_cast<uint32_t>(AVSV_SUSI_ACT_MOD); + } else { + si_assignment.assignmentAct = static_cast<uint32_t>(AVSV_SUSI_ACT_ASGN); + } + } else { + si_assignment.assignmentAct = static_cast<uint32_t>(AVSV_SUSI_ACT_DEL); + } + add_sisu_state_info(&msg, &si_assignment); } diff --git a/osaf/services/saf/amf/amfnd/include/avnd_mds.h b/osaf/services/saf/amf/amfnd/include/avnd_mds.h --- a/osaf/services/saf/amf/amfnd/include/avnd_mds.h +++ b/osaf/services/saf/amf/amfnd/include/avnd_mds.h @@ -31,10 +31,10 @@ #define AVND_MDS_H /* In Service upgrade support */ -#define AVND_MDS_SUB_PART_VERSION 6 +#define AVND_MDS_SUB_PART_VERSION 7 #define AVND_AVD_SUBPART_VER_MIN 1 -#define AVND_AVD_SUBPART_VER_MAX 6 +#define AVND_AVD_SUBPART_VER_MAX 7 #define AVND_AVND_SUBPART_VER_MIN 1 #define AVND_AVND_SUBPART_VER_MAX 1 diff --git a/osaf/services/saf/amf/amfnd/mds.cc b/osaf/services/saf/amf/amfnd/mds.cc --- a/osaf/services/saf/amf/amfnd/mds.cc +++ b/osaf/services/saf/amf/amfnd/mds.cc @@ -41,14 +41,16 @@ const MDS_CLIENT_MSG_FORMAT_VER avnd_avd_msg_fmt_map_table[] = { AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2, AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4, - AVSV_AVD_AVND_MSG_FMT_VER_4, AVSV_AVD_AVND_MSG_FMT_VER_6 + AVSV_AVD_AVND_MSG_FMT_VER_4, AVSV_AVD_AVND_MSG_FMT_VER_6, + AVSV_AVD_AVND_MSG_FMT_VER_7 }; /* messages from director */ const MDS_CLIENT_MSG_FORMAT_VER avd_avnd_msg_fmt_map_table[] = { AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2, AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4, - AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6 + AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6, + AVSV_AVD_AVND_MSG_FMT_VER_7 }; const MDS_CLIENT_MSG_FORMAT_VER avnd_avnd_msg_fmt_map_table[] = { diff --git a/osaf/services/saf/amf/config/amf_classes.xml b/osaf/services/saf/amf/config/amf_classes.xml --- a/osaf/services/saf/amf/config/amf_classes.xml +++ b/osaf/services/saf/amf/config/amf_classes.xml @@ -320,6 +320,20 @@ <type>SA_UINT32_T</type> <category>SA_RUNTIME</category> </attr> + <attr> + <name>osafAmfSGSuOperationList</name> + <type>SA_NAME_T</type> + <category>SA_RUNTIME</category> + <flag>SA_MULTI_VALUE</flag> + <flag>SA_CACHED</flag> + </attr> + <attr> + <name>osafAmfSGFsmState</name> + <type>SA_UINT32_T</type> + <category>SA_RUNTIME</category> + <flag>SA_CACHED</flag> + <default-value>0</default-value> + </attr> </class> <class name="SaAmfSGType"> <category>SA_CONFIG</category> @@ -501,6 +515,13 @@ <type>SA_UINT32_T</type> <category>SA_RUNTIME</category> </attr> + <attr> + <name>osafAmfSUSwitch</name> + <type>SA_UINT32_T</type> + <category>SA_RUNTIME</category> + <flag>SA_CACHED</flag> + <default-value>0</default-value> + </attr> </class> <class name="SaAmfSUType"> <category>SA_CONFIG</category> @@ -733,6 +754,13 @@ <category>SA_RUNTIME</category> <flag>SA_CACHED</flag> </attr> + <attr> + <name>osafAmfSISUFsmState</name> + <type>SA_UINT32_T</type> + <category>SA_RUNTIME</category> + <flag>SA_CACHED</flag> + <default-value>0</default-value> + </attr> </class> <class name="SaAmfSvcTypeCSTypes"> <category>SA_CONFIG</category> ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel