diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 7807913c1cc73cd2b3b551e14bde4fef5d3695a3..c14cdf7bd1f2fd7bcd2b5aab9c57f6f0099006e1 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -27,6 +27,7 @@ import os
 import os.path
 import re
 import tempfile
+import time
 from cStringIO import StringIO
 
 from ganeti import utils
@@ -333,31 +334,57 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     self._SaveKVMRuntime(instance, kvm_runtime)
     self._ExecuteKVMRuntime(instance, kvm_runtime)
 
+  def _CallMonitorCommand(self, instance_name, command):
+    """Invoke a command on the instance monitor.
+
+    """
+    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
+             (utils.ShellQuote(command),
+              constants.SOCAT_PATH,
+              utils.ShellQuote(self._InstanceMonitor(instance_name))))
+    result = utils.RunCmd(socat)
+    if result.failed:
+      msg = ("Failed to send command '%s' to instance %s."
+             " output: %s, error: %s, fail_reason: %s" %
+             (instance.name, result.stdout, result.stderr, result.fail_reason))
+      raise errors.HypervisorError(msg)
+
+    return result
+
+  def _RetryInstancePowerdown(self, instance, pid, timeout=30):
+    """Wait for an instance  to power down.
+
+    """
+    # Wait up to $timeout seconds
+    end = time.time() + timeout
+    wait = 1
+    while time.time() < end and utils.IsProcessAlive(pid):
+      self._CallMonitorCommand(instance.name, 'system_powerdown')
+      time.sleep(wait)
+      # Make wait time longer for next try
+      if wait < 5:
+        wait *= 1.3
+
   def StopInstance(self, instance, force=False):
     """Stop an instance.
 
     """
-    socat_bin = constants.SOCAT_PATH
     pid_file = self._PIDS_DIR + "/%s" % instance.name
     pid = utils.ReadPidFile(pid_file)
     if pid > 0 and utils.IsProcessAlive(pid):
       if force or not instance.hvparams[constants.HV_ACPI]:
         utils.KillProcess(pid)
       else:
-        # This only works if the instance os has acpi support
-        monitor_socket = '%s/%s.monitor'  % (self._CTRL_DIR, instance.name)
-        socat = '%s -u STDIN UNIX-CONNECT:%s' % (socat_bin, monitor_socket)
-        command = "echo 'system_powerdown' | %s" % socat
-        result = utils.RunCmd(command)
-        if result.failed:
-          raise errors.HypervisorError("Failed to stop instance %s: %s" %
-                                       (instance.name, result.fail_reason))
+        self._RetryInstancePowerdown(instance, pid)
 
     if not utils.IsProcessAlive(pid):
       utils.RemoveFile(pid_file)
       utils.RemoveFile(self._InstanceMonitor(instance.name))
       utils.RemoveFile(self._InstanceSerial(instance.name))
       utils.RemoveFile(self._InstanceKVMRuntime(instance.name))
+      return True
+    else:
+      return False
 
   def RebootInstance(self, instance):
     """Reboot an instance.