From 8fbf5ac7fadafe22dcbaa25d557954eed54509ad Mon Sep 17 00:00:00 2001 From: Guido Trotter <ultrotter@google.com> Date: Wed, 30 Sep 2009 17:25:29 +0100 Subject: [PATCH] LUSetNodeParams: Don't break config on mc demotion. If --force is used to demote an MC, but then there are not enough MCs in the cluster, the configuration gets corrupted until a node is promoted. In order to avoid that we only allow demotion with --force if the node is offlined or drained at the same time, and we don't have any other node available to promote. Signed-off-by: Guido Trotter <ultrotter@google.com> Reviewed-by: Olivier Tharan <olive@google.com> --- lib/cmdlib.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 3f36b0a04..e1056903c 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -2970,14 +2970,21 @@ class LUSetNodeParams(LogicalUnit): raise errors.OpPrereqError("The master role can be changed" " only via masterfailover") - if ((self.op.master_candidate == False or self.op.offline == True or - self.op.drained == True) and node.master_candidate): + # Boolean value that tells us whether we're offlining or draining the node + offline_or_drain = self.op.offline == True or self.op.drained == True + + if (node.master_candidate and + (self.op.master_candidate == False or offline_or_drain)): cp_size = self.cfg.GetClusterInfo().candidate_pool_size - num_candidates, _, _ = self.cfg.GetMasterCandidateStats() - if num_candidates <= cp_size: + mc_now, mc_should, mc_max = self.cfg.GetMasterCandidateStats() + if mc_now <= cp_size: msg = ("Not enough master candidates (desired" - " %d, new value will be %d)" % (cp_size, num_candidates-1)) - if self.op.force: + " %d, new value will be %d)" % (cp_size, mc_now-1)) + # Only allow forcing the operation if it's an offline/drain operation, + # and we could not possibly promote more nodes. + # FIXME: this can still lead to issues if in any way another node which + # could be promoted appears in the meantime. + if self.op.force and offline_or_drain and mc_should == mc_max: self.LogWarning(msg) else: raise errors.OpPrereqError(msg) -- GitLab