Revision 6804faa0

b/htools/Ganeti/HTools/Cluster.hs
61 61
    , tryAlloc
62 62
    , tryMGAlloc
63 63
    , tryReloc
64
    , tryEvac
65 64
    , tryNodeEvac
66 65
    , tryChangeGroup
67 66
    , collapseFailures
......
811 810
                                \destinations required (" ++ show reqn ++
812 811
                                                  "), only one supported"
813 812

  
814
-- | Change an instance's secondary node.
815
evacInstance :: (Monad m) =>
816
                [Ndx]                      -- ^ Excluded nodes
817
             -> Instance.List              -- ^ The current instance list
818
             -> (Node.List, AllocSolution) -- ^ The current state
819
             -> Idx                        -- ^ The instance to evacuate
820
             -> m (Node.List, AllocSolution)
821
evacInstance ex_ndx il (nl, old_as) idx = do
822
  -- FIXME: hardcoded one node here
823

  
824
  -- Longer explanation: evacuation is currently hardcoded to DRBD
825
  -- instances (which have one secondary); hence, even if the
826
  -- IAllocator protocol can request N nodes for an instance, and all
827
  -- the message parsing/loading pass this, this implementation only
828
  -- supports one; this situation needs to be revisited if we ever
829
  -- support more than one secondary, or if we change the storage
830
  -- model
831
  new_as <- tryReloc nl il idx 1 ex_ndx
832
  case asSolutions new_as of
833
    -- an individual relocation succeeded, we kind of compose the data
834
    -- from the two solutions
835
    csol@(nl', _, _, _):_ ->
836
        return (nl', new_as { asSolutions = csol:asSolutions old_as })
837
    -- this relocation failed, so we fail the entire evac
838
    _ -> fail $ "Can't evacuate instance " ++
839
         Instance.name (Container.find idx il) ++
840
             ": " ++ describeSolution new_as
841

  
842
-- | Try to evacuate a list of nodes.
843
tryEvac :: (Monad m) =>
844
            Node.List       -- ^ The node list
845
         -> Instance.List   -- ^ The instance list
846
         -> [Idx]           -- ^ Instances to be evacuated
847
         -> [Ndx]           -- ^ Restricted nodes (the ones being evacuated)
848
         -> m AllocSolution -- ^ Solution list
849
tryEvac nl il idxs ex_ndx = do
850
  (_, sol) <- foldM (evacInstance ex_ndx il) (nl, emptyAllocSolution) idxs
851
  return sol
852

  
853 813
-- | Function which fails if the requested mode is change secondary.
854 814
--
855 815
-- This is useful since except DRBD, no other disk template can
b/htools/Ganeti/HTools/IAlloc.hs
26 26
module Ganeti.HTools.IAlloc
27 27
    ( readRequest
28 28
    , runIAllocator
29
    , processRelocate
29 30
    ) where
30 31

  
31 32
import Data.Either ()
b/htools/Ganeti/HTools/QC.hs
908 908
               (xnl, xi, _, _):[] ->
909 909
                   let sdx = Instance.sNode xi
910 910
                       il' = Container.add (Instance.idx xi) xi il
911
                   in case Cluster.tryEvac xnl il' [Instance.idx xi] [sdx] of
912
                        Just _ -> True
911
                   in case IAlloc.processRelocate defGroupList xnl il'
912
                          (Instance.idx xi) 1 [sdx] of
913
                        Types.Ok _ -> True
913 914
                        _ -> False
914 915
               _ -> False
915 916

  

Also available in: Unified diff