With the addition of the total relative reserved memory, the optimal
cluster score no longer is 0 but the fraction of a machine that in
total is unused to keep N+1 redundancy. Add a function computing this
optimal value.

Signed-off-by: Klaus Aehlig <[email protected]>
---
 src/Ganeti/HTools/Cluster.hs | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/Ganeti/HTools/Cluster.hs b/src/Ganeti/HTools/Cluster.hs
index b62a426..73a0978 100644
--- a/src/Ganeti/HTools/Cluster.hs
+++ b/src/Ganeti/HTools/Cluster.hs
@@ -76,6 +76,7 @@ module Ganeti.HTools.Cluster
   , doNextBalance
   , tryBalance
   , compCV
+  , optimalCVScore
   , compCVNodes
   , compDetailedCV
   , printStats
@@ -117,6 +118,7 @@ import qualified Ganeti.HTools.Container as Container
 import qualified Ganeti.HTools.Instance as Instance
 import qualified Ganeti.HTools.Nic as Nic
 import qualified Ganeti.HTools.Node as Node
+import qualified Ganeti.HTools.PeerMap as P
 import qualified Ganeti.HTools.Group as Group
 import Ganeti.HTools.Types
 import Ganeti.Compat
@@ -357,6 +359,12 @@ computeAllocationDelta cini cfin =
                        }
   in (rini, rfin, runa)
 
+-- | Coefficient for the total reserved memory in the cluster metric. We
+-- use a (local) constant here, as it is also used in the computation of
+-- the best possible cluster score.
+reservedMemRtotalCoeff :: Double
+reservedMemRtotalCoeff = 0.25
+
 -- | The names and weights of the individual elements in the CV list, together
 -- with their statistical accumulation function and a bit to decide whether it
 -- is a statistics for online nodes.
@@ -382,9 +390,27 @@ detailedCVInfoExt = [ ((0.5,  "free_mem_cv"), 
(getStdDevStatistics, True))
                       , (getStdDevStatistics, True))
                     , ((0.5,  "spindles_cv_forth"), (getStdDevStatistics, 
True))
                     , ((1,  "location_score"), (getSumStatistics, True))
-                    , ((0.25,  "reserved_mem_rtotal"), (getSumStatistics, 
True))
+                    , ( (reservedMemRtotalCoeff,  "reserved_mem_rtotal")
+                      , (getSumStatistics, True))
                     ]
 
+-- | Compute the lower bound of the cluster score, i.e., the sum of the minimal
+-- values for all cluster score values that are not 0 on a perfectly balanced
+-- cluster.
+optimalCVScore :: Node.List -> Double
+optimalCVScore nodelist = fromMaybe 0 $ do
+  let nodes = Container.elems nodelist
+  unless (length nodes > 1) Nothing
+  let nodeMems = map Node.tMem nodes
+      totalMem = sum nodeMems
+      totalMemOneLessNode = totalMem - maximum nodeMems
+  unless (totalMemOneLessNode > 0) Nothing
+  let totalDrbdMem = fromIntegral . sum $ map (P.sumElems . Node.peers) nodes
+      optimalUsage = totalDrbdMem / totalMem
+      optimalUsageOneLessNode = totalDrbdMem / totalMemOneLessNode
+      relativeReserved = optimalUsageOneLessNode - optimalUsage
+  return $ reservedMemRtotalCoeff * relativeReserved
+
 -- | The names and weights of the individual elements in the CV list.
 detailedCVInfo :: [(Double, String)]
 detailedCVInfo = map fst detailedCVInfoExt
-- 
2.2.0.rc0.207.ga3a616c

Reply via email to