osaf/services/saf/smfsv/config/smfsv_classes.xml    |    7 +
 osaf/services/saf/smfsv/config/smfsv_objects.xml    |    4 +
 osaf/services/saf/smfsv/smfd/SmfCampaign.hh         |    1 +
 osaf/services/saf/smfsv/smfd/SmfStepTypes.cc        |   16 ++
 osaf/services/saf/smfsv/smfd/SmfUpgradeProcedure.cc |  129 +++++++++++--------
 osaf/services/saf/smfsv/smfd/SmfUpgradeStep.cc      |  129 ++++++++++++++-----
 osaf/services/saf/smfsv/smfd/SmfUpgradeStep.hh      |   33 ++++-
 osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc    |   15 ++
 osaf/services/saf/smfsv/smfd/smfd_cb.h              |    1 +
 9 files changed, 239 insertions(+), 96 deletions(-)


If SMF config attr smfKeepDuState is set to >0 (true), the upgrade
procedures will complete leaving the AU/DU in the same admin state
as before the procedure was started.

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
@@ -385,6 +385,13 @@
                         <flag>SA_WRITABLE</flag>
                         <default-value>0</default-value>
                </attr>
+               <attr>
+                       <name>smfKeepDuState</name>
+                       <type>SA_UINT32_T</type>
+                       <category>SA_CONFIG</category>
+                        <flag>SA_WRITABLE</flag>
+                        <default-value>0</default-value>
+               </attr>
        </class>
        <class name="OpenSafSmfCampRestartInfo">
                <category>SA_RUNTIME</category>
diff --git a/osaf/services/saf/smfsv/config/smfsv_objects.xml 
b/osaf/services/saf/smfsv/config/smfsv_objects.xml
--- a/osaf/services/saf/smfsv/config/smfsv_objects.xml
+++ b/osaf/services/saf/smfsv/config/smfsv_objects.xml
@@ -77,6 +77,10 @@
                        <name>smfVerifyTimeout</name>
                        <value>100000000000</value>
                </attr>
+               <attr>
+                       <name>smfKeepDuState</name>
+                       <value>0</value>
+               </attr>
        </object>
        <object class="SaAmfCompBaseType">
                <dn>safCompType=OpenSafCompTypeSMF</dn>
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
@@ -47,6 +47,7 @@
 #define SMF_VERIFY_TIMEOUT_ATTR   "smfVerifyTimeout"
 #define SMF_CLUSTER_CONTROLLERS_ATTR "smfClusterControllers"
 #define SMF_SS_AFFECTED_NODES_ENABLE_ATTR "smfSSAffectedNodesEnable"
+#define SMF_KEEP_DU_STATE_ATTR    "smfKeepDuState"
 #define SMF_UPDATE_ELAPSED_TIME_INTERVAL 10000
 
 class SmfUpgradeCampaign;
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
@@ -396,6 +396,10 @@ SmfStepTypeAuLock::execute()
                 return false;
         }
 
+        /* Copy the initial states of the DUs to AUs, so the activation phase 
will leave */
+        /* the units in the same state as before locking                       
          */
+        m_step->copyDuInitStateToAu();
+
         /* Instantiate activation units */
         LOG_NO("STEP: Instantiate activation units");
         if (m_step->instantiateActivationUnits() == false) {
@@ -669,6 +673,10 @@ SmfStepTypeAuLockAct::execute()
                 return false;
        }
 
+        /* Copy the initial states of the DUs to AUs, so the activation phase 
will leave */
+        /* the units in the same state as before locking                       
          */
+        m_step->copyDuInitStateToAu();
+
         /* Instantiate activation units */
         LOG_NO("STEP: Instantiate activation units");
         if (m_step->instantiateActivationUnits() == false) {
@@ -1360,6 +1368,10 @@ SmfStepTypeNodeReboot::execute()
                 return false;
         }
 
+        /* Copy the initial states of the DUs to AUs, so the activation phase 
will leave */
+        /* the units in the same state as before locking                       
          */
+        m_step->copyDuInitStateToAu();
+
         /* Instantiate activation units */
         LOG_NO("STEP: Instantiate activation units");
         if (m_step->instantiateActivationUnits() == false) {
@@ -1731,6 +1743,10 @@ SmfStepTypeNodeRebootAct::execute()
         }
         // Here the rebooted node is up and running
 
+        /* Copy the initial states of the DUs to AUs, so the activation phase 
will leave */
+        /* the units in the same state as before locking                       
          */
