diff --git a/Ganeti/HTools/Cluster.hs b/Ganeti/HTools/Cluster.hs
index d3aec7ca22eaa357b4526b9786d08168d8f3bb3a..eb5e95b8af3aad9fc300a53c5b5546b5d6e0ed78 100644
--- a/Ganeti/HTools/Cluster.hs
+++ b/Ganeti/HTools/Cluster.hs
@@ -36,6 +36,7 @@ module Ganeti.HTools.Cluster
     , Removal
     , Score
     , IMove(..)
+    , CStats(..)
     -- * Generic functions
     , totalResources
     -- * First phase functions
@@ -102,6 +103,16 @@ data IMove = Failover                -- ^ Failover the instance (f)
 data Table = Table Node.List Instance.List Score [Placement]
              deriving (Show)
 
+data CStats = CStats { cs_fmem :: Int -- ^ Cluster free mem
+                     , cs_fdsk :: Int -- ^ Cluster free disk
+                     , cs_amem :: Int -- ^ Cluster allocatable mem
+                     , cs_adsk :: Int -- ^ Cluster allocatable disk
+                     , cs_acpu :: Int -- ^ Cluster allocatable cpus
+                     , cs_mmem :: Int -- ^ Max node allocatable mem
+                     , cs_mdsk :: Int -- ^ Max node allocatable disk
+                     , cs_mcpu :: Int -- ^ Max node allocatable cpu
+                     }
+
 -- * Utility functions
 
 -- | Returns the delta of a solution or -1 for Nothing.
@@ -143,19 +154,38 @@ computeBadItems nl il =
   in
     (bad_nodes, bad_instances)
 
+emptyCStats :: CStats
+emptyCStats = CStats { cs_fmem = 0
+                     , cs_fdsk = 0
+                     , cs_amem = 0
+                     , cs_adsk = 0
+                     , cs_acpu = 0
+                     , cs_mmem = 0
+                     , cs_mdsk = 0
+                     , cs_mcpu = 0
+                     }
+
+updateCStats :: CStats -> Node.Node -> CStats
+updateCStats cs node =
+    let CStats { cs_fmem = x_fmem, cs_fdsk = x_fdsk,
+                 cs_amem = x_amem, cs_acpu = x_acpu, cs_adsk = x_adsk,
+                 cs_mmem = x_mmem, cs_mdsk = x_mdsk, cs_mcpu = x_mcpu }
+            = cs
+        inc_amem = (Node.f_mem node) - (Node.r_mem node)
+        inc_amem' = if inc_amem > 0 then inc_amem else 0
+    in CStats { cs_fmem = x_fmem + (Node.f_mem node)
+              , cs_fdsk = x_fdsk + (Node.f_dsk node)
+              , cs_amem = x_amem + inc_amem'
+              , cs_adsk = x_adsk
+              , cs_acpu = x_acpu
+              , cs_mmem = max x_mmem inc_amem'
+              , cs_mdsk = max x_mdsk (Node.f_dsk node)
+              , cs_mcpu = x_mcpu
+              }
+
 -- | Compute the total free disk and memory in the cluster.
-totalResources :: Node.List -> (Int, Int, Int, Int, Int)
-totalResources nl =
-    foldl'
-    (\ (mem, dsk, amem, mmem, mdsk) node ->
-         let inc_amem = (Node.f_mem node) - (Node.r_mem node)
-         in (mem + (Node.f_mem node),
-             dsk + (Node.f_dsk node),
-             amem + (if inc_amem > 0 then inc_amem else 0),
-             max mmem inc_amem,
-             max mdsk (Node.f_dsk node)
-            )
-    ) (0, 0, 0, 0, 0) (Container.elems nl)
+totalResources :: Node.List -> CStats
+totalResources = foldl' updateCStats emptyCStats . Container.elems
 
 -- | Compute the mem and disk covariance.
 compDetailedCV :: Node.List -> (Double, Double, Double, Double, Double, Double)
