diff --git a/Ganeti/HTools/Cluster.hs b/Ganeti/HTools/Cluster.hs
index c9454893c519497c31dd7b637ec54db1c45ed950..694e99703e0fcf156ff113e62c3d9196b63b6fad 100644
--- a/Ganeti/HTools/Cluster.hs
+++ b/Ganeti/HTools/Cluster.hs
@@ -32,8 +32,10 @@ module Ganeti.HTools.Cluster
       AllocSolution
     , Table(..)
     , CStats(..)
+    , AllocStats
     -- * Generic functions
     , totalResources
+    , computeAllocationDelta
     -- * First phase functions
     , computeBadItems
     -- * Second phase functions
@@ -103,6 +105,9 @@ data CStats = CStats { csFmem :: Int    -- ^ Cluster free mem
                      , csNinst :: Int   -- ^ The total number of instances
                      }
 
+-- | Currently used, possibly to allocate, unallocable
+type AllocStats = (RSpec, RSpec, RSpec)
+
 -- * Utility functions
 
 -- | Verifies the N+1 status and return the affected nodes.
@@ -179,6 +184,23 @@ totalResources nl =
     let cs = foldl' updateCStats emptyCStats . Container.elems $ nl
     in cs { csScore = compCV nl }
 
+-- | Compute the delta between two cluster state.
+--
+-- This is used when doing allocations, to understand better the
+-- available cluster resources.
+computeAllocationDelta :: CStats -> CStats -> AllocStats
+computeAllocationDelta cini cfin =
+    let CStats {csImem = i_imem, csIdsk = i_idsk, csIcpu = i_icpu} = cini
+        CStats {csImem = f_imem, csIdsk = f_idsk, csIcpu = f_icpu,
+                csTmem = t_mem, csTdsk = t_dsk, csVcpu = v_cpu } = cfin
+        rini = RSpec i_icpu i_imem i_idsk
+        rfin = RSpec f_icpu f_imem f_idsk
+        un_cpu = if v_cpu == Node.noLimitInt
+                 then Node.noLimitInt
+                 else v_cpu - f_icpu
+        runa = RSpec un_cpu (truncate t_mem - f_imem) (truncate t_dsk - f_idsk)
+    in (rini, rfin, runa)
+
 -- | The names of the individual elements in the CV list
 detailedCVNames :: [String]
 detailedCVNames = [ "free_mem_cv"