Hi Alex,
Reviewed and tested the patch.
Ack.
/Neel.
On 2017/03/01 07:49 AM, Alex Jones wrote:
> 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.notificationObject));
> + 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.notificationClassId))
> {
> + 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