ok, Ack from me. Thanks, Neel.
On 2016/08/29 06:09 PM, Rafael Odzakow wrote: > For nodesForSingleStep only PLs are allowed for now. There is a plan > to include SCs but that is for the future. > > Also having procedures with SCs in the campaign is not possible until > SI swap is implemented. > > > On 08/29/2016 02:30 PM, Neelakanta Reddy wrote: >> Hi Rafel, >> >> Reviewed and tested the patch. >> minor comments inline. >> >> Questions: >> >> 1. For the new attribute "nodesForSingleStep" only PLs are allowed? >> 2. I tested giving controllers >> immcfg -a numberOfSingleSteps=2 -a nodesForSingleStep=SC-1 -a >> nodesForSingleStep=SC-2 openSafSmfExecControl=MergeCampToSS2 >> >> The steps created are "SmfBalancedProcedure" are created for PL >> and normal "safSmfProc=proc2 " created for SCs >> >> Thanks, >> Neel. >> >> On 2016/08/27 01:59 PM, Rafael Odzakow wrote: >>> osaf/services/saf/smfsv/config/smfsv_classes.xml | 13 + >>> osaf/services/saf/smfsv/smfd/Makefile.am | 6 +- >>> osaf/services/saf/smfsv/smfd/SmfCampState.cc | 126 +---- >>> osaf/services/saf/smfsv/smfd/SmfCampaign.cc | 78 ++- >>> osaf/services/saf/smfsv/smfd/SmfCampaign.hh | 1 + >>> osaf/services/saf/smfsv/smfd/SmfExecControl.cc | 423 >>> ++++++++++++++++++++ >>> osaf/services/saf/smfsv/smfd/SmfExecControl.h | 64 +++ >>> osaf/services/saf/smfsv/smfd/SmfProcState.cc | 7 +- >>> osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.cc | 32 +- >>> osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.hh | 24 +- >>> osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.cc | 14 +- >>> osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.hh | 20 +- >>> osaf/services/saf/smfsv/smfd/SmfUpgradeStep.hh | 13 +- >>> osaf/services/saf/smfsv/smfd/smfd.h | 2 +- >>> 14 files changed, 638 insertions(+), 185 deletions(-) >>> >>> >>> diff --git a/osaf/services/saf/smfsv/config/smfsv_classes.xml >>> b/osaf/services/saf/smfsv/config/smfsv_classes.xml >>> --- a/osaf/services/saf/smfsv/config/smfsv_classes.xml >>> +++ b/osaf/services/saf/smfsv/config/smfsv_classes.xml >>> @@ -531,5 +531,18 @@ >>> <flag>SA_WRITABLE</flag> >>> <default-value>0</default-value> >>> </attr> >>> + <attr> >>> + <name>numberOfSingleSteps</name> >>> + <type>SA_UINT32_T</type> >>> + <category>SA_CONFIG</category> >>> + <flag>SA_WRITABLE</flag> >>> + </attr> >>> + <attr> >>> + <name>nodesForSingleStep</name> >>> + <type>SA_STRING_T</type> >>> + <category>SA_CONFIG</category> >>> + <flag>SA_WRITABLE</flag> >>> + <flag>SA_MULTI_VALUE</flag> >>> + </attr> >>> </class> >>> </imm:IMM-contents> >>> diff --git a/osaf/services/saf/smfsv/smfd/Makefile.am >>> b/osaf/services/saf/smfsv/smfd/Makefile.am >>> --- a/osaf/services/saf/smfsv/smfd/Makefile.am >>> +++ b/osaf/services/saf/smfsv/smfd/Makefile.am >>> @@ -49,7 +49,8 @@ noinst_HEADERS = \ >>> SmfCampaignWrapup.hh \ >>> SmfCampaignInit.hh \ >>> SmfCallback.hh \ >>> - SmfCbkUtil.hh >>> + SmfCbkUtil.hh \ >>> + SmfExecControl.h >>> osafsmfd_CXXFLAGS = $(AM_CXXFLAGS) @XML2_CFLAGS@ >>> @@ -87,7 +88,8 @@ osafsmfd_SOURCES = \ >>> SmfCampaignInit.cc \ >>> SmfCampaignWrapup.cc \ >>> SmfCallback.cc \ >>> - SmfCbkUtil.cc >>> + SmfCbkUtil.cc \ >>> + SmfExecControl.cc >>> osafsmfd_LDFLAGS = \ >>> $(AM_LDFLAGS) \ >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfCampState.cc >>> b/osaf/services/saf/smfsv/smfd/SmfCampState.cc >>> --- a/osaf/services/saf/smfsv/smfd/SmfCampState.cc >>> +++ b/osaf/services/saf/smfsv/smfd/SmfCampState.cc >>> @@ -32,8 +32,10 @@ >>> #include "SmfCampaignThread.hh" >>> #include "SmfCampaign.hh" >>> #include "SmfProcedureThread.hh" >>> +#include "smfsv_defs.h" >>> #include <immutil.h> >>> #include <sstream> >>> +#include "SmfUpgradeAction.hh" >>> /* >>> ======================================================================== >>> >>> * DEFINITIONS >>> * >>> ======================================================================== >>> >>> @@ -764,12 +766,7 @@ SmfCampStateExecuting::execute(SmfUpgrad >>> //must be restarted. The execution shall continue at step >>> execution phase. The procedure initialization >>> //and step calculation was performed before the move of control. >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> bool execProcFound = false; >>> @@ -817,13 +814,7 @@ SmfCampStateExecuting::executeProc(SmfUp >>> //The procedure vector is sorted in execution level order (low >>> -> high) >>> //Lowest number shall be executed first. >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> - >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> int execLevel = -1; >>> @@ -912,12 +903,7 @@ SmfCampStateExecuting::suspend(SmfUpgrad >>> TRACE("SmfCampStateExecuting::suspend implementation"); >>> /* Send suspend message to all procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -966,12 +952,7 @@ SmfCampStateExecuting::procResult(SmfUpg >>> LOG_NO("CAMP: Procedure %s returned STEPUNDONE", >>> i_procedure->getProcName().c_str()); >>> /* Send suspend message to all procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> for (iter = procedures.begin(); iter != >>> procedures.end(); ++iter) { >>> @@ -1114,21 +1095,8 @@ SmfCampStateExecCompleted::commit(SmfUpg >>> i_camp->resetMaintenanceState(); // No action if it fails >>> //Remove the procedure runtime objects >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - i_camp->getMergedProc()->commit(); >>> - >>> - } else { >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> - >>> - std::vector < SmfUpgradeProcedure * >::iterator iter; >>> - for (iter = procedures.begin(); iter != >>> procedures.end(); ++iter) { >>> - (*iter)->commit(); >>> - } >>> + for (auto proc: i_camp->getProcedures()) { >>> + proc->commit(); >>> } >>> i_camp->removeRunTimeObjects(); // No action if it fails >>> @@ -1213,12 +1181,7 @@ SmfCampStateSuspendingExec::execute(SmfU >>> //in while in SuspendingExec state >>> i_camp->setProcExecutionMode(smfd_cb->procExecutionMode); >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> bool initialFound = false; >>> @@ -1358,12 +1321,7 @@ SmfCampStateExecSuspended::execute(SmfUp >>> i_camp->setProcExecutionMode(smfd_cb->procExecutionMode); >>> /* Send execute to all suspended procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -1423,12 +1381,7 @@ SmfCampStateExecSuspended::rollback(SmfU >>> } >>> /* Send rollback to all suspended procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -1728,12 +1681,7 @@ SmfCampStateSuspendedByErrorDetected::ex >>> i_camp->setProcExecutionMode(smfd_cb->procExecutionMode); >>> /* Send execute to all suspended/undone procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -1789,12 +1737,7 @@ SmfCampStateSuspendedByErrorDetected::ro >>> } >>> /* Send rollback to all suspended/undone procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -1873,12 +1816,7 @@ SmfCampRollingBack::rollback(SmfUpgradeC >>> TRACE_ENTER(); >>> TRACE("SmfCampRollingBack::rollback implementation"); >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::reverse_iterator iter; >>> @@ -1960,12 +1898,7 @@ SmfCampRollingBack::rollbackProc(SmfUpgr >>> //The procedure vector is sorted in execution level order (low >>> -> high) >>> //Highest number shall be rolled back first so start from end >>> of list. >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::reverse_iterator iter; >>> @@ -2017,7 +1950,8 @@ SmfCampRollingBack::rollbackSingleMergeP >>> { >>> TRACE_ENTER(); >>> LOG_NO("CAMP:: Rollback merged single step procedure only"); >>> - SmfUpgradeProcedure * mergedProc = i_camp->getMergedProc(); >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> + SmfUpgradeProcedure * mergedProc = procedures.at(0); >>> if (mergedProc->getState() == SA_SMF_PROC_COMPLETED) { >>> SmfProcedureThread *procThread = >>> mergedProc->getProcThread(); >>> PROCEDURE_EVT *evt = new PROCEDURE_EVT(); >>> @@ -2046,12 +1980,7 @@ SmfCampRollingBack::suspend(SmfUpgradeCa >>> TRACE("SmfCampRollingBack::suspend implementation"); >>> /* Send suspend message to all procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -2172,12 +2101,7 @@ SmfCampRollbackSuspended::rollback(SmfUp >>> TRACE("SmfCampRollbackSuspended::rollback implementation"); >>> /* Send rollback to all suspended procedures */ >>> - std::vector < SmfUpgradeProcedure * > procedures; >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - procedures.push_back(i_camp->getMergedProc()); >>> - } else { >>> - procedures = i_camp->getProcedures(); >>> - } >>> + std::vector<SmfUpgradeProcedure*> procedures = >>> i_camp->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >::iterator iter; >>> @@ -2345,16 +2269,8 @@ SmfCampRollbackCompleted::commit(SmfUpgr >>> i_camp->resetMaintenanceState(); // No action if it fails >>> //Remove the procedure runtime objects >>> - if (i_camp->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> - i_camp->getMergedProc()->commit(); >>> - >>> - } else { >>> - const std::vector < SmfUpgradeProcedure * >& >>> procedures = i_camp->getProcedures(); >>> - std::vector < SmfUpgradeProcedure * >>> >::const_iterator iter; >>> - >>> - for (iter = procedures.begin(); iter != >>> procedures.end(); ++iter) { >>> - (*iter)->commit(); >>> - } >>> + for (auto proc: i_camp->getProcedures()) { >>> + proc->commit(); >>> } >>> i_camp->removeRunTimeObjects(); // No action if >>> it fails >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfCampaign.cc >>> b/osaf/services/saf/smfsv/smfd/SmfCampaign.cc >>> --- a/osaf/services/saf/smfsv/smfd/SmfCampaign.cc >>> +++ b/osaf/services/saf/smfsv/smfd/SmfCampaign.cc >>> @@ -18,6 +18,7 @@ >>> #include <sys/stat.h> >>> #include <new> >>> #include <vector> >>> +#include <algorithm> >>> #include <string> >>> #include <sys/time.h> >>> @@ -30,7 +31,9 @@ >>> #include "SmfUpgradeProcedure.hh" >>> #include "SmfUpgradeMethod.hh" >>> #include "SmfProcedureThread.hh" >>> +#include "SmfUpgradeAction.hh" >>> #include "SmfUtils.hh" >>> +#include "SmfExecControl.h" >>> #include "saAis.h" >>> #include <saSmf.h> >>> @@ -661,6 +664,10 @@ SmfCampaign::initExecution(void) >>> SaAisErrorT >>> SmfCampaign::startProcedureThreads() >>> { >>> + // If any procedure start goes badly two things happen: >>> delete of the >>> + // upgrade campaign pointer to terminate and remove >>> previously started >>> + // procedures. Return SA_AIS_OK to not change campaign >>> state and allow >>> + // reexecution >>> TRACE_ENTER(); >>> SmfUpgradeCampaign *p_uc = getUpgradeCampaign(); >>> if (p_uc->getProcExecutionMode() == >>> SMF_MERGE_TO_SINGLE_STEP) { >>> @@ -676,25 +683,26 @@ SmfCampaign::startProcedureThreads() >>> std::string singleProcDN = >>> singleProc->getProcName() + "," + >>> SmfCampaignThread::instance()->campaign()->getDn(); >>> singleProc->setDn(singleProcDN); >>> - p_uc->setMergedProc(singleProc); >>> + p_uc->addModifiedProcedure(singleProc); >>> - /* Start procedure thread */ >>> - SmfProcedureThread *procThread = new >>> SmfProcedureThread(singleProc); >>> - /* The procThread will set itself when started >>> correctly */ >>> - singleProc->setProcThread(NULL); >>> - >>> - LOG_NO("SmfCampaign::startProcedureThreads, >>> Starting procedure thread %s", >>> - singleProc->getProcName().c_str()); >>> - procThread->start(); >>> - /* Check if procedure thread started correctly */ >>> - if (singleProc->getProcThread() == NULL) { >>> - std::string error = "Start of procedure >>> thread failed for " + singleProcDN; >>> - LOG_ER("%s", error.c_str()); >>> - SmfCampaignThread::instance()->campaign()->setError(error); >>> - delete p_uc; // To terminate and remove any >>> previously started procedure threads >>> - /* Don't change campaign state to allow >>> reexecution */ >>> + if (startProcedure(singleProc) == false) { >>> + delete p_uc; >>> return SA_AIS_OK; >>> } >>> + } else if (p_uc->getProcExecutionMode() == >>> SMF_BALANCED_MODE) { >>> + SmfExecControl execc; >>> + if (!execc.initBalancedMode()) { >>> + return SA_AIS_ERR_INIT; >>> + } >>> + auto procedures = p_uc->getProcedures(); >>> + TRACE("SmfCampaign::startProcedureThreads, number >>> of procedures=[%zu]", procedures.size()); >>> + for (auto proc: procedures) { >>> + if (startProcedure(proc) == false) { >>> + delete p_uc; >>> + return SA_AIS_OK; >>> + } >>> + } >>> + >>> } else { >>> const std::vector < SmfUpgradeProcedure * >& >>> procedures = p_uc->getProcedures(); >>> std::vector < SmfUpgradeProcedure * >>> >::const_iterator iter; >>> @@ -718,24 +726,10 @@ SmfCampaign::startProcedureThreads() >>> } >>> (*iter)->setDn(dn); >>> - /* Start procedure thread */ >>> - SmfProcedureThread *procThread = new >>> SmfProcedureThread(*iter); >>> - /* The procThread will set itself when >>> started correctly */ >>> - (*iter)->setProcThread(NULL); >>> - >>> - TRACE("SmfCampaign::startProcedureThreads, Starting procedure >>> thread %s", (*iter)->getProcName().c_str()); >>> - procThread->start(); >>> - >>> - /* Check if procedure thread started >>> correctly */ >>> - if ((*iter)->getProcThread() == NULL) { >>> - std::string error = "Start of >>> procedure thread failed for " + dn; >>> - LOG_ER("%s", error.c_str()); >>> - SmfCampaignThread::instance()->campaign()->setError(error); >>> - delete p_uc; // To terminate and >>> remove any previously started procedure threads >>> - /* Don't change campaign state to >>> allow reexecution */ >>> + if (startProcedure(*iter) == false) { >>> + delete p_uc; >>> return SA_AIS_OK; >>> } >>> - >>> iter++; >>> } >>> } >>> @@ -743,6 +737,26 @@ SmfCampaign::startProcedureThreads() >>> return SA_AIS_OK; //Will never return here, just for compiler >>> } >>> +//-------------------------------------------------------------------------- >>> >>> >>> +// Starts one upgrade procedure thread, return false on failure >>> +//-------------------------------------------------------------------------- >>> >>> >>> +bool >>> +SmfCampaign::startProcedure(SmfUpgradeProcedure* procedure) { >>> + SmfProcedureThread *procedure_thread = new >>> SmfProcedureThread(procedure); >>> + // The procThread will set itself when started correctly >>> + procedure->setProcThread(nullptr); >>> + TRACE("SmfCampaign::startProcedure dn: %s", >>> procedure->getDn().c_str()); >>> + procedure_thread->start(); >>> + >>> + if (procedure->getProcThread() == nullptr) { >>> + std::string error = "Start of procedure thread >>> failed for " + procedure->getDn(); >>> + LOG_ER("%s", error.c_str()); >>> + SmfCampaignThread::instance()->campaign()->setError(error); >>> + return false; >>> + } >>> + return true; >>> +} >>> + >>> /** >>> * procResult >>> * Takes care of procedure result >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfCampaign.hh >>> b/osaf/services/saf/smfsv/smfd/SmfCampaign.hh >>> --- a/osaf/services/saf/smfsv/smfd/SmfCampaign.hh >>> +++ b/osaf/services/saf/smfsv/smfd/SmfCampaign.hh >>> @@ -107,6 +107,7 @@ class SmfCampaign { >>> void stopElapsedTime(); >>> private: >>> + bool startProcedure(SmfUpgradeProcedure* procedure); >>> std::string m_dn; >>> std::string m_cmpg; >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfExecControl.cc >>> b/osaf/services/saf/smfsv/smfd/SmfExecControl.cc >>> new file mode 100644 >>> --- /dev/null >>> +++ b/osaf/services/saf/smfsv/smfd/SmfExecControl.cc >>> @@ -0,0 +1,423 @@ >>> +/* >>> + * >>> + * (C) Copyright 2009 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): Ericsson AB >>> + * >>> + */ >>> + >>> +#include "SmfExecControl.h" >>> +#include <list> >>> +#include <limits> >>> +#include <algorithm> >>> +#include "logtrace.h" >>> +#include "immutil.h" >>> +#include "SmfUpgradeProcedure.hh" >>> +#include "SmfUpgradeMethod.hh" >>> +#include "SmfUtils.hh" >>> +#include "SmfUpgradeAction.hh" >>> +#include "SmfUpgradeCampaign.hh" >>> + >>> + >>> +bool readExecControlObject(unsigned int* numberOfSingleSteps, >>> + std::vector<std::string>* >>> nodesForSingleStep); >>> + >>> +bool removeDuplicateActivationUnits(SmfUpgradeProcedure * i_newproc, >>> + SmfUpgradeStep *newStep); >>> + >>> +static bool isNodeInGroup(const std::string& node, >>> + const std::vector<std::string>& group) { >>> + return std::find(group.begin(), group.end(), node) != group.end(); >>> +} >>> + >>> + >>> +SmfExecControl::SmfExecControl() : m_numberofss(1) { >>> + m_campaign = SmfCampaignThread::instance()->campaign(); >>> +} >>> + >>> +bool SmfExecControl::initBalancedMode() { >>> + TRACE_ENTER(); >>> + // Enable balanced mode by adding and modifying the procedures in >>> the >>> + // campaign. Calls calculateSteps before the procedures are >>> started in order >>> + // to get the activation units of the steps. >>> + m_originalprocs = m_campaign->getUpgradeCampaign()->getProcedures(); >>> + for (auto proc : m_originalprocs) { >>> + proc->setDn(proc->getProcName() + "," + m_campaign->getDn()); >>> + if (!proc->calculateSteps()) { >>> + TRACE("Step calculation failed"); >>> + return false; >>> + } >>> + } >>> + if (!readExecControlObject(&m_numberofss, &m_nodesforss)) { >>> + return false; >>> + } >>> + if (!setNodesForSingleStep()) { >>> + return false; >>> + } >>> + createBalancedProcedures(); >>> + >>> + for (auto bproc : m_balancedprocs) { >>> + std::vector<SmfUpgradeStep*> steps; >>> + std::vector<SmfUpgradeAction*> initactions; >>> + std::vector<SmfUpgradeAction*> wrapupactions; >>> + // Each new balanced procedure needs to copy some steps from >>> the original >>> + // procedures. >>> + for (auto step : getStepsMatchingBalancedGroup(bproc)) { >>> + // copy the steps together with actions and callbacks >>> + auto oproc = step->getProcedure(); >>> + steps.insert(steps.end(), >>> + oproc->getProcSteps().begin(), >>> + oproc->getProcSteps().end()); >>> + initactions.insert(initactions.end(), >>> + oproc->getInitActions().begin(), >>> + oproc->getInitActions().end()); >>> + wrapupactions.insert(wrapupactions.end(), >>> + oproc->getWrapupActions().begin(), >>> + oproc->getWrapupActions().end()); >>> + bproc->getCallbackList(oproc->getUpgradeMethod()); >>> + } >>> + if (!steps.empty()) { >>> + SmfUpgradeStep* newstep = createMergedStep(bproc, steps); >>> + addInitAndWrapupActionsToProcedure(bproc, initactions, >>> wrapupactions); >>> + removeDuplicateActivationUnits(bproc, newstep); >>> + bproc->addProcStep(newstep); >>> + } >>> + } >>> + >>> + // add all the procedures >>> + for (auto proc : m_originalprocs) { >>> + if (!proc->getIsMergedProcedure()) { >>> + TRACE("adding original procedure %s to upgrade campaign", >>> proc->getDn().c_str()); >>> + m_campaign->getUpgradeCampaign()->addModifiedProcedure(proc); >>> + } else { >>> + TRACE("skipping original procedure %s", proc->getDn().c_str()); >>> + } >>> + proc->setIsMergedProcedure(false); // Clear the flag >>> + } >>> + for (auto proc : m_balancedprocs) { >>> + TRACE("adding balanced procedure %s to upgrade campaign", >>> proc->getDn().c_str()); >>> + m_campaign->getUpgradeCampaign()->addModifiedProcedure(proc); >>> + } >>> + >>> + TRACE_LEAVE(); >>> + return true; >>> +} >>> + >>> +std::vector<SmfUpgradeStep*> >>> SmfExecControl::getStepsMatchingBalancedGroup( >>> + SmfUpgradeProcedure* procedure) { >>> + TRACE_ENTER(); >>> + // Check if the steps are in the balanced group of the procedure. >>> If so mark >>> + // as completed and return the matching steps. >>> + std::vector<SmfUpgradeStep*> steps; >>> + for (auto oproc : m_originalprocs) { >>> + for (auto ostep : oproc->getProcSteps()) { >>> + if (isNodeInGroup(ostep->getSwNode(), >>> procedure->getBalancedGroup())) { >>> + if (ostep->getState() != SA_SMF_STEP_COMPLETED) { >>> + // step will be started in a new merged step >>> + ostep->setStepState(SA_SMF_STEP_COMPLETED); >>> + steps.push_back(ostep); >>> + } >>> + } >>> + } >>> + } >>> + TRACE_LEAVE(); >>> + return steps; >>> +} >>> + >>> +bool SmfExecControl::setNodesForSingleStep() { >>> + // nodesForSingleStep might contain nodes outside of our scope. >>> Modify this >>> + // list to only use the nodes that are found in the campaign. >>> + TRACE_ENTER(); >>> + std::vector<std::string> nodes_included; >>> + for (auto proc : m_originalprocs) { >>> + proc->setIsMergedProcedure(true); // Mark the procedures to be >>> modified >>> + if (proc->getUpgradeMethod()->getUpgradeMethod() == >>> SA_SMF_ROLLING) { >>> + for (auto step : proc->getProcSteps()) { >>> + if (isNodeInGroup(step->getSwNode(), m_nodesforss)) { >>> + if (!isNodeInGroup(step->getSwNode(), nodes_included)) { >>> + nodes_included.push_back(step->getSwNode()); >>> + } >>> + } else { >>> + // This procedure is not to be modified >>> + proc->setIsMergedProcedure(false); >>> + } >>> + } >>> + } >>> + } >>> + m_nodesforss = nodes_included; >>> + TRACE_LEAVE(); >>> + return true; >>> +} >>> + >>> +void SmfExecControl::createBalancedProcedures() { >>> + // Creates new procedures based on the ExecControl configuration >>> + TRACE_ENTER(); >>> + // chunk is the size of the balanced group >>> + unsigned int chunk = (m_nodesforss.size() + m_numberofss - 1) / >>> m_numberofss; >>> + TRACE("balanced group size will be %i", chunk); >>> + std::vector<std::string>::iterator itr; >>> + std::vector<std::string>::iterator iend; >>> + // Set the procedure exec level to be as high as possible >>> + int procExecLvl = std::numeric_limits<int>::max() - m_numberofss >>> - 1; >>> + for (itr = m_nodesforss.begin(); iend < m_nodesforss.end(); itr >>> += chunk) { >>> + iend = itr + chunk; >>> + SmfUpgradeProcedure *ssproc = new(std::nothrow) >>> SmfUpgradeProcedure; >>> + if (iend >= m_nodesforss.end()) { >>> + iend = m_nodesforss.end(); >>> + } >>> + ssproc->setUpgradeMethod(new(std::nothrow) SmfSinglestepUpgrade); >>> + ssproc->setProcName("safSmfProc=SmfBalancedProcedure" + >>> std::to_string(procExecLvl)); >>> + std::string cdn = >>> SmfCampaignThread::instance()->campaign()->getDn(); >>> + ssproc->setDn(ssproc->getProcName() + "," + cdn); >>> + ssproc->setExecLevel(std::to_string(procExecLvl)); >>> + ssproc->setIsMergedProcedure(true); // For cleanup purposes >>> + // Each new procedure holds the balanced group it steps over >>> + ssproc->setBalancedGroup(std::vector<std::string>(itr, iend)); >>> + m_balancedprocs.push_back(ssproc); >>> + procExecLvl++; >>> + } >>> + TRACE_LEAVE(); >>> +} >>> + >>> +SmfUpgradeStep* SmfExecControl::createMergedStep( >>> + SmfUpgradeProcedure* procedure, >>> + const std::vector<SmfUpgradeStep*>& steps) { >>> + // Create a merged step based on the upgrade steps passed in. >>> + // The in/out-parameter procedure shall be one of the procedures >>> that was >>> + // created with help of the createBalancedProcedures() method. >>> + TRACE_ENTER(); >>> + SmfUpgradeStep* newstep = new(std::nothrow)SmfUpgradeStep; >>> + osafassert(newstep != nullptr); >>> + newstep->setRdn("safSmfStep=0001"); >>> + newstep->setDn(newstep->getRdn() + "," + procedure->getDn()); >>> + newstep->setMaxRetry(0); >>> + newstep->setRestartOption(0); >>> + std::list <unitNameAndState> deact; >>> + for (auto step : steps) { >>> + if (isNodeInGroup(step->getSwNode(), >>> procedure->getBalancedGroup())) { >>> + TRACE("adding modifications, deact and bundle ref from node:%s", >>> + step->getSwNode().c_str()); >>> + newstep->addModifications(step->getModifications()); >>> + deact.insert(deact.end(), >>> + step->getDeactivationUnitList().begin(), >>> + step->getDeactivationUnitList().end()); >>> + procedure->mergeBundleRefRollingToSingleStep(newstep, step); >>> + } >>> + } >>> + TRACE_LEAVE(); >>> + return newstep; >>> +} >>> + >>> +void SmfExecControl::addInitAndWrapupActionsToProcedure( >>> + SmfUpgradeProcedure* procedure, >>> + const std::vector<SmfUpgradeAction*>& initactions, >>> + const std::vector<SmfUpgradeAction*>& wrapupactions) { >>> + // Add Init/WrapupActions to the procedure. The Actions themself >>> contain a >>> + // pointer to the procedure. >>> + TRACE_ENTER(); >>> + procedure->addInitActions(initactions); >>> + procedure->addWrapupActions(wrapupactions); >>> + for (auto iac : initactions) { >>> + const SmfCallbackAction* cba = dynamic_cast<const >>> SmfCallbackAction*>(iac); >>> + if (cba != nullptr) { >>> + const_cast<SmfCallbackAction*>(cba)->setCallbackProcedure(procedure); >>> + } >>> + } >>> + for (auto wac : wrapupactions) { >>> + const SmfCallbackAction* cba = dynamic_cast<const >>> SmfCallbackAction*>(wac); >>> + if (cba != nullptr) { >>> + const_cast<SmfCallbackAction*>(cba)->setCallbackProcedure(procedure); >>> + } >>> + } >>> + TRACE_LEAVE(); >>> +} >>> + >>> +void SmfExecControl::trace() { >>> + for (auto proc : >>> m_campaign->getUpgradeCampaign()->getProcedures()) { >>> + TRACE("-procedure %s to upgrade campaign", proc->getDn().c_str()); >>> + TRACE("-merged procedure %i", proc->getIsMergedProcedure()); >>> + for (auto step : proc->getProcSteps()) { >>> + TRACE("-step : %s, state %i", step->getDn().c_str(), >>> step->getState()); >>> + } >>> + for (auto iact : proc->getInitActions()) { >>> + auto cba = dynamic_cast<SmfCallbackAction*>(iact); >>> + TRACE("-iact cb label : %s", >>> cba->getCallback().getCallbackLabel().c_str()); >>> + } >>> + } >>> +} >>> + >>> +bool readExecControlObject(unsigned int* numberOfSingleSteps, >>> + std::vector<std::string>* >>> nodesForSingleStep) { >>> + // Read the attributes from the exec control object from the IMM. >>> The OI >>> + // will prevent any changes once a campaign is running. >>> + SmfImmUtils immutil; >>> + SaImmAttrValuesT_2 **attributes; >>> + if (immutil.getObject(SMF_CONFIG_OBJECT_DN, &attributes) == false) { >>> + LOG_ER("Could not get SMF config object from IMM %s", >>> SMF_CONFIG_OBJECT_DN); >>> + return false; >>> + } >>> + const char* execdn = immutil_getStringAttr( >>> + (const SaImmAttrValuesT_2 **)attributes, >>> OPENSAF_SMF_EXEC_CONTROL, 0); >>> + if (execdn == NULL || strcmp(execdn, "") == 0) { >>> + LOG_ER("Could not get %s attrs from SmfConfig", >>> OPENSAF_SMF_EXEC_CONTROL); >>> + return false; >>> + } >>> + if (immutil.getObject(execdn, &attributes) == false) { >>> + LOG_ER("Failed to get object from attribute %s", >>> OPENSAF_SMF_EXEC_CONTROL); >>> + return false; >>> + } >>> + SaAisErrorT rc; >>> + SaUint32T numnodes; >>> + rc = >>> immutil_getAttrValuesNumber(const_cast<char*>("nodesForSingleStep"), >>> + (const SaImmAttrValuesT_2 >>> **)attributes, >>> + &numnodes); >>> + if (rc != SA_AIS_OK) { >>> + LOG_ER("nodesForSingleStep not configured"); >>> + return false; >>> + } >>> + const char* node; >>> + for (unsigned int i = 0; i < numnodes; i++) { >>> + node = immutil_getStringAttr((const >>> SaImmAttrValuesT_2**)attributes, >>> + "nodesForSingleStep", i); >>> + if (node == NULL) { >>> + break; >>> + } >>> + nodesForSingleStep->push_back("safAmfNode=" + std::string(node) + >>> + ",safAmfCluster=myAmfCluster"); >>> + } >>> + const SaUint32T* numss = immutil_getUint32Attr( >>> + (const SaImmAttrValuesT_2 **)attributes, >>> "numberOfSingleSteps", 0); >>> + if (numss == NULL) { >>> + LOG_ER("could not read numberOfSingleSteps"); >>> + return false; >>> + } >>> + >>> + *numberOfSingleSteps = *numss; >>> + >>> + TRACE("numberOfSingleSteps %i", *numberOfSingleSteps); >>> + for (auto node : *nodesForSingleStep) { >>> + TRACE("nodesForSingleStep %s", node.c_str()); >>> + } >>> + osafassert(numberOfSingleSteps != 0); >>> + return true; >>> +} >>> + >>> +bool removeDuplicateActivationUnits(SmfUpgradeProcedure * i_newproc, >>> + SmfUpgradeStep *newStep) { >>> + // Remove any (de)activation unit duplicates and add them to the >>> step. >>> + // Activation and deactivation units are the same because rolling >>> and >>> + // formodify is symetric. >>> + TRACE_ENTER(); >>> + std::list < unitNameAndState > tmpDU; >>> + std::multimap<std::string, objectInst> objInstances; >>> + if (i_newproc->getImmComponentInfo(objInstances) == false) { >>> + TRACE("Config info from IMM could not be read"); >>> + return false; >>> + } >>> + >>> + // Remove DU duplicates >>> + tmpDU.sort(compare_du_part); >>> + tmpDU.unique(unique_du_part); >>> + >>> + // Reduce the DU list, check if smaller scope is within bigger >>> scope. >>> + std::pair<std::multimap<std::string, objectInst>::iterator, >>> + std::multimap<std::string, objectInst>::iterator> >>> nodeName_mm; >>> + std::multimap<std::string, objectInst>::iterator iter; >>> + >>> + std::list < unitNameAndState > nodeLevelDU; >>> + std::list < unitNameAndState >::iterator unit_iter; >>> + // Find DU on node level and save them in a separate list >>> + for (unit_iter = tmpDU.begin(); unit_iter != tmpDU.end();) { >>> + if ((*unit_iter).name.find("safAmfNode=") == 0) { // DU is a >>> node node >>> + // A node will never be optimized away, save it >>> + nodeLevelDU.push_back(*unit_iter); >>> + // Remove the node and update iterator >>> + unit_iter = tmpDU.erase(unit_iter); >>> + } else { >>> + ++unit_iter; >>> + } >>> + } >>> + >>> + // For all found nodes, look if some other DU (comp/SU) is within >>> scope >>> + // tmpDU contain all DU except the node level ones which was >>> removed above >>> + // and saved in nodeLevelDU list >>> + std::list < unitNameAndState >::iterator itr; >>> + for (itr = nodeLevelDU.begin(); itr != nodeLevelDU.end(); ++itr) { >>> + // For all comp/SU found in the scope of the node. Find out if >>> any >>> + // remaining DU is within it. >>> + // Get all components/SU within the node >>> + nodeName_mm = objInstances.equal_range((*itr).name); >>> + for (iter = nodeName_mm.first; iter != nodeName_mm.second; >>> ++iter) { >>> + // For all comp/SU sound in the scope of the node. >> sound --> found >>> + // Find out if any remaininf DU is within it >> remaininf --> remaining >>> + for (unit_iter = tmpDU.begin(); unit_iter != tmpDU.end();) { >>> + if ((*unit_iter).name == (*iter).second.suDN) { // Check SU >>> + TRACE("[%s] is in scope of [%s], remove it from DU list", >>> + (*unit_iter).name.c_str(), (*itr).name.c_str()); >>> + // Remove the node and update iterator >>> + unit_iter = tmpDU.erase(unit_iter); >>> + } else if ((*unit_iter).name == (*iter).second.compDN) { >>> // Check comp >>> + TRACE("[%s] is in scope of [%s], remove it from DU list", >>> + (*unit_iter).name.c_str(), (*itr).name.c_str()); >>> + // Remove the node and update iterator >>> + unit_iter = tmpDU.erase(unit_iter); >>> + } else { >>> + ++unit_iter; >>> + } >>> + } >>> + } >>> + } >>> + >>> + // tmpDU contain all DU which was not in the scope of an included >>> node Find >>> + // DU on SU level and save them in a separate list. Remove SU >>> from tmpDU list >>> + std::list < unitNameAndState > suLevelDU; >>> + for (unit_iter = tmpDU.begin(); unit_iter != tmpDU.end();) { >>> + if ((*unit_iter).name.find("safSu=") == 0) { // DU is a SU >>> + // A node will never be optimized away, save it >>> + suLevelDU.push_back(*unit_iter); >>> + unit_iter = tmpDU.erase(unit_iter); // Remove the SU and >>> update iterator >>> + } else { >>> + ++unit_iter; >>> + } >>> + } >>> + >>> + // For all SU in the suLevelDU list, look if remaining DU in >>> tmpDU is within >>> + // scope of the SU >>> + std::list < unitNameAndState >::iterator su_iter; >>> + for (su_iter = suLevelDU.begin(); su_iter != suLevelDU.end(); >>> ++su_iter) { >>> + for (unit_iter = tmpDU.begin(); unit_iter != tmpDU.end();) { >>> + if ((*unit_iter).name.find((*su_iter).name) != >>> std::string::npos) { >>> + // The component was in the scope of the SU >>> + TRACE("[%s] is in scope of [%s], remove it from DU list", >>> + (*unit_iter).name.c_str(), (*su_iter).name.c_str()); >>> + // Remove the Component and update iterator >>> + unit_iter = tmpDU.erase(unit_iter); >>> + } else { >>> + ++unit_iter; >>> + } >>> + } >>> + } >>> + >>> + newStep->addDeactivationUnits(nodeLevelDU); // Add the node >>> level DU >>> + newStep->addDeactivationUnits(suLevelDU); // Add the SU level DU >>> + newStep->addDeactivationUnits(tmpDU); // Add the comp level DU >>> + >>> + // Rolling and forModify are symetric, add the node level DU >>> + newStep->addActivationUnits(nodeLevelDU); >>> + // Rolling and forModify are symetric, Add the SU level DU >>> + newStep->addActivationUnits(suLevelDU); >>> + // Rolling and forModify are symetric, Add the comp level DU >>> + newStep->addActivationUnits(tmpDU); >>> + >>> + TRACE_LEAVE(); >>> + return true; >>> +} >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfExecControl.h >>> b/osaf/services/saf/smfsv/smfd/SmfExecControl.h >>> new file mode 100644 >>> --- /dev/null >>> +++ b/osaf/services/saf/smfsv/smfd/SmfExecControl.h >>> @@ -0,0 +1,64 @@ >>> +/* >>> + * >>> + * (C) Copyright 2009 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): Ericsson AB >>> + * >>> + */ >>> +#ifndef OPENSAF_STAGING_OSAF_SERVICES_SAF_SMFSV_SMFD_SMFEXECCONTROL_H_ >>> +#define OPENSAF_STAGING_OSAF_SERVICES_SAF_SMFSV_SMFD_SMFEXECCONTROL_H_ >>> + >>> +#include <vector> >>> +#include <string> >>> +#include "base/macros.h" >>> +#include "SmfUpgradeStep.hh" >>> +#include "SmfUpgradeAction.hh" >>> + >>> +/* >>> +* This class enables the balanced mode feature. This mode changes >>> the execution >>> +* of rolling procedures to be merged into one or several single >>> steps that are >>> +* spread out across the cluster nodes. This feature is used to give >>> a faster >>> +* upgrade time compared to rolling one node at a time, possibly >>> several times >>> +* for each node. By splittting the procedures it into several >>> single steps >>> +* across the nodes a total service outage can be avoided. >>> +*/ >>> + >>> +class SmfExecControl { >>> + public: >>> + SmfExecControl(); >>> + bool initBalancedMode(); >>> + >>> + const std::vector<SmfUpgradeProcedure*>& getProcedures() { >>> + return m_balancedprocs; } >>> + >>> + private: >>> + bool setNodesForSingleStep(); >>> + void createBalancedProcedures(); >>> + SmfUpgradeStep* createMergedStep(SmfUpgradeProcedure* procedure, >>> + const >>> std::vector<SmfUpgradeStep*>& steps); >>> + std::vector<SmfUpgradeStep*> >>> getStepsMatchingBalancedGroup(SmfUpgradeProcedure* procedure); >>> + void addInitAndWrapupActionsToProcedure( >>> + SmfUpgradeProcedure* procedure, >>> + const std::vector<SmfUpgradeAction*>& initactions, >>> + const std::vector<SmfUpgradeAction*>& wrapupactions); >>> + void trace(); >>> + >>> + unsigned int m_numberofss; >>> + SmfCampaign* m_campaign; >>> + std::vector<std::string> m_nodesforss; >>> + std::vector<SmfUpgradeProcedure*> m_balancedprocs; >>> + std::vector<SmfUpgradeProcedure*> m_originalprocs; >>> + >>> + DELETE_COPY_AND_MOVE_OPERATORS(SmfExecControl); >>> +}; >>> + >>> +#endif // >>> OPENSAF_STAGING_OSAF_SERVICES_SAF_SMFSV_SMFD_SMFEXECCONTROL_H_ >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfProcState.cc >>> b/osaf/services/saf/smfsv/smfd/SmfProcState.cc >>> --- a/osaf/services/saf/smfsv/smfd/SmfProcState.cc >>> +++ b/osaf/services/saf/smfsv/smfd/SmfProcState.cc >>> @@ -36,6 +36,7 @@ >>> #include "SmfRollback.hh" >>> #include "SmfUtils.hh" >>> #include "smfd.h" >>> +#include "SmfExecControl.h" >>> /* >>> ======================================================================== >>> >>> * DEFINITIONS >>> @@ -241,8 +242,8 @@ SmfProcStateInitial::executeInit(SmfUpgr >>> { >>> TRACE_ENTER(); >>> LOG_NO("PROC: Start procedure init actions"); >>> - if >>> (SmfCampaignThread::instance()->campaign()->getUpgradeCampaign()->getProcExecutionMode() >>> - == SMF_MERGE_TO_SINGLE_STEP) { >>> + int procExecMode = >>> SmfCampaignThread::instance()->campaign()->getUpgradeCampaign()->getProcExecutionMode(); >>> + if (procExecMode == SMF_MERGE_TO_SINGLE_STEP) { >>> LOG_NO("SmfProcStateInitial::executeInit, Merge >>> procedures into single step"); >>> if( !i_proc->mergeStepIntoSingleStep(i_proc)) { >>> changeState(i_proc, >>> SmfProcStateExecFailed::instance()); >>> @@ -250,6 +251,8 @@ SmfProcStateInitial::executeInit(SmfUpgr >>> TRACE_LEAVE(); >>> return SMF_PROC_FAILED; >>> } >>> + } else if (procExecMode == SMF_BALANCED_MODE) { >>> + TRACE("SmfProcStateInitial::executeInit, In >>> balanced mode, calculation already done"); >>> } else { >>> TRACE("SmfProcStateInitial::executeInit, Calculate >>> steps"); >>> if( !i_proc->calculateSteps() ) { >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.cc >>> b/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.cc >>> --- a/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.cc >>> +++ b/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.cc >>> @@ -84,22 +84,26 @@ class SmfUpgradeProcedure; >>> // >>> ------------------------------------------------------------------------------ >>> SmfUpgradeCampaign::~SmfUpgradeCampaign() >>> { >>> - TRACE_ENTER(); >>> - //Delete merged procedure first since it contain references >>> to other proc >>> - //Check campaign state, if verify fails the campaign is still >>> in state initial >>> - //and the merged procedure is not yet created. >>> - if ((getProcExecutionMode() == SMF_MERGE_TO_SINGLE_STEP) && >>> - (m_state->getState() != SA_SMF_CMPG_INITIAL)) { >>> - delete(m_mergedProcedure); >>> + TRACE_ENTER(); >>> + for (auto &it: m_procedure) { >>> + delete it; >>> } >>> + m_procedure.clear(); >>> + m_originalProcedures.clear(); >>> + TRACE_LEAVE(); >>> +} >>> - std::vector < SmfUpgradeProcedure * >::iterator iter; >>> - >>> - for (iter = m_procedure.begin(); iter != m_procedure.end(); >>> ++iter) { >>> - delete(*iter); >>> - } >>> - >>> - TRACE_LEAVE(); >>> +// >>> ------------------------------------------------------------------------------ >>> +// addModifiedProcedure() >>> +// >>> ------------------------------------------------------------------------------ >>> +void SmfUpgradeCampaign::addModifiedProcedure(SmfUpgradeProcedure* >>> procedure) { >>> + int execMode = getProcExecutionMode(); >>> + osafassert(execMode != SMF_STANDARD_MODE); >>> + if (m_originalProcedures.size() == 0) { >>> + m_originalProcedures = m_procedure; >>> + m_procedure.clear(); >>> + } >>> + m_procedure.push_back(procedure); >>> } >>> // >>> ------------------------------------------------------------------------------ >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.hh >>> b/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.hh >>> --- a/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.hh >>> +++ b/osaf/services/saf/smfsv/smfd/SmfUpgradeCampaign.hh >>> @@ -400,23 +400,19 @@ void verify(); >>> SaAisErrorT checkSmfRestartIndicator(); >>> /// >>> -/// Purpose: get procedure list >>> -/// @param None. >>> -/// @return list of procedures. >>> +/// Purpose: Get the unmodified procedures, no merged procedures >>> included >>> /// >>> - const std::vector < SmfUpgradeProcedure * >& getProcedures() { >>> return m_procedure; } >>> + const std::vector<SmfUpgradeProcedure*>& >>> getOriginalProcedures() { return m_originalProcedures; }; >>> -/// Purpose: set the merged procedure >>> -/// @param A SmfUpgradeProcedure * >>> -/// @return the procedure. >>> /// >>> - void setMergedProc(SmfUpgradeProcedure * proc) { >>> m_mergedProcedure = proc; } >>> +/// Purpose: Add the merged procedure while saving the original >>> +/// >>> + void addModifiedProcedure(SmfUpgradeProcedure* procedure); >>> -/// Purpose: get the merged procedure >>> -/// @param None. >>> -/// @return the procedure. >>> /// >>> - SmfUpgradeProcedure * getMergedProc() { return >>> m_mergedProcedure; } >>> +/// Purpose: Can be used with any procedure execution mode >>> +/// >>> + const std::vector<SmfUpgradeProcedure*>& getProcedures() { >>> return m_procedure; } >>> /// Purpose: Set the procedure ecxecution mode >>> /// @param The execution mode. >>> @@ -482,8 +478,8 @@ private: >>> std::string m_configurationBase; >>> SmfCampaignInit m_campInit; >>> SmfCampaignWrapup m_campWrapup; >>> - std::vector < SmfUpgradeProcedure * >m_procedure; >>> - SmfUpgradeProcedure * m_mergedProcedure; >>> + std::vector<SmfUpgradeProcedure*> m_procedure; >>> + std::vector<SmfUpgradeProcedure*> m_originalProcedures; >>> SaTimeT m_waitToCommit; >>> SaTimeT m_waitToAllowNewCampaign; >>> int m_noOfExecutingProc; >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.cc >>> b/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.cc >>> --- a/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.cc >>> +++ b/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.cc >>> @@ -51,6 +51,7 @@ >>> #include "SmfUpgradeAction.hh" >>> #include "SmfUtils.hh" >>> #include "smfd.h" >>> +#include "SmfExecControl.h" >>> // This static member variable is the object counter for upgrade >>> procedures >>> unsigned long SmfUpgradeProcedure::s_procCounter = 1; >>> @@ -1171,7 +1172,7 @@ SmfUpgradeProcedure::mergeStepIntoSingle >>> std::list < unitNameAndState > forAddRemoveDU; >>> std::list < unitNameAndState > tmpDU; >>> SmfUpgradeCampaign * camp = >>> SmfCampaignThread::instance()->campaign()->getUpgradeCampaign(); >>> - const std::vector < SmfUpgradeProcedure * >& procedures = >>> camp->getProcedures(); >>> + const std::vector < SmfUpgradeProcedure * >& procedures = >>> camp->getOriginalProcedures(); >>> std::vector < SmfUpgradeProcedure * >::const_iterator >>> proc_iter; >>> for (proc_iter = procedures.begin(); proc_iter != >>> procedures.end(); proc_iter++) { >>> LOG_NO("Merging [%s] into a single step >>> procedure", (*proc_iter)->getName().c_str()); >>> @@ -2779,10 +2780,13 @@ SmfUpgradeProcedure::getImmSteps() >>> TRACE("Rolling upgrade"); >>> rc = getImmStepsRolling(); >>> } else if (upgradeMethod->getUpgradeMethod() == >>> SA_SMF_SINGLE_STEP) { >>> - if >>> (SmfCampaignThread::instance()->campaign()->getUpgradeCampaign()->getProcExecutionMode() >>> - == SMF_MERGE_TO_SINGLE_STEP) { //This is a merged >>> single step >>> + unsigned int execMode = >>> SmfCampaignThread::instance()->campaign()->getUpgradeCampaign()->getProcExecutionMode(); >>> + if (execMode == SMF_MERGE_TO_SINGLE_STEP) { //This >>> is a merged single step >>> TRACE("Merged single step upgrade"); >>> rc = getImmStepsMergedSingleStep(); >>> + } else if (execMode == SMF_BALANCED_MODE) { >>> + TRACE("Balanced single step upgrade"); >>> + rc = getImmStepsSingleStep(); >>> } else { //This is a written normal single step >>> TRACE("Single step upgrade"); >>> rc = getImmStepsSingleStep(); >>> @@ -3140,7 +3144,7 @@ SmfUpgradeProcedure::getImmStepsMergedSi >>> int initActionId = 1; >>> int wrapupActionId = 1; >>> SmfUpgradeCampaign * camp = >>> SmfCampaignThread::instance()->campaign()->getUpgradeCampaign(); >>> - const std::vector < SmfUpgradeProcedure * >& procedures = >>> camp->getProcedures(); >>> + const std::vector < SmfUpgradeProcedure * >& procedures = >>> camp->getOriginalProcedures(); >>> std::vector < SmfUpgradeProcedure * >::const_iterator >>> proc_iter; >>> for (proc_iter = procedures.begin(); proc_iter != >>> procedures.end(); proc_iter++) { >>> LOG_NO("SmfUpgradeProcedure::getImmStepsMergedSingleStep: Fetch >>> callbacks and wrapup actions from [%s]", >>> @@ -3415,7 +3419,7 @@ SmfUpgradeProcedure::bundleRefFromSsCamp >>> //---------------------------------------------------------------- >>> //Read all the bundles to add/remove from the parsed camaign >>> SmfUpgradeCampaign * camp = >>> SmfCampaignThread::instance()->campaign()->getUpgradeCampaign(); >>> - const std::vector < SmfUpgradeProcedure * >& procedures = >>> camp->getProcedures(); >>> + const std::vector < SmfUpgradeProcedure * >& procedures = >>> camp->getOriginalProcedures(); >>> std::vector < SmfUpgradeProcedure * >::const_iterator proc_iter; >>> std::list < SmfBundleRef > bundlesOldProcSS; >>> std::list < SmfBundleRef *> bundlesOldProcRO; >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.hh >>> b/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.hh >>> --- a/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.hh >>> +++ b/osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.hh >>> @@ -551,7 +551,7 @@ class SmfUpgradeProcedure { >>> /// @param - >>> /// @return The list of upgrade steps. >>> /// >>> - const std::vector < SmfUpgradeStep * >& getProcSteps() { >>> return m_procSteps; } >>> + std::vector < SmfUpgradeStep * >& getProcSteps() { return >>> m_procSteps; } >>> /// >>> /// Purpose: Add the list of upgrade steps >>> @@ -706,6 +706,7 @@ class SmfUpgradeProcedure { >>> /// >>> void setIsMergedProcedure(bool i_state) >>> { m_isMergedProcedure = i_state; } >>> + bool getIsMergedProcedure() {return m_isMergedProcedure; } >>> /// >>> /// Purpose: Reset the object counter of upgrade procedures >>> @@ -717,8 +718,6 @@ class SmfUpgradeProcedure { >>> friend class SmfProcState; >>> friend class SmfCampStateSuspendingExec; >>> - private: >>> - >>> /// >>> /// Purpose: Get iformation from AMF config in IMM about >>> Components, SUs and nodes needed for upgrade >>> /// @param A reference to a std::multimap<std::string, objectInst> >>> @@ -726,6 +725,20 @@ class SmfUpgradeProcedure { >>> /// >>> bool getImmComponentInfo(std::multimap<std::string, >>> objectInst> &i_objects); >>> + >>> +/// >>> +/// Purpose: When merging with SMF_BALANCED_MODE we need to keep >>> track of which balanced group procedures belong to. >>> +/// >>> + const std::vector<std::string>& getBalancedGroup() { return >>> m_balancedGroup; } >>> + >>> +/// >>> +/// Purpose: When merging with SMF_BALANCED_MODE we need to keep >>> track of which balanced group procedures belong to. >>> +/// >>> + void setBalancedGroup(std::vector<std::string> group) { >>> m_balancedGroup = group; } >>> + >>> + private: >>> + >>> + >>> /// >>> /// Purpose: Change the procedure stste. If i_onlyInternalState >>> == false, the IMM procedure object is updated and >>> /// a state change event is sent >>> @@ -765,6 +778,7 @@ class SmfUpgradeProcedure { >>> std::list < SmfCallback * >m_afterUnlock; //Container of >>> the procedure callbacks to be invoked onstep, ataction >>> sem_t m_semaphore; >>> bool m_isMergedProcedure; >>> + std::vector<std::string> m_balancedGroup; >>> }; >>> ////////////////////////////////////////////////// >>> diff --git a/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.hh >>> b/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.hh >>> --- a/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.hh >>> +++ b/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.hh >>> @@ -707,6 +707,12 @@ class SmfUpgradeStep { >>> /// @return true on success else false >>> /// >>> bool readSmfClusterControllers(); >>> +/// >>> +/// Purpose: Set step state >>> +/// @param The state >>> +/// @return None >>> +/// >>> + void setStepState(SaSmfStepStateT i_state); >>> friend class SmfStepState; >>> @@ -761,13 +767,6 @@ class SmfUpgradeStep { >>> void setImmStateAndSendNotification(SaSmfStepStateT i_state); >>> /// >>> -/// Purpose: Set step state >>> -/// @param The state >>> -/// @return None >>> -/// >>> - void setStepState(SaSmfStepStateT i_state); >>> - >>> -/// >>> /// Purpose: Disables copy constructor >>> /// >>> SmfUpgradeStep(const SmfUpgradeStep &); >>> diff --git a/osaf/services/saf/smfsv/smfd/smfd.h >>> b/osaf/services/saf/smfsv/smfd/smfd.h >>> --- a/osaf/services/saf/smfsv/smfd/smfd.h >>> +++ b/osaf/services/saf/smfsv/smfd/smfd.h >>> @@ -60,7 +60,7 @@ extern "C" { >>> /* SMF execution modes */ >>> #define SMF_STANDARD_MODE 0 >>> #define SMF_MERGE_TO_SINGLE_STEP 1 >>> -#define SMF_MERGE_TO_NODE_ROLLING 2 >>> +#define SMF_BALANCED_MODE 2 >>> /* >>> ======================================================================== >>> >>> * TYPE DEFINITIONS >> > ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel