On Wed, Jul 29, 2015 at 06:06:28PM +0200, 'Klaus Aehlig' via ganeti-devel wrote:
It is perfectly sufficient to wait for new load data to
be collected on the new node for a just moved instance before
continuing with any further balancing operations (the data
will stabilize eventually). However, for quick moves, e.g.,
when evacuating a drained move, such delay can be annoying.
Therefore, also accept pre-migration load data for the instance
which can be found on other nodes; this is justified, as the
monitoring daemons will clean up old load data in a timely
fashion and most likely an instance will continue what it
was doing after a move.

Signed-off-by: Klaus Aehlig <[email protected]>
---
src/Ganeti/MaintD/Balance.hs | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/src/Ganeti/MaintD/Balance.hs b/src/Ganeti/MaintD/Balance.hs
index ce3a477..9c88ef4 100644
--- a/src/Ganeti/MaintD/Balance.hs
+++ b/src/Ganeti/MaintD/Balance.hs
@@ -44,6 +44,7 @@ import Control.Monad (liftM)
import Control.Monad.IO.Class (liftIO)
import qualified Data.Set as Set
import qualified Data.Map as Map
+import Data.Maybe (mapMaybe)
import qualified Data.Traversable as Traversable
import System.IO.Error (tryIOError)
import Text.Printf (printf)
@@ -124,8 +125,16 @@ getXenInstances = do
      getXen _ = []
  return $ Set.fromList (answer >>= getXen)

+-- | Look for an instance in a given report.
+findInstanceLoad :: String -> AllReports -> Maybe Double
+findInstanceLoad  name r | MonD.InstanceCpuReport m <- rIndividual r =
+  Map.lookup name m
+findInstanceLoad _ _ = Nothing
+
-- | Update the CPU load of one instance based on the reports.
--- Fail if instance CPU load is not (yet) available.
+-- Fail if instance CPU load is not (yet) available. However, do
+-- accpet missing load data for instances on offline nodes, as well
+-- as old load data for recently migrated instances.
updateCPUInstance :: Node.List
                  -> Container.Container AllReports
                  -> Set.Set String
@@ -135,13 +144,17 @@ updateCPUInstance nl reports xeninsts inst =
  let name = Instance.name inst
      nidx = Instance.pNode inst
  in if name `Set.member` xeninsts
-    then let rep = rIndividual $ Container.find nidx reports
-         in case rep of MonD.InstanceCpuReport m | Map.member name m ->
-                          return $ inst { Instance.util = zeroUtil {
-                                             cpuWeight = m Map.! name } }
-                        _ | Node.offline $ Container.find nidx nl ->
-                          return $ inst { Instance.util = zeroUtil }
-                        _ -> fail $ "Xen CPU data unavailable for " ++ name
+    then let onNodeLoad = findInstanceLoad name (Container.find nidx reports)
+             allLoads = mapMaybe (findInstanceLoad name)
+                          $ Container.elems reports
+         in case () of
+           _ | Just load <- onNodeLoad ->
+                 return $ inst { Instance.util = zeroUtil { cpuWeight = load } 
}
+           _ | (load:_) <- allLoads ->
+                 return $ inst { Instance.util = zeroUtil { cpuWeight = load } 
}
+           _ | Node.offline $ Container.find nidx nl ->
+                 return $ inst { Instance.util = zeroUtil }
+           _ -> fail $ "Xen CPU data unavailable for " ++ name
    else let rep = rTotal $ Container.find nidx reports
         in case rep of MonD.CPUavgloadReport (CPUavgload _ _ ndload) ->
                          let w = ndload * fromIntegral (Instance.vcpus inst)
--
2.5.0.rc2.392.g76e840b


LGTM

Reply via email to