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(&notificationFilterHandles, 
> 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

Reply via email to