osaf/services/saf/amf/amfnd/Makefile.am | 3 +- osaf/services/saf/amf/amfnd/amfnd.cc | 4 +- osaf/services/saf/amf/amfnd/clc.cc | 13 +- osaf/services/saf/amf/amfnd/clm.cc | 4 +- osaf/services/saf/amf/amfnd/compdb.cc | 46 ++++++- osaf/services/saf/amf/amfnd/di.cc | 12 +- osaf/services/saf/amf/amfnd/err.cc | 12 +- osaf/services/saf/amf/amfnd/evt.cc | 9 + osaf/services/saf/amf/amfnd/hcdb.cc | 39 +++++- osaf/services/saf/amf/amfnd/imm.cc | 140 +++++++++++++++++++++++ osaf/services/saf/amf/amfnd/include/Makefile.am | 3 +- osaf/services/saf/amf/amfnd/include/avnd_comp.h | 6 +- osaf/services/saf/amf/amfnd/include/avnd_evt.h | 7 + osaf/services/saf/amf/amfnd/include/avnd_proxy.h | 4 +- osaf/services/saf/amf/amfnd/include/avnd_su.h | 14 +- osaf/services/saf/amf/amfnd/include/imm.h | 2 + osaf/services/saf/amf/amfnd/main.cc | 7 +- osaf/services/saf/amf/amfnd/su.cc | 6 +- osaf/services/saf/amf/amfnd/sudb.cc | 47 +++++++ osaf/services/saf/amf/amfnd/susm.cc | 140 +++++++++++++++------- osaf/services/saf/amf/amfnd/term.cc | 4 +- 21 files changed, 419 insertions(+), 103 deletions(-)
If immnd is down and Amf decides to instantiate some SU, then there is a deadlock between Amfnd and Imm. Amf calls Imm api to read imm attributes during SU instantiation and stuck because Imm is down. Imm waits for Amfnd to instantiate/restart it. So, both waits for each other. This is a deadlock. So, the fix bypasses main thread for information reading and does process of SU instantiation in a main thread. So, when Imm is down, its instantiation/restart happens in the main thread. If any SU instantiation request comes, then Amfnd routes that request in a separate thread, that threads stuck in Imm api call untill Imm is not restarted and responds to Imm api call. This obviates the deadlock between Amfnd and Imm. diff --git a/osaf/services/saf/amf/amfnd/Makefile.am b/osaf/services/saf/amf/amfnd/Makefile.am --- a/osaf/services/saf/amf/amfnd/Makefile.am +++ b/osaf/services/saf/amf/amfnd/Makefile.am @@ -60,7 +60,8 @@ osafamfnd_SOURCES = \ term.cc \ tmr.cc \ util.cc \ - verify.cc + verify.cc \ + imm.cc osafamfnd_LDADD = \ $(top_builddir)/osaf/tools/safimm/src/libimmutil.la \ diff --git a/osaf/services/saf/amf/amfnd/amfnd.cc b/osaf/services/saf/amf/amfnd/amfnd.cc --- a/osaf/services/saf/amf/amfnd/amfnd.cc +++ b/osaf/services/saf/amf/amfnd/amfnd.cc @@ -393,9 +393,9 @@ uint32_t avnd_evt_avd_reboot_evh(AVND_CB TODO: This for loop can be removed if AVD remembers and checkpoints alarms sent due to error report. */ - for (AVND_COMP *comp = (AVND_COMP *)ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)0); + for (AVND_COMP *comp = (AVND_COMP *)compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)0); comp; - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)&comp->name)) { + comp = (AVND_COMP *) compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)&comp->name)) { /* Skip OpenSAF and external components */ if (comp->su->is_ncs || comp->su->su_is_external) diff --git a/osaf/services/saf/amf/amfnd/clc.cc b/osaf/services/saf/amf/amfnd/clc.cc --- a/osaf/services/saf/amf/amfnd/clc.cc +++ b/osaf/services/saf/amf/amfnd/clc.cc @@ -37,6 +37,7 @@ #include <logtrace.h> #include <avnd.h> +#include <avnd_su.h> /* static function declarations */ static uint32_t avnd_comp_clc_uninst_inst_hdler(AVND_CB *, AVND_COMP *); @@ -697,7 +698,7 @@ static int all_comps_terminated(void) TRACE_ENTER(); /* Scan all components to see if we're done terminating all comps */ - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)0); + comp = (AVND_COMP *)compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)0); while (comp != 0) { if ((comp->pres != SA_AMF_PRESENCE_UNINSTANTIATED) && (comp->pres != SA_AMF_PRESENCE_INSTANTIATION_FAILED) && @@ -707,7 +708,7 @@ static int all_comps_terminated(void) break; } - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)&comp->name); + comp = (AVND_COMP *) compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)&comp->name); } TRACE_LEAVE2("%d", all_comps_terminated); @@ -723,9 +724,9 @@ static bool all_app_comps_terminated(voi { AVND_COMP *comp; - for (comp = (AVND_COMP *)ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)0); + for (comp = (AVND_COMP *)compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)0); comp; - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)&comp->name)) { + comp = (AVND_COMP *) compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)&comp->name)) { /* Skip OpenSAF and external components */ if (comp->su->is_ncs || comp->su->su_is_external) @@ -776,7 +777,7 @@ uint32_t avnd_comp_clc_fsm_run(AVND_CB * rc = avnd_di_oper_send(cb, cb->failed_su, SA_AMF_NODE_FAILOVER); osafassert(NCSCC_RC_SUCCESS == rc); /* delete all SUSI record in amfnd database */ - tmp_su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)0); + tmp_su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)0); while (tmp_su != nullptr) { if (tmp_su->is_ncs || tmp_su->su_is_external) { /* Don't delete middleware SUSI. We are only performing appl @@ -785,7 +786,7 @@ uint32_t avnd_comp_clc_fsm_run(AVND_CB * } else { avnd_su_si_del(cb, &tmp_su->name); } - tmp_su = (AVND_SU *) ncs_patricia_tree_getnext(&cb->sudb, + tmp_su = (AVND_SU *) sudb_rec_get_next(&cb->sudb, (uint8_t *)&tmp_su->name); } diff --git a/osaf/services/saf/amf/amfnd/clm.cc b/osaf/services/saf/amf/amfnd/clm.cc --- a/osaf/services/saf/amf/amfnd/clm.cc +++ b/osaf/services/saf/amf/amfnd/clm.cc @@ -57,12 +57,12 @@ static void clm_node_left(SaClmNodeIdT n LOG_NO("This node has exited the cluster"); avnd_cb->node_info.member = SA_FALSE; - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)0); + comp = (AVND_COMP *)compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)0); while( comp != nullptr ) { if(comp->su->is_ncs != true ) { avnd_comp_clc_fsm_run(avnd_cb, comp, AVND_COMP_CLC_PRES_FSM_EV_TERM); } - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&avnd_cb->compdb,(uint8_t *)&comp->name); + comp = (AVND_COMP *)compdb_rec_get_next(&avnd_cb->compdb,(uint8_t *)&comp->name); } goto done; } diff --git a/osaf/services/saf/amf/amfnd/compdb.cc b/osaf/services/saf/amf/amfnd/compdb.cc --- a/osaf/services/saf/amf/amfnd/compdb.cc +++ b/osaf/services/saf/amf/amfnd/compdb.cc @@ -37,7 +37,9 @@ #include <logtrace.h> #include <avnd.h> +#include "osaf_utility.h" +static pthread_mutex_t compdb_mutex = PTHREAD_MUTEX_INITIALIZER; // // TODO(HANO) Temporary use this function instead of strdup which uses malloc. // Later on remove this function and use std::string instead @@ -433,7 +435,9 @@ AVND_COMP *avnd_compdb_rec_add(AVND_CB * */ comp->tree_node.bit = 0; comp->tree_node.key_info = (uint8_t *)&comp->name; + osaf_mutex_lock_ordie(&compdb_mutex); *rc = ncs_patricia_tree_add(&cb->compdb, &comp->tree_node); + osaf_mutex_unlock_ordie(&compdb_mutex); if (NCSCC_RC_SUCCESS != *rc) { *rc = AVND_ERR_TREE; goto err; @@ -463,8 +467,11 @@ AVND_COMP *avnd_compdb_rec_add(AVND_CB * return comp; err: - if (AVND_ERR_DLL == *rc) + if (AVND_ERR_DLL == *rc) { + osaf_mutex_lock_ordie(&compdb_mutex); ncs_patricia_tree_del(&cb->compdb, &comp->tree_node); + osaf_mutex_unlock_ordie(&compdb_mutex); + } if (comp) { if (comp->comp_hdl) @@ -538,7 +545,9 @@ uint32_t avnd_compdb_rec_del(AVND_CB *cb /* * Remove from the patricia tree. */ + osaf_mutex_lock_ordie(&compdb_mutex); rc = ncs_patricia_tree_del(&cb->compdb, &comp->tree_node); + osaf_mutex_unlock_ordie(&compdb_mutex); if (NCSCC_RC_SUCCESS != rc) { LOG_ER("%s: %s tree del failed", __FUNCTION__, name->value); rc = AVND_ERR_TREE; @@ -893,7 +902,7 @@ uint32_t avnd_comptype_oper_req(AVND_CB osafassert(comp_type_name); // 2. search each component for a matching compType - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *) 0); + comp = (AVND_COMP *) compdb_rec_get_next(&cb->compdb, (uint8_t *) 0); while (comp != 0) { if (strncmp((const char*) comp->saAmfCompType.value, comp_type_name, comp->saAmfCompType.length) == 0) { // 3. comptype found, check if component uses this comptype attribute value or if @@ -1017,7 +1026,7 @@ uint32_t avnd_comptype_oper_req(AVND_CB LOG_WA("Unexpected attribute id: %d", param->attr_id); } } - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *) & comp->name); + comp = (AVND_COMP *) compdb_rec_get_next(&cb->compdb, (uint8_t *) & comp->name); } } case AVSV_OBJ_OPR_DEL: @@ -1740,9 +1749,6 @@ static AVND_COMP *avnd_comp_create(const comp->avd_updt_flag = false; - /* synchronize comp oper state */ - m_AVND_COMP_OPER_STATE_AVD_SYNC(avnd_cb, comp, rc); - // comp->cap = info->cap; comp->node_id = avnd_cb->node_info.nodeId; comp->pres = SA_AMF_PRESENCE_UNINSTANTIATED; @@ -1764,10 +1770,13 @@ static AVND_COMP *avnd_comp_create(const /* Add to the patricia tree. */ comp->tree_node.key_info = (uint8_t *)&comp->name; + osaf_mutex_lock_ordie(&compdb_mutex); if(ncs_patricia_tree_add(&avnd_cb->compdb, &comp->tree_node) != NCSCC_RC_SUCCESS) { LOG_ER("ncs_patricia_tree_add FAILED for '%s'", comp_name->value); + osaf_mutex_unlock_ordie(&compdb_mutex); goto done; } + osaf_mutex_unlock_ordie(&compdb_mutex); /* Add to the comp-list (maintained by su) */ m_AVND_SUDB_REC_COMP_ADD(*su, *comp, rc); @@ -1931,3 +1940,28 @@ done1: return res; } +/** + * This function return Comp rec. + * @param Pointer to COMPDB. + * @param Pointer to Comp name. + * @return Pointer to Comp. + */ +AVND_COMP *compdb_rec_get(NCS_PATRICIA_TREE *compdb, const SaNameT *name) { + osaf_mutex_lock_ordie(&compdb_mutex); + AVND_COMP *comp = (AVND_COMP *)ncs_patricia_tree_get(compdb, (uint8_t *)(name)); + osaf_mutex_unlock_ordie(&compdb_mutex); + return comp; +} + +/** + * This function return next Comp rec. + * @param Pointer to COMPDB. + * @param Pointer to COMP name. + * @return Pointer to COMP. + */ +AVND_COMP *compdb_rec_get_next(NCS_PATRICIA_TREE *compdb, uint8_t *name) { + osaf_mutex_lock_ordie(&compdb_mutex); + AVND_COMP *comp = (AVND_COMP *)ncs_patricia_tree_getnext(compdb, (uint8_t *)(name)); + osaf_mutex_unlock_ordie(&compdb_mutex); + return comp; +} 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 @@ -650,7 +650,7 @@ uint32_t avnd_evt_mds_avd_dn_evh(AVND_CB // check for pending messages FROM director // scan all SUs "siq" message list, if anyone is not empty reboot - const AVND_SU *su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)0); + const AVND_SU *su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)0); while (su != 0) { LOG_NO("Checking '%s' for pending messages", su->name.value); @@ -669,7 +669,7 @@ uint32_t avnd_evt_mds_avd_dn_evh(AVND_CB } } - su = (AVND_SU *)ncs_patricia_tree_getnext( + su = (AVND_SU *)sudb_rec_get_next( &cb->sudb, (uint8_t *)&su->name); } // record we are now 'headless' @@ -1543,7 +1543,7 @@ void avnd_sync_csicomp(AVND_CB *cb) msg.info.avd->msg_info.n2d_nd_csicomp_state_info.csicomp_list = nullptr; // add CSICOMP objects - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)0); + comp = (AVND_COMP *)compdb_rec_get_next(&cb->compdb, (uint8_t *)0); while (comp != nullptr) { TRACE("syncing comp: %s", comp->name.value); for (csi = m_AVND_CSI_REC_FROM_COMP_DLL_NODE_GET(m_NCS_DBLIST_FIND_FIRST(&comp->csi_list)); @@ -1566,7 +1566,7 @@ void avnd_sync_csicomp(AVND_CB *cb) } add_comp_state_info(&msg, comp); - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)&comp->name); + comp = (AVND_COMP *)compdb_rec_get_next(&cb->compdb, (uint8_t *)&comp->name); } LOG_NO("%d CSICOMP states synced", msg.info.avd->msg_info.n2d_nd_csicomp_state_info.num_csicomp); @@ -1611,7 +1611,7 @@ void avnd_sync_sisu(AVND_CB *cb) msg.info.avd->msg_info.n2d_nd_sisu_state_info.sisu_list = nullptr; // gather SISU states - su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)0); + su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)0); while (su != nullptr) { TRACE("syncing su: %s", su->name.value); @@ -1629,7 +1629,7 @@ void avnd_sync_sisu(AVND_CB *cb) add_su_state_info(&msg, su); - su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)&su->name); + su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)&su->name); } LOG_NO("%d SISU states sent", msg.info.avd->msg_info.n2d_nd_sisu_state_info.num_sisu); diff --git a/osaf/services/saf/amf/amfnd/err.cc b/osaf/services/saf/amf/amfnd/err.cc --- a/osaf/services/saf/amf/amfnd/err.cc +++ b/osaf/services/saf/amf/amfnd/err.cc @@ -1010,9 +1010,9 @@ uint32_t avnd_err_rcvr_node_failover(AVN failed_su->admin_op_Id = static_cast<SaAmfAdminOperationIdT>(0); } /* Unordered cleanup of all local application components */ - for (comp = (AVND_COMP *)ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)nullptr); + for (comp = (AVND_COMP *)compdb_rec_get_next(&cb->compdb, (uint8_t *)nullptr); comp != nullptr; - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)&comp->name)) { + comp = (AVND_COMP *) compdb_rec_get_next(&cb->compdb, (uint8_t *)&comp->name)) { if (comp->su->is_ncs || comp->su->su_is_external) continue; @@ -1495,7 +1495,7 @@ uint32_t avnd_evt_tmr_node_err_esc_evh(A LOG_NO("SU failover probation timer expired"); - su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)0); + su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)0); while (su != 0) { /* Only reset to those Sus, which have affected the node err esc.*/ if (su->su_err_esc_level == AVND_ERR_ESC_LEVEL_2) { @@ -1506,7 +1506,7 @@ uint32_t avnd_evt_tmr_node_err_esc_evh(A &su->name, su->su_restart_cnt); su->su_err_esc_level = AVND_ERR_ESC_LEVEL_0; } - su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)&su->name); + su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)&su->name); } /* reset all parameters */ @@ -1605,9 +1605,9 @@ void cleanup_all_comps_and_reboot(AVND_C uint32_t rc = NCSCC_RC_SUCCESS; /* Unordered cleanup of all local application components */ - for (comp = (AVND_COMP *)ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)nullptr); + for (comp = (AVND_COMP *)compdb_rec_get_next(&cb->compdb, (uint8_t *)nullptr); comp != nullptr; - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)&comp->name)) { + comp = (AVND_COMP *) compdb_rec_get_next(&cb->compdb, (uint8_t *)&comp->name)) { if (comp->su->is_ncs || comp->su->su_is_external) continue; diff --git a/osaf/services/saf/amf/amfnd/evt.cc b/osaf/services/saf/amf/amfnd/evt.cc --- a/osaf/services/saf/amf/amfnd/evt.cc +++ b/osaf/services/saf/amf/amfnd/evt.cc @@ -169,6 +169,11 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb, /* nothing to be copied, evt type should do. */ break; + case AVND_EVT_IR: + /* Only SU name to be copied. */ + memcpy(&evt->info.ir_evt.su_name, info, sizeof(SaNameT)); + break; + case AVND_EVT_PID_EXIT: evt->info.pm_evt.comp_name = ((AVND_COMP_PM_REC *)info)->comp->name; evt->info.pm_evt.pid = ((AVND_COMP_PM_REC *)info)->pid; @@ -296,6 +301,10 @@ void avnd_evt_destroy(AVND_EVT *evt) case AVND_EVT_PID_EXIT: break; + /* Imm Reader event */ + case AVND_EVT_IR: + break; + default: LOG_NO("%s: unknown event type %u", __FUNCTION__, type); break; diff --git a/osaf/services/saf/amf/amfnd/hcdb.cc b/osaf/services/saf/amf/amfnd/hcdb.cc --- a/osaf/services/saf/amf/amfnd/hcdb.cc +++ b/osaf/services/saf/amf/amfnd/hcdb.cc @@ -37,8 +37,11 @@ #include <saImmOm.h> #include <immutil.h> #include <string> +#include "osaf_utility.h" static NCS_PATRICIA_TREE hctypedb; /* healthcheck type db */ +static pthread_mutex_t hcdb_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t hctypedb_mutex = PTHREAD_MUTEX_INITIALIZER; /**************************************************************************** Name : avnd_hcdb_init @@ -72,7 +75,10 @@ AVND_HC *avnd_hcdb_rec_get(AVND_CB *cb, memset(&dn, 0, sizeof(dn)); dn.length = snprintf((char *)dn.value, SA_MAX_NAME_LENGTH, "safHealthcheckKey=%s,%s", hc_key->name.key, hc_key->comp_name.value); - return (AVND_HC *)ncs_patricia_tree_get(&cb->hcdb, (uint8_t *)&dn); + osaf_mutex_lock_ordie(&hcdb_mutex); + AVND_HC *hc = (AVND_HC *)ncs_patricia_tree_get(&cb->hcdb, (uint8_t *)&dn); + osaf_mutex_unlock_ordie(&hcdb_mutex); + return hc; } AVND_HCTYPE *avnd_hctypedb_rec_get(const SaNameT *comp_type_dn, const SaAmfHealthcheckKeyT *key) @@ -82,7 +88,10 @@ AVND_HCTYPE *avnd_hctypedb_rec_get(const memset(&dn, 0, sizeof(dn)); dn.length = snprintf((char *)dn.value, SA_MAX_NAME_LENGTH, "safHealthcheckKey=%s,%s", key->key, comp_type_dn->value); - return (AVND_HCTYPE *)ncs_patricia_tree_get(&hctypedb, (uint8_t *)&dn); + osaf_mutex_lock_ordie(&hctypedb_mutex); + AVND_HCTYPE *hctype = (AVND_HCTYPE *)ncs_patricia_tree_get(&hctypedb, (uint8_t *)&dn); + osaf_mutex_unlock_ordie(&hctypedb_mutex); + return hctype; } /**************************************************************************** @@ -126,7 +135,9 @@ AVND_HC *avnd_hcdb_rec_add(AVND_CB *cb, /* Add to the patricia tree */ hc->tree_node.bit = 0; hc->tree_node.key_info = (uint8_t *)&hc->key; + osaf_mutex_lock_ordie(&hcdb_mutex); *rc = ncs_patricia_tree_add(&cb->hcdb, &hc->tree_node); + osaf_mutex_unlock_ordie(&hcdb_mutex); if (NCSCC_RC_SUCCESS != *rc) { *rc = AVND_ERR_TREE; goto err; @@ -170,7 +181,9 @@ uint32_t avnd_hcdb_rec_del(AVND_CB *cb, } /* remove from the patricia tree */ + osaf_mutex_lock_ordie(&hcdb_mutex); rc = ncs_patricia_tree_del(&cb->hcdb, &hc->tree_node); + osaf_mutex_unlock_ordie(&hcdb_mutex); if (NCSCC_RC_SUCCESS != rc) { rc = AVND_ERR_TREE; goto err; @@ -209,7 +222,9 @@ static AVND_HC *hc_create(AVND_CB *cb, S memcpy(hc->name.value, dn->value, dn->length); hc->name.length = dn->length; hc->tree_node.key_info = (uint8_t *)&hc->name; + osaf_mutex_lock_ordie(&hcdb_mutex); rc = ncs_patricia_tree_add(&cb->hcdb, &hc->tree_node); + osaf_mutex_unlock_ordie(&hcdb_mutex); done: if (rc != NCSCC_RC_SUCCESS) { @@ -291,7 +306,9 @@ static AVND_HCTYPE *hctype_create(AVND_C } hc->tree_node.key_info = (uint8_t *)&hc->name; + osaf_mutex_lock_ordie(&hctypedb_mutex); rc = ncs_patricia_tree_add(&hctypedb, &hc->tree_node); + osaf_mutex_unlock_ordie(&hctypedb_mutex); done: if (rc != NCSCC_RC_SUCCESS) { @@ -331,13 +348,17 @@ SaAisErrorT avnd_hctype_config_get(SaImm TRACE_1("'%s'", hc_name.value); //A record may get created in the context of some other component of same comptype. AVND_HCTYPE *hctype = nullptr; + osaf_mutex_lock_ordie(&hctypedb_mutex); if ((hctype = (AVND_HCTYPE *)ncs_patricia_tree_get(&hctypedb, (uint8_t *)&hc_name)) == nullptr) { + osaf_mutex_unlock_ordie(&hctypedb_mutex); if (hctype_create(avnd_cb, &hc_name, attributes) == nullptr) goto done2; } - else + else { TRACE_2("Record already exists"); + osaf_mutex_unlock_ordie(&hctypedb_mutex); + } } error = SA_AIS_OK; @@ -388,7 +409,7 @@ static void comp_hctype_update_compdb(AV osafassert(comp_type_name); // 2. search each component for a matching compType - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)0); + comp = (AVND_COMP *)compdb_rec_get_next(&cb->compdb, (uint8_t *)0); while (comp != 0) { if (strncmp((const char*) comp->saAmfCompType.value, comp_type_name, comp->saAmfCompType.length) == 0) { @@ -429,7 +450,7 @@ static void comp_hctype_update_compdb(AV } } } - comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)&comp->name); + comp = (AVND_COMP *) compdb_rec_get_next(&cb->compdb, (uint8_t *)&comp->name); } } @@ -439,7 +460,9 @@ uint32_t avnd_hc_oper_req(AVND_CB *cb, A TRACE_ENTER2("'%s'", param->name.value); + osaf_mutex_lock_ordie(&hcdb_mutex); AVND_HC *hc = (AVND_HC *)ncs_patricia_tree_get(&cb->hcdb, (uint8_t *)¶m->name); + osaf_mutex_unlock_ordie(&hcdb_mutex); switch (param->act) { case AVSV_OBJ_OPR_MOD: { @@ -468,7 +491,9 @@ uint32_t avnd_hc_oper_req(AVND_CB *cb, A case AVSV_OBJ_OPR_DEL: { if (hc != nullptr) { + osaf_mutex_lock_ordie(&hcdb_mutex); rc = ncs_patricia_tree_del(&cb->hcdb, &hc->tree_node); + osaf_mutex_unlock_ordie(&hcdb_mutex); osafassert(rc == NCSCC_RC_SUCCESS); LOG_IN("Deleted '%s'", param->name.value); } else { @@ -498,7 +523,9 @@ uint32_t avnd_hctype_oper_req(AVND_CB *c uint32_t rc = NCSCC_RC_FAILURE; TRACE_ENTER2("'%s'", param->name.value); + osaf_mutex_lock_ordie(&hctypedb_mutex); AVND_HCTYPE *hctype = (AVND_HCTYPE *)ncs_patricia_tree_get(&hctypedb, (uint8_t *)¶m->name); + osaf_mutex_unlock_ordie(&hctypedb_mutex); switch (param->act) { case AVSV_OBJ_OPR_MOD: { @@ -529,7 +556,9 @@ uint32_t avnd_hctype_oper_req(AVND_CB *c case AVSV_OBJ_OPR_DEL: { if (hctype != nullptr) { + osaf_mutex_lock_ordie(&hctypedb_mutex); rc = ncs_patricia_tree_del(&hctypedb, &hctype->tree_node); + osaf_mutex_unlock_ordie(&hctypedb_mutex); osafassert(rc == NCSCC_RC_SUCCESS); LOG_IN("Deleted '%s'", param->name.value); } else { diff --git a/osaf/services/saf/amf/amfnd/imm.cc b/osaf/services/saf/amf/amfnd/imm.cc new file mode 100644 --- /dev/null +++ b/osaf/services/saf/amf/amfnd/imm.cc @@ -0,0 +1,140 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Oracle + * + */ + +#include <thread> +#include "avnd.h" +#include <poll.h> +#include <imm.h> + +ir_cb_t ir_cb; +struct pollfd ImmReader::fds[]; +extern const AVND_EVT_HDLR g_avnd_func_list[AVND_EVT_MAX]; + +/** + * This thread will read classes and object information thereby allowing main + * thread to proceed with other important work. + * As of now, SU instantiation needs imm data to be read, so + * only this event is being handled here. + * Going forward, we need to use this function for similar purposes. + * @param _cb + * + * @return void* + */ +void ImmReader::imm_reader_thread() { + uint32_t rc = SA_AIS_OK; + AVND_EVT *evt; + TRACE_ENTER(); + NCS_SEL_OBJ mbx_fd; + + /* create the mail box */ + rc = m_NCS_IPC_CREATE(&ir_cb.mbx); + if (NCSCC_RC_SUCCESS != rc) { + LOG_CR("AvND Mailbox creation failed"); + exit(EXIT_FAILURE); + } + TRACE("Ir mailbox creation success"); + + /* attach the mail box */ + rc = m_NCS_IPC_ATTACH(&ir_cb.mbx); + if (NCSCC_RC_SUCCESS != rc) { + LOG_CR("Ir mailbox attach failed"); + exit(EXIT_FAILURE); + } + + mbx_fd = ncs_ipc_get_sel_obj(&ir_cb.mbx); + fds[FD_MBX].fd = mbx_fd.rmv_obj; + fds[FD_MBX].events = POLLIN; + + while (1) { + if (poll(fds, irfds, -1) == (-1)) { + if (errno == EINTR) { + continue; + } + + LOG_ER("poll Fail - %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (fds[FD_MBX].revents & POLLIN) { + while (nullptr != (evt = (AVND_EVT *)ncs_ipc_non_blk_recv(&ir_cb.mbx))) + ir_process_event(evt); + } + } + TRACE_LEAVE(); +} + +/** + * Start a imm reader thread. + * @param Nothing. + * @return Nothing. + */ +void ImmReader::imm_reader_thread_create() { + TRACE_ENTER(); + + std::thread t {imm_reader_thread}; + t.detach(); + + TRACE_LEAVE(); +} + +/** + * This function process events, which requires reading data from imm. + * As of now, SU instantiation needs to read data, so diverting SU + * instantiation in this thread. Going forward, we need to use this + * function for similar purposes. + * @param Event pointer. + * @return Nothing. + */ +void ImmReader::ir_process_event(AVND_EVT *evt) { + uint32_t res = NCSCC_RC_SUCCESS; + AVND_SU *su = 0; + TRACE_ENTER2("Evt type:%u", evt->type); + + /* get the su */ + su = m_AVND_SUDB_REC_GET(avnd_cb->sudb, evt->info.ir_evt.su_name); + if (!su) { + TRACE("SU'%s', not found in DB", evt->info.ir_evt.su_name.value); + goto done; + } + + res = avnd_comp_config_get_su(su); + { + AVND_EVT *evt_ir = 0; + TRACE("Sending to main thread."); + evt_ir = avnd_evt_create(avnd_cb, AVND_EVT_IR, 0, nullptr, &su->name, 0, 0); + if (res == NCSCC_RC_SUCCESS) + evt_ir->info.ir_evt.status = true; + else + evt_ir->info.ir_evt.status = false; + + res = m_NCS_IPC_SEND(&avnd_cb->mbx, evt_ir, evt_ir->priority); + + if (NCSCC_RC_SUCCESS != res) + LOG_CR("AvND send event to main thread mailbox failed, type = %u", evt_ir->type); + + TRACE("Imm Read:'%d'", evt_ir->info.ir_evt.status); + + /* if failure, free the event */ + if (NCSCC_RC_SUCCESS != res && evt_ir) + avnd_evt_destroy(evt_ir); + } +done: + if (evt) + avnd_evt_destroy(evt); + + TRACE_LEAVE2("res '%u'", res); +} diff --git a/osaf/services/saf/amf/amfnd/include/Makefile.am b/osaf/services/saf/amf/amfnd/include/Makefile.am --- a/osaf/services/saf/amf/amfnd/include/Makefile.am +++ b/osaf/services/saf/amf/amfnd/include/Makefile.am @@ -36,5 +36,6 @@ noinst_HEADERS = \ avnd_su.h \ avnd_tmr.h \ avnd_util.h \ - avnd_proxy.h + avnd_proxy.h \ + imm.h diff --git a/osaf/services/saf/amf/amfnd/include/avnd_comp.h b/osaf/services/saf/amf/amfnd/include/avnd_comp.h --- a/osaf/services/saf/amf/amfnd/include/avnd_comp.h +++ b/osaf/services/saf/amf/amfnd/include/avnd_comp.h @@ -590,11 +590,11 @@ typedef struct avnd_comp_tag { /* macro to get a component record from comp-db */ #define m_AVND_COMPDB_REC_GET(compdb, name) \ - (AVND_COMP *)ncs_patricia_tree_get(&(compdb), (uint8_t *)&(name)) + compdb_rec_get(&(compdb), &(name)) /* macro to get the next component record from comp-db */ #define m_AVND_COMPDB_REC_GET_NEXT(compdb, name) \ - (AVND_COMP *)ncs_patricia_tree_getnext(&(compdb), (uint8_t *)&(name)) + compdb_rec_get_next(&(compdb), (uint8_t *)&(name)) /* macro to add a csi record to the comp-csi list */ #define m_AVND_COMPDB_REC_CSI_ADD(comp, csi, rc) \ @@ -922,5 +922,7 @@ extern void comp_reset_restart_count(con extern void clear_error_report_alarm(AVND_COMP *comp); bool nonrestartable(const AVND_COMP *comp); uint32_t csi_count(const AVND_COMP *comp); +extern AVND_COMP *compdb_rec_get(NCS_PATRICIA_TREE *compdb, const SaNameT *name); +extern AVND_COMP *compdb_rec_get_next(NCS_PATRICIA_TREE *compdb, uint8_t *name); #endif /* !AVND_COMP_H */ diff --git a/osaf/services/saf/amf/amfnd/include/avnd_evt.h b/osaf/services/saf/amf/amfnd/include/avnd_evt.h --- a/osaf/services/saf/amf/amfnd/include/avnd_evt.h +++ b/osaf/services/saf/amf/amfnd/include/avnd_evt.h @@ -110,6 +110,7 @@ typedef enum avnd_evt_type { AVND_EVT_LAST_STEP_TERM, AVND_EVT_PID_EXIT, AVND_EVT_TMR_QSCING_CMPL, + AVND_EVT_IR, AVND_EVT_MAX } AVND_EVT_TYPE; @@ -157,6 +158,11 @@ typedef struct avnd_pm_mon_evt { AVND_COMP_PM_REC *pm_rec; } AVND_PM_MON_EVT; +typedef struct avnd_ir_evt { + SaNameT su_name; /* su-name */ + bool status; /* Result of Imm read, true is succ. */ +} AVND_IR_EVT; + /* AVND top-level event structure */ typedef struct avnd_evt_tag { struct avnd_evt_tag *next; @@ -175,6 +181,7 @@ typedef struct avnd_evt_tag { AVND_CLC_EVT clc; AVND_COMP_FSM_EVT comp_fsm; AVND_PM_MON_EVT pm_evt; + AVND_IR_EVT ir_evt; } info; } AVND_EVT; diff --git a/osaf/services/saf/amf/amfnd/include/avnd_proxy.h b/osaf/services/saf/amf/amfnd/include/avnd_proxy.h --- a/osaf/services/saf/amf/amfnd/include/avnd_proxy.h +++ b/osaf/services/saf/amf/amfnd/include/avnd_proxy.h @@ -30,11 +30,11 @@ /* macro to get a component record from comp-db */ #define m_AVND_INT_EXT_COMPDB_REC_GET(compdb, name) \ - (AVND_COMP *)ncs_patricia_tree_get(&(compdb), (uint8_t *)&(name)) + compdb_rec_get(&(compdb), &(name)) /* macro to get the next component record from comp-db */ #define m_AVND_INT_EXT_COMPDB_REC_GET_NEXT(compdb, name) \ - (AVND_COMP *)ncs_patricia_tree_getnext(&(compdb), (uint8_t *)&(name)) + compdb_rec_get_next(&(compdb), (uint8_t *)&(name)) typedef struct avnd_node_id_to_mds_dest_map_tag { NCS_PATRICIA_NODE tree_node; diff --git a/osaf/services/saf/amf/amfnd/include/avnd_su.h b/osaf/services/saf/amf/amfnd/include/avnd_su.h --- a/osaf/services/saf/amf/amfnd/include/avnd_su.h +++ b/osaf/services/saf/amf/amfnd/include/avnd_su.h @@ -326,18 +326,11 @@ typedef struct avnd_su_tag { /* macro to get the SU recrod from the SU database */ #define m_AVND_SUDB_REC_GET(sudb, name) \ - (AVND_SU *)ncs_patricia_tree_get(&(sudb), (uint8_t *)&(name)) - -/* macro to get the next SU recrod from the SU database */ -#define m_AVND_SUDB_REC_GET_NEXT(sudb, name) \ - (AVND_SU *)ncs_patricia_tree_getnext(&(sudb), (uint8_t *)&(name)) + sudb_rec_get(&(sudb), &(name)) /* macro to add a component to the su-comp list */ #define m_AVND_SUDB_REC_COMP_ADD(su, comp, rc) \ -{ \ - (comp).su_dll_node.key = (uint8_t *)&((comp).inst_level); \ - (rc) = ncs_db_link_list_add(&(su).comp_list, &(comp).su_dll_node); \ -}; + sudb_rec_comp_add(&su, &comp, &rc) /* macro to remove a component from the su-comp list */ #define m_AVND_SUDB_REC_COMP_REM(su, comp) \ @@ -424,4 +417,7 @@ bool isFailed(const AVND_SU *su); bool isRestartSet(const AVND_SU *su); bool su_evaluate_restarting_state(AVND_SU *su); bool all_csis_in_restarting_state(const AVND_SU *su, AVND_COMP_CSI_REC * exclude_csi = nullptr); +extern AVND_SU *sudb_rec_get(NCS_PATRICIA_TREE *sudb, const SaNameT *name); +extern AVND_SU *sudb_rec_get_next(NCS_PATRICIA_TREE *sudb, uint8_t *name); +extern void sudb_rec_comp_add(AVND_SU *su, AVND_COMP *comp, uint32_t *rc); #endif diff --git a/osaf/services/saf/amf/amfnd/include/imm.h b/osaf/services/saf/amf/amfnd/include/imm.h --- a/osaf/services/saf/amf/amfnd/include/imm.h +++ b/osaf/services/saf/amf/amfnd/include/imm.h @@ -43,4 +43,6 @@ class ImmReader { void operator=(const ImmReader&); }; +extern uint32_t avnd_evt_ir_evh(struct avnd_cb_tag *cb, struct avnd_evt_tag *evt); + #endif diff --git a/osaf/services/saf/amf/amfnd/main.cc b/osaf/services/saf/amf/amfnd/main.cc --- a/osaf/services/saf/amf/amfnd/main.cc +++ b/osaf/services/saf/amf/amfnd/main.cc @@ -31,6 +31,7 @@ #include "immutil.h" #include "logtrace.h" #include "nid_api.h" +#include <imm.h> #define FD_MBX 0 #define FD_TERM 1 @@ -117,7 +118,8 @@ extern const AVND_EVT_HDLR g_avnd_func_l avnd_evt_comp_pres_fsm_evh, /* AVND_EVT_COMP_PRES_FSM_EV */ avnd_evt_last_step_term_evh, /* AVND_EVT_LAST_STEP_TERM */ avnd_evt_pid_exit_evh, /* AVND_EVT_PID_EXIT */ - avnd_evt_tmr_qscing_cmpl_evh /* AVND_EVT_TMR_QSCING_CMPL */ + avnd_evt_tmr_qscing_cmpl_evh, /* AVND_EVT_TMR_QSCING_CMPL */ + avnd_evt_ir_evh /* AVND_EVT_IR */ }; extern struct ImmutilWrapperProfile immutilWrapperProfile; @@ -534,7 +536,7 @@ void avnd_main_process(void) LOG_ER("signal TERM failed: %s", strerror(errno)); goto done; } - + ImmReader::imm_reader_thread_create(); mbx_fd = ncs_ipc_get_sel_obj(&avnd_cb->mbx); fds[FD_MBX].fd = mbx_fd.rmv_obj; fds[FD_MBX].events = POLLIN; @@ -634,6 +636,7 @@ void avnd_evt_process(AVND_EVT *evt) done: if (evt) avnd_evt_destroy(evt); + TRACE_LEAVE(); } /***************************************************************************** diff --git a/osaf/services/saf/amf/amfnd/su.cc b/osaf/services/saf/amf/amfnd/su.cc --- a/osaf/services/saf/amf/amfnd/su.cc +++ b/osaf/services/saf/amf/amfnd/su.cc @@ -245,7 +245,7 @@ static uint32_t avnd_avd_su_update_on_fo * updates are not received in the message. */ memset(&su_name, 0, sizeof(SaNameT)); - while (nullptr != (su = (AVND_SU *)ncs_patricia_tree_getnext(&cb->sudb, (uint8_t *)&su_name))) { + while (nullptr != (su = (AVND_SU *)sudb_rec_get_next(&cb->sudb, (uint8_t *)&su_name))) { su_name = su->name; if (false == su->avd_updt_flag) { @@ -595,14 +595,14 @@ uint32_t avnd_su_curr_info_del(AVND_CB * static bool comp_in_term_failed_state(void) { AVND_COMP *comp = - (AVND_COMP *)ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)0); + (AVND_COMP *)compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)0); while (comp != nullptr) { if (comp->pres == SA_AMF_PRESENCE_TERMINATION_FAILED) return true; comp = (AVND_COMP *) - ncs_patricia_tree_getnext(&avnd_cb->compdb, (uint8_t *)&comp->name); + compdb_rec_get_next(&avnd_cb->compdb, (uint8_t *)&comp->name); } return false; diff --git a/osaf/services/saf/amf/amfnd/sudb.cc b/osaf/services/saf/amf/amfnd/sudb.cc --- a/osaf/services/saf/amf/amfnd/sudb.cc +++ b/osaf/services/saf/amf/amfnd/sudb.cc @@ -29,6 +29,9 @@ #include "avnd.h" #include <immutil.h> +#include "osaf_utility.h" + +static pthread_mutex_t sudb_mutex = PTHREAD_MUTEX_INITIALIZER; /**************************************************************************** Name : avnd_sudb_init @@ -143,7 +146,9 @@ AVND_SU *avnd_sudb_rec_add(AVND_CB *cb, */ su->tree_node.bit = 0; su->tree_node.key_info = (uint8_t *)&su->name; + osaf_mutex_lock_ordie(&sudb_mutex); *rc = ncs_patricia_tree_add(&cb->sudb, &su->tree_node); + osaf_mutex_unlock_ordie(&sudb_mutex); if (NCSCC_RC_SUCCESS != *rc) { *rc = AVND_ERR_TREE; goto err; @@ -205,7 +210,9 @@ uint32_t avnd_sudb_rec_del(AVND_CB *cb, osafassert(su->si_list.n_nodes == 0); /* remove from the patricia tree */ + osaf_mutex_lock_ordie(&sudb_mutex); rc = ncs_patricia_tree_del(&cb->sudb, &su->tree_node); + osaf_mutex_unlock_ordie(&sudb_mutex); if (NCSCC_RC_SUCCESS != rc) { LOG_NO("%s: %s tree del failed", __FUNCTION__, su->name.value); rc = AVND_ERR_TREE; @@ -270,3 +277,43 @@ done: TRACE_LEAVE(); return rc; } + +/** + * This function return SU rec. + * @param Pointer to SUDB. + * @param Pointer to SU name. + * @return Pointer to SU. + */ +AVND_SU * sudb_rec_get(NCS_PATRICIA_TREE *sudb, const SaNameT *name) { + osaf_mutex_lock_ordie(&sudb_mutex); + AVND_SU *su = (AVND_SU *)ncs_patricia_tree_get(sudb, (uint8_t *)(name)); + osaf_mutex_unlock_ordie(&sudb_mutex); + return su; +} + +/** + * This function return next SU rec. + * @param Pointer to SUDB. + * @param Pointer to SU name. + * @return Pointer to SU. + */ +AVND_SU *sudb_rec_get_next(NCS_PATRICIA_TREE *sudb, uint8_t *name) { + osaf_mutex_lock_ordie(&sudb_mutex); + AVND_SU *su = (AVND_SU *)ncs_patricia_tree_getnext(sudb, (uint8_t *)(name)); + osaf_mutex_unlock_ordie(&sudb_mutex); + return su; +} + +/** + * This function adds comp to the comp-list + * @param Pointer to SUDB. + * @param Pointer to SU name. + * @return Pointer to SU. + */ +void sudb_rec_comp_add(AVND_SU *su, AVND_COMP *comp, uint32_t *rc) { + osaf_mutex_lock_ordie(&sudb_mutex); + comp->su_dll_node.key = (uint8_t *)&((comp)->inst_level); + *rc = ncs_db_link_list_add(&(su)->comp_list, &(comp)->su_dll_node); + osaf_mutex_unlock_ordie(&sudb_mutex); +} + diff --git a/osaf/services/saf/amf/amfnd/susm.cc b/osaf/services/saf/amf/amfnd/susm.cc --- a/osaf/services/saf/amf/amfnd/susm.cc +++ b/osaf/services/saf/amf/amfnd/susm.cc @@ -34,6 +34,7 @@ */ #include "avnd.h" +#include "imm.h" /* static function declarations */ static uint32_t avnd_su_pres_uninst_suinst_hdler(AVND_CB *, AVND_SU *, AVND_COMP *); @@ -1335,54 +1336,16 @@ uint32_t avnd_evt_avd_su_pres_evh(AVND_C goto done; } } else { /* => instantiate the su */ - TRACE("SU term state is set to false"); - /* Reset admn term operation flag */ - m_AVND_SU_ADMN_TERM_RESET(su); - /* Add components belonging to this SU if components were not added before. - This can happen in runtime when SU is first added and then comp. When SU is added amfd will - send SU info to amfnd, at this point of time no component exists in IMM DB, so SU list of comp is - empty. When comp are added later, it is not sent to amfnd as amfnd reads comp info from IMM DB. - Now when unlock-inst is done then avnd_evt_avd_su_pres_msg is called. At this point of time, we - are not having Comp info in SU list, so need to add it. - - If component exists as it would be in case controller is coming up with all entities configured, - then avnd_comp_config_get_su() will not read anything, it will return success. - - Trying to read config info of openSAF SUs may result in a deadlock condition when IMMND calls AMF - register sync call(after AMF invokes instantiate script in NoRed SU instantiation sequence) and - amfnd reads immsv database using search_initializie sync api(AMF reads database for middleware - 2N SUs during 2N Red SU instantiation). This is purely dependent on timing when immnd is - registering with AMF and AMF is reading config from immnd during controller coming up. - Fix for the above problem is that Middleware Components wont be dynamically added in the case - of openSAF SUs, so don't refresh config info if it is openSAF SU. */ - - if ((false == su->is_ncs) && (avnd_comp_config_get_su(su) != NCSCC_RC_SUCCESS)) { - if (cb->scs_absence_max_duration == 0) { - m_AVND_SU_REG_FAILED_SET(su); - /* Will transition to instantiation-failed when instantiated */ - LOG_ER("'%s':FAILED", __FUNCTION__); - rc = NCSCC_RC_FAILURE; - goto done; - } else { - // @TODO(garylee) this is a temporary workaround: IMM is not accepting OM connections - // and a component needs to be restarted. - LOG_CR("'%s': failed to refresh components in SU. Attempt to reuse old config", __FUNCTION__); - } - } - /* trigger su instantiation for pi su */ - if (m_AVND_SU_IS_PREINSTANTIABLE(su)) { - TRACE("SU instantiation for PI SUs, running the SU presence state FSM:'%s'", su->name.value); - rc = avnd_su_pres_fsm_run(cb, su, 0, AVND_SU_PRES_FSM_EV_INST); - } - else { - if (m_AVND_SU_IS_REG_FAILED(su)) { - /* The SU configuration is bad, we cannot do much other transition to failed state */ - TRACE_2("SU Configuration is bad"); - avnd_su_pres_state_set(cb, su, SA_AMF_PRESENCE_INSTANTIATION_FAILED); - m_AVND_SU_ALL_TERM_RESET(su); - } else - osafassert(0); - } + AVND_EVT *evt_ir = 0; + TRACE("Sending to Imm thread."); + evt_ir = avnd_evt_create(cb, AVND_EVT_IR, 0, nullptr, &info->su_name, 0, 0); + rc = m_NCS_IPC_SEND(&ir_cb.mbx, evt_ir, evt_ir->priority); + if (NCSCC_RC_SUCCESS != rc) + LOG_CR("AvND send event to IR mailbox failed, type = %u", evt_ir->type); + /* if failure, free the event */ + if (NCSCC_RC_SUCCESS != rc && evt_ir) + avnd_evt_destroy(evt_ir); + } done: @@ -3783,3 +3746,84 @@ done: TRACE_LEAVE2("%u", rc); return rc; } + +/** + * @brief This function processes events from IR thread. + * + * @param ptr to the AvND control block + * @param ptr to the AvND event + * + * @return NCSCC_RC_FAILURE/NCSCC_RC_SUCCESS + */ +uint32_t avnd_evt_ir_evh(struct avnd_cb_tag *cb, struct avnd_evt_tag *evt) +{ + uint32_t rc = NCSCC_RC_SUCCESS; + AVND_SU *su = 0; + TRACE_ENTER2("su name '%s'", evt->info.ir_evt.su_name.value); + + /* get the su */ + su = m_AVND_SUDB_REC_GET(cb->sudb, evt->info.ir_evt.su_name); + if (!su) { + TRACE("SU'%s', not found in DB", evt->info.ir_evt.su_name.value); + goto done; + } + + TRACE("SU term state is set to false"); + /* Reset admn term operation flag */ + m_AVND_SU_ADMN_TERM_RESET(su); + /* Add components belonging to this SU if components were not added before. + This can happen in runtime when SU is first added and then comp. When SU is added amfd will + send SU info to amfnd, at this point of time no component exists in IMM DB, so SU list of comp is + empty. When comp are added later, it is not sent to amfnd as amfnd reads comp info from IMM DB. + Now when unlock-inst is done then avnd_evt_avd_su_pres_msg is called. At this point of time, we + are not having Comp info in SU list, so need to add it. + + If component exists as it would be in case controller is coming up with all entities configured, + then avnd_comp_config_get_su() will not read anything, it will return success. + + Trying to read config info of openSAF SUs may result in a deadlock condition when IMMND calls AMF + register sync call(after AMF invokes instantiate script in NoRed SU instantiation sequence) and + amfnd reads immsv database using search_initializie sync api(AMF reads database for middleware + 2N SUs during 2N Red SU instantiation). This is purely dependent on timing when immnd is + registering with AMF and AMF is reading config from immnd during controller coming up. + Fix for the above problem is that Middleware Components wont be dynamically added in the case + of openSAF SUs, so don't refresh config info if it is openSAF SU. */ + + if ((false == su->is_ncs) && (evt->info.ir_evt.status == false)) { + if (cb->scs_absence_max_duration == 0) { + m_AVND_SU_REG_FAILED_SET(su); + /* Will transition to instantiation-failed when instantiated */ + LOG_ER("'%s':FAILED", __FUNCTION__); + rc = NCSCC_RC_FAILURE; + goto done; + } else { + // @TODO(garylee) this is a temporary workaround: IMM is not accepting OM connections + // and a component needs to be restarted. + LOG_CR("'%s': failed to refresh components in SU. Attempt to reuse old config", __FUNCTION__); + } + } + /* trigger su instantiation for pi su */ + if (m_AVND_SU_IS_PREINSTANTIABLE(su)) { + /* Update the comp oper state. */ + for (AVND_COMP *comp = m_AVND_COMP_FROM_SU_DLL_NODE_GET(m_NCS_DBLIST_FIND_FIRST(&su->comp_list)); + comp; + comp = m_AVND_COMP_FROM_SU_DLL_NODE_GET(m_NCS_DBLIST_FIND_NEXT(&comp->su_dll_node))) { + m_AVND_COMP_OPER_STATE_AVD_SYNC(avnd_cb, comp, rc); + } + TRACE("SU instantiation for PI SUs, running the SU presence state FSM:'%s'", su->name.value); + rc = avnd_su_pres_fsm_run(cb, su, 0, AVND_SU_PRES_FSM_EV_INST); + } + else { + if (m_AVND_SU_IS_REG_FAILED(su)) { + /* The SU configuration is bad, we cannot do much other transition to failed state */ + TRACE_2("SU Configuration is bad"); + avnd_su_pres_state_set(cb, su, SA_AMF_PRESENCE_INSTANTIATION_FAILED); + m_AVND_SU_ALL_TERM_RESET(su); + } else + osafassert(0); + } + +done: + TRACE_LEAVE(); + return rc; +} diff --git a/osaf/services/saf/amf/amfnd/term.cc b/osaf/services/saf/amf/amfnd/term.cc --- a/osaf/services/saf/amf/amfnd/term.cc +++ b/osaf/services/saf/amf/amfnd/term.cc @@ -64,7 +64,7 @@ void avnd_last_step_clean(AVND_CB *cb) LOG_NO("Terminating all AMF components"); - comp = (AVND_COMP *)ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)0); + comp = (AVND_COMP *)compdb_rec_get_next(&cb->compdb, (uint8_t *)0); while (comp != nullptr) { if (false == comp->su->su_is_external) { /* Don't call cleanup script for PI/NPI components in UNINSTANTIATED state.*/ @@ -80,7 +80,7 @@ void avnd_last_step_clean(AVND_CB *cb) } comp = (AVND_COMP *) - ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *)&comp->name); + compdb_rec_get_next(&cb->compdb, (uint8_t *)&comp->name); } /* Stop was called early or some other problem */ ------------------------------------------------------------------------------ Mobile security can be enabling, not merely restricting. Employees who bring their own devices (BYOD) to work are irked by the imposition of MDM restrictions. Mobile Device Manager Plus allows you to control only the apps on BYO-devices by containerizing them, leaving personal data untouched! https://ad.doubleclick.net/ddm/clk/304595813;131938128;j _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel