Revision 2060348b Ganeti/HTools/Node.hs

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

Also available in: Unified diff