Also support obtaining memory data in the mond backend of the htools,
by using the output provided by the kvm RSS data collector.

Signed-off-by: Klaus Aehlig <[email protected]>
---
 src/Ganeti/HTools/Backend/MonD.hs | 61 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/Ganeti/HTools/Backend/MonD.hs 
b/src/Ganeti/HTools/Backend/MonD.hs
index ad7e490..ea1a31c 100644
--- a/src/Ganeti/HTools/Backend/MonD.hs
+++ b/src/Ganeti/HTools/Backend/MonD.hs
@@ -48,6 +48,7 @@ module Ganeti.HTools.Backend.MonD
   , mkReport
   , totalCPUCollector
   , xenCPUCollector
+  , kvmRSSCollector
   ) where
 
 import Control.Monad
@@ -63,8 +64,9 @@ import qualified Text.JSON as J
 import Ganeti.BasicTypes
 import qualified Ganeti.Constants as C
 import Ganeti.Cpu.Types
-import qualified Ganeti.DataCollectors.XenCpuLoad as XenCpuLoad
 import qualified Ganeti.DataCollectors.CPUload as CPUload
+import qualified Ganeti.DataCollectors.KvmRSS as KvmRSS
+import qualified Ganeti.DataCollectors.XenCpuLoad as XenCpuLoad
 import Ganeti.DataCollectors.Types ( DCReport, DCCategory
                                    , dcReportData, dcReportName
                                    , getCategoryName )
@@ -83,6 +85,7 @@ import Ganeti.Utils (exitIfBad)
 -- | The actual data types for MonD's Data Collectors.
 data Report = CPUavgloadReport CPUavgload
             | InstanceCpuReport (Map.Map String Double)
+            | InstanceRSSReport (Map.Map String Double)
 
 -- | Type describing a data collector basic information.
 data DataCollector = DataCollector
@@ -195,14 +198,66 @@ xenCPUCollector = DataCollector { dName = 
XenCpuLoad.dcName
                                 , dUse = useInstanceCpuData
                                 }
 
+-- * kvm instance RSS collector
+
+-- | Parse results of the kvm instance RSS data Collector
+mkKvmRSSReport :: DCReport -> Maybe Report
+mkKvmRSSReport =
+  liftM InstanceRSSReport . maybeParseMap . dcReportData
+
+-- | Update cluster data based on per-instance RSS data.
+-- Also set the node's memoy util pool correctly. Our unit
+-- of memory usage is pages; there are 256 pages per MiB
+-- of node memory not used by the node itself.
+useInstanceRSSData :: [(Node.Node, Report)]
+                   -> (Node.List, Instance.List)
+                   -> Result (Node.List, Instance.List)
+useInstanceRSSData reports (nl, il) = do
+  let toMap (InstanceRSSReport m) = Just m
+      toMap _                     = Nothing
+  let usage = Map.unions $ mapMaybe (toMap . snd) reports
+      missingData = (Set.fromList . map Instance.name $ IntMap.elems il)
+                    Set.\\ Map.keysSet usage
+  unless (Set.null missingData)
+    . Bad . (++) "No RSS information available for "
+    . show $ Set.elems missingData
+  let updateInstance inst =
+        let mem = Map.lookup (Instance.name inst) usage
+            dynU = Instance.util inst
+            dynU' = maybe dynU (\m -> dynU { memWeight = m }) mem
+        in inst { Instance.util = dynU' }
+  let il' = IntMap.map updateInstance il
+  let updateNode node =
+        let mem = sum
+                  . map (\ idx -> maybe 0 (memWeight . Instance.util)
+                                  $ IntMap.lookup idx il')
+                  $ Node.pList node
+            dynU = Node.utilLoad node
+            dynU' = dynU { memWeight = mem }
+            pool = Node.utilPool node
+            nodePages = (Node.tMem node - fromIntegral (Node.nMem node)) * 
256.0
+            pool' = pool { memWeight = nodePages }
+        in node { Node.utilLoad = dynU', Node.utilPool = pool' }
+  let nl' = IntMap.map updateNode nl
+  return (nl', il')
+
+-- | Update cluster data based on the per-instance CPU usage
+kvmRSSCollector :: DataCollector
+kvmRSSCollector = DataCollector { dName = KvmRSS.dcName
+                                , dCategory = KvmRSS.dcCategory
+                                , dMkReport = mkKvmRSSReport
+                                , dUse = useInstanceRSSData
+                                }
+
 -- * Collector choice
 
 -- | The list of Data Collectors used by hail and hbal.
 collectors :: Options -> [DataCollector]
 collectors opts
   | optIgnoreDynu opts = []
-  | optMonDXen opts = [ xenCPUCollector ]
-  | otherwise = [ totalCPUCollector ]
+  | otherwise =
+      (if optMonDXen opts then [ xenCPUCollector ] else [ totalCPUCollector ] )
+      ++ [ kvmRSSCollector | optMonDKvmRSS opts ]
 
 -- * Querying infrastructure
 
-- 
2.6.0.rc2.230.g3dd15c0

Reply via email to