From 07b49e412d4020c9fc1cbf979edf376e9ed1e18a Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Fri, 9 Oct 2009 11:13:20 +0100
Subject: [PATCH] Hypervisors: Add retry= to StopInstance

Currently some hypervisors need the stop operations to be retried more
than once, while other ones only do it in one pass. With this change
we'll handle retries outside the hypervisor code, but telling whether
this is the first try or not.

Since this option is not used for now, all hypervisors just return if
called with retry set to on, maintaining the old behavior. Since the
fake hypervisor has an idempotent StopInstance call, we avoid returning
in that case.

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Olivier Tharan <olive@google.com>
---
 lib/hypervisor/hv_base.py   | 13 +++++++++++--
 lib/hypervisor/hv_chroot.py |  4 +++-
 lib/hypervisor/hv_fake.py   |  2 +-
 lib/hypervisor/hv_kvm.py    |  4 +++-
 lib/hypervisor/hv_xen.py    |  4 +++-
 5 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index 4eaade63f..21784d218 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -111,8 +111,17 @@ class BaseHypervisor(object):
     """Start an instance."""
     raise NotImplementedError
 
-  def StopInstance(self, instance, force=False):
-    """Stop an instance."""
+  def StopInstance(self, instance, force=False, retry=False):
+    """Stop an instance
+
+    @type instance: L{objects.Instance}
+    @param instance: instance to stop
+    @type force: boolean
+    @param force: whether to do a "hard" stop (destroy)
+    @type retry: boolean
+    @param retry: whether this is just a retry call
+
+    """
     raise NotImplementedError
 
   def RebootInstance(self, instance):
diff --git a/lib/hypervisor/hv_chroot.py b/lib/hypervisor/hv_chroot.py
index 2ff41cd17..9c335e744 100644
--- a/lib/hypervisor/hv_chroot.py
+++ b/lib/hypervisor/hv_chroot.py
@@ -171,7 +171,7 @@ class ChrootManager(hv_base.BaseHypervisor):
       raise HypervisorError("Can't run the chroot start script: %s" %
                             result.output)
 
-  def StopInstance(self, instance, force=False):
+  def StopInstance(self, instance, force=False, retry=False):
     """Stop an instance.
 
     This method has complicated cleanup tests, as we must:
@@ -180,6 +180,8 @@ class ChrootManager(hv_base.BaseHypervisor):
       - finally unmount the instance dir
 
     """
+    if retry:
+      return
     root_dir = "%s/%s" % (self._ROOT_DIR, instance.name)
     if not os.path.exists(root_dir):
       return
diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py
index 393072c65..d53fff72a 100644
--- a/lib/hypervisor/hv_fake.py
+++ b/lib/hypervisor/hv_fake.py
@@ -130,7 +130,7 @@ class FakeHypervisor(hv_base.BaseHypervisor):
       raise errors.HypervisorError("Failed to start instance %s: %s" %
                                    (instance.name, err))
 
-  def StopInstance(self, instance, force=False):
+  def StopInstance(self, instance, force=False, retry=False):
     """Stop an instance.
 
     For the fake hypervisor, this just removes the file in the base
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 74005f075..bd3334565 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -535,10 +535,12 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       if wait < 5:
         wait *= 1.3
 
-  def StopInstance(self, instance, force=False):
+  def StopInstance(self, instance, force=False, retry=False):
     """Stop an instance.
 
     """
+    if retry:
+      return
     pidfile, pid, alive = self._InstancePidAlive(instance.name)
     if pid > 0 and alive:
       if force or not instance.hvparams[constants.HV_ACPI]:
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index 32385a298..28101023a 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -178,10 +178,12 @@ class XenHypervisor(hv_base.BaseHypervisor):
                                    (instance.name, result.fail_reason,
                                     result.output))
 
-  def StopInstance(self, instance, force=False):
+  def StopInstance(self, instance, force=False, retry=False):
     """Stop an instance.
 
     """
+    if retry:
+      return
     self._RemoveConfigFile(instance.name)
     if force:
       command = ["xm", "destroy", instance.name]
-- 
GitLab