Hi Alex Ack I have made a regression test with your latest 2144 and 2145 patches. This regression test does of course not specifically test your changes but does not indicate any problems in other areas.
Thanks Lennart > -----Original Message----- > From: Alex Jones [mailto:[email protected]] > Sent: den 1 mars 2017 03:20 > To: [email protected]; Lennart Lund > <[email protected]>; Rafael Odzakow > <[email protected]> > Cc: [email protected] > Subject: [PATCH 1 of 1] smfd: add support for asynchronous detection of > failed AMF entities [#2145] > > src/smf/smfd/SmfCampState.cc | 68 ++++++++++ > src/smf/smfd/SmfCampState.h | 7 + > src/smf/smfd/SmfCampaignThread.cc | 233 > ++++++++++++++++++++++++++++++++++++- > src/smf/smfd/SmfCampaignThread.h | 15 ++ > src/smf/smfd/SmfStepTypes.cc | 32 ++-- > src/smf/smfd/SmfUpgradeCampaign.cc | 20 +++ > src/smf/smfd/SmfUpgradeCampaign.h | 7 + > 7 files changed, 363 insertions(+), 19 deletions(-) > > > This patch adds support for section 4.2.1.3 of SMF A.01.02 spec. > > diff --git a/src/smf/smfd/SmfCampState.cc > b/src/smf/smfd/SmfCampState.cc > --- a/src/smf/smfd/SmfCampState.cc > +++ b/src/smf/smfd/SmfCampState.cc > @@ -191,6 +191,18 @@ SmfCampState::commit(SmfUpgradeCampaign > } > > > //------------------------------------------------------------------------------ > +// asyncFailure() > +//------------------------------------------------------------------------------ > +SmfCampResultT > +SmfCampState::asyncFailure(SmfUpgradeCampaign * i_camp) > +{ > + TRACE_ENTER(); > + LOG_NO("SmfCampState::asyncFailure default implementation. No > state change"); > + TRACE_LEAVE(); > + return SMF_CAMP_DONE; > +} > + > +//------------------------------------------------------------------------------ > // procResult() > > //------------------------------------------------------------------------------ > SmfCampResultT > @@ -926,6 +938,37 @@ SmfCampStateExecuting::suspend(SmfUpgrad > } > > > //------------------------------------------------------------------------------ > +// asyncFailure() > +//------------------------------------------------------------------------------ > +SmfCampResultT > +SmfCampStateExecuting::asyncFailure(SmfUpgradeCampaign * i_camp) > +{ > + TRACE_ENTER(); > + TRACE("SmfCampStateExecuting::asyncFailure implementation"); > + > + /* Send suspend message to all procedures */ > + std::vector<SmfUpgradeProcedure*> procedures = i_camp- > >getProcedures(); > + > + std::vector < SmfUpgradeProcedure * >::iterator iter; > + > + for (iter = procedures.begin(); iter != procedures.end(); ++iter) { > + TRACE("SmfCampStateExecuting::Procedure %s, send suspend", > + (*iter)->getProcName().c_str()); > + SmfProcedureThread *procThread = (*iter)->getProcThread(); > + PROCEDURE_EVT *evt = new PROCEDURE_EVT(); > + evt->type = PROCEDURE_EVT_SUSPEND; > + procThread->send(evt); > + } > + > + i_camp->m_noOfProcResponses = 0; > + changeState(i_camp, SmfCampStateErrorDetected::instance()); > + /* Wait for suspend responses from all procedures > (SmfCampStateSuspendingExec::procResult) */ > + > + TRACE_LEAVE(); > + return SMF_CAMP_SUSPENDING; > +} > + > +//------------------------------------------------------------------------------ > // procResult() > > //------------------------------------------------------------------------------ > SmfCampResultT > @@ -1215,6 +1258,19 @@ SmfCampStateSuspendingExec::execute(SmfU > } > > > //------------------------------------------------------------------------------ > +// asyncFailure() > +//------------------------------------------------------------------------------ > +SmfCampResultT > +SmfCampStateSuspendingExec::asyncFailure(SmfUpgradeCampaign * > i_camp) > +{ > + TRACE_ENTER(); > + TRACE("SmfCampStateSuspendingExec::asyncFailure > implementation"); > + changeState(i_camp, > SmfCampStateErrorDetectedInSuspending::instance()); > + TRACE_LEAVE(); > + return SMF_CAMP_DONE; > +} > + > +//------------------------------------------------------------------------------ > // procResult() > > //------------------------------------------------------------------------------ > SmfCampResultT > @@ -1991,6 +2047,18 @@ SmfCampRollingBack::suspend(SmfUpgradeCa > } > > > //------------------------------------------------------------------------------ > +// asyncFailure() > +//------------------------------------------------------------------------------ > +SmfCampResultT > +SmfCampRollingBack::asyncFailure(SmfUpgradeCampaign * i_camp) > +{ > + TRACE_ENTER(); > + TRACE("SmfCampRollingBack::asyncFailure implementation"); > + > + return SmfCampRollingBack::suspend(i_camp); > +} > + > +//------------------------------------------------------------------------------ > // procResult() > > //------------------------------------------------------------------------------ > SmfCampResultT > diff --git a/src/smf/smfd/SmfCampState.h b/src/smf/smfd/SmfCampState.h > --- a/src/smf/smfd/SmfCampState.h > +++ b/src/smf/smfd/SmfCampState.h > @@ -72,6 +72,8 @@ class SmfCampState { > > virtual SmfCampResultT commit(SmfUpgradeCampaign * i_camp); > > + virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * > i_camp); > + > virtual SmfCampResultT procResult(SmfUpgradeCampaign * i_camp, > SmfUpgradeProcedure * i_procedure, > SmfProcResultT i_result); > @@ -132,6 +134,8 @@ class SmfCampStateExecuting:public SmfCa > > virtual SmfCampResultT suspend(SmfUpgradeCampaign * i_camp); > > + virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * > i_camp); > + > virtual SmfCampResultT procResult(SmfUpgradeCampaign * i_camp, > SmfUpgradeProcedure * i_procedure, > SmfProcResultT i_result); > @@ -182,6 +186,8 @@ class SmfCampStateSuspendingExec:public > > virtual SmfCampResultT execute(SmfUpgradeCampaign * i_camp); > > + virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * > i_camp); > + > virtual SmfCampResultT procResult(SmfUpgradeCampaign * i_camp, > SmfUpgradeProcedure * i_procedure, > SmfProcResultT i_result); > @@ -345,6 +351,7 @@ class SmfCampRollingBack:public SmfCampS > virtual SmfCampResultT > rollbackSingleMergeProc(SmfUpgradeCampaign * i_camp); > virtual SmfCampResultT rollbackInit(SmfUpgradeCampaign * > i_camp); > virtual SmfCampResultT suspend(SmfUpgradeCampaign * i_camp); > + virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * > i_camp); > virtual SmfCampResultT procResult(SmfUpgradeCampaign * i_camp, > SmfUpgradeProcedure * i_procedure, > SmfProcResultT i_result); > diff --git a/src/smf/smfd/SmfCampaignThread.cc > b/src/smf/smfd/SmfCampaignThread.cc > --- a/src/smf/smfd/SmfCampaignThread.cc > +++ b/src/smf/smfd/SmfCampaignThread.cc > @@ -40,6 +40,7 @@ > #include "smf/smfd/smfd_long_dn.h" > > SmfCampaignThread *SmfCampaignThread::s_instance = NULL; > +SaNtfSubscriptionIdT SmfCampaignThread::operStateSubId(1); > > #define SMF_RDA_RETRY_COUNT 25 /* This is taken as the csi's are assigned > in parallel */ > > @@ -141,7 +142,12 @@ void SmfCampaignThread::main(NCSCONTEXT > SmfCampaignThread::~SmfCampaignThread() > { > TRACE_ENTER(); > - SaAisErrorT rc = saNtfFinalize(m_ntfHandle); > + SaAisErrorT rc(saNtfNotificationUnsubscribe(operStateSubId)); > + if (rc != SA_AIS_OK) { > + LOG_ER("Failed to unsubscribe to oper state notifications > %u", rc); > + } > + > + rc = saNtfFinalize(m_ntfHandle); > if (rc != SA_AIS_OK) { > LOG_ER("Failed to finalize NTF handle %u", rc); > } > @@ -304,10 +310,14 @@ int SmfCampaignThread::initNtf(void) > { > SaAisErrorT rc = SA_AIS_ERR_TRY_AGAIN; > SaVersionT ntfVersion = { 'A', 1, 1 }; > + SaNtfCallbacksT callbacks = { > + ntfNotificationCallback, > + 0 > + }; > unsigned int numOfTries = 50; > > while (rc == SA_AIS_ERR_TRY_AGAIN && numOfTries > 0) { > - rc = saNtfInitialize(&m_ntfHandle, NULL, &ntfVersion); > + rc = saNtfInitialize(&m_ntfHandle, &callbacks, &ntfVersion); > if (rc != SA_AIS_ERR_TRY_AGAIN) { > break; > } > @@ -320,9 +330,200 @@ int SmfCampaignThread::initNtf(void) > return -1; > } > > + // subscribe to operational state change notifications generated by > AMF > + rc = initNtfSubscriptions(); > + if (rc != SA_AIS_OK) { > + LOG_ER("initNtfSubscriptions FAILED rc=%s", saf_error(rc)); > + return -1; > + } > + > return 0; > } > > +SaAisErrorT SmfCampaignThread::initNtfSubscriptions(void) { > + TRACE_ENTER(); > + SaAisErrorT rc(SA_AIS_OK); > + > + do { > + SaNtfStateChangeNotificationFilterT stateChangeFilter; > + > + SaAisErrorT rc(saNtfStateChangeNotificationFilterAllocate( > + m_ntfHandle, > + &stateChangeFilter, > + 0, > + 0, > + 0, > + 0, > + 0, > + 0)); > + > + if (rc != SA_AIS_OK) { > + LOG_ER("saNtfAttributeChangeNotificationFilterAllocate FAILED rc=%s", > + saf_error(rc)); > + break; > + } > + > + SaNtfNotificationTypeFilterHandlesT notificationFilterHandles = { > + 0, > + 0, > + stateChangeFilter.notificationFilterHandle, > + 0, > + 0 > + }; > + > + rc = saNtfNotificationSubscribe(¬ificationFilterHandles, > operStateSubId); > + > + if (rc != SA_AIS_OK) { > + LOG_ER("saNtfNotificationSubscribe FAILED rc=%s", saf_error(rc)); > + break; > + } > + > + rc = > saNtfNotificationFilterFree(stateChangeFilter.notificationFilterHandle); > + if (rc != SA_AIS_OK) { > + LOG_ER("saNtfNotificationFilterFree FAILED rc=%s", saf_error(rc)); > + break; > + } > + } while (false); > + > + TRACE_LEAVE(); > + return rc; > +} > + > +bool SmfCampaignThread::isAMFOperState(const SaNtfClassIdT& classId) > const { > + TRACE_ENTER(); > + bool status(false); > + > + if (classId.vendorId == SA_NTF_VENDOR_ID_SAF && > + classId.majorId == SA_SVC_AMF && > + classId.minorId == SA_AMF_NTFID_SU_OP_STATE) { > + status = true; > + } > + > + TRACE_LEAVE2("%i", status); > + return status; > +} > + > +void SmfCampaignThread::handleStateChangeNotification( > + const SaNtfStateChangeNotificationT& stateChangeNotification) { > + TRACE_ENTER(); > + if (stateChangeNotification.notificationHeader.eventType) { > + if (*stateChangeNotification.notificationHeader.eventType == > + SA_NTF_OBJECT_STATE_CHANGE) { > + handleObjectStateChangeNotification(stateChangeNotification); > + } else { > + TRACE("ignoring state change notification with event type: %i", > + *stateChangeNotification.notificationHeader.eventType); > + } > + } > + TRACE_LEAVE(); > +} > + > +void SmfCampaignThread::handleAmfObjectStateChangeNotification( > + const SaNtfStateChangeNotificationT& stateChangeNotification) { > + TRACE_ENTER(); > + > + do { > + bool disabled(false); > + > + // see if this is a failure of an upgraded SU > + for (SaUint16T i(0); i < stateChangeNotification.numStateChanges; i++) { > + if (stateChangeNotification.changedStates[i].newState == > + SA_AMF_OPERATIONAL_DISABLED) { > + disabled = true; > + break; > + } > + } > + > + if (!disabled) { > + TRACE("state change is not to DISABLED -- ignoring"); > + break; > + } > + > + for (SaUint16T i(0); > + i < stateChangeNotification.notificationHeader.numAdditionalInfo; > + i++) { > + if > (stateChangeNotification.notificationHeader.additionalInfo[i].infoId != > + SA_AMF_MAINTENANCE_CAMPAIGN_DN || > + > stateChangeNotification.notificationHeader.additionalInfo[i].infoType > + != SA_NTF_VALUE_LDAP_NAME) { > + continue; > + } > + > + SaNameT *name(0); > + SaUint16T dataSize(0); > + > + SaAisErrorT rc(saNtfPtrValGet( > + stateChangeNotification.notificationHandle, > + > &stateChangeNotification.notificationHeader.additionalInfo[i].infoValue, > + reinterpret_cast<void **>(&name), > + &dataSize)); > + > + if (rc == SA_AIS_OK) { > + SaConstStringT maintenanceCampaign(saAisNameBorrow(name)); > + > + if (!strcmp(maintenanceCampaign, > + s_instance->m_campaign->getDn().c_str())) { > + LOG_ER("SU: %s failed after upgrade in campaign", > + > saAisNameBorrow(stateChangeNotification.notificationHeader.notificationO > bject)); > + s_instance->m_campaign->getUpgradeCampaign()->asyncFailure(); > + > + std::string error(saAisNameBorrow( > + stateChangeNotification.notificationHeader.notificationObject)); > + > + error += " failed after upgrade"; > + s_instance->m_campaign->setError(error); > + } else { > + LOG_ER("maintenance campaign received from AMF (%s) is not the " > + "same as ours (%s)", > + maintenanceCampaign, > + s_instance->m_campaign->getDn().c_str()); > + } > + } else { > + LOG_ER("saNtfPtrValGet failed: %d", rc); > + } > + } > + } while (false); > + > + TRACE_LEAVE(); > +} > + > +void SmfCampaignThread::handleObjectStateChangeNotification( > + const SaNtfStateChangeNotificationT& stateChangeNotification) { > + TRACE_ENTER(); > + > + if (stateChangeNotification.notificationHeader.notificationClassId && > + > isAMFOperState(*stateChangeNotification.notificationHeader.notificationCl > assId)) { > + handleAmfObjectStateChangeNotification(stateChangeNotification); > + } else { > + TRACE("ignoring non-AMF state change notification"); > + } > + > + TRACE_LEAVE(); > +} > + > +void SmfCampaignThread::ntfNotificationCallback( > + SaNtfSubscriptionIdT subId, > + const SaNtfNotificationsT *notification) { > + TRACE_ENTER(); > + > + do { > + if (subId != operStateSubId) { > + TRACE("unknown subscription id received in ntfNotificationCallback: > %d", > + subId); > + break; > + } > + > + if (notification->notificationType == SA_NTF_TYPE_STATE_CHANGE) { > + s_instance->handleStateChangeNotification( > + notification->notification.stateChangeNotification); > + } else { > + TRACE("ignoring NTF notification of type: %i", > + notification->notificationType); > + } > + } while (false); > + > + TRACE_LEAVE(); > +} > /** > * SmfCampaignThread::send > * send event to the thread. > @@ -673,18 +874,31 @@ int SmfCampaignThread::handleEvents(void > { > TRACE_ENTER(); > NCS_SEL_OBJ mbx_fd = ncs_ipc_get_sel_obj(&m_mbx); > - struct pollfd fds[1]; > + > + SaSelectionObjectT ntfSelObj(0); > + > + SaAisErrorT rc(saNtfSelectionObjectGet(m_ntfHandle, &ntfSelObj)); > + if (rc != SA_AIS_OK) { > + LOG_ER("saNtfSelectionObjectGet FAILED - %s", > saf_error(rc)); > + return 1; > + } > + > + struct pollfd fds[2]; > > /* Set up all file descriptors to listen to */ > fds[0].fd = mbx_fd.rmv_obj; > fds[0].events = POLLIN; > fds[0].revents = 0; > > + fds[1].fd = ntfSelObj; > + fds[1].events = POLLIN; > + fds[1].revents = 0; > + > TRACE("Campaign thread %s waiting for events", m_campaign- > >getDn().c_str()); > > while (m_running) { > > - int ret = poll(fds, 1, SMF_UPDATE_ELAPSED_TIME_INTERVAL); > + int ret = poll(fds, sizeof(fds) / sizeof(pollfd), > SMF_UPDATE_ELAPSED_TIME_INTERVAL); > > if (ret == -1) { > if (errno == EINTR) > @@ -700,7 +914,16 @@ int SmfCampaignThread::handleEvents(void > processEvt(); > } > > - m_campaign->updateElapsedTime(); > + if (fds[1].revents & POLLIN) { > + // dispatch NTF events > + rc = saNtfDispatch(m_ntfHandle, SA_DISPATCH_ALL); > + > + if (rc != SA_AIS_OK) { > + LOG_ER("saNtfDispatch FAILED - %s", > saf_error(rc)); > + } > + } > + > + m_campaign->updateElapsedTime(); > } > TRACE_LEAVE(); > return 0; > diff --git a/src/smf/smfd/SmfCampaignThread.h > b/src/smf/smfd/SmfCampaignThread.h > --- a/src/smf/smfd/SmfCampaignThread.h > +++ b/src/smf/smfd/SmfCampaignThread.h > @@ -190,9 +190,24 @@ class SmfCampaignThread { > > SaAisErrorT createImmHandle(SmfCampaign * i_campaign); > SaAisErrorT deleteImmHandle(); > + SaAisErrorT initNtfSubscriptions(void); > + > + void handleStateChangeNotification(const > SaNtfStateChangeNotificationT&); > + > + void handleObjectStateChangeNotification( > + const SaNtfStateChangeNotificationT&); > + > + void handleAmfObjectStateChangeNotification( > + const SaNtfStateChangeNotificationT&); > + > + bool isAMFOperState(const SaNtfClassIdT&) const; > + > + static void ntfNotificationCallback(SaNtfSubscriptionIdT, > + const SaNtfNotificationsT *); > > static void main(NCSCONTEXT info); > static SmfCampaignThread *s_instance; > + static SaNtfSubscriptionIdT operStateSubId; > > NCSCONTEXT m_task_hdl; > SYSF_MBX m_mbx; /* mailbox */ > diff --git a/src/smf/smfd/SmfStepTypes.cc b/src/smf/smfd/SmfStepTypes.cc > --- a/src/smf/smfd/SmfStepTypes.cc > +++ b/src/smf/smfd/SmfStepTypes.cc > @@ -1247,8 +1247,8 @@ SmfStepTypeNodeReboot::execute() > return false; > } > > - /* Modify information model and set maintenance status */ > - LOG_NO("STEP: Modify information model and set maintenance > status"); > + /* Modify information model */ > + LOG_NO("STEP: Modify information model"); > if (m_step->modifyInformationModel() != SA_AIS_OK) { > LOG_ER("Failed to Modify information model in > step=%s",m_step- > >getRdn().c_str()); > return false; > @@ -1261,11 +1261,6 @@ SmfStepTypeNodeReboot::execute() > return false; > } > > - if (m_step->setMaintenanceStateActUnits() == false) { > - LOG_ER("Failed to set maintenance state in step=%s",m_step- > >getRdn().c_str()); > - return false; > - } > - > /* The action below is an add on to > SMF.--------------------------------------- > */ > /* See if any of the software bundles installed at online > installation has > the */ > /* saSmfBundleInstallOfflineScope attribute set to > SA_SMF_CMD_SCOPE_PLM_EE */ > @@ -1372,6 +1367,13 @@ SmfStepTypeNodeReboot::execute() > /* the units in the same state as before locking > */ > m_step->copyDuInitStateToAu(); > > + /* Now that the node is up, set the maintenance status */ > + LOG_NO("STEP: Set Maintenance Status"); > + if (m_step->setMaintenanceStateActUnits() == false) { > + LOG_ER("Failed to set maintenance state in step=%s",m_step- > >getRdn().c_str()); > + return false; > + } > + > /* Instantiate activation units */ > LOG_NO("STEP: Instantiate activation units"); > if (m_step->instantiateActivationUnits() == false) { > @@ -1685,8 +1687,8 @@ SmfStepTypeNodeRebootAct::execute() > return false; > } > > - /* Modify information model and set maintenance status */ > - LOG_NO("STEP: Modify information model and set maintenance > status"); > + /* Modify information model */ > + LOG_NO("STEP: Modify information model"); > if (m_step->modifyInformationModel() != SA_AIS_OK) { > LOG_ER("Failed to Modify information model in > step=%s",m_step- > >getRdn().c_str()); > return false; > @@ -1699,11 +1701,6 @@ SmfStepTypeNodeRebootAct::execute() > return false; > } > > - if (m_step->setMaintenanceStateActUnits() == false) { > - LOG_ER("Failed to set maintenance state in step=%s",m_step- > >getRdn().c_str()); > - return false; > - } > - > /* Offline installation of new software */ > LOG_NO("STEP: Offline installation of new software"); > if (m_step->offlineInstallNewBundles() == false) { > @@ -1746,6 +1743,13 @@ SmfStepTypeNodeRebootAct::execute() > /* the units in the same state as before locking > */ > m_step->copyDuInitStateToAu(); > > + /* Now that the node is up, set the maintenance status */ > + LOG_NO("STEP: Set Maintenance Status"); > + if (m_step->setMaintenanceStateActUnits() == false) { > + LOG_ER("Failed to set maintenance state in step=%s",m_step- > >getRdn().c_str()); > + return false; > + } > + > /* Instantiate activation units */ > LOG_NO("STEP: Instantiate activation units"); > if (m_step->instantiateActivationUnits() == false) { > diff --git a/src/smf/smfd/SmfUpgradeCampaign.cc > b/src/smf/smfd/SmfUpgradeCampaign.cc > --- a/src/smf/smfd/SmfUpgradeCampaign.cc > +++ b/src/smf/smfd/SmfUpgradeCampaign.cc > @@ -942,6 +942,26 @@ SmfUpgradeCampaign::commit() > } > > > //------------------------------------------------------------------------------ > +// asyncFailure() > +//------------------------------------------------------------------------------ > +void > +SmfUpgradeCampaign::asyncFailure() > +{ > + TRACE_ENTER(); > + SmfCampResultT campResult; > + > + while (1) { > + campResult = m_state->asyncFailure(this); > + > + if (campResult != SMF_CAMP_CONTINUE) { > + break; > + } > + } > + > + TRACE_LEAVE(); > +} > + > +//------------------------------------------------------------------------------ > // procResult() > > //------------------------------------------------------------------------------ > void > diff --git a/src/smf/smfd/SmfUpgradeCampaign.h > b/src/smf/smfd/SmfUpgradeCampaign.h > --- a/src/smf/smfd/SmfUpgradeCampaign.h > +++ b/src/smf/smfd/SmfUpgradeCampaign.h > @@ -354,6 +354,13 @@ void verify(); > void commit(); > > /// > +/// Purpose: Report Async failure > +/// @param None. > +/// @return None. > +/// > + void asyncFailure(); > + > +/// > /// Purpose: Procedure result. > /// @param None. > /// @return None. ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opensaf-devel
