Commit 33bb2d08 authored by Klaus Aehlig's avatar Klaus Aehlig

Support restricted migration

Make hbal support an option to disallow ReplacePrimary moves
and restrict ReplaceAndFailover to instances where the primary
node is drained. If used in evacuation mode, the only migration
moves will be off the drained nodes.
Signed-off-by: default avatarKlaus Aehlig <aehlig@google.com>
Reviewed-by: default avatarHrvoje Ribicic <riba@google.com>
parent 23dc58d5
......@@ -550,27 +550,39 @@ checkSingleStep ini_tbl target cur_tbl move =
possibleMoves :: MirrorType -- ^ The mirroring type of the instance
-> Bool -- ^ Whether the secondary node is a valid new node
-> Bool -- ^ Whether we can change the primary node
-> (Bool, Bool) -- ^ Whether migration is restricted and whether
-- the instance primary is offline
-> Ndx -- ^ Target node candidate
-> [IMove] -- ^ List of valid result moves
possibleMoves MirrorNone _ _ _ = []
possibleMoves MirrorNone _ _ _ _ = []
possibleMoves MirrorExternal _ False _ = []
possibleMoves MirrorExternal _ False _ _ = []
possibleMoves MirrorExternal _ True tdx =
possibleMoves MirrorExternal _ True _ tdx =
[ FailoverToAny tdx ]
possibleMoves MirrorInternal _ False tdx =
possibleMoves MirrorInternal _ False _ tdx =
[ ReplaceSecondary tdx ]
possibleMoves MirrorInternal True True tdx =
possibleMoves MirrorInternal _ _ (True, False) tdx =
[ ReplaceSecondary tdx
]
possibleMoves MirrorInternal True True (False, _) tdx =
[ ReplaceSecondary tdx
, ReplaceAndFailover tdx
, ReplacePrimary tdx
, FailoverAndReplace tdx
]
possibleMoves MirrorInternal False True tdx =
possibleMoves MirrorInternal True True (True, True) tdx =
[ ReplaceSecondary tdx
, ReplaceAndFailover tdx
, FailoverAndReplace tdx
]
possibleMoves MirrorInternal False True _ tdx =
[ ReplaceSecondary tdx
, ReplaceAndFailover tdx
]
......@@ -579,10 +591,12 @@ possibleMoves MirrorInternal False True tdx =
checkInstanceMove :: [Ndx] -- ^ Allowed target node indices
-> Bool -- ^ Whether disk moves are allowed
-> Bool -- ^ Whether instance moves are allowed
-> Bool -- ^ Whether migration is restricted
-> Table -- ^ Original table
-> Instance.Instance -- ^ Instance to move
-> Table -- ^ Best new table for this instance
checkInstanceMove nodes_idx disk_moves inst_moves ini_tbl target =
checkInstanceMove nodes_idx disk_moves inst_moves rest_mig
ini_tbl@(Table nl _ _ _) target =
let opdx = Instance.pNode target
osdx = Instance.sNode target
bad_nodes = [opdx, osdx]
......@@ -593,9 +607,13 @@ checkInstanceMove nodes_idx disk_moves inst_moves ini_tbl target =
-- if drbd and allowed to failover
then checkSingleStep ini_tbl target ini_tbl Failover
else ini_tbl
primary_drained = Node.offline
. flip Container.find nl
$ Instance.pNode target
all_moves =
if disk_moves
then concatMap (possibleMoves mir_type use_secondary inst_moves)
then concatMap (possibleMoves mir_type use_secondary inst_moves
(rest_mig, primary_drained))
nodes
else []
in
......@@ -606,10 +624,11 @@ checkInstanceMove nodes_idx disk_moves inst_moves ini_tbl target =
checkMove :: [Ndx] -- ^ Allowed target node indices
-> Bool -- ^ Whether disk moves are allowed
-> Bool -- ^ Whether instance moves are allowed
-> Bool -- ^ Whether migration is restricted
-> Table -- ^ The current solution
-> [Instance.Instance] -- ^ List of instances still to move
-> Table -- ^ The new solution
checkMove nodes_idx disk_moves inst_moves ini_tbl victims =
checkMove nodes_idx disk_moves inst_moves rest_mig ini_tbl victims =
let Table _ _ _ ini_plc = ini_tbl
-- we're using rwhnf from the Control.Parallel.Strategies
-- package; we don't need to use rnf as that would force too
......@@ -617,7 +636,7 @@ checkMove nodes_idx disk_moves inst_moves ini_tbl victims =
-- multi-threaded case the weak head normal form is enough to
-- spark the evaluation
tables = parMap rwhnf (checkInstanceMove nodes_idx disk_moves
inst_moves ini_tbl)
inst_moves rest_mig ini_tbl)
victims
-- iterate over all instances, computing the best move
best_tbl = foldl' compareTables ini_tbl tables
......@@ -641,10 +660,11 @@ tryBalance :: Table -- ^ The starting table
-> Bool -- ^ Allow disk moves
-> Bool -- ^ Allow instance moves
-> Bool -- ^ Only evacuate moves
-> Bool -- ^ Restrict migration
-> Score -- ^ Min gain threshold
-> Score -- ^ Min gain
-> Maybe Table -- ^ The resulting table and commands
tryBalance ini_tbl disk_moves inst_moves evac_mode mg_limit min_gain =
tryBalance ini_tbl disk_moves inst_moves evac_mode rest_mig mg_limit min_gain =
let Table ini_nl ini_il ini_cv _ = ini_tbl
all_inst = Container.elems ini_il
all_nodes = Container.elems ini_nl
......@@ -657,7 +677,8 @@ tryBalance ini_tbl disk_moves inst_moves evac_mode mg_limit min_gain =
reloc_inst = filter (\i -> Instance.movable i &&
Instance.autoBalance i) all_inst'
node_idx = map Node.idx online_nodes
fin_tbl = checkMove node_idx disk_moves inst_moves ini_tbl reloc_inst
fin_tbl = checkMove node_idx disk_moves inst_moves rest_mig
ini_tbl reloc_inst
(Table _ _ fin_cv _) = fin_tbl
in
if fin_cv < ini_cv && (ini_cv > mg_limit || ini_cv - fin_cv >= min_gain)
......
......@@ -73,6 +73,7 @@ options = do
, oPrintCommands
, oDataFile
, oEvacMode
, oRestrictedMigrate
, oRapiMaster
, luxi
, oIAllocSrc
......@@ -122,6 +123,7 @@ iterateDepth :: Bool -- ^ Whether to print moves
-> Int -- ^ Remaining length
-> Bool -- ^ Allow disk moves
-> Bool -- ^ Allow instance moves
-> Bool -- ^ Resrict migration
-> Int -- ^ Max node name len
-> Int -- ^ Max instance name len
-> [MoveJob] -- ^ Current command list
......@@ -131,13 +133,13 @@ iterateDepth :: Bool -- ^ Whether to print moves
-> Bool -- ^ Enable evacuation mode
-> IO (Cluster.Table, [MoveJob]) -- ^ The resulting table
-- and commands
iterateDepth printmove ini_tbl max_rounds disk_moves inst_moves nmlen imlen
cmd_strs min_score mg_limit min_gain evac_mode =
iterateDepth printmove ini_tbl max_rounds disk_moves inst_moves rest_mig nmlen
imlen cmd_strs min_score mg_limit min_gain evac_mode =
let Cluster.Table ini_nl ini_il _ _ = ini_tbl
allowed_next = Cluster.doNextBalance ini_tbl max_rounds min_score
m_fin_tbl = if allowed_next
then Cluster.tryBalance ini_tbl disk_moves inst_moves
evac_mode mg_limit min_gain
evac_mode rest_mig mg_limit min_gain
else Nothing
in case m_fin_tbl of
Just fin_tbl ->
......@@ -154,7 +156,7 @@ iterateDepth printmove ini_tbl max_rounds disk_moves inst_moves nmlen imlen
putStrLn sol_line
hFlush stdout
iterateDepth printmove fin_tbl max_rounds disk_moves inst_moves
nmlen imlen upd_cmd_strs min_score
rest_mig nmlen imlen upd_cmd_strs min_score
mg_limit min_gain evac_mode
Nothing -> return (ini_tbl, cmd_strs)
......@@ -389,6 +391,7 @@ main opts args = do
(fin_tbl, cmd_strs) <- iterateDepth True ini_tbl (optMaxLength opts)
(optDiskMoves opts)
(optInstMoves opts)
(optRestrictedMigrate opts)
nmlen imlen [] min_cv
(optMinGainLim opts) (optMinGain opts)
(optEvacMode opts)
......
......@@ -261,6 +261,7 @@ executeSimulation opts ini_tbl min_cv gidx nl il = do
(optMaxLength opts)
(optDiskMoves opts)
(optInstMoves opts)
False
nmlen imlen [] min_cv
(optMinGainLim opts) (optMinGain opts)
(optEvacMode opts)
......
......@@ -68,7 +68,7 @@ isNodeBig size node = Node.availDisk node > size * Types.unitDsk
&& Node.availCpu node > size * Types.unitCpu
canBalance :: Cluster.Table -> Bool -> Bool -> Bool -> Bool
canBalance tbl dm im evac = isJust $ Cluster.tryBalance tbl dm im evac 0 0
canBalance tbl dm im evac = isJust $ Cluster.tryBalance tbl dm im evac False 0 0
-- | Assigns a new fresh instance to a cluster; this is not
-- allocation, so no resource checks are done.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment