Allow unconditional failovers off offline nodes
authorKlaus Aehlig <aehlig@google.com>
Fri, 29 May 2015 15:50:43 +0000 (17:50 +0200)
committerKlaus Aehlig <aehlig@google.com>
Fri, 29 May 2015 16:18:39 +0000 (18:18 +0200)
Normally, we should not place instances on nodes that do
not have enough disks. However, there is one exception: if
we failover an instance from an offline node, that node can
well be secondary of that instance---the fact that it is currently
primary proves it has enough disks space. The reason why we have
to handle that case special is that if a node is offline, we sometimes
cannot determine the amount of disk available, hence the conservative
estimation is 0.

Signed-off-by: Klaus Aehlig <aehlig@google.com>
Reviewed-by: Hrvoje Ribicic <riba@google.com>

src/Ganeti/HTools/Cluster.hs
src/Ganeti/HTools/Node.hs

index cbf0ac1..f76a05b 100644 (file)
@@ -460,7 +460,8 @@ applyMove nl inst Failover =
       int_s = Node.removeSec old_s inst
       new_nl = do -- Maybe monad
         new_p <- Node.addPriEx (Node.offline old_p) int_s inst
-        new_s <- Node.addSec int_p inst old_sdx
+        new_s <- Node.addSecExEx (Node.offline old_p) (Node.offline old_p)
+                   int_p inst old_sdx
         let new_inst = Instance.setBoth inst old_sdx old_pdx
         return (Container.addTwo old_pdx new_s old_sdx new_p nl,
                 new_inst, old_sdx, old_pdx)
index 346f6bd..fecc5fc 100644 (file)
@@ -66,6 +66,7 @@ module Ganeti.HTools.Node
   , addPriEx
   , addSec
   , addSecEx
+  , addSecExEx
   -- * Stats
   , availDisk
   , availMem
@@ -571,7 +572,15 @@ addSec = addSecEx False
 
 -- | Adds a secondary instance (extended version).
 addSecEx :: Bool -> Node -> Instance.Instance -> T.Ndx -> T.OpResult Node
-addSecEx force t inst pdx =
+addSecEx = addSecExEx False
+
+-- | Adds a secondary instance (doubly extended version). The first parameter
+-- tells `addSecExEx` to ignore disks completly. There is only one legitimate
+-- use case for this, and this is failing over a DRBD instance where the primary
+-- node is offline (and hence will become the secondary afterwards).
+addSecExEx :: Bool
+           -> Bool -> Node -> Instance.Instance -> T.Ndx -> T.OpResult Node
+addSecExEx ignore_disks force t inst pdx =
   let iname = Instance.idx inst
       old_peers = peers t
       old_mem = fMem t
@@ -593,7 +602,7 @@ addSecEx force t inst pdx =
       strict = not force
   in case () of
        _ | not (Instance.hasSecondary inst) -> Bad T.FailDisk
-         | new_dsk <= 0 -> Bad T.FailDisk
+         | not ignore_disks && new_dsk <= 0 -> Bad T.FailDisk
          | new_dsk < loDsk t && strict -> Bad T.FailDisk
          | exclStorage t && new_free_sp < 0 -> Bad T.FailSpindles
          | new_inst_sp > hiSpindles t && strict -> Bad T.FailDisk