+        m_step->copyDuInitStateToAu();
+
         /* Instantiate activation units */
         LOG_NO("STEP: Instantiate activation units");
         if (m_step->instantiateActivationUnits() == false) {
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
@@ -543,8 +543,11 @@ SmfUpgradeProcedure::calculateRollingSte
                        SmfUpgradeStep *newStep = new SmfUpgradeStep();
                        newStep->setRdn(rdnStr);
                        newStep->setDn(newStep->getRdn() + "," + getDn());
-                       newStep->addActivationUnit(*it);
-                       newStep->addDeactivationUnit(*it);
+                       unitNameAndState tmp;
+                       tmp.name = *it;
+                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                       newStep->addActivationUnit(tmp);
+                       newStep->addDeactivationUnit(tmp);
                        
newStep->setMaxRetry(i_rollingUpgrade->getStepMaxRetryCount());
                        
newStep->setRestartOption(i_rollingUpgrade->getStepRestartOption());
                        newStep->addSwRemove(nodeTemplate->getSwRemoveList());
@@ -598,8 +601,11 @@ SmfUpgradeProcedure::calculateRollingSte
                         osafassert(newStep != NULL);
                         newStep->setRdn(rdnStr);
                         newStep->setDn(newStep->getRdn() + "," + getDn());
-                        newStep->addActivationUnit(*itActDeact);
-                        newStep->addDeactivationUnit(*itActDeact);
+                        unitNameAndState tmp;
+                        tmp.name = *itActDeact;
+                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                        newStep->addActivationUnit(tmp);
+                        newStep->addDeactivationUnit(tmp);
                         
newStep->setMaxRetry(i_rollingUpgrade->getStepMaxRetryCount());
                         
newStep->setRestartOption(i_rollingUpgrade->getStepRestartOption());
                         newStep->addSwRemove(nodeTemplate->getSwRemoveList());
@@ -805,7 +811,10 @@ bool SmfUpgradeProcedure::calculateSingl
                                }
                                std::list<std::string>::const_iterator a;
                                for (a = actUnits.begin(); a != actUnits.end(); 
a++) {
-                                       newStep->addActivationUnit(*a);
+                                       unitNameAndState tmp;
+                                       tmp.name = *a;
+                                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                                       newStep->addActivationUnit(tmp);
                                }
                        } else {
                                if (e->getName().length() == 0) {
@@ -826,7 +835,10 @@ bool SmfUpgradeProcedure::calculateSingl
                entityList.unique();
                std::list<std::string>::iterator entity;
                for (entity = entityList.begin(); entity != entityList.end(); 
entity++) {
-                       newStep->addActivationUnit(*entity);
+                       unitNameAndState tmp;
+                       tmp.name = *entity;
+                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                       newStep->addActivationUnit(tmp);
                }
                entityList.clear();
 
@@ -870,7 +882,10 @@ bool SmfUpgradeProcedure::calculateSingl
                                }
                                std::list<std::string>::const_iterator a;
                                for (a = deactUnits.begin(); a != 
deactUnits.end(); a++) {
-                                       newStep->addDeactivationUnit(*a);
+                                       unitNameAndState tmp;
+                                       tmp.name = *a;
+                                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                                       newStep->addDeactivationUnit(tmp);
                                }
                        } else {
                                if (e->getName().length() == 0){
@@ -901,7 +916,10 @@ bool SmfUpgradeProcedure::calculateSingl
                entityList.sort();
                entityList.unique();
                for (entity = entityList.begin(); entity != entityList.end(); 
entity++) {
-                       newStep->addDeactivationUnit(*entity);
+                       unitNameAndState tmp;
+                       tmp.name = *entity;
+                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                       newStep->addDeactivationUnit(tmp);
                }
                entityList.clear();
 
@@ -997,8 +1015,11 @@ bool SmfUpgradeProcedure::calculateSingl
 
                std::list<std::string>::const_iterator a;
                for (a = actDeactUnits.begin(); a != actDeactUnits.end(); a++) {
-                       newStep->addDeactivationUnit(*a);
-                       newStep->addActivationUnit(*a);
+                       unitNameAndState tmp;
+                       tmp.name = *a;
+                        tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                       newStep->addDeactivationUnit(tmp);
+                       newStep->addActivationUnit(tmp);
                }
 
                std::list<std::string>::const_iterator n;
@@ -1372,7 +1393,7 @@ SmfUpgradeProcedure::addStepModification
        SaImmAttrValuesT_2 **attributes;
        std::list < std::string > objectList;
        std::list < std::string >::const_iterator objit;
-       const std::string & auNodeName = 
i_newStep->getActivationUnitList().front();
+       const std::string & auNodeName = 
i_newStep->getActivationUnitList().front().name;
        std::multimap<std::string, objectInst>::iterator iter;
        std::pair<std::multimap<std::string, objectInst>::iterator, 
std::multimap<std::string, objectInst>::iterator> nodeName_mm;
 
@@ -1575,10 +1596,10 @@ SmfUpgradeProcedure::addStepModification
        } else {
                //No parent type was set, apply the modifications on the entity 
pointed out by the activation units.
                //The optional modifyOperation RDN attribute if added when 
applying the modification
-               std::list < std::string >::const_iterator auEntityIt;
-               const std::list < std::string > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
+               std::list < unitNameAndState >::const_iterator auEntityIt;
+               const std::list < unitNameAndState > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
                for (auEntityIt = auEntityList.begin(); auEntityIt != 
auEntityList.end(); ++auEntityIt) {
-                       if (!addStepModificationList(i_newStep, *auEntityIt, 
i_modificationList)) {
+                       if (!addStepModificationList(i_newStep, 
(*auEntityIt).name, i_modificationList)) {
                                
LOG_NO("SmfUpgradeProcedure::addStepModificationsSuOrComp: 
addStepModificationList fails");
                                return false;
                        }
@@ -1640,8 +1661,8 @@ SmfUpgradeProcedure::addStepModification
         TRACE_ENTER();
 
        std::list < std::string >::const_iterator strIter;
-        std::list < std::string >::const_iterator auEntityIt;
-        const std::list < std::string > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
+        std::list < unitNameAndState >::const_iterator auEntityIt;
+        const std::list < unitNameAndState > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
        std::string typeDn   = i_parentType->getTypeDn();
        std::string parentDn = i_parentType->getParentDn();
 
@@ -1669,23 +1690,23 @@ SmfUpgradeProcedure::addStepModification
                        for (auEntityIt = auEntityList.begin(); auEntityIt != 
auEntityList.end(); ++auEntityIt) {
                                //This test is because in single step upgrades 
the SU/Comp step mod routines are called 
                                //also when the AU/DU is a node.
-                               if((*auEntityIt).find("safAmfNode=") == 0) { 
//Node as AU/DU
-                                       if((*objit).second.nodeDN == 
(*auEntityIt)) {
-                                               TRACE("Instance %s is within 
scope of %s", (*objit).second.suDN.c_str(), (*auEntityIt).c_str());
+                               if((*auEntityIt).name.find("safAmfNode=") == 0) 
{ //Node as AU/DU
+                                       if((*objit).second.nodeDN == 
(*auEntityIt).name) {
+                                               TRACE("Instance %s is within 
scope of %s", (*objit).second.suDN.c_str(), (*auEntityIt).name.c_str());
                                                
matchingSU.push_back((*objit).second.suDN);
                                                break;
                                        }
                                }
 
-                               if((*objit).second.suDN == (*auEntityIt)) {
-                                       TRACE("Instance %s is within scope of 
%s", (*objit).second.suDN.c_str(), (*auEntityIt).c_str());
+                               if((*objit).second.suDN == (*auEntityIt).name) {
+                                       TRACE("Instance %s is within scope of 
%s", (*objit).second.suDN.c_str(), (*auEntityIt).name.c_str());
                                        //The i_objects map contain all 
instances on component level.
                                        //One SU may give multiple matches 
since one SU may contain several components.
                                        //Save the matching enties and remove 
duplicates when all matching is finished.
                                        
matchingSU.push_back((*objit).second.suDN);
                                        break;
                                } else {
-                                       TRACE("Instance %s is NOT within scope 
of %s", (*objit).second.suDN.c_str(), (*auEntityIt).c_str());
+                                       TRACE("Instance %s is NOT within scope 
of %s", (*objit).second.suDN.c_str(), (*auEntityIt).name.c_str());
                                }
                        }
                        //Remove duplicates
@@ -1717,8 +1738,8 @@ SmfUpgradeProcedure::addStepModification
         TRACE_ENTER();
 
        std::list < std::string >::const_iterator strIter;
-        std::list < std::string >::const_iterator auEntityIt;
-        const std::list < std::string > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
+        std::list < unitNameAndState >::const_iterator auEntityIt;
+        const std::list < unitNameAndState > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
        std::string typeDn   = i_parentType->getTypeDn();
        std::string parentDn = i_parentType->getParentDn();
 
@@ -1744,29 +1765,29 @@ SmfUpgradeProcedure::addStepModification
                        for (auEntityIt = auEntityList.begin(); auEntityIt != 
auEntityList.end(); ++auEntityIt) {
                                //This test is because in single step upgrades 
the SU/Comp step mod routines are called 
                                //also when the AU/DU is a node.
-                               if((*auEntityIt).find("safAmfNode=") == 0) { 
//Node as AU/DU
-                                       if((*objit).second.nodeDN == 
(*auEntityIt)) {
-                                               TRACE("Instance %s is within 
scope of %s", (*objit).second.compDN.c_str(), (*auEntityIt).c_str());
+                               if((*auEntityIt).name.find("safAmfNode=") == 0) 
{ //Node as AU/DU
+                                       if((*objit).second.nodeDN == 
(*auEntityIt).name) {
+                                               TRACE("Instance %s is within 
scope of %s", (*objit).second.compDN.c_str(), (*auEntityIt).name.c_str());
                                                if 
(!addStepModificationList(i_newStep, (*objit).second.compDN, 
i_modificationList)) {
                                                        
LOG_NO("SmfUpgradeProcedure::addStepModificationsComp: addStepModificationList 
fails");
                                                        TRACE_LEAVE();
                                                        return false;
                                                }
                                        } else {
-                                               TRACE("Instance %s is NOT 
within scope of %s", (*objit).second.compDN.c_str(), (*auEntityIt).c_str());
+                                               TRACE("Instance %s is NOT 
within scope of %s", (*objit).second.compDN.c_str(), 
(*auEntityIt).name.c_str());
                                        }
                                }
 
                                //If the AU/DU DN is found within the Component 
DN, the component is within the scope
-                               if(((*objit).second.compDN).find(*auEntityIt) 
!= std::string::npos) {
-                                       TRACE("Instance %s is within scope of 
%s", (*objit).second.compDN.c_str(), (*auEntityIt).c_str());
+                               
if(((*objit).second.compDN).find((*auEntityIt).name) != std::string::npos) {
+                                       TRACE("Instance %s is within scope of 
%s", (*objit).second.compDN.c_str(), (*auEntityIt).name.c_str());
                                        if (!addStepModificationList(i_newStep, 
(*objit).second.compDN, i_modificationList)) {
                                                
LOG_NO("SmfUpgradeProcedure::addStepModificationsComp: addStepModificationList 
fails");
                                                TRACE_LEAVE();
                                                return false;
                                        }
                                } else {
-                                       TRACE("Instance %s is NOT within scope 
of %s", (*objit).second.compDN.c_str(), (*auEntityIt).c_str());
+                                       TRACE("Instance %s is NOT within scope 
of %s", (*objit).second.compDN.c_str(), (*auEntityIt).name.c_str());
                                }
                        }
                }
@@ -1787,8 +1808,8 @@ SmfUpgradeProcedure::addStepModification
         TRACE_ENTER();
 
        std::list < std::string >::const_iterator strIter;
-        std::list < std::string >::const_iterator auEntityIt;
-        const std::list < std::string > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
+        std::list < unitNameAndState >::const_iterator auEntityIt;
+        const std::list < unitNameAndState > &auEntityList = 
i_newStep->getActivationUnitList(); //Single step may have many activation units
        std::string typeDn   = i_parentType->getTypeDn();
        std::string parentDn = i_parentType->getParentDn();
 
@@ -1811,9 +1832,9 @@ SmfUpgradeProcedure::addStepModification
                for (auEntityIt = auEntityList.begin(); auEntityIt != 
auEntityList.end(); ++auEntityIt) {
                        //This test is because in single step upgrades the 
SU/Comp step mod routines are called 
                        //also when the AU/DU is a node.
-                       if((*auEntityIt).find("safAmfNode=") == 0) { //Node as 
AU/DU
-                               if((*objit).second.nodeDN == (*auEntityIt)) {
-                                       TRACE("Instance %s is within scope of 
%s", (*objit).second.suDN.c_str(), (*auEntityIt).c_str());
+                       if((*auEntityIt).name.find("safAmfNode=") == 0) { 
//Node as AU/DU
+                               if((*objit).second.nodeDN == 
(*auEntityIt).name) {
+                                       TRACE("Instance %s is within scope of 
%s", (*objit).second.suDN.c_str(), (*auEntityIt).name.c_str());
                                        //The i_objects map contain all 
instances on component level.
                                        //One SU may give multiple matches 
since one SU may contain several components.
                                        //Save the matching enties and remove 
duplicates when all matching is finished.
@@ -1822,15 +1843,15 @@ SmfUpgradeProcedure::addStepModification
                                }
                        }
 
-                       if((*objit).second.suDN == (*auEntityIt)) {
-                               TRACE("Instance %s is within scope of %s", 
(*objit).second.suDN.c_str(), (*auEntityIt).c_str());
+                       if((*objit).second.suDN == (*auEntityIt).name) {
+                               TRACE("Instance %s is within scope of %s", 
(*objit).second.suDN.c_str(), (*auEntityIt).name.c_str());
                                //The i_objects map contain all instances on 
component level.
                                //One SU may give multiple matches since one SU 
may contain several components.
                                //Save the matching enties and remove 
duplicates when all matching is finished.
                                matchingSU.push_back((*objit).second.suDN);
                                break;
                        } else {
-                               TRACE("Instance %s is NOT within scope of %s", 
(*objit).second.suDN.c_str(), (*auEntityIt).c_str());
+                               TRACE("Instance %s is NOT within scope of %s", 
(*objit).second.suDN.c_str(), (*auEntityIt).name.c_str());
                        }
                }
                //Remove duplicates
@@ -1944,11 +1965,11 @@ SmfUpgradeProcedure::createImmStep(SmfUp
                 return rc;
         }
 
-       std::list < std::string >::const_iterator iter;
-       std::list < std::string >::const_iterator iterE;
+       std::list < unitNameAndState >::const_iterator iter;
+       std::list < unitNameAndState >::const_iterator iterE;
 
        /* Create the SaSmfDeactivationUnit object if there ia any object to 
deactivate */
-       const std::list < std::string >& deactList = 
i_step->getDeactivationUnitList();
+       const std::list < unitNameAndState >& deactList = 
i_step->getDeactivationUnitList();
        if (deactList.size() != 0) {
                SmfImmRTCreateOperation icoSaSmfDeactivationUnit;
                icoSaSmfDeactivationUnit.setClassName("SaSmfDeactivationUnit");
@@ -1968,7 +1989,7 @@ SmfUpgradeProcedure::createImmStep(SmfUp
                iter = deactList.begin();
                iterE = deactList.end();
                while (iter != iterE) {
-                       attrsaSmfDuActedOn.addValue(*iter);
+                       attrsaSmfDuActedOn.addValue((*iter).name);
                        iter++;
                }
 
@@ -2073,7 +2094,7 @@ SmfUpgradeProcedure::createImmStep(SmfUp
        }
 
        /* Create the SaSmfActivationUnit object if there is any object to 
activate */
-       const std::list < std::string >& actList = 
i_step->getActivationUnitList();
+       const std::list < unitNameAndState >& actList = 
i_step->getActivationUnitList();
        if(actList.size() != 0) {
                SmfImmRTCreateOperation icoSaSmfActivationUnit;
                icoSaSmfActivationUnit.setClassName("SaSmfActivationUnit");
@@ -2089,11 +2110,11 @@ SmfUpgradeProcedure::createImmStep(SmfUp
                SmfImmAttribute attrsaSmfAuActedOn;
                attrsaSmfAuActedOn.setName("saSmfAuActedOn");
                attrsaSmfAuActedOn.setType("SA_IMM_ATTR_SANAMET");
-               const std::list < std::string > actList = 
i_step->getActivationUnitList();
+               const std::list < unitNameAndState > actList = 
i_step->getActivationUnitList();
                iter = actList.begin();
                iterE = actList.end();
                while (iter != iterE) {
-                       attrsaSmfAuActedOn.addValue(*iter);
+                       attrsaSmfAuActedOn.addValue((*iter).name);
                        iter++;
                }
 
@@ -2522,9 +2543,11 @@ SmfUpgradeProcedure::readCampaignImmMode
                        for(ix = 0; (au = immutil_getNameAttr((const 
SaImmAttrValuesT_2 **)attributes, 
                                                              "saSmfAuActedOn", 
ix)) != NULL; ix++) {
                                TRACE("addActivationUnit %s", 
osaf_extended_name_borrow(au));
-                               std::string str = osaf_extended_name_borrow(au);
-                               if(str != "") {
-                                       
i_newStep->addActivationUnit(osaf_extended_name_borrow(au));
+                               unitNameAndState tmp;
+                               tmp.name = osaf_extended_name_borrow(au);
+                                tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                               if(tmp.name != "") {
+                                       i_newStep->addActivationUnit(tmp);
                                } else {
                                        TRACE("No activation unit, must be SW 
install");
                                }
@@ -2604,9 +2627,11 @@ SmfUpgradeProcedure::readCampaignImmMode
                        for(ix = 0; (du = immutil_getNameAttr((const 
SaImmAttrValuesT_2 **)attributes, 
                                                              "saSmfDuActedOn", 
ix)) != NULL; ix++) {
                                TRACE("addDeactivationUnit %s", 
osaf_extended_name_borrow(du));
-                               std::string str = osaf_extended_name_borrow(du);
-                               if(str != "") {
-                                       
i_newStep->addDeactivationUnit(osaf_extended_name_borrow(du));
+                               unitNameAndState tmp;
+                               tmp.name = osaf_extended_name_borrow(du);
+                                tmp.initState = SA_AMF_ADMIN_UNLOCKED;
+                               if(tmp.name != "") {
+                                       i_newStep->addDeactivationUnit(tmp);
                                } else {
                                        TRACE("No deactivation unit, must be SW 
remove");
                                }
diff --git a/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.cc 
b/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.cc
--- a/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.cc
+++ b/osaf/services/saf/smfsv/smfd/SmfUpgradeStep.cc
@@ -372,7 +372,7 @@ SmfUpgradeStep::setImmStateAndSendNotifi
 // addActivationUnit()
 
//------------------------------------------------------------------------------
 void 
-SmfUpgradeStep::addActivationUnit(const std::string & i_activationUnit)
+SmfUpgradeStep::addActivationUnit(const unitNameAndState & i_activationUnit)
 {
        m_activationUnit.m_actedOn.push_back(i_activationUnit);
 }
@@ -380,7 +380,7 @@ SmfUpgradeStep::addActivationUnit(const 
 
//------------------------------------------------------------------------------
 // getActivationUnits()
 
//------------------------------------------------------------------------------
-const std::list < std::string > &
+const std::list < unitNameAndState > &
 SmfUpgradeStep::getActivationUnitList()
 {
        return m_activationUnit.m_actedOn;
@@ -390,7 +390,7 @@ SmfUpgradeStep::getActivationUnitList()
 // addDeactivationUnit()
 
//------------------------------------------------------------------------------
 void 
-SmfUpgradeStep::addDeactivationUnit(const std::string & i_deactivationUnit)
+SmfUpgradeStep::addDeactivationUnit(const unitNameAndState & 
i_deactivationUnit)
 {
        m_deactivationUnit.m_actedOn.push_back(i_deactivationUnit);
 }
@@ -398,7 +398,7 @@ SmfUpgradeStep::addDeactivationUnit(cons
 
//------------------------------------------------------------------------------
 // getDeactivationUnits()
 
//------------------------------------------------------------------------------
-const std::list < std::string > &
+const std::list < unitNameAndState > &
 SmfUpgradeStep::getDeactivationUnitList()
 {
        return m_deactivationUnit.m_actedOn;
@@ -649,7 +649,7 @@ bool
 SmfUpgradeStep::lockDeactivationUnits()
 {
        TRACE("lock deactivation units");
-       const SaImmAdminOperationParamsT_2 *params[1] = {NULL}; 
+       const SaImmAdminOperationParamsT_2 *params[1] = {NULL};
        return callAdminOperation(SA_AMF_ADMIN_LOCK, params, 
m_deactivationUnit.m_actedOn);
 }
 
@@ -671,7 +671,8 @@ bool
 SmfUpgradeStep::terminateDeactivationUnits()
 {
        TRACE("terminate deactivation units");
-       const SaImmAdminOperationParamsT_2 *params[1] = {NULL}; 
+       const SaImmAdminOperationParamsT_2 *params[1] = {NULL};
+       std::list < unitNameAndState >::iterator dnit;
        return callAdminOperation(SA_AMF_ADMIN_LOCK_INSTANTIATION, params, 
m_deactivationUnit.m_actedOn);
 }
 
@@ -886,14 +887,15 @@ SmfUpgradeStep::setMaintenanceState(SmfA
        SmfImmUtils immUtil;
         std::list < std::string > suList;
         std::list < std::string >::iterator it;
+        std::list < unitNameAndState >::iterator unitIt;
 
-        for (it = i_units.m_actedOn.begin(); it != i_units.m_actedOn.end(); 
++it) {
-                if ((*it).find("safAmfNode") == 0) { 
+        for (unitIt = i_units.m_actedOn.begin(); unitIt != 
i_units.m_actedOn.end(); ++unitIt) {
+               if ((*unitIt).name.find("safAmfNode") == 0) {
                         //If DN is a node, set saAmfSUMaintenanceCampaign for 
all SUs on the node
-                       // Find all SU's on the node
-                        std::list < std::string > objectList;
-                        SaImmAttrValuesT_2 **attributes;
-                       (void)immUtil.getChildren("", objectList, 
SA_IMM_SUBTREE, "SaAmfSU");
+                       // Find all SU's on the node
+                       std::list < std::string > objectList;
+                SaImmAttrValuesT_2 **attributes;
+                (void)immUtil.getChildren("", objectList, SA_IMM_SUBTREE, 
"SaAmfSU");
 
                         std::list < std::string >::const_iterator suit;
                        for (suit = objectList.begin(); suit != 
objectList.end(); ++suit) {
@@ -905,28 +907,28 @@ SmfUpgradeStep::setMaintenanceState(SmfA
                                                                     
"saAmfSUHostedByNode",
                                                                     0);
                                         if ((hostedByNode != NULL)
-                                            && (strcmp((*it).c_str(), 
osaf_extended_name_borrow(hostedByNode)) == 0)) {
+                                            && (strcmp((*unitIt).name.c_str(), 
osaf_extended_name_borrow(hostedByNode)) == 0)) {
                                                 /* The SU is hosted by the AU 
node */
                                                 suList.push_back(*suit);
                                         }
                                }
                        }
-                } else if ((*it).find("safSu") == 0) { 
+                } else if ((*unitIt).name.find("safSu") == 0) {
                         //If DN is a SU, set saAmfSUMaintenanceCampaign for 
this SU only
-                        suList.push_back(*it);
-                } else if ((*it).find("safComp") == 0) {
+                        suList.push_back((*unitIt).name);
+                } else if ((*unitIt).name.find("safComp") == 0) {
                         //IF DN is a component, set saAmfSUMaintenanceCampaign 
for the hosting SU
                         //Extract the SU name from the DN
-                       std::string::size_type pos = (*it).find(",");
+                       std::string::size_type pos = (*unitIt).name.find(",");
                        if (pos == std::string::npos) {
-                               LOG_NO("SmfUpgradeStep::setMaintenanceState(): 
Separator \",\" not found in %s", (*it).c_str());
+                               LOG_NO("SmfUpgradeStep::setMaintenanceState(): 
Separator \",\" not found in %s", (*unitIt).name.c_str());
                                TRACE_LEAVE();
                                return false;
                        }
-                        std::string su = ((*it).substr(pos + 1, 
std::string::npos));
+                        std::string su = ((*unitIt).name.substr(pos + 1, 
std::string::npos));
                         suList.push_back(su);
                 } else {
-                        LOG_NO("SmfUpgradeStep::setMaintenanceState(): unknown 
activation unit type %s", (*it).c_str());
+                        LOG_NO("SmfUpgradeStep::setMaintenanceState(): unknown 
activation unit type %s", (*unitIt).name.c_str());
                         TRACE_LEAVE();
                         return false;
                 }
@@ -1352,9 +1354,9 @@ SmfUpgradeStep::calculateStepType()
                //Single step
                //Try the activation unit list, if empty try the deactivation 
unit list
                if (!this->getActivationUnitList().empty()) {
-                       firstAuDu = this->getActivationUnitList().front();
+                       firstAuDu = this->getActivationUnitList().front().name;
                } else if (!this->getDeactivationUnitList().empty()) {
-                       firstAuDu = this->getDeactivationUnitList().front();
+                       firstAuDu = 
this->getDeactivationUnitList().front().name;
                } else {
                        //No activation/deactivation, just SW installation
                        className = "SaAmfNode";
@@ -1363,7 +1365,7 @@ SmfUpgradeStep::calculateStepType()
        } else { 
                //Rolling
                if (!this->getActivationUnitList().empty()) {
-                       firstAuDu = this->getActivationUnitList().front();
+                       firstAuDu = this->getActivationUnitList().front().name;
                } else {
                        //No activation/deactivation, just SW installation
                        className = "SwInstallNode"; //Fake name for SW 
installation only
@@ -2085,69 +2087,93 @@ SmfUpgradeStep::callBundleScript(SmfInst
 bool 
 SmfUpgradeStep::callAdminOperation(unsigned int i_operation,
                                    const SaImmAdminOperationParamsT_2 ** 
i_params,
-                                   const std::list < std::string > &i_dnList)
+                                   std::list <unitNameAndState> &i_dnList)
 {
-       std::list < std::string >::const_iterator dnit;
+        //This routine is only used from the upgrade steps
+       std::list < unitNameAndState >::iterator dnit;
        SmfImmUtils immUtil;
        bool result = true;
 
        TRACE_ENTER();
 
        for (dnit = i_dnList.begin(); dnit != i_dnList.end(); ++dnit) {
-               SaAisErrorT rc = immUtil.callAdminOperation((*dnit), 
i_operation, i_params, smfd_cb->adminOpTimeout);
+                //The initial deactivation unit(DU) admin state is saved in 
the given DU list (i_dnList).
+                //The DU admin state is not read from IMM but is known from 
the result from adminOp.
+                //The saved DU admin state is used in the unlocking phase to 
avoid the DU to enter a different admin state than it
+                //originally have.
+                //If the admin state is "empty" the unlocking will proceed 
regardless of original state.
+
+                //If AU/DU original state was SA_AMF_ADMIN_LOCKED, don't unlock
+                if ((i_operation == SA_AMF_ADMIN_UNLOCK) && ((*dnit).initState 
== SA_AMF_ADMIN_LOCKED)) {
+                        LOG_NO("AU/DU [%s] shall remain SA_AMF_ADMIN_LOCKED, 
continue", (*dnit).name.c_str());
+                        continue;
+                }
+
+                //If AU/DU original state was 
SA_AMF_ADMIN_LOCKED_INSTANTIATION don't instantiate or unlock
+                if (((i_operation == SA_AMF_ADMIN_UNLOCK_INSTANTIATION) || 
(i_operation == SA_AMF_ADMIN_UNLOCK)) &&
+                    ((*dnit).initState == SA_AMF_ADMIN_LOCKED_INSTANTIATION)) {
+                        LOG_NO("AU/DU [%s] shall remain 
SA_AMF_ADMIN_LOCKED_INSTANTIATION, continue", (*dnit).name.c_str());
+                        continue;
+                }
+
+               SaAisErrorT rc = immUtil.callAdminOperation((*dnit).name, 
i_operation, i_params, smfd_cb->adminOpTimeout);
 
                //In case the upgrade step is re-executed the operation may 
result in the followng result codes
                //depending on the state of the entity
                // SA_AIS_ERR_NO_OP, in case the operation is already performed
-               // SA_AIS_ERR_BAD_OPERATION, in case the entity is already in 
loacked-instantiation admin state
+               // SA_AIS_ERR_BAD_OPERATION, in case the entity is already in 
locked-instantiation admin state
                switch (i_operation) {
                case SA_AMF_ADMIN_LOCK:
                        if(rc == SA_AIS_ERR_NO_OP) {
-                               TRACE("Entity %s already in state LOCKED, 
continue", (*dnit).c_str());
+                               TRACE("Entity %s already in state LOCKED, 
continue", (*dnit).name.c_str());
+                                //Save the state for act/deact pointed out
+                               (*dnit).initState = SA_AMF_ADMIN_LOCKED;
                        } else if (rc == SA_AIS_ERR_BAD_OPERATION) {
-                               TRACE("Entity %s already in state 
LOCKED-INSTANTIATION, continue", (*dnit).c_str());
+                               TRACE("Entity %s already in state 
LOCKED-INSTANTIATION, continue", (*dnit).name.c_str());
                        } else if (rc != SA_AIS_OK) {
-                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).c_str());
+                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).name.c_str());
                                result = false;
                                goto done;
                        }
                        break;
                case SA_AMF_ADMIN_UNLOCK:
                        if(rc == SA_AIS_ERR_NO_OP) {
-                               TRACE("Entity %s already in state UNLOCKED, 
continue", (*dnit).c_str());
+                               TRACE("Entity %s already in state UNLOCKED, 
continue", (*dnit).name.c_str());
                        } else if (rc != SA_AIS_OK) {
-                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).c_str());
+                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).name.c_str());
                                result = false;
                                goto done;
                        }
                        break;
                case SA_AMF_ADMIN_LOCK_INSTANTIATION:
                        if(rc == SA_AIS_ERR_NO_OP) {
-                               TRACE("Entity %s already in state 
LOCKED-INSTANTIATED, continue", (*dnit).c_str());
+                               TRACE("Entity %s already in state 
LOCKED-INSTANTIATED, continue", (*dnit).name.c_str());
+                               //Save the state for act/deact pointed out
+                               (*dnit).initState = 
SA_AMF_ADMIN_LOCKED_INSTANTIATION;
                        } else if (rc != SA_AIS_OK) {
-                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).c_str());
+                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).name.c_str());
                                result = false;
                                goto done;
                        }
                        break;
                case SA_AMF_ADMIN_UNLOCK_INSTANTIATION:
                        if(rc == SA_AIS_ERR_NO_OP) {
-                               TRACE("Entity %s already in state 
UNLOCKED-INSTANTIATED, continue", (*dnit).c_str());
+                               TRACE("Entity %s already in state 
UNLOCKED-INSTANTIATED, continue", (*dnit).name.c_str());
                        } else if (rc != SA_AIS_OK) {
-                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).c_str());
+                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).name.c_str());
                                result = false;
                                goto done;
                        }
                        break;
                case SA_AMF_ADMIN_RESTART:
                        if (rc != SA_AIS_OK) {
-                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).c_str());
+                               LOG_NO("Failed to call admin operation %u on 
%s", i_operation, (*dnit).name.c_str());
                                result = false;
                                goto done;
                        }
                        break;
                default:
-                       LOG_NO("Unknown admin operation %u on %s", i_operation, 
(*dnit).c_str());
+                       LOG_NO("Unknown admin operation %u on %s", i_operation, 
(*dnit).name.c_str());
                        result = false;
                        goto done;
                        break;
@@ -2160,6 +2186,33 @@ done:
 }
 
 
//------------------------------------------------------------------------------
+// copyDuInitStateToAu()
+//------------------------------------------------------------------------------
+void
+SmfUpgradeStep::copyDuInitStateToAu()
+{
+               TRACE_ENTER();
+               if (smfd_cb->smfKeepDuState == 0) { //Classic behavior, unlock 
at deactivation
+                       TRACE_LEAVE();
+                       return;
+               }
+
+               std::list < unitNameAndState >::iterator i_du;
+               std::list < unitNameAndState >::iterator i_au;
+               // For each DN given in m_activationUnit, check if DN is found 
in m_deactivationUnit.
+               // If DN is found copy the DU initial state.
+               for (i_au = m_activationUnit.m_actedOn.begin(); i_au != 
m_activationUnit.m_actedOn.end(); ++i_au) {
+                       for (i_du = m_deactivationUnit.m_actedOn.begin(); i_du 
!= m_deactivationUnit.m_actedOn.end(); ++i_du) {
+                               if ((*i_au).name == (*i_du).name) {
+                                               (*i_au).initState = 
(*i_du).initState;
+                                               break;
+                               }
+                       }
+               }
+               TRACE_LEAVE();
+}
+
+//------------------------------------------------------------------------------
 // nodeReboot()
 
//------------------------------------------------------------------------------
 bool 
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
@@ -27,6 +27,7 @@
 #include <vector>
 #include <list>
 
+#include <saAmf.h>
 #include <saSmf.h>
 #include <saImmOi.h>
 #include "SmfStepState.hh"
@@ -56,6 +57,11 @@ struct SmfNodeUpInfo {
         unsigned int nd_up_cntr;
 };
 
+struct unitNameAndState{
+         std::string name;
+         SaAmfAdminStateT initState;
+};
+
 /* ========================================================================
  *   DATA DECLARATIONS
  * ========================================================================
@@ -84,8 +90,16 @@ class SmfActivationUnit {
       ~SmfActivationUnit() 
       {
       }
+#if 0
+      typedef enum {
+          SA_AMF_ADMIN_UNLOCKED =1,
+          SA_AMF_ADMIN_LOCKED = 2,
+          SA_AMF_ADMIN_LOCKED_INSTANTIATION = 3,
+          SA_AMF_ADMIN_SHUTTING_DOWN = 4
+      } SaAmfAdminStateT;
+#endif
 
-      std::list < std::string > m_actedOn;
+      std::list < unitNameAndState > m_actedOn;
 };
 
 ///
@@ -225,28 +239,28 @@ class SmfUpgradeStep {
 /// @param    A DN to an activation unit 
 /// @return   None
 ///
-       void addActivationUnit(const std::string & i_activationUnit);
+       void addActivationUnit(const unitNameAndState & i_activationUnit);
 
 ///
 /// Purpose:  Get the activation unit DN
 /// @param     
 /// @return   A list of DN to activation units
 ///
-       const std::list < std::string > &getActivationUnitList();
+       const std::list < unitNameAndState > &getActivationUnitList();
 
 ///
 /// Purpose:  Add an deactivation unit DN
 /// @param    A DN to an deactivation unit 
 /// @return   None
 ///
-       void addDeactivationUnit(const std::string & i_deactivationUnit);
+       void addDeactivationUnit(const unitNameAndState & i_deactivationUnit);
 
 ///
 /// Purpose:  Get the deactivation unit DN
 /// @param     
 /// @return   A list of DN to deactivation units
 ///
-       const std::list < std::string > &getDeactivationUnitList();
+       const std::list < unitNameAndState > &getDeactivationUnitList();
 
 ///
 /// Purpose:  Add a sw bundle to remove
@@ -625,6 +639,13 @@ class SmfUpgradeStep {
 ///
        bool nodeReboot();
 
+///
+/// Purpose:  Copy initial admin state of deactivation units to activation 
units
+/// @param    -
+/// @return   -
+///
+       void copyDuInitStateToAu();
+
        bool checkAndInvokeCallback (const std::list < SmfCallback * > 
&callback_list, unsigned int camp_phase);
 
         friend class SmfStepState;
@@ -670,7 +691,7 @@ class SmfUpgradeStep {
 /// @return   -
 ///
        bool callAdminOperation(unsigned int i_operation, const 
SaImmAdminOperationParamsT_2 ** params,
-                               const std::list < std::string > &i_dnList);
+                               std::list < unitNameAndState > &i_dnList);
 
 ///
 /// Purpose:  Set the state in IMM step object and send state change 
notification
diff --git a/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc 
b/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc
--- a/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc
+++ b/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc
@@ -1153,6 +1153,19 @@ uint32_t read_config_and_set_control_blo
                 }
         }
 
+       const SaUint32T *keepDuState = immutil_getUint32Attr((const 
SaImmAttrValuesT_2 **)attributes,
+                       SMF_KEEP_DU_STATE_ATTR, 0);
+       unsigned int tmp_keep_du_state = 0;
+
+       if (keepDuState == NULL) {
+               //Not found, set default value
+               keepDuState = &tmp_keep_du_state;
+               LOG_NO("Attr %s is not available in %s, using default value 
%d", 
+                      SMF_KEEP_DU_STATE_ATTR, SMF_CONFIG_OBJECT_DN, 
*keepDuState);
+       } else {
+               LOG_NO("smfKeepDuState = %d", *keepDuState);
+       }
+
        cb->backupCreateCmd = strdup(backupCreateCmd);
        cb->bundleCheckCmd = strdup(bundleCheckCmd);
        cb->nodeCheckCmd = strdup(nodeCheckCmd);
@@ -1170,6 +1183,8 @@ uint32_t read_config_and_set_control_blo
        cb->smfInactivatePbeDuringUpgrade = *smfInactivatePbeDuringUpgrade;
        cb->smfVerifyEnable = *smfVerifyEnable;
        cb->smfVerifyTimeout = *verifyTimeout;
+       cb->smfKeepDuState = *keepDuState;
+
        TRACE_LEAVE();
        return NCSCC_RC_SUCCESS;
 }
diff --git a/osaf/services/saf/smfsv/smfd/smfd_cb.h 
b/osaf/services/saf/smfsv/smfd/smfd_cb.h
--- a/osaf/services/saf/smfsv/smfd/smfd_cb.h
+++ b/osaf/services/saf/smfsv/smfd/smfd_cb.h
@@ -60,6 +60,7 @@ typedef struct smfd_cb {
        SaUint32T smfVerifyEnable;                  /* dis/enable pre-campaign 
verification callbacks */
        SaTimeT smfVerifyTimeout;                   /* pre-campaign 
verification timeout */
         char *smfClusterControllers[2];/* list of nodes where amfd is execting 
*/
+       SaUint32T smfKeepDuState;                   /* Keep DU state in an 
upgrade if true (>0) */
        SaInvocationT cbk_inv_id;                   /* Invocation ID of the 
callback */
        SMFD_SMFND_ADEST_INVID_MAP *smfnd_list;     /* SMFNDs need to respond 
to the callback. */
        uint32_t no_of_smfnd;

------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to