Revision 2060348b
b/Ganeti/HTools/Cluster.hs | ||
---|---|---|
120 | 120 |
let bad_nodes = verifyN1 $ getOnline nl |
121 | 121 |
bad_instances = map (\idx -> Container.find idx il) . |
122 | 122 |
sort . nub $ |
123 |
concatMap (\ n -> Node.slist n ++ Node.plist n) bad_nodes
|
|
123 |
concatMap (\ n -> Node.sList n ++ Node.pList n) bad_nodes
|
|
124 | 124 |
in |
125 | 125 |
(bad_nodes, bad_instances) |
126 | 126 |
|
... | ... | |
155 | 155 |
cs_xmem = x_xmem, cs_nmem = x_nmem, cs_ninst = x_ninst |
156 | 156 |
} |
157 | 157 |
= cs |
158 |
inc_amem = Node.f_mem node - Node.r_mem node
|
|
158 |
inc_amem = Node.fMem node - Node.rMem node
|
|
159 | 159 |
inc_amem' = if inc_amem > 0 then inc_amem else 0 |
160 | 160 |
inc_adsk = Node.availDisk node |
161 |
inc_imem = truncate (Node.t_mem node) - Node.n_mem node
|
|
162 |
- Node.x_mem node - Node.f_mem node
|
|
163 |
inc_icpu = Node.u_cpu node
|
|
164 |
inc_idsk = truncate (Node.t_dsk node) - Node.f_dsk node
|
|
161 |
inc_imem = truncate (Node.tMem node) - Node.nMem node
|
|
162 |
- Node.xMem node - Node.fMem node
|
|
163 |
inc_icpu = Node.uCpu node
|
|
164 |
inc_idsk = truncate (Node.tDsk node) - Node.fDsk node
|
|
165 | 165 |
|
166 |
in cs { cs_fmem = x_fmem + Node.f_mem node
|
|
167 |
, cs_fdsk = x_fdsk + Node.f_dsk node
|
|
166 |
in cs { cs_fmem = x_fmem + Node.fMem node
|
|
167 |
, cs_fdsk = x_fdsk + Node.fDsk node
|
|
168 | 168 |
, cs_amem = x_amem + inc_amem' |
169 | 169 |
, cs_adsk = x_adsk + inc_adsk |
170 | 170 |
, cs_acpu = x_acpu |
... | ... | |
174 | 174 |
, cs_imem = x_imem + inc_imem |
175 | 175 |
, cs_idsk = x_idsk + inc_idsk |
176 | 176 |
, cs_icpu = x_icpu + inc_icpu |
177 |
, cs_tmem = x_tmem + Node.t_mem node
|
|
178 |
, cs_tdsk = x_tdsk + Node.t_dsk node
|
|
179 |
, cs_tcpu = x_tcpu + Node.t_cpu node
|
|
180 |
, cs_xmem = x_xmem + Node.x_mem node
|
|
181 |
, cs_nmem = x_nmem + Node.n_mem node
|
|
182 |
, cs_ninst = x_ninst + length (Node.plist node)
|
|
177 |
, cs_tmem = x_tmem + Node.tMem node
|
|
178 |
, cs_tdsk = x_tdsk + Node.tDsk node
|
|
179 |
, cs_tcpu = x_tcpu + Node.tCpu node
|
|
180 |
, cs_xmem = x_xmem + Node.xMem node
|
|
181 |
, cs_nmem = x_nmem + Node.nMem node
|
|
182 |
, cs_ninst = x_ninst + length (Node.pList node)
|
|
183 | 183 |
} |
184 | 184 |
|
185 | 185 |
-- | Compute the total free disk and memory in the cluster. |
... | ... | |
204 | 204 |
let |
205 | 205 |
all_nodes = Container.elems nl |
206 | 206 |
(offline, nodes) = partition Node.offline all_nodes |
207 |
mem_l = map Node.p_mem nodes
|
|
208 |
dsk_l = map Node.p_dsk nodes
|
|
207 |
mem_l = map Node.pMem nodes
|
|
208 |
dsk_l = map Node.pDsk nodes
|
|
209 | 209 |
mem_cv = varianceCoeff mem_l |
210 | 210 |
dsk_cv = varianceCoeff dsk_l |
211 | 211 |
n1_l = length $ filter Node.failN1 nodes |
212 | 212 |
n1_score = fromIntegral n1_l / |
213 | 213 |
fromIntegral (length nodes)::Double |
214 |
res_l = map Node.p_rem nodes
|
|
214 |
res_l = map Node.pRem nodes
|
|
215 | 215 |
res_cv = varianceCoeff res_l |
216 |
offline_inst = sum . map (\n -> (length . Node.plist $ n) +
|
|
217 |
(length . Node.slist $ n)) $ offline
|
|
218 |
online_inst = sum . map (\n -> (length . Node.plist $ n) +
|
|
219 |
(length . Node.slist $ n)) $ nodes
|
|
216 |
offline_inst = sum . map (\n -> (length . Node.pList $ n) +
|
|
217 |
(length . Node.sList $ n)) $ offline
|
|
218 |
online_inst = sum . map (\n -> (length . Node.pList $ n) +
|
|
219 |
(length . Node.sList $ n)) $ nodes
|
|
220 | 220 |
off_score = if offline_inst == 0 |
221 | 221 |
then 0::Double |
222 | 222 |
else fromIntegral offline_inst / |
223 | 223 |
fromIntegral (offline_inst + online_inst)::Double |
224 |
cpu_l = map Node.p_cpu nodes
|
|
224 |
cpu_l = map Node.pCpu nodes
|
|
225 | 225 |
cpu_cv = varianceCoeff cpu_l |
226 | 226 |
in [mem_cv, dsk_cv, n1_score, res_cv, off_score, cpu_cv] |
227 | 227 |
|
... | ... | |
245 | 245 |
-> IMove -> OpResult (Node.List, Instance.Instance, Ndx, Ndx) |
246 | 246 |
-- Failover (f) |
247 | 247 |
applyMove nl inst Failover = |
248 |
let old_pdx = Instance.pnode inst
|
|
249 |
old_sdx = Instance.snode inst
|
|
248 |
let old_pdx = Instance.pNode inst
|
|
249 |
old_sdx = Instance.sNode inst
|
|
250 | 250 |
old_p = Container.find old_pdx nl |
251 | 251 |
old_s = Container.find old_sdx nl |
252 | 252 |
int_p = Node.removePri old_p inst |
... | ... | |
261 | 261 |
|
262 | 262 |
-- Replace the primary (f:, r:np, f) |
263 | 263 |
applyMove nl inst (ReplacePrimary new_pdx) = |
264 |
let old_pdx = Instance.pnode inst
|
|
265 |
old_sdx = Instance.snode inst
|
|
264 |
let old_pdx = Instance.pNode inst
|
|
265 |
old_sdx = Instance.sNode inst
|
|
266 | 266 |
old_p = Container.find old_pdx nl |
267 | 267 |
old_s = Container.find old_sdx nl |
268 | 268 |
tgt_n = Container.find new_pdx nl |
... | ... | |
283 | 283 |
|
284 | 284 |
-- Replace the secondary (r:ns) |
285 | 285 |
applyMove nl inst (ReplaceSecondary new_sdx) = |
286 |
let old_pdx = Instance.pnode inst
|
|
287 |
old_sdx = Instance.snode inst
|
|
286 |
let old_pdx = Instance.pNode inst
|
|
287 |
old_sdx = Instance.sNode inst
|
|
288 | 288 |
old_s = Container.find old_sdx nl |
289 | 289 |
tgt_n = Container.find new_sdx nl |
290 | 290 |
int_s = Node.removeSec old_s inst |
... | ... | |
297 | 297 |
|
298 | 298 |
-- Replace the secondary and failover (r:np, f) |
299 | 299 |
applyMove nl inst (ReplaceAndFailover new_pdx) = |
300 |
let old_pdx = Instance.pnode inst
|
|
301 |
old_sdx = Instance.snode inst
|
|
300 |
let old_pdx = Instance.pNode inst
|
|
301 |
old_sdx = Instance.sNode inst
|
|
302 | 302 |
old_p = Container.find old_pdx nl |
303 | 303 |
old_s = Container.find old_sdx nl |
304 | 304 |
tgt_n = Container.find new_pdx nl |
... | ... | |
315 | 315 |
|
316 | 316 |
-- Failver and replace the secondary (f, r:ns) |
317 | 317 |
applyMove nl inst (FailoverAndReplace new_sdx) = |
318 |
let old_pdx = Instance.pnode inst
|
|
319 |
old_sdx = Instance.snode inst
|
|
318 |
let old_pdx = Instance.pNode inst
|
|
319 |
old_sdx = Instance.sNode inst
|
|
320 | 320 |
old_p = Container.find old_pdx nl |
321 | 321 |
old_s = Container.find old_sdx nl |
322 | 322 |
tgt_n = Container.find new_sdx nl |
... | ... | |
402 | 402 |
-> Table -- ^ Best new table for this instance |
403 | 403 |
checkInstanceMove nodes_idx disk_moves ini_tbl target = |
404 | 404 |
let |
405 |
opdx = Instance.pnode target
|
|
406 |
osdx = Instance.snode target
|
|
405 |
opdx = Instance.pNode target
|
|
406 |
osdx = Instance.sNode target
|
|
407 | 407 |
nodes = filter (\idx -> idx /= opdx && idx /= osdx) nodes_idx |
408 | 408 |
use_secondary = elem osdx nodes_idx |
409 | 409 |
aft_failover = if use_secondary -- if allowed to failover |
... | ... | |
428 | 428 |
best_tbl = |
429 | 429 |
foldl' |
430 | 430 |
(\ step_tbl em -> |
431 |
if Instance.snode em == Node.noSecondary then step_tbl
|
|
431 |
if Instance.sNode em == Node.noSecondary then step_tbl
|
|
432 | 432 |
else compareTables step_tbl $ |
433 | 433 |
checkInstanceMove nodes_idx disk_moves ini_tbl em) |
434 | 434 |
ini_tbl victims |
... | ... | |
531 | 531 |
tryReloc nl il xid 1 ex_idx = |
532 | 532 |
let all_nodes = getOnline nl |
533 | 533 |
inst = Container.find xid il |
534 |
ex_idx' = Instance.pnode inst:ex_idx
|
|
534 |
ex_idx' = Instance.pNode inst:ex_idx
|
|
535 | 535 |
valid_nodes = filter (not . flip elem ex_idx' . Node.idx) all_nodes |
536 | 536 |
valid_idxes = map Node.idx valid_nodes |
537 | 537 |
sols1 = foldl' (\cstate x -> |
... | ... | |
603 | 603 |
inam = Instance.name inst |
604 | 604 |
npri = Container.nameOf nl p |
605 | 605 |
nsec = Container.nameOf nl s |
606 |
opri = Container.nameOf nl $ Instance.pnode inst
|
|
607 |
osec = Container.nameOf nl $ Instance.snode inst
|
|
606 |
opri = Container.nameOf nl $ Instance.pNode inst
|
|
607 |
osec = Container.nameOf nl $ Instance.sNode inst
|
|
608 | 608 |
(moves, cmds) = computeMoves inst inam opri osec npri nsec |
609 | 609 |
ostr = printf "%s:%s" opri osec::String |
610 | 610 |
nstr = printf "%s:%s" npri nsec::String |
... | ... | |
619 | 619 |
involvedNodes il plc = |
620 | 620 |
let (i, np, ns, _, _) = plc |
621 | 621 |
inst = Container.find i il |
622 |
op = Instance.pnode inst
|
|
623 |
os = Instance.snode inst
|
|
622 |
op = Instance.pNode inst
|
|
623 |
os = Instance.sNode inst
|
|
624 | 624 |
in nub [np, ns, op, os] |
625 | 625 |
|
626 | 626 |
-- | Inner function for splitJobs, that either appends the next job to |
b/Ganeti/HTools/Instance.hs | ||
---|---|---|
40 | 40 |
, vcpus :: Int -- ^ Number of VCPUs |
41 | 41 |
, running :: Bool -- ^ Whether the instance |
42 | 42 |
-- is running |
43 |
, run_st :: String -- ^ Original (text) run status
|
|
44 |
, pnode :: T.Ndx -- ^ Original primary node
|
|
45 |
, snode :: T.Ndx -- ^ Original secondary node
|
|
43 |
, runSt :: String -- ^ Original (text) run status
|
|
44 |
, pNode :: T.Ndx -- ^ Original primary node
|
|
45 |
, sNode :: T.Ndx -- ^ Original secondary node
|
|
46 | 46 |
, idx :: T.Idx -- ^ Internal index for |
47 | 47 |
-- book-keeping |
48 | 48 |
} deriving (Show) |
... | ... | |
76 | 76 |
"running" -> True |
77 | 77 |
"ERROR_up" -> True |
78 | 78 |
_ -> False, |
79 |
run_st = run_init,
|
|
80 |
pnode = pn,
|
|
81 |
snode = sn,
|
|
79 |
runSt = run_init,
|
|
80 |
pNode = pn,
|
|
81 |
sNode = sn,
|
|
82 | 82 |
idx = -1 |
83 | 83 |
} |
84 | 84 |
|
... | ... | |
104 | 104 |
setPri :: Instance -- ^ the original instance |
105 | 105 |
-> T.Ndx -- ^ the new primary node |
106 | 106 |
-> Instance -- ^ the modified instance |
107 |
setPri t p = t { pnode = p }
|
|
107 |
setPri t p = t { pNode = p }
|
|
108 | 108 |
|
109 | 109 |
-- | Changes the secondary node of the instance. |
110 | 110 |
setSec :: Instance -- ^ the original instance |
111 | 111 |
-> T.Ndx -- ^ the new secondary node |
112 | 112 |
-> Instance -- ^ the modified instance |
113 |
setSec t s = t { snode = s }
|
|
113 |
setSec t s = t { sNode = s }
|
|
114 | 114 |
|
115 | 115 |
-- | Changes both nodes of the instance. |
116 | 116 |
setBoth :: Instance -- ^ the original instance |
117 | 117 |
-> T.Ndx -- ^ new primary node index |
118 | 118 |
-> T.Ndx -- ^ new secondary node index |
119 | 119 |
-> Instance -- ^ the modified instance |
120 |
setBoth t p s = t { pnode = p, snode = s } |
|
120 |
setBoth t p s = t { pNode = p, sNode = s } |
b/Ganeti/HTools/Loader.hs | ||
---|---|---|
100 | 100 |
-> [(Ndx, Node.Node)] |
101 | 101 |
fixNodes accu (idx, inst) = |
102 | 102 |
let |
103 |
pdx = Instance.pnode inst
|
|
104 |
sdx = Instance.snode inst
|
|
103 |
pdx = Instance.pNode inst
|
|
104 |
sdx = Instance.sNode inst
|
|
105 | 105 |
pold = fromJust $ lookup pdx accu |
106 | 106 |
pnew = Node.setPri pold idx |
107 | 107 |
pnew' = Node.addCpus pnew (Instance.vcpus inst) |
... | ... | |
156 | 156 |
Container.mapAccum |
157 | 157 |
(\ msgs node -> |
158 | 158 |
let nname = Node.name node |
159 |
nilst = map (flip Container.find il) (Node.plist node)
|
|
159 |
nilst = map (flip Container.find il) (Node.pList node)
|
|
160 | 160 |
dilst = filter (not . Instance.running) nilst |
161 | 161 |
adj_mem = sum . map Instance.mem $ dilst |
162 |
delta_mem = truncate (Node.t_mem node)
|
|
163 |
- Node.n_mem node
|
|
164 |
- Node.f_mem node
|
|
162 |
delta_mem = truncate (Node.tMem node)
|
|
163 |
- Node.nMem node
|
|
164 |
- Node.fMem node
|
|
165 | 165 |
- nodeImem node il |
166 | 166 |
+ adj_mem |
167 |
delta_dsk = truncate (Node.t_dsk node)
|
|
168 |
- Node.f_dsk node
|
|
167 |
delta_dsk = truncate (Node.tDsk node)
|
|
168 |
- Node.fDsk node
|
|
169 | 169 |
- nodeIdsk node il |
170 | 170 |
newn = Node.setFmem (Node.setXmem node delta_mem) |
171 |
(Node.f_mem node - adj_mem)
|
|
171 |
(Node.fMem node - adj_mem)
|
|
172 | 172 |
umsg1 = [printf "node %s is missing %d MB ram \ |
173 | 173 |
\and %d GB disk" |
174 | 174 |
nname delta_mem (delta_dsk `div` 1024) | |
... | ... | |
181 | 181 |
nodeImem node il = |
182 | 182 |
let rfind = flip Container.find il |
183 | 183 |
in sum . map (Instance.mem . rfind) |
184 |
$ Node.plist node
|
|
184 |
$ Node.pList node
|
|
185 | 185 |
|
186 | 186 |
-- | Compute the amount of disk used by instances on a node (either primary |
187 | 187 |
-- or secondary). |
... | ... | |
189 | 189 |
nodeIdsk node il = |
190 | 190 |
let rfind = flip Container.find il |
191 | 191 |
in sum . map (Instance.dsk . rfind) |
192 |
$ Node.plist node ++ Node.slist node |
|
192 |
$ Node.pList node ++ Node.sList node |
b/Ganeti/HTools/Node.hs | ||
---|---|---|
27 | 27 |
|
28 | 28 |
module Ganeti.HTools.Node |
29 | 29 |
( Node(failN1, name, idx, |
30 |
t_mem, n_mem, f_mem, r_mem, x_mem,
|
|
31 |
t_dsk, f_dsk,
|
|
32 |
t_cpu, u_cpu,
|
|
33 |
p_mem, p_dsk, p_rem, p_cpu,
|
|
34 |
m_dsk, m_cpu, lo_dsk, hi_cpu,
|
|
35 |
plist, slist, offline)
|
|
30 |
tMem, nMem, fMem, rMem, xMem,
|
|
31 |
tDsk, fDsk,
|
|
32 |
tCpu, uCpu,
|
|
33 |
pMem, pDsk, pRem, pCpu,
|
|
34 |
mDsk, mCpu, loDsk, hiCpu,
|
|
35 |
pList, sList, offline)
|
|
36 | 36 |
, List |
37 | 37 |
-- * Constructor |
38 | 38 |
, create |
... | ... | |
75 | 75 |
|
76 | 76 |
-- | The node type. |
77 | 77 |
data Node = Node { name :: String -- ^ The node name |
78 |
, t_mem :: Double -- ^ Total memory (MiB)
|
|
79 |
, n_mem :: Int -- ^ Node memory (MiB)
|
|
80 |
, f_mem :: Int -- ^ Free memory (MiB)
|
|
81 |
, x_mem :: Int -- ^ Unaccounted memory (MiB)
|
|
82 |
, t_dsk :: Double -- ^ Total disk space (MiB)
|
|
83 |
, f_dsk :: Int -- ^ Free disk space (MiB)
|
|
84 |
, t_cpu :: Double -- ^ Total CPU count
|
|
85 |
, u_cpu :: Int -- ^ Used VCPU count
|
|
86 |
, plist :: [T.Idx]-- ^ List of primary instance indices
|
|
87 |
, slist :: [T.Idx]-- ^ List of secondary instance indices
|
|
78 |
, tMem :: Double -- ^ Total memory (MiB)
|
|
79 |
, nMem :: Int -- ^ Node memory (MiB)
|
|
80 |
, fMem :: Int -- ^ Free memory (MiB)
|
|
81 |
, xMem :: Int -- ^ Unaccounted memory (MiB)
|
|
82 |
, tDsk :: Double -- ^ Total disk space (MiB)
|
|
83 |
, fDsk :: Int -- ^ Free disk space (MiB)
|
|
84 |
, tCpu :: Double -- ^ Total CPU count
|
|
85 |
, uCpu :: Int -- ^ Used VCPU count
|
|
86 |
, pList :: [T.Idx]-- ^ List of primary instance indices
|
|
87 |
, sList :: [T.Idx]-- ^ List of secondary instance indices
|
|
88 | 88 |
, idx :: T.Ndx -- ^ Internal index for book-keeping |
89 | 89 |
, peers :: PeerMap.PeerMap -- ^ Pnode to instance mapping |
90 | 90 |
, failN1:: Bool -- ^ Whether the node has failed n1 |
91 |
, r_mem :: Int -- ^ Maximum memory needed for
|
|
91 |
, rMem :: Int -- ^ Maximum memory needed for
|
|
92 | 92 |
-- failover by primaries of this node |
93 |
, p_mem :: Double -- ^ Percent of free memory
|
|
94 |
, p_dsk :: Double -- ^ Percent of free disk
|
|
95 |
, p_rem :: Double -- ^ Percent of reserved memory
|
|
96 |
, p_cpu :: Double -- ^ Ratio of virtual to physical CPUs
|
|
97 |
, m_dsk :: Double -- ^ Minimum free disk ratio
|
|
98 |
, m_cpu :: Double -- ^ Max ratio of virt-to-phys CPUs
|
|
99 |
, lo_dsk :: Int -- ^ Autocomputed from m_dsk low disk
|
|
93 |
, pMem :: Double -- ^ Percent of free memory
|
|
94 |
, pDsk :: Double -- ^ Percent of free disk
|
|
95 |
, pRem :: Double -- ^ Percent of reserved memory
|
|
96 |
, pCpu :: Double -- ^ Ratio of virtual to physical CPUs
|
|
97 |
, mDsk :: Double -- ^ Minimum free disk ratio
|
|
98 |
, mCpu :: Double -- ^ Max ratio of virt-to-phys CPUs
|
|
99 |
, loDsk :: Int -- ^ Autocomputed from mDsk low disk
|
|
100 | 100 |
-- threshold |
101 |
, hi_cpu :: Int -- ^ Autocomputed from m_cpu high cpu
|
|
101 |
, hiCpu :: Int -- ^ Autocomputed from mCpu high cpu
|
|
102 | 102 |
-- threshold |
103 | 103 |
, offline :: Bool -- ^ Whether the node should not be used |
104 | 104 |
-- for allocations and skipped from |
... | ... | |
142 | 142 |
Node |
143 | 143 |
{ |
144 | 144 |
name = name_init, |
145 |
t_mem = mem_t_init,
|
|
146 |
n_mem = mem_n_init,
|
|
147 |
f_mem = mem_f_init,
|
|
148 |
t_dsk = dsk_t_init,
|
|
149 |
f_dsk = dsk_f_init,
|
|
150 |
t_cpu = cpu_t_init,
|
|
151 |
u_cpu = 0,
|
|
152 |
plist = [],
|
|
153 |
slist = [],
|
|
145 |
tMem = mem_t_init,
|
|
146 |
nMem = mem_n_init,
|
|
147 |
fMem = mem_f_init,
|
|
148 |
tDsk = dsk_t_init,
|
|
149 |
fDsk = dsk_f_init,
|
|
150 |
tCpu = cpu_t_init,
|
|
151 |
uCpu = 0,
|
|
152 |
pList = [],
|
|
153 |
sList = [],
|
|
154 | 154 |
failN1 = True, |
155 | 155 |
idx = -1, |
156 | 156 |
peers = PeerMap.empty, |
157 |
r_mem = 0,
|
|
158 |
p_mem = fromIntegral mem_f_init / mem_t_init,
|
|
159 |
p_dsk = fromIntegral dsk_f_init / dsk_t_init,
|
|
160 |
p_rem = 0,
|
|
161 |
p_cpu = 0,
|
|
157 |
rMem = 0,
|
|
158 |
pMem = fromIntegral mem_f_init / mem_t_init,
|
|
159 |
pDsk = fromIntegral dsk_f_init / dsk_t_init,
|
|
160 |
pRem = 0,
|
|
161 |
pCpu = 0,
|
|
162 | 162 |
offline = offline_init, |
163 |
x_mem = 0,
|
|
164 |
m_dsk = noLimit,
|
|
165 |
m_cpu = noLimit,
|
|
166 |
lo_dsk = noLimitInt,
|
|
167 |
hi_cpu = noLimitInt
|
|
163 |
xMem = 0,
|
|
164 |
mDsk = noLimit,
|
|
165 |
mCpu = noLimit,
|
|
166 |
loDsk = noLimitInt,
|
|
167 |
hiCpu = noLimitInt
|
|
168 | 168 |
} |
169 | 169 |
|
170 | 170 |
-- | Changes the index. |
... | ... | |
185 | 185 |
|
186 | 186 |
-- | Sets the unnaccounted memory. |
187 | 187 |
setXmem :: Node -> Int -> Node |
188 |
setXmem t val = t { x_mem = val }
|
|
188 |
setXmem t val = t { xMem = val }
|
|
189 | 189 |
|
190 | 190 |
-- | Sets the max disk usage ratio |
191 | 191 |
setMdsk :: Node -> Double -> Node |
192 |
setMdsk t val = t { m_dsk = val,
|
|
193 |
lo_dsk = if val == noLimit
|
|
192 |
setMdsk t val = t { mDsk = val,
|
|
193 |
loDsk = if val == noLimit
|
|
194 | 194 |
then noLimitInt |
195 |
else floor (val * t_dsk t) }
|
|
195 |
else floor (val * tDsk t) }
|
|
196 | 196 |
|
197 | 197 |
-- | Sets the max cpu usage ratio |
198 | 198 |
setMcpu :: Node -> Double -> Node |
199 |
setMcpu t val = t { m_cpu = val, hi_cpu = floor (val * t_cpu t) }
|
|
199 |
setMcpu t val = t { mCpu = val, hiCpu = floor (val * tCpu t) }
|
|
200 | 200 |
|
201 | 201 |
-- | Computes the maximum reserved memory for peers from a peer map. |
202 | 202 |
computeMaxRes :: PeerMap.PeerMap -> PeerMap.Elem |
... | ... | |
207 | 207 |
buildPeers t il = |
208 | 208 |
let mdata = map |
209 | 209 |
(\i_idx -> let inst = Container.find i_idx il |
210 |
in (Instance.pnode inst, Instance.mem inst))
|
|
211 |
(slist t)
|
|
210 |
in (Instance.pNode inst, Instance.mem inst))
|
|
211 |
(sList t)
|
|
212 | 212 |
pmap = PeerMap.accumArray (+) mdata |
213 | 213 |
new_rmem = computeMaxRes pmap |
214 |
new_failN1 = f_mem t <= new_rmem
|
|
215 |
new_prem = fromIntegral new_rmem / t_mem t
|
|
216 |
in t {peers=pmap, failN1 = new_failN1, r_mem = new_rmem, p_rem = new_prem}
|
|
214 |
new_failN1 = fMem t <= new_rmem
|
|
215 |
new_prem = fromIntegral new_rmem / tMem t
|
|
216 |
in t {peers=pmap, failN1 = new_failN1, rMem = new_rmem, pRem = new_prem}
|
|
217 | 217 |
|
218 | 218 |
-- | Assigns an instance to a node as primary without other updates. |
219 | 219 |
setPri :: Node -> T.Idx -> Node |
220 |
setPri t ix = t { plist = ix:plist t }
|
|
220 |
setPri t ix = t { pList = ix:pList t }
|
|
221 | 221 |
|
222 | 222 |
-- | Assigns an instance to a node as secondary without other updates. |
223 | 223 |
setSec :: Node -> T.Idx -> Node |
224 |
setSec t ix = t { slist = ix:slist t }
|
|
224 |
setSec t ix = t { sList = ix:sList t }
|
|
225 | 225 |
|
226 | 226 |
-- | Add primary cpus to a node |
227 | 227 |
addCpus :: Node -> Int -> Node |
228 | 228 |
addCpus t count = |
229 |
let new_count = u_cpu t + count
|
|
230 |
in t { u_cpu = new_count, p_cpu = fromIntegral new_count / t_cpu t }
|
|
229 |
let new_count = uCpu t + count
|
|
230 |
in t { uCpu = new_count, pCpu = fromIntegral new_count / tCpu t }
|
|
231 | 231 |
|
232 | 232 |
-- * Update functions |
233 | 233 |
|
234 | 234 |
-- | Sets the free memory. |
235 | 235 |
setFmem :: Node -> Int -> Node |
236 | 236 |
setFmem t new_mem = |
237 |
let new_n1 = new_mem <= r_mem t
|
|
238 |
new_mp = fromIntegral new_mem / t_mem t
|
|
237 |
let new_n1 = new_mem <= rMem t
|
|
238 |
new_mp = fromIntegral new_mem / tMem t
|
|
239 | 239 |
in |
240 |
t { f_mem = new_mem, failN1 = new_n1, p_mem = new_mp }
|
|
240 |
t { fMem = new_mem, failN1 = new_n1, pMem = new_mp }
|
|
241 | 241 |
|
242 | 242 |
-- | Removes a primary instance. |
243 | 243 |
removePri :: Node -> Instance.Instance -> Node |
244 | 244 |
removePri t inst = |
245 | 245 |
let iname = Instance.idx inst |
246 |
new_plist = delete iname (plist t)
|
|
247 |
new_mem = f_mem t + Instance.mem inst
|
|
248 |
new_dsk = f_dsk t + Instance.dsk inst
|
|
249 |
new_mp = fromIntegral new_mem / t_mem t
|
|
250 |
new_dp = fromIntegral new_dsk / t_dsk t
|
|
251 |
new_failn1 = new_mem <= r_mem t
|
|
252 |
new_ucpu = u_cpu t - Instance.vcpus inst
|
|
253 |
new_rcpu = fromIntegral new_ucpu / t_cpu t
|
|
254 |
in t {plist = new_plist, f_mem = new_mem, f_dsk = new_dsk,
|
|
255 |
failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp,
|
|
256 |
u_cpu = new_ucpu, p_cpu = new_rcpu}
|
|
246 |
new_plist = delete iname (pList t)
|
|
247 |
new_mem = fMem t + Instance.mem inst
|
|
248 |
new_dsk = fDsk t + Instance.dsk inst
|
|
249 |
new_mp = fromIntegral new_mem / tMem t
|
|
250 |
new_dp = fromIntegral new_dsk / tDsk t
|
|
251 |
new_failn1 = new_mem <= rMem t
|
|
252 |
new_ucpu = uCpu t - Instance.vcpus inst
|
|
253 |
new_rcpu = fromIntegral new_ucpu / tCpu t
|
|
254 |
in t {pList = new_plist, fMem = new_mem, fDsk = new_dsk,
|
|
255 |
failN1 = new_failn1, pMem = new_mp, pDsk = new_dp,
|
|
256 |
uCpu = new_ucpu, pCpu = new_rcpu}
|
|
257 | 257 |
|
258 | 258 |
-- | Removes a secondary instance. |
259 | 259 |
removeSec :: Node -> Instance.Instance -> Node |
260 | 260 |
removeSec t inst = |
261 | 261 |
let iname = Instance.idx inst |
262 |
pnode = Instance.pnode inst
|
|
263 |
new_slist = delete iname (slist t)
|
|
264 |
new_dsk = f_dsk t + Instance.dsk inst
|
|
262 |
pnode = Instance.pNode inst
|
|
263 |
new_slist = delete iname (sList t)
|
|
264 |
new_dsk = fDsk t + Instance.dsk inst
|
|
265 | 265 |
old_peers = peers t |
266 | 266 |
old_peem = PeerMap.find pnode old_peers |
267 | 267 |
new_peem = old_peem - Instance.mem inst |
268 | 268 |
new_peers = PeerMap.add pnode new_peem old_peers |
269 |
old_rmem = r_mem t
|
|
269 |
old_rmem = rMem t
|
|
270 | 270 |
new_rmem = if old_peem < old_rmem then |
271 | 271 |
old_rmem |
272 | 272 |
else |
273 | 273 |
computeMaxRes new_peers |
274 |
new_prem = fromIntegral new_rmem / t_mem t
|
|
275 |
new_failn1 = f_mem t <= new_rmem
|
|
276 |
new_dp = fromIntegral new_dsk / t_dsk t
|
|
277 |
in t {slist = new_slist, f_dsk = new_dsk, peers = new_peers,
|
|
278 |
failN1 = new_failn1, r_mem = new_rmem, p_dsk = new_dp,
|
|
279 |
p_rem = new_prem}
|
|
274 |
new_prem = fromIntegral new_rmem / tMem t
|
|
275 |
new_failn1 = fMem t <= new_rmem
|
|
276 |
new_dp = fromIntegral new_dsk / tDsk t
|
|
277 |
in t {sList = new_slist, fDsk = new_dsk, peers = new_peers,
|
|
278 |
failN1 = new_failn1, rMem = new_rmem, pDsk = new_dp,
|
|
279 |
pRem = new_prem}
|
|
280 | 280 |
|
281 | 281 |
-- | Adds a primary instance. |
282 | 282 |
addPri :: Node -> Instance.Instance -> T.OpResult Node |
283 | 283 |
addPri t inst = |
284 | 284 |
let iname = Instance.idx inst |
285 |
new_mem = f_mem t - Instance.mem inst
|
|
286 |
new_dsk = f_dsk t - Instance.dsk inst
|
|
287 |
new_failn1 = new_mem <= r_mem t
|
|
288 |
new_ucpu = u_cpu t + Instance.vcpus inst
|
|
289 |
new_pcpu = fromIntegral new_ucpu / t_cpu t
|
|
290 |
new_dp = fromIntegral new_dsk / t_dsk t
|
|
291 |
l_cpu = m_cpu t
|
|
285 |
new_mem = fMem t - Instance.mem inst
|
|
286 |
new_dsk = fDsk t - Instance.dsk inst
|
|
287 |
new_failn1 = new_mem <= rMem t
|
|
288 |
new_ucpu = uCpu t + Instance.vcpus inst
|
|
289 |
new_pcpu = fromIntegral new_ucpu / tCpu t
|
|
290 |
new_dp = fromIntegral new_dsk / tDsk t
|
|
291 |
l_cpu = mCpu t
|
|
292 | 292 |
in if new_mem <= 0 then T.OpFail T.FailMem |
293 |
else if new_dsk <= 0 || m_dsk t > new_dp then T.OpFail T.FailDisk
|
|
293 |
else if new_dsk <= 0 || mDsk t > new_dp then T.OpFail T.FailDisk
|
|
294 | 294 |
else if new_failn1 && not (failN1 t) then T.OpFail T.FailMem |
295 | 295 |
else if l_cpu >= 0 && l_cpu < new_pcpu then T.OpFail T.FailCPU |
296 | 296 |
else |
297 |
let new_plist = iname:plist t
|
|
298 |
new_mp = fromIntegral new_mem / t_mem t
|
|
299 |
r = t { plist = new_plist, f_mem = new_mem, f_dsk = new_dsk,
|
|
300 |
failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp,
|
|
301 |
u_cpu = new_ucpu, p_cpu = new_pcpu }
|
|
297 |
let new_plist = iname:pList t
|
|
298 |
new_mp = fromIntegral new_mem / tMem t
|
|
299 |
r = t { pList = new_plist, fMem = new_mem, fDsk = new_dsk,
|
|
300 |
failN1 = new_failn1, pMem = new_mp, pDsk = new_dp,
|
|
301 |
uCpu = new_ucpu, pCpu = new_pcpu }
|
|
302 | 302 |
in T.OpGood r |
303 | 303 |
|
304 | 304 |
-- | Adds a secondary instance. |
... | ... | |
306 | 306 |
addSec t inst pdx = |
307 | 307 |
let iname = Instance.idx inst |
308 | 308 |
old_peers = peers t |
309 |
old_mem = f_mem t
|
|
310 |
new_dsk = f_dsk t - Instance.dsk inst
|
|
309 |
old_mem = fMem t
|
|
310 |
new_dsk = fDsk t - Instance.dsk inst
|
|
311 | 311 |
new_peem = PeerMap.find pdx old_peers + Instance.mem inst |
312 | 312 |
new_peers = PeerMap.add pdx new_peem old_peers |
313 |
new_rmem = max (r_mem t) new_peem
|
|
314 |
new_prem = fromIntegral new_rmem / t_mem t
|
|
313 |
new_rmem = max (rMem t) new_peem
|
|
314 |
new_prem = fromIntegral new_rmem / tMem t
|
|
315 | 315 |
new_failn1 = old_mem <= new_rmem |
316 |
new_dp = fromIntegral new_dsk / t_dsk t
|
|
317 |
in if new_dsk <= 0 || m_dsk t > new_dp then T.OpFail T.FailDisk
|
|
316 |
new_dp = fromIntegral new_dsk / tDsk t
|
|
317 |
in if new_dsk <= 0 || mDsk t > new_dp then T.OpFail T.FailDisk
|
|
318 | 318 |
else if new_failn1 && not (failN1 t) then T.OpFail T.FailMem |
319 |
else let new_slist = iname:slist t
|
|
320 |
r = t { slist = new_slist, f_dsk = new_dsk,
|
|
319 |
else let new_slist = iname:sList t
|
|
320 |
r = t { sList = new_slist, fDsk = new_dsk,
|
|
321 | 321 |
peers = new_peers, failN1 = new_failn1, |
322 |
r_mem = new_rmem, p_dsk = new_dp,
|
|
323 |
p_rem = new_prem }
|
|
322 |
rMem = new_rmem, pDsk = new_dp,
|
|
323 |
pRem = new_prem }
|
|
324 | 324 |
in T.OpGood r |
325 | 325 |
|
326 | 326 |
-- * Stats functions |
... | ... | |
328 | 328 |
-- | Computes the amount of available disk on a given node |
329 | 329 |
availDisk :: Node -> Int |
330 | 330 |
availDisk t = |
331 |
let _f = f_dsk t
|
|
332 |
_l = lo_dsk t
|
|
331 |
let _f = fDsk t
|
|
332 |
_l = loDsk t
|
|
333 | 333 |
in |
334 | 334 |
if _l == noLimitInt |
335 | 335 |
then _f |
... | ... | |
342 | 342 |
-- | String converter for the node list functionality. |
343 | 343 |
list :: Int -> Node -> String |
344 | 344 |
list mname t = |
345 |
let pl = length $ plist t
|
|
346 |
sl = length $ slist t
|
|
347 |
mp = p_mem t
|
|
348 |
dp = p_dsk t
|
|
349 |
cp = p_cpu t
|
|
345 |
let pl = length $ pList t
|
|
346 |
sl = length $ sList t
|
|
347 |
mp = pMem t
|
|
348 |
dp = pDsk t
|
|
349 |
cp = pCpu t
|
|
350 | 350 |
off = offline t |
351 | 351 |
fn = failN1 t |
352 |
tmem = t_mem t
|
|
353 |
nmem = n_mem t
|
|
354 |
xmem = x_mem t
|
|
355 |
fmem = f_mem t
|
|
352 |
tmem = tMem t
|
|
353 |
nmem = nMem t
|
|
354 |
xmem = xMem t
|
|
355 |
fmem = fMem t
|
|
356 | 356 |
imem = truncate tmem - nmem - xmem - fmem |
357 | 357 |
in |
358 | 358 |
if off |
... | ... | |
362 | 362 |
printf " %c %-*s %5.0f %5d %5d %5d %5d %5d %5.0f %5d\ |
363 | 363 |
\ %4.0f %4d %3d %3d %6.4f %6.4f %5.2f" |
364 | 364 |
(if off then '-' else if fn then '*' else ' ') |
365 |
mname (name t) tmem nmem imem xmem fmem (r_mem t)
|
|
366 |
(t_dsk t / 1024) (f_dsk t `div` 1024)
|
|
367 |
(t_cpu t) (u_cpu t)
|
|
365 |
mname (name t) tmem nmem imem xmem fmem (rMem t)
|
|
366 |
(tDsk t / 1024) (fDsk t `div` 1024)
|
|
367 |
(tCpu t) (uCpu t)
|
|
368 | 368 |
pl sl mp dp cp |
b/Ganeti/HTools/QC.hs | ||
---|---|---|
154 | 154 |
where _types = (inst::Instance.Instance, name::String) |
155 | 155 |
|
156 | 156 |
prop_Instance_setPri inst pdx = |
157 |
Instance.pnode (Instance.setPri inst pdx) == pdx
|
|
157 |
Instance.pNode (Instance.setPri inst pdx) == pdx
|
|
158 | 158 |
where _types = (inst::Instance.Instance, pdx::Types.Ndx) |
159 | 159 |
|
160 | 160 |
prop_Instance_setSec inst sdx = |
161 |
Instance.snode (Instance.setSec inst sdx) == sdx
|
|
161 |
Instance.sNode (Instance.setSec inst sdx) == sdx
|
|
162 | 162 |
where _types = (inst::Instance.Instance, sdx::Types.Ndx) |
163 | 163 |
|
164 | 164 |
prop_Instance_setBoth inst pdx sdx = |
165 |
Instance.pnode si == pdx && Instance.snode si == sdx
|
|
165 |
Instance.pNode si == pdx && Instance.sNode si == sdx
|
|
166 | 166 |
where _types = (inst::Instance.Instance, pdx::Types.Ndx, sdx::Types.Ndx) |
167 | 167 |
si = Instance.setBoth inst pdx sdx |
168 | 168 |
|
169 | 169 |
prop_Instance_runStatus_True inst = |
170 | 170 |
let run_st = Instance.running inst |
171 |
run_tx = Instance.run_st inst
|
|
171 |
run_tx = Instance.runSt inst
|
|
172 | 172 |
in |
173 | 173 |
run_tx == "running" || run_tx == "ERROR_up" ==> run_st == True |
174 | 174 |
|
175 | 175 |
prop_Instance_runStatus_False inst = |
176 | 176 |
let run_st = Instance.running inst |
177 |
run_tx = Instance.run_st inst
|
|
177 |
run_tx = Instance.runSt inst
|
|
178 | 178 |
in |
179 | 179 |
run_tx /= "running" && run_tx /= "ERROR_up" ==> run_st == False |
180 | 180 |
|
... | ... | |
213 | 213 |
(Instance.name i == name && |
214 | 214 |
Instance.vcpus i == vcpus && |
215 | 215 |
Instance.mem i == mem && |
216 |
Instance.pnode i == pdx &&
|
|
217 |
Instance.snode i == rsdx)
|
|
216 |
Instance.pNode i == pdx &&
|
|
217 |
Instance.sNode i == rsdx)
|
|
218 | 218 |
|
219 | 219 |
test_Text = |
220 | 220 |
[ run prop_Text_Load_Instance |
... | ... | |
223 | 223 |
-- Node tests |
224 | 224 |
|
225 | 225 |
-- | Check that an instance add with too high memory or disk will be rejected |
226 |
prop_Node_addPri node inst = (Instance.mem inst >= Node.f_mem node ||
|
|
227 |
Instance.dsk inst >= Node.f_dsk node) &&
|
|
226 |
prop_Node_addPri node inst = (Instance.mem inst >= Node.fMem node ||
|
|
227 |
Instance.dsk inst >= Node.fDsk node) &&
|
|
228 | 228 |
not (Node.failN1 node) |
229 | 229 |
==> |
230 | 230 |
isFailure (Node.addPri node inst) |
... | ... | |
233 | 233 |
|
234 | 234 |
-- | Check that an instance add with too high memory or disk will be rejected |
235 | 235 |
prop_Node_addSec node inst pdx = |
236 |
(Instance.mem inst >= (Node.f_mem node - Node.r_mem node) ||
|
|
237 |
Instance.dsk inst >= Node.f_dsk node) &&
|
|
236 |
(Instance.mem inst >= (Node.fMem node - Node.rMem node) ||
|
|
237 |
Instance.dsk inst >= Node.fDsk node) &&
|
|
238 | 238 |
not (Node.failN1 node) |
239 | 239 |
==> isFailure (Node.addSec node inst pdx) |
240 | 240 |
where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int) |
... | ... | |
250 | 250 |
-- | Check that the cluster score is close to zero for a homogeneous cluster |
251 | 251 |
prop_Score_Zero node count = |
252 | 252 |
((not $ Node.offline node) && (not $ Node.failN1 node) && (count > 0) && |
253 |
(Node.t_dsk node > 0) && (Node.t_mem node > 0)) ==>
|
|
253 |
(Node.tDsk node > 0) && (Node.tMem node > 0)) ==>
|
|
254 | 254 |
let fn = Node.buildPeers node Container.empty |
255 | 255 |
nlst = (zip [1..] $ replicate count fn)::[(Types.Ndx, Node.Node)] |
256 | 256 |
nl = Container.fromAssocList nlst |
b/hscan.hs | ||
---|---|---|
60 | 60 |
serializeNode :: String -> Node.Node -> String |
61 | 61 |
serializeNode csf node = |
62 | 62 |
printf "%s|%.0f|%d|%d|%.0f|%d|%.0f|%c" (Node.name node ++ csf) |
63 |
(Node.t_mem node) (Node.n_mem node) (Node.f_mem node)
|
|
64 |
(Node.t_dsk node) (Node.f_dsk node) (Node.t_cpu node)
|
|
63 |
(Node.tMem node) (Node.nMem node) (Node.fMem node)
|
|
64 |
(Node.tDsk node) (Node.fDsk node) (Node.tCpu node)
|
|
65 | 65 |
(if Node.offline node then 'Y' else 'N') |
66 | 66 |
|
67 | 67 |
-- | Generate node file data from node objects |
... | ... | |
74 | 74 |
serializeInstance csf nl inst = |
75 | 75 |
let |
76 | 76 |
iname = Instance.name inst ++ csf |
77 |
pnode = Container.nameOf nl (Instance.pnode inst) ++ csf
|
|
78 |
sidx = Instance.snode inst
|
|
77 |
pnode = Container.nameOf nl (Instance.pNode inst) ++ csf
|
|
78 |
sidx = Instance.sNode inst
|
|
79 | 79 |
snode = (if sidx == Node.noSecondary |
80 | 80 |
then "" |
81 | 81 |
else Container.nameOf nl sidx ++ csf) |
82 | 82 |
in |
83 | 83 |
printf "%s|%d|%d|%d|%s|%s|%s" |
84 | 84 |
iname (Instance.mem inst) (Instance.dsk inst) |
85 |
(Instance.vcpus inst) (Instance.run_st inst)
|
|
85 |
(Instance.vcpus inst) (Instance.runSt inst)
|
|
86 | 86 |
pnode snode |
87 | 87 |
|
88 | 88 |
-- | Generate instance file data from instance objects |
... | ... | |
98 | 98 |
ccv = Cluster.compCV nl |
99 | 99 |
nodes = Container.elems nl |
100 | 100 |
insts = Container.elems il |
101 |
t_ram = sum . map Node.t_mem $ nodes
|
|
102 |
t_dsk = sum . map Node.t_dsk $ nodes
|
|
103 |
f_ram = sum . map Node.f_mem $ nodes
|
|
104 |
f_dsk = sum . map Node.f_dsk $ nodes
|
|
101 |
t_ram = sum . map Node.tMem $ nodes
|
|
102 |
t_dsk = sum . map Node.tDsk $ nodes
|
|
103 |
f_ram = sum . map Node.fMem $ nodes
|
|
104 |
f_dsk = sum . map Node.fDsk $ nodes
|
|
105 | 105 |
in |
106 | 106 |
printf "%5d %5d %5d %5d %6.0f %6d %6.0f %6d %.8f" |
107 | 107 |
(length nodes) (length insts) |
b/hspace.hs | ||
---|---|---|
257 | 257 |
hPutStr stderr . unlines $ |
258 | 258 |
map (\i -> printf "Inst: %*s %-*s %-*s" |
259 | 259 |
ix_namelen (Instance.name i) |
260 |
nmlen (Container.nameOf fin_nl $ Instance.pnode i)
|
|
261 |
nmlen (let sdx = Instance.snode i
|
|
260 |
nmlen (Container.nameOf fin_nl $ Instance.pNode i)
|
|
261 |
nmlen (let sdx = Instance.sNode i
|
|
262 | 262 |
in if sdx == Node.noSecondary then "" |
263 | 263 |
else Container.nameOf fin_nl sdx) |
264 | 264 |
) fin_ixes |
Also available in: Unified diff