This fix extends, and also improves the previous one of #2209 which was
done for node level DU/AU. In particular, it eliminates any duplicate AU/DU
on SU and component level when merging forAddRemove and forModify/Rolling
procedures into a single-step procedure for one-step upgrade execution mode.

Improvement is made to remove units that have duplicates within the
forAddRemoveDU/AU lists themselves, but not having duplicate in the merged
symmetric DU/AU lists, which is the case that #2209 failed to consider.
---
 src/smf/smfd/SmfUpgradeProcedure.cc | 104 +++++++++++++++---------------------
 src/smf/smfd/SmfUpgradeStep.h       |   5 ++
 2 files changed, 49 insertions(+), 60 deletions(-)

diff --git a/src/smf/smfd/SmfUpgradeProcedure.cc 
b/src/smf/smfd/SmfUpgradeProcedure.cc
index 2937c70..598edcc 100644
--- a/src/smf/smfd/SmfUpgradeProcedure.cc
+++ b/src/smf/smfd/SmfUpgradeProcedure.cc
@@ -1,6 +1,7 @@
 /*
  *
  * (C) Copyright 2009 The OpenSAF Foundation
+ * Copyright (C) 2018 Ericsson AB. All Rights Reserved.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -1295,11 +1296,18 @@ bool 
SmfUpgradeProcedure::mergeStepIntoSingleStep(SmfUpgradeProcedure *i_proc,
     getCallbackList((*proc_elem).getUpgradeMethod());
   }
 
-  // Remove DU duplicates
-  LOG_NO("Remove duplicates from the merged DU list");
+  // Remove duplicates from tmpDU list
+  LOG_NO("Remove duplicates from the merged symmetric DU/AU list");
   tmpDU.sort(compare_du_part);
   tmpDU.unique(unique_du_part);
 
+  // Remove duplicates from forAddRemoveDU/AU lists
+  LOG_NO("Remove duplicates from the forAddRemoveDU/AU lists");
+  forAddRemoveDU.sort(compare_du_part);
+  forAddRemoveDU.unique(unique_du_part);
+  forAddRemoveAU.sort(compare_du_part);
+  forAddRemoveAU.unique(unique_du_part);
+
   // Reduce the DU list, check if smaller scope is within bigger scope.
   LOG_NO("Optimize AU/DU");
   std::pair<std::multimap<std::string, objectInst>::iterator,
@@ -1382,67 +1390,43 @@ bool 
SmfUpgradeProcedure::mergeStepIntoSingleStep(SmfUpgradeProcedure *i_proc,
     }
   }
 
-  // For forAddRemove AU/DU the node level AU/DU will be optimized with other
-  // rolling/formodify proceduers. Because node will never be optimized away.
-  // But AU/DU at SU/Comp will not be optimized for AddRemove and will be as 
is,
-  // because there is a chance that Su/comp can be removed if they are in the
-  // scope of the node/Su.
-
-  std::list<unitNameAndState>::iterator addRemoveUnit_iter, nodeLevel_iter;
-  for (addRemoveUnit_iter = forAddRemoveAU.begin();
-       addRemoveUnit_iter != forAddRemoveAU.end();) {
-    for (nodeLevel_iter = nodeLevelDU.begin();
-         nodeLevel_iter != nodeLevelDU.end(); ++nodeLevel_iter) {
-      if ((*addRemoveUnit_iter).name == (*nodeLevel_iter).name) {
-        // if item is already presented in nodeLevelDU, erase it from the
-        // forAddRemove list
-        LOG_NO(
-            "[%s] is already presented in the merged DU list, remove it from 
forAddRemoveAU list",
-            (*addRemoveUnit_iter).name.c_str());
-        addRemoveUnit_iter = forAddRemoveAU.erase(addRemoveUnit_iter);
-        break;
-      }
-    }
-    if (nodeLevel_iter == nodeLevelDU.end()) {
-      ++addRemoveUnit_iter;
-    }
-  }
-
-  for (addRemoveUnit_iter = forAddRemoveDU.begin();
-       addRemoveUnit_iter != forAddRemoveDU.end();) {
-    for (nodeLevel_iter = nodeLevelDU.begin();
-         nodeLevel_iter != nodeLevelDU.end(); ++nodeLevel_iter) {
-      if ((*addRemoveUnit_iter).name == (*nodeLevel_iter).name) {
-        // if item is already presented in nodeLevelDU, erase it from the
-        // forAddRemove list
-        LOG_NO(
-            "[%s] is already presented in the merged DU list, remove it from 
forAddRemoveDU list",
-            (*addRemoveUnit_iter).name.c_str());
-        addRemoveUnit_iter = forAddRemoveDU.erase(addRemoveUnit_iter);
-        break;
-      }
-    }
-    if (nodeLevel_iter == nodeLevelDU.end()) {
-      ++addRemoveUnit_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
-  newStep->addActivationUnits(nodeLevelDU);    // Rolling and forModify are
-                                             // symetric, add the node level DU
-  newStep->addActivationUnits(
-      suLevelDU);  // Rolling and forModify are symetric, Add the SU level DU
-  newStep->addActivationUnits(
-      tmpDU);  // Rolling and forModify are symetric, Add the comp level DU
-
-  // Copy the forAddRemove AU/DU(except the optimized nodes) into the lists as
-  // is. They must be run as specified in the campaign.
+  // Compile all the optimized symmetric DU lists on Node, SU, Comp levels
+  // into one single merged symmetric DU list
+  //
+  // Copy nodeLevelDU list first, then append suLevelDU and tmpDU lists in turn
+  std::list<unitNameAndState> allSymmetricDU(nodeLevelDU);
+  allSymmetricDU.splice(allSymmetricDU.end(), suLevelDU);
+  allSymmetricDU.splice(allSymmetricDU.end(), tmpDU);  // tmpDU is compLevelDU
+
+  // The following loop removes any duplicate between the forAddRemoveDU/AU
+  // lists and the merged symmetric DU list (forModify/Rolling procedures).
+  // This is to avoid campaign failure due to repeating an admin operation
+  // twice on the same DU/AU object
+  std::list<unitNameAndState>::size_type init_list_size;
+  for (auto &symmetric_du : allSymmetricDU) {
+    // Remove any duplicate from forAddRemoveDU list
+    init_list_size = forAddRemoveDU.size();
+    forAddRemoveDU.remove(symmetric_du);
+    if (forAddRemoveDU.size() < init_list_size)
+      LOG_NO("[%s] is already presented in the merged symmetric DU list, "
+             "remove it from forAddRemoveDU list", symmetric_du.name.c_str());
+
+    // Remove any duplicate from forAddRemoveAU list
+    init_list_size = forAddRemoveAU.size();
+    forAddRemoveAU.remove(symmetric_du);
+    if (forAddRemoveAU.size() < init_list_size)
+      LOG_NO("[%s] is already presented in the merged symmetric AU list, "
+             "remove it from forAddRemoveAU list", symmetric_du.name.c_str());
+  }  // for (auto &symmetric_du : allSymmetricDU)
+
+  // Add the final DU and AU lists after the merge->optimize->de-duplicate
+  // process to the single step of the merged procedure
+  newStep->addDeactivationUnits(allSymmetricDU);
   newStep->addDeactivationUnits(forAddRemoveDU);
+  newStep->addActivationUnits(allSymmetricDU);
   newStep->addActivationUnits(forAddRemoveAU);
 
-  // Add the merged single step to the procedure if allocated in this method
+  // Add the single step to the merged procedure if allocated in this method
   if (i_newStep == 0) {
     i_proc->addProcStep(newStep);
   }
diff --git a/src/smf/smfd/SmfUpgradeStep.h b/src/smf/smfd/SmfUpgradeStep.h
index c4fd22b..2766ace 100644
--- a/src/smf/smfd/SmfUpgradeStep.h
+++ b/src/smf/smfd/SmfUpgradeStep.h
@@ -1,6 +1,7 @@
 /*
  *
  * (C) Copyright 2009 The OpenSAF Foundation
+ * Copyright (C) 2018 Ericsson AB. All Rights Reserved.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -67,6 +68,10 @@ struct unitNameAndState {
   std::string name;
   SaAmfAdminStateT initState;
   SaAmfAdminStateT currentState;
+
+  bool operator==(const unitNameAndState& unit) const {
+    return name == unit.name;
+  }
 };
 
 /* ========================================================================
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to