diff --git a/hbal.hs b/hbal.hs
index 65fca7950d1271b150c92da2662c4a8cd5b851cd..e299607ea1a10a3976d4aad2dbde74f47a17b7e8 100644
--- a/hbal.hs
+++ b/hbal.hs
@@ -317,14 +317,16 @@ main = do
 
   when (optShowNodes opts) $
        do
-         let (orig_mem, orig_disk, _, _, _) = Cluster.totalResources nl
-             (final_mem, final_disk, _, _, _) = Cluster.totalResources fin_nl
+         let ini_cs = Cluster.totalResources nl
+             fin_cs = Cluster.totalResources fin_nl
          putStrLn ""
          putStrLn "Final cluster status:"
          putStrLn $ Cluster.printNodes fin_nl
          when (verbose > 3) $
               do
-                printf "Original: mem=%d disk=%d\n" orig_mem orig_disk
-                printf "Final:    mem=%d disk=%d\n" final_mem final_disk
+                printf "Original: mem=%d disk=%d\n"
+                       (Cluster.cs_fmem ini_cs) (Cluster.cs_fdsk ini_cs)
+                printf "Final:    mem=%d disk=%d\n"
+                       (Cluster.cs_fmem fin_cs) (Cluster.cs_fdsk fin_cs)
   when oneline $
          putStrLn $ formatOneline ini_cv (length ord_plc) fin_cv
diff --git a/hn1.hs b/hn1.hs
index 0549ddc1b7fab95b725e18507400f7b1a79d46f3..dac2b76e0dcfa9a7c3a56b63af512cbb8ec53d32 100644
--- a/hn1.hs
+++ b/hn1.hs
@@ -228,10 +228,12 @@ main = do
 
   when (optShowNodes opts) $
        do
-         let (orig_mem, orig_disk,  _, _, _) = Cluster.totalResources nl
-             (final_mem, final_disk, _, _, _) = Cluster.totalResources ns
+         let ini_cs = Cluster.totalResources nl
+             fin_cs = Cluster.totalResources ns
          putStrLn ""
          putStrLn "Final cluster status:"
          putStrLn $ Cluster.printNodes ns
-         printf "Original: mem=%d disk=%d\n" orig_mem orig_disk
-         printf "Final:    mem=%d disk=%d\n" final_mem final_disk
+         printf "Original: mem=%d disk=%d\n"
+                    (Cluster.cs_fmem ini_cs) (Cluster.cs_fdsk ini_cs)
+         printf "Final:    mem=%d disk=%d\n"
+                    (Cluster.cs_fmem fin_cs) (Cluster.cs_fdsk fin_cs)
diff --git a/hspace.hs b/hspace.hs
index 8cd4e14c05295a5ca3f22aa6fb680289c5dfd031..ed0255e965490266b99d8e57e08d521ac449f49a 100644
--- a/hspace.hs
+++ b/hspace.hs
@@ -187,13 +187,13 @@ iterateDepth nl il newinst nreq ixes =
                                         fromJust sols''
                      in iterateDepth xnl il newinst nreq (xi:ixes)
 
-printStats :: String -> (Int, Int, Int, Int, Int) -> IO ()
-printStats kind (mem, dsk, amem, mmem, mdsk) = do
-  printf "%s free RAM: %d\n" kind mem
-  printf "%s allocatable RAM: %d\n" kind amem
-  printf "%s free disk: %d\n" kind dsk
-  printf "%s max node allocatable RAM: %d\n" kind mmem
-  printf "%s max node allocatable disk: %d\n" kind mdsk
+printStats :: String -> Cluster.CStats -> IO ()
+printStats kind cs = do
+  printf "%s free RAM: %d\n" kind (Cluster.cs_fmem cs)
+  printf "%s allocatable RAM: %d\n" kind (Cluster.cs_amem cs)
+  printf "%s free disk: %d\n" kind (Cluster.cs_fdsk cs)
+  printf "%s max node allocatable RAM: %d\n" kind (Cluster.cs_mmem cs)
+  printf "%s max node allocatable disk: %d\n" kind (Cluster.cs_mdsk cs)
 
 -- | Main function.
 main :: IO ()