xend: Time-out if guest fails to suspend
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 12 Mar 2009 11:00:52 +0000 (11:00 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 12 Mar 2009 11:00:52 +0000 (11:00 +0000)
If a guest fails to re-write control/shutdown node within a minute,
fail the suspend operation.

Signed-off-by: John Levon <john.levon@sun.com>
tools/python/xen/xend/XendCheckpoint.py
tools/python/xen/xend/XendDomainInfo.py

index a333b581e6225c08e2231bca4fc50bc7149d373e..a0ea01166575da97a6409be87c488cff64bc126f 100644 (file)
@@ -114,7 +114,7 @@ def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1):
             if line == "suspend":
                 log.debug("Suspending %d ...", dominfo.getDomid())
                 dominfo.shutdown('suspend')
-                dominfo.waitForShutdown()
+                dominfo.waitForSuspend()
             if line in ('suspend', 'suspended'):
                 dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2,
                                        domain_name)
index 88a2c2f5eb3d086f4cbe038374f551629c177ae6..4ec5679fb8132c9d8c2fcfeefdfc971d45d63677 100644 (file)
@@ -2544,6 +2544,31 @@ class XendDomainInfo:
         finally:
             self.state_updated.release()
 
+    def waitForSuspend(self):
+        """Wait for the guest to respond to a suspend request by
+        shutting down.  If the guest hasn't re-written control/shutdown
+        after a certain amount of time, it's obviously not listening and
+        won't suspend, so we give up.  HVM guests with no PV drivers
+        should already be shutdown.
+        """
+        state = "suspend"
+        nr_tries = 60
+
+        self.state_updated.acquire()
+        try:
+            while self._stateGet() in (DOM_STATE_RUNNING,DOM_STATE_PAUSED):
+                self.state_updated.wait(1.0)
+                if state == "suspend":
+                    if nr_tries == 0:
+                        msg = ('Timeout waiting for domain %s to suspend'
+                            % self.domid)
+                        self._writeDom('control/shutdown', '')
+                        raise XendError(msg)
+                    state = self.readDom('control/shutdown')
+                    nr_tries -= 1
+        finally:
+            self.state_updated.release()
+
     #
     # TODO: recategorise - called from XendCheckpoint
     #