Should the migration port already be taken, Ganeti will try and start a
socat daemon that will immediately die, leaving Ganeti to pipe the
migration data into whatever process that happens to be listening. This
patch prevents that from happening by checking if the socat daemon
started by Ganeti is ready to accept the migration data.

Signed-off-by: Hrvoje Ribicic <[email protected]>
---
 lib/hypervisor/hv_xen.py | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index 3439cb2..5ec50e1 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -36,6 +36,7 @@ import logging
 import errno
 import string # pylint: disable=W0402
 import shutil
+import time
 from cStringIO import StringIO
 
 from ganeti import constants
@@ -1150,8 +1151,18 @@ class XenHypervisor(hv_base.BaseHypervisor):
       # And try and kill a previous daemon
       XenHypervisor._KillMigrationDaemon(instance)
 
-      utils.StartDaemon(["socat", "TCP-LISTEN:%d,bind=%s" % (port, target),
-                         "SYSTEM:'xl migrate-receive'"], pidfile=pidfile)
+      listening_arg = "TCP-LISTEN:%d,bind=%s" % (port, target)
+      socat_pid = utils.StartDaemon(["socat", listening_arg,
+                                     "SYSTEM:'xl migrate-receive'"],
+                                     pidfile=pidfile)
+
+      # Wait for a while to make sure the socat process has successfully 
started
+      # listening
+      time.sleep(1)
+      if not utils.IsProcessAlive(socat_pid):
+        raise errors.HypervisorError("Could not start receiving socat process"
+                                     " on port %d: check if port is available" 
%
+                                     port)
 
   def FinalizeMigrationDst(self, instance, info, success):
     """Finalize an instance migration.
-- 
2.2.0.rc0.207.ga3a616c

Reply via email to