osaf/libs/common/amf/include/amf_d2nmsg.h | 1 + osaf/services/saf/amf/amfd/comp.cc | 18 +++++ osaf/services/saf/amf/amfd/csi.cc | 24 ++++++ osaf/services/saf/amf/amfd/csiattr.cc | 25 +++++++ osaf/services/saf/amf/amfd/include/comp.h | 2 + osaf/services/saf/amf/amfd/include/csi.h | 2 + osaf/services/saf/amf/amfd/include/mds.h | 4 +- osaf/services/saf/amf/amfd/include/node.h | 2 +- osaf/services/saf/amf/amfd/include/util.h | 2 + osaf/services/saf/amf/amfd/mds.cc | 8 +- osaf/services/saf/amf/amfd/node.cc | 3 + osaf/services/saf/amf/amfd/util.cc | 97 +++++++++++++++++++++++++++- osaf/services/saf/amf/config/amf_classes.xml | 6 + 13 files changed, 187 insertions(+), 7 deletions(-)
Contains: 1)Support for new attribute osafAmfCSICommunicateCsiAttributeChange in class SaAmfCSI. 2)Upon modification of CSI attribute value for a object of class SaAmfCSIAttribute, AMFD will send a message to AMFND with new list. For a NON PROXIED NPI component, message will not be sent if osafAmfCSICommunicateCsiAttributeChange is false. 3)AMFD now also maintains MDS install version of all AMFNDs in std::map<SaClmNodeIdT, MDS_SVC_PVT_SUB_PART_VER> nds_mds_ver_db. It will be updated whenever AMFD gets MDS_UP and MDS_DOWN for AMFND. Using this AMFD can decide whether message is meant for particular AMFND much before encode callback given by MDS. 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 { diff --git a/osaf/services/saf/amf/amfd/comp.cc b/osaf/services/saf/amf/amfd/comp.cc --- a/osaf/services/saf/amf/amfd/comp.cc +++ b/osaf/services/saf/amf/amfd/comp.cc @@ -1783,4 +1783,22 @@ bool AVD_COMP::saaware() const AVD_COMP_TYPE *comptype = comptype_db->find(Amf::to_string(&saAmfCompType)); return (IS_COMP_SAAWARE(comptype->saAmfCtCompCategory)); } +/** + * @brief Checks if component is proxied pi. + * @Return true/false. + */ +bool AVD_COMP::proxied_pi() const +{ + AVD_COMP_TYPE *comptype = comptype_db->find(Amf::to_string(&saAmfCompType)); + return (IS_COMP_PROXIED_PI(comptype->saAmfCtCompCategory)); +} +/** + * @brief Checks if component is proxied npi. + * @Return true/false. + */ +bool AVD_COMP::proxied_npi() const +{ + AVD_COMP_TYPE *comptype = comptype_db->find(Amf::to_string(&saAmfCompType)); + return (IS_COMP_PROXIED_NPI(comptype->saAmfCtCompCategory)); +} 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 @@ -381,6 +381,12 @@ static void csi_get_attr_and_add_to_mode TRACE_ENTER2("DEP not configured, marking rank 1. Csi'%s', Rank'%u'",csi->name.value,csi->rank); } + if ((immutil_getAttrValuesNumber(const_cast<SaImmAttrNameT>("osafAmfCSICommunicateCsiAttributeChange"), + attributes, &values_number) != SA_AIS_OK)) { + TRACE("Default for osafAmfCSICommunicateCsiAttributeChange set to false"); + csi->osafAmfCSICommunicateCsiAttributeChange = false; //Default value is always 0. + } + csi->cstype = cstype_db->find(Amf::to_string(&csi->saAmfCSType)); csi->si = avd_si_get(si_name); @@ -578,6 +584,20 @@ static SaAisErrorT csi_ccb_completed_mod report_ccb_validation_error(opdata, "CS Type not found '%s'", cstype_name.value); goto done; } + } else if (!strcmp(attr_mod->modAttr.attrName, "osafAmfCSICommunicateCsiAttributeChange")) { + if ((attr_mod->modType == SA_IMM_ATTR_VALUES_DELETE) || + (attr_mod->modAttr.attrValues == nullptr)) { + report_ccb_validation_error(opdata, + "Invalid modification of osafAmfCSICommunicateCsiAttributeChange, valid (0 or 1)"); + goto done; + } + uint32_t val = *((uint32_t*)attr_mod->modAttr.attrValues[0]); + if ((val != true) && (val != false)) { + report_ccb_validation_error(opdata, + "Modification of osafAmfCSICommunicateCsiAttributeChange fails," + " Invalid Input %d",val); + goto done; + } } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfCSIDependencies")) { //Reject replacement of CSI deps, only deletion and addition are supported. if (attr_mod->modType == SA_IMM_ATTR_VALUES_REPLACE) { @@ -886,6 +906,10 @@ static void csi_ccb_apply_modify_hdlr(st csi->saAmfCSType = cstype_name; csi->cstype = csi_type; avd_cstype_add_csi(csi); + } else if (!strcmp(attr_mod->modAttr.attrName, "osafAmfCSICommunicateCsiAttributeChange")) { + csi->osafAmfCSICommunicateCsiAttributeChange = *((bool*)attr_mod->modAttr.attrValues[0]); + LOG_NO("Modified osafAmfCSICommunicateCsiAttributeChange for '%s' to '%u'", + csi->name.value, csi->osafAmfCSICommunicateCsiAttributeChange); } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfCSIDependencies")) { if (attr_mod->modType == SA_IMM_ATTR_VALUES_ADD) { assert(attr_mod->modAttr.attrValuesNumber == 1); diff --git a/osaf/services/saf/amf/amfd/csiattr.cc b/osaf/services/saf/amf/amfd/csiattr.cc --- a/osaf/services/saf/amf/amfd/csiattr.cc +++ b/osaf/services/saf/amf/amfd/csiattr.cc @@ -607,6 +607,31 @@ static void csiattr_modify_apply(CcbUtil avd_csi_add_csiattr(csi, csiattr); } } /* while */ + if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE) { + //Send a new message to amfnds to issue callbacks to the components. + std::map<SaClmNodeIdT, MDS_SVC_PVT_SUB_PART_VER>::iterator it; + for (AVD_COMP_CSI_REL *compcsi = csi->list_compcsi; compcsi != nullptr; + compcsi = compcsi->csi_csicomp_next) { + it = nds_mds_ver_db.find(compcsi->comp->su->su_on_node->node_info.nodeId); + + //Check if this amfnd is capable of this functionality. + if (it->second < AVSV_AVD_AVND_MSG_FMT_VER_7) { + TRACE_3("not sending to '%s' on :%x with mds version:'%u'", + compcsi->comp->comp_info.name.value, + compcsi->comp->su->su_on_node->node_info.nodeId, + it->second); + continue; + } + //For a NPI component check osafAmfCSICommunicateCsiAttributeChange is enabled. + if (((compcsi->csi->osafAmfCSICommunicateCsiAttributeChange == true) && + (compcsi->comp->saaware() == false)) || + (compcsi->comp->saaware()== true) || + (compcsi->comp->proxied_pi() == true) || + (compcsi->comp->proxied_npi() == true)) + avd_snd_compcsi_msg(compcsi->comp, compcsi->csi, compcsi, + AVSV_COMPCSI_ATTR_CHANGE_AND_NO_ACK); + } + } } diff --git a/osaf/services/saf/amf/amfd/include/comp.h b/osaf/services/saf/amf/amfd/include/comp.h --- a/osaf/services/saf/amf/amfd/include/comp.h +++ b/osaf/services/saf/amf/amfd/include/comp.h @@ -159,6 +159,8 @@ SaAisErrorT check_comp_stability() const void set_assigned(bool assigned) {assign_flag = assigned;} bool assigned() const {return assign_flag;} bool saaware() const; + bool proxied_pi() const; + bool proxied_npi() const; private: void initialize(); // disallow copy and assign 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 @@ -67,6 +67,8 @@ class AVD_CSI { uint32_t rank {}; /* The rank of the CSI in the SI * Checkpointing - Sent as a one time update. */ + bool osafAmfCSICommunicateCsiAttributeChange = false; /*To control invocation of INSTANTIATE script of NON PROXIED NPI comp + upon modification of CSIAttributes of assigned csi.*/ AVD_SI *si {}; /* SI encompassing this csi */ 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,10 +33,10 @@ /* 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 diff --git a/osaf/services/saf/amf/amfd/include/node.h b/osaf/services/saf/amf/amfd/include/node.h --- a/osaf/services/saf/amf/amfd/include/node.h +++ b/osaf/services/saf/amf/amfd/include/node.h @@ -160,7 +160,7 @@ struct NodeNameCompare: public std::bina extern AmfDb<std::string, AVD_AVND> *node_name_db; extern AmfDb<uint32_t, AVD_AVND> *node_id_db; extern AmfDb<uint32_t, AVD_FAIL_OVER_NODE> *node_list_db; - +extern std::map<SaClmNodeIdT, MDS_SVC_PVT_SUB_PART_VER> nds_mds_ver_db; class AVD_AMF_NG { public: AVD_AMF_NG(); 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); +uint32_t avd_snd_compcsi_msg(AVD_COMP *comp, AVD_CSI *csi, + avd_comp_csi_rel_tag *compcsi, AVSV_COMPCSI_ACT act); #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,7 +45,7 @@ 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[] = { @@ -427,7 +427,9 @@ static uint32_t avd_mds_svc_evt(MDS_CALL LOG_ER("%s: ncs_ipc_send failed", __FUNCTION__); delete evt; } - } + } + nds_mds_ver_db[evt_info->i_node_id] = evt_info->i_rem_svc_pvt_ver; + break; default: @@ -448,7 +450,7 @@ static uint32_t avd_mds_svc_evt(MDS_CALL case NCSMDS_SVC_ID_AVND: { AVD_EVT *evt = new AVD_EVT(); - + nds_mds_ver_db.erase(evt_info->i_node_id); evt->rcv_evt = AVD_EVT_MDS_AVND_DOWN; evt->info.node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt_info->i_dest); TRACE("avnd %" PRIx64 " down", evt_info->i_dest); diff --git a/osaf/services/saf/amf/amfd/node.cc b/osaf/services/saf/amf/amfd/node.cc --- a/osaf/services/saf/amf/amfd/node.cc +++ b/osaf/services/saf/amf/amfd/node.cc @@ -29,6 +29,9 @@ AmfDb<std::string, AVD_AVND> *node_name_db = 0; /* SaNameT index */ AmfDb<uint32_t, AVD_AVND> *node_id_db = 0; /* SaClmNodeIdT index */ +//Remember MDS install version of AMFNDs. It can be used to send msg to AMFNDs based on their versions. +std::map<SaClmNodeIdT, MDS_SVC_PVT_SUB_PART_VER> nds_mds_ver_db; + bool operator<(const AVD_AVND &lhs, const AVD_AVND &rhs) { if (strncmp((const char*) lhs.name.value, (const char*) rhs.name.value, lhs.name.length) < 0) return true; diff --git a/osaf/services/saf/amf/amfd/util.cc b/osaf/services/saf/amf/amfd/util.cc --- a/osaf/services/saf/amf/amfd/util.cc +++ b/osaf/services/saf/amf/amfd/util.cc @@ -1752,6 +1752,16 @@ static void free_d2n_pg_msg_info(AVSV_DN info->mem_list.numberOfItems = 0; } +static void free_d2n_compcsi_info(AVSV_DND_MSG *compcsi_msg) +{ + AVSV_D2N_COMPCSI_ASSIGN_MSG_INFO *compcsi = &compcsi_msg->msg_info.d2n_compcsi_assign_msg_info; + + if (compcsi->info.attrs.list != nullptr) { + delete [] (compcsi->info.attrs.list); + compcsi->info.attrs.list = nullptr; + } +} + /**************************************************************************** Name : d2n_msg_free @@ -1785,6 +1795,9 @@ void d2n_msg_free(AVSV_DND_MSG *msg) case AVSV_D2N_PG_TRACK_ACT_RSP_MSG: free_d2n_pg_msg_info(msg); break; + case AVSV_D2N_COMPCSI_ASSIGN_MSG: + free_d2n_compcsi_info(msg); + break; default: break; } @@ -1923,4 +1936,86 @@ bool admin_op_is_valid(SaImmAdminOperati child_dn->value[i] = '\0'; child_dn->length = i; return 0; - } +} + + /** + * @brief Sends a message to AMFND for a COMPCSI. + * As of now sends modified list of CSI's attributes to + * the AMFND which host assigned component(compcsi). + * @param ptr to comp + * @param ptr to csi + * @param ptr to compcsi + * @param act(action of type AVSV_COMPCSI_ACT) + * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. + */ +uint32_t avd_snd_compcsi_msg(AVD_COMP *comp, AVD_CSI *csi, AVD_COMP_CSI_REL *compcsi, AVSV_COMPCSI_ACT act) { + AVD_DND_MSG *compcsi_msg = nullptr; + AVSV_CSI_ATTRS *ptr_csiattr = nullptr; + AVSV_ATTR_NAME_VAL *i_ptr = nullptr; + AVD_CSI_ATTR *attr_ptr = nullptr; + AVD_AVND *avnd = nullptr; + + TRACE_ENTER2("'%s', '%s', act:%u", comp->comp_info.name.value, csi->name.value, act); + + //Depending upon the message sub type retrieve node from eligible entity. + if (act == AVSV_COMPCSI_ATTR_CHANGE_AND_NO_ACK) { + avnd = comp->su->get_node_ptr(); + } + if ((avnd->node_state == AVD_AVND_STATE_ABSENT) || + (avnd->node_state == AVD_AVND_STATE_GO_DOWN)) { + TRACE_LEAVE(); + return NCSCC_RC_SUCCESS; + } + + /* prepare the COMP CSI message. */ + compcsi_msg = new AVSV_DND_MSG(); + compcsi_msg->msg_type = AVSV_D2N_COMPCSI_ASSIGN_MSG; + compcsi_msg->msg_info.d2n_compcsi_assign_msg_info.node_id = avnd->node_info.nodeId; + compcsi_msg->msg_info.d2n_compcsi_assign_msg_info.msg_act = act; + compcsi_msg->msg_info.d2n_compcsi_assign_msg_info.comp_name = compcsi->comp->comp_info.name; + compcsi_msg->msg_info.d2n_compcsi_assign_msg_info.csi_name = csi->name; + switch (act) { + case AVSV_COMPCSI_ATTR_CHANGE_AND_NO_ACK: + ptr_csiattr = &compcsi_msg->msg_info.d2n_compcsi_assign_msg_info.info.attrs; + ptr_csiattr->list = new AVSV_ATTR_NAME_VAL[compcsi->csi->num_attributes]; + /* initilize both the message pointer and the database pointer. Also init the + * message content. + */ + i_ptr = ptr_csiattr->list; + attr_ptr = compcsi->csi->list_attributes; + ptr_csiattr->number = 0; + + /* Scan the list of attributes for the CSI and add it to the message */ + while ((attr_ptr != nullptr) && (ptr_csiattr->number < compcsi->csi->num_attributes)) { + memcpy(i_ptr, &attr_ptr->name_value, sizeof(AVSV_ATTR_NAME_VAL)); + ptr_csiattr->number++; + i_ptr = i_ptr + 1; + attr_ptr = attr_ptr->attr_next; + } + break; + default: + d2n_msg_free(compcsi_msg); + TRACE_LEAVE(); + return NCSCC_RC_FAILURE; + break; + } + + //Generate new msg_id. + compcsi_msg->msg_info.d2n_compcsi_assign_msg_info.msg_id = ++(avnd->snd_msg_id); + + //Send COMP CSI message*/ + TRACE("Sending %u to %x", AVSV_D2N_COMPCSI_ASSIGN_MSG, avnd->node_info.nodeId); + if (avd_d2n_msg_snd(avd_cb, avnd, compcsi_msg) != NCSCC_RC_SUCCESS) { + LOG_ER("Send to %x failed",avnd->node_info.nodeId); + --(avnd->snd_msg_id); + d2n_msg_free(compcsi_msg); + TRACE_LEAVE(); + return NCSCC_RC_FAILURE; + } + //Checkpoint to standby AMFD. + m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, avnd, AVSV_CKPT_AVND_SND_MSG_ID); + + TRACE_LEAVE(); + return NCSCC_RC_SUCCESS; +} + 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 @@ -771,6 +771,12 @@ <flag>SA_WRITABLE</flag> <flag>SA_MULTI_VALUE</flag> </attr> + <attr> + <name>osafAmfCSICommunicateCsiAttributeChange</name> + <type>SA_UINT32_T</type> + <category>SA_CONFIG</category> + <flag>SA_WRITABLE</flag> + </attr> </class> <class name="SaAmfCSType"> <category>SA_CONFIG</category> ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel