osaf/services/saf/smfsv/smfd/SmfCampaignThread.cc | 235 +++++++++++++++++++++- osaf/services/saf/smfsv/smfd/SmfCampaignThread.hh | 15 + osaf/services/saf/smfsv/smfd/SmfStepTypes.cc | 32 +- 3 files changed, 263 insertions(+), 19 deletions(-)
This patch adds support for section 4.2.1.3 of SMF A.01.02 spec. diff --git a/osaf/services/saf/smfsv/smfd/SmfCampaignThread.cc b/osaf/services/saf/smfsv/smfd/SmfCampaignThread.cc --- a/osaf/services/saf/smfsv/smfd/SmfCampaignThread.cc +++ b/osaf/services/saf/smfsv/smfd/SmfCampaignThread.cc @@ -39,6 +39,7 @@ #include "SmfUtils.hh" 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 */ @@ -140,7 +141,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); } @@ -303,10 +309,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; } @@ -319,9 +329,202 @@ 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()->suspend(); + s_instance->m_campaign->getUpgradeCampaign()->setCampState( + SA_SMF_CMPG_ERROR_DETECTED); + + 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. @@ -672,18 +875,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) @@ -699,7 +915,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/osaf/services/saf/smfsv/smfd/SmfCampaignThread.hh b/osaf/services/saf/smfsv/smfd/SmfCampaignThread.hh --- a/osaf/services/saf/smfsv/smfd/SmfCampaignThread.hh +++ b/osaf/services/saf/smfsv/smfd/SmfCampaignThread.hh @@ -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/osaf/services/saf/smfsv/smfd/SmfStepTypes.cc b/osaf/services/saf/smfsv/smfd/SmfStepTypes.cc --- a/osaf/services/saf/smfsv/smfd/SmfStepTypes.cc +++ b/osaf/services/saf/smfsv/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) { ------------------------------------------------------------------------------ Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE. Training and support from Colfax. Order your platform today. http://sdm.link/xeonphi _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel