-}
module Ganeti.HTools.Node
- ( Node(failN1, name, idx, t_mem, n_mem, f_mem, r_mem, t_dsk, f_dsk,
- p_mem, p_dsk, p_rem,
+ ( Node(failN1, name, idx, t_mem, n_mem, f_mem, r_mem,
+ t_dsk, f_dsk,
+ t_cpu, u_cpu,
+ p_mem, p_dsk, p_rem, p_cpu,
+ m_dsk, m_cpu,
plist, slist, offline)
, List
-- * Constructor
, setFmem
, setPri
, setSec
+ , setMdsk
+ , setMcpu
+ , addCpus
-- * Instance (re)location
, removePri
, removeSec
, x_mem :: Int -- ^ Unaccounted memory (MiB)
, t_dsk :: Double -- ^ Total disk space (MiB)
, f_dsk :: Int -- ^ Free disk space (MiB)
+ , t_cpu :: Double -- ^ Total CPU count
+ , u_cpu :: Int -- ^ Used VCPU count
, plist :: [T.Idx]-- ^ List of primary instance indices
, slist :: [T.Idx]-- ^ List of secondary instance indices
, idx :: T.Ndx -- ^ Internal index for book-keeping
, p_mem :: Double -- ^ Percent of free memory
, p_dsk :: Double -- ^ Percent of free disk
, p_rem :: Double -- ^ Percent of reserved memory
+ , p_cpu :: Double -- ^ Ratio of virtual to physical CPUs
+ , m_dsk :: Double -- ^ Minimum free disk ratio
+ , m_cpu :: Double -- ^ Max ratio of virt-to-phys CPUs
, offline :: Bool -- ^ Whether the node should not be used
-- for allocations and skipped from
-- score computations
noSecondary :: T.Ndx
noSecondary = -1
+-- | No limit value
+noLimit :: Double
+noLimit = -1
+
-- * Initialization functions
-- | Create a new node.
--
-- The index and the peers maps are empty, and will be need to be
-- update later via the 'setIdx' and 'buildPeers' functions.
-create :: String -> Double -> Int -> Int -> Double -> Int -> Bool -> Node
+create :: String -> Double -> Int -> Int -> Double
+ -> Int -> Double -> Bool -> Node
create name_init mem_t_init mem_n_init mem_f_init
- dsk_t_init dsk_f_init offline_init =
+ dsk_t_init dsk_f_init cpu_t_init offline_init =
Node
{
name = name_init,
f_mem = mem_f_init,
t_dsk = dsk_t_init,
f_dsk = dsk_f_init,
+ t_cpu = cpu_t_init,
+ u_cpu = 0,
plist = [],
slist = [],
failN1 = True,
p_mem = (fromIntegral mem_f_init) / mem_t_init,
p_dsk = (fromIntegral dsk_f_init) / dsk_t_init,
p_rem = 0,
+ p_cpu = 0,
offline = offline_init,
- x_mem = 0
+ x_mem = 0,
+ m_dsk = noLimit,
+ m_cpu = noLimit
}
-- | Changes the index.
setXmem :: Node -> Int -> Node
setXmem t val = t { x_mem = val }
+-- | Sets the max disk usage ratio
+setMdsk :: Node -> Double -> Node
+setMdsk t val = t { m_dsk = val }
+
+-- | Sets the max cpu usage ratio
+setMcpu :: Node -> Double -> Node
+setMcpu t val = t { m_cpu = val }
+
-- | Computes the maximum reserved memory for peers from a peer map.
computeMaxRes :: PeerMap.PeerMap -> PeerMap.Elem
computeMaxRes new_peers = PeerMap.maxElem new_peers
setSec :: Node -> T.Idx -> Node
setSec t idx = t { slist = idx:(slist t) }
+-- | Add primary cpus to a node
+addCpus :: Node -> Int -> Node
+addCpus t count =
+ let new_count = (u_cpu t) + count
+ in t { u_cpu = new_count, p_cpu = (fromIntegral new_count) / (t_cpu t) }
+
-- * Update functions
-- | Sets the free memory.
failHealth :: Int -> Int -> Bool
failHealth new_mem new_dsk = new_mem <= 0 || new_dsk <= 0
+-- | Given new limits, check if any of them are overtaken
+failLimits :: Node -> Double -> Double -> Bool
+failLimits t new_dsk new_cpu =
+ let l_dsk = m_dsk t
+ l_cpu = m_cpu t
+ in (l_dsk > new_dsk) || (l_cpu >= 0 && l_cpu < new_cpu)
+
-- | Removes a primary instance.
removePri :: Node -> Instance.Instance -> Node
removePri t inst =
new_mp = (fromIntegral new_mem) / (t_mem t)
new_dp = (fromIntegral new_dsk) / (t_dsk t)
new_failn1 = computeFailN1 (r_mem t) new_mem new_dsk
+ new_ucpu = (u_cpu t) - (Instance.vcpus inst)
+ new_rcpu = (fromIntegral new_ucpu) / (t_cpu t)
in t {plist = new_plist, f_mem = new_mem, f_dsk = new_dsk,
- failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp}
+ failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp,
+ u_cpu = new_ucpu, p_cpu = new_rcpu}
-- | Removes a secondary instance.
removeSec :: Node -> Instance.Instance -> Node
let iname = Instance.idx inst
new_mem = f_mem t - Instance.mem inst
new_dsk = f_dsk t - Instance.dsk inst
- new_failn1 = computeFailN1 (r_mem t) new_mem new_dsk in
- if (failHealth new_mem new_dsk) || (new_failn1 && not (failN1 t)) then
+ new_failn1 = computeFailN1 (r_mem t) new_mem new_dsk
+ new_ucpu = (u_cpu t) + (Instance.vcpus inst)
+ new_pcpu = (fromIntegral new_ucpu) / (t_cpu t)
+ new_dp = (fromIntegral new_dsk) / (t_dsk t)
+ in
+ if (failHealth new_mem new_dsk) || (new_failn1 && not (failN1 t)) ||
+ (failLimits t new_dp new_pcpu)
+ then
Nothing
else
let new_plist = iname:(plist t)
new_mp = (fromIntegral new_mem) / (t_mem t)
- new_dp = (fromIntegral new_dsk) / (t_dsk t)
in
Just t {plist = new_plist, f_mem = new_mem, f_dsk = new_dsk,
- failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp}
+ failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp,
+ u_cpu = new_ucpu, p_cpu = new_pcpu}
-- | Adds a secondary instance.
addSec :: Node -> Instance.Instance -> T.Ndx -> Maybe Node
new_peers = PeerMap.add pdx new_peem old_peers
new_rmem = max (r_mem t) new_peem
new_prem = (fromIntegral new_rmem) / (t_mem t)
- new_failn1 = computeFailN1 new_rmem old_mem new_dsk in
- if (failHealth old_mem new_dsk) || (new_failn1 && not (failN1 t)) then
- Nothing
- else
- let new_slist = iname:(slist t)
- new_dp = (fromIntegral new_dsk) / (t_dsk t)
- in
- Just t {slist = new_slist, f_dsk = new_dsk,
- peers = new_peers, failN1 = new_failn1,
- r_mem = new_rmem, p_dsk = new_dp,
- p_rem = new_prem}
+ new_failn1 = computeFailN1 new_rmem old_mem new_dsk
+ new_dp = (fromIntegral new_dsk) / (t_dsk t)
+ in if (failHealth old_mem new_dsk) || (new_failn1 && not (failN1 t)) ||
+ (failLimits t new_dp noLimit)
+ then
+ Nothing
+ else
+ let new_slist = iname:(slist t)
+ in
+ Just t {slist = new_slist, f_dsk = new_dsk,
+ peers = new_peers, failN1 = new_failn1,
+ r_mem = new_rmem, p_dsk = new_dp,
+ p_rem = new_prem}
-- * Display functions
-- | String converter for the node list functionality.
list :: Int -> Node -> String
list mname t =
- let pl = plist t
- sl = slist t
+ let pl = length $ plist t
+ sl = length $ slist t
mp = p_mem t
dp = p_dsk t
+ cp = p_cpu t
off = offline t
fn = failN1 t
tmem = t_mem t
fmem = f_mem t
imem = (truncate tmem) - nmem - xmem - fmem
in
- printf " %c %-*s %5.0f %5d %5d %5d %5d %5d %5.0f %5d %3d %3d %.5f %.5f"
+ if off
+ then printf " - %-*s %57s %3d %3d"
+ mname (name t) "" pl sl
+ else
+ printf " %c %-*s %5.0f %5d %5d %5d %5d %5d %5.0f %5d\
+ \ %4.0f %4d %3d %3d %6.4f %6.4f %5.2f"
(if off then '-' else if fn then '*' else ' ')
mname (name t) tmem nmem imem xmem fmem (r_mem t)
((t_dsk t) / 1024) ((f_dsk t) `div` 1024)
- (length pl) (length sl)
- mp dp
+ (t_cpu t) (u_cpu t)
+ pl sl mp dp cp