From fe48262190eea55a2e8d5ac3147f0aa6e59ea55b Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Sun, 30 Mar 2008 14:54:34 +0000
Subject: [PATCH] Change the order of config updates in some LUs

In the start and stop instance LUs, the configuration update is done
right at the end. This means that if, for example, the instance shutdown
succeeds, but the drive deactivation fails, the next run of the watcher
will start the instance again, as it's still marked in running mode.

This patch changes these two LUs so that first the update the
configuration to the desired state, and only then we proceed to update
the config. This ensures that the state saved is the desired state.

Because the config might be updated even though the LU failed, this
patch also modifies the mcpu.Processor.ExecOpCode method to run the
RunConfigUpdate hook in a finally: phase while the lu.Exec is done in
its try phase. This ensures that config update hooks (tries to) run at
all times when the config is updated.

Reviewed-by: schreiberal
---
 lib/cmdlib.py |  6 +++---
 lib/mcpu.py   | 18 ++++++++++--------
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 87fa149b6..9cbe8ab05 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2011,6 +2011,8 @@ class LUStartupInstance(LogicalUnit):
     force = self.op.force
     extra_args = getattr(self.op, "extra_args", "")
 
+    self.cfg.MarkInstanceUp(instance.name)
+
     node_current = instance.primary_node
 
     _StartInstanceDisks(self.cfg, instance, force)
@@ -2019,8 +2021,6 @@ class LUStartupInstance(LogicalUnit):
       _ShutdownInstanceDisks(instance, self.cfg)
       raise errors.OpExecError("Could not start instance")
 
-    self.cfg.MarkInstanceUp(instance.name)
-
 
 class LURebootInstance(LogicalUnit):
   """Reboot an instance.
@@ -2136,10 +2136,10 @@ class LUShutdownInstance(LogicalUnit):
     """
     instance = self.instance
     node_current = instance.primary_node
+    self.cfg.MarkInstanceDown(instance.name)
     if not rpc.call_instance_shutdown(node_current, instance):
       logger.Error("could not shutdown instance")
 
-    self.cfg.MarkInstanceDown(instance.name)
     _ShutdownInstanceDisks(instance, self.cfg)
 
 
diff --git a/lib/mcpu.py b/lib/mcpu.py
index d941aef50..f7f03ea61 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -125,14 +125,16 @@ class Processor(object):
     lu.CheckPrereq()
     hm = HooksMaster(rpc.call_hooks_runner, self, lu)
     hm.RunPhase(constants.HOOKS_PHASE_PRE)
-    result = lu.Exec(self._feedback_fn)
-    hm.RunPhase(constants.HOOKS_PHASE_POST)
-    if lu.cfg is not None:
-      # we use lu.cfg and not self.cfg as for init cluster, self.cfg
-      # is None but lu.cfg has been recently initialized in the
-      # lu.Exec method
-      if write_count != lu.cfg.write_count:
-        hm.RunConfigUpdate()
+    try:
+      result = lu.Exec(self._feedback_fn)
+      hm.RunPhase(constants.HOOKS_PHASE_POST)
+    finally:
+      if lu.cfg is not None:
+        # we use lu.cfg and not self.cfg as for init cluster, self.cfg
+        # is None but lu.cfg has been recently initialized in the
+        # lu.Exec method
+        if write_count != lu.cfg.write_count:
+          hm.RunConfigUpdate()
 
     return result
 
-- 
GitLab