Index: /trunk/src/VBox/Main/ConsoleImpl-LiveMigration.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl-LiveMigration.cpp	(revision 23662)
+++ /trunk/src/VBox/Main/ConsoleImpl-LiveMigration.cpp	(revision 23663)
@@ -24,5 +24,7 @@
 *******************************************************************************/
 #include "ConsoleImpl.h"
+#include "Global.h"
 #include "Logging.h"
+#include "ProgressImpl.h"
 
 #include <iprt/err.h>
@@ -43,18 +45,68 @@
 *******************************************************************************/
 /**
- * Argument package for Console::migrationServeConnection.
- */
-typedef struct MIGRATIONSTATE
-{
-    Console    *pConsole;
-    IMachine   *pMachine;
-    PVM         pVM;
-    const char *pszPassword;
-    void       *pvVMCallbackTask;
-    RTSOCKET    hSocket;
-    uint64_t    offStream;
-    int         rc;
-} MIGRATIONSTATE;
-typedef MIGRATIONSTATE *PMIGRATIONSTATE;
+ * Base class for the migration state.
+ *
+ * These classes are used as advanced structs, not as proper classes.
+ */
+class MigrationState
+{
+public:
+    ComPtr<Console>     mptrConsole;
+    PVM                 mpVM;
+    Utf8Str             mstrPassword;
+
+    /** @name stream stuff
+     * @{  */
+    RTSOCKET            mhSocket;
+    uint64_t            moffStream;
+    /** @} */
+
+    MigrationState(Console *pConsole, PVM pVM)
+        : mptrConsole(pConsole)
+        , mpVM(pVM)
+        , mhSocket(NIL_RTSOCKET)
+        , moffStream(UINT64_MAX / 2)
+    {
+    }
+};
+
+
+/**
+ * Migration state used by the source side.
+ */
+class MigrationStateSrc : public MigrationState
+{
+public:
+    ComPtr<Progress>    mptrProgress;
+    Utf8Str             mstrHostname;
+    uint32_t            muPort;
+
+    MigrationStateSrc(Console *pConsole, PVM pVM)
+        : MigrationState(pConsole, pVM)
+        , muPort(UINT32_MAX)
+    {
+    }
+};
+
+
+/**
+ * Migration state used by the destiation side.
+ */
+class MigrationStateDst : public MigrationState
+{
+public:
+    IMachine           *mpMachine;
+    void               *mpvVMCallbackTask;
+    int                 mRc;
+
+    MigrationStateDst(Console *pConsole, PVM pVM, IMachine *pMachine)
+        : MigrationState(pConsole, pVM)
+        , mpMachine(pMachine)
+        , mpvVMCallbackTask(NULL)
+        , mRc(VINF_SUCCESS)
+    {
+    }
+};
+
 
 
@@ -66,13 +118,120 @@
 
 /**
+ * Reads a string from the socket.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pState      The live migration state structure.
+ * @param   pszBuf      The output buffer.
+ * @param   cchBuf      The size of the output buffer.
+ *
+ */
+static int migrationTcpReadLine(MigrationState *pState, char *pszBuf, size_t cchBuf)
+{
+    char       *pszStart = pszBuf;
+    RTSOCKET    Sock     = pState->mhSocket;
+
+    AssertReturn(cchBuf > 1, VERR_INTERNAL_ERROR);
+
+    /* dead simple (stupid) approach. */
+    for (;;)
+    {
+        char ch;
+        int rc = RTTcpRead(Sock, &ch, sizeof(ch), NULL);
+        if (RT_FAILURE(rc))
+        {
+            LogRel(("Migration: RTTcpRead -> %Rrc while reading string ('%s')\n", rc, pszStart));
+            return rc;
+        }
+        if (    ch == '\n'
+            ||  ch == '\0')
+            return VINF_SUCCESS;
+        if (cchBuf <= 1)
+        {
+            LogRel(("Migration: String buffer overflow: '%s'\n", pszStart));
+            return VERR_BUFFER_OVERFLOW;
+        }
+        *pszBuf++ = ch;
+        *pszBuf   = '\0';
+        cchBuf--;
+    }
+}
+
+
+static int migrationTcpWriteACK(MigrationState *pState)
+{
+    int rc = RTTcpWrite(pState->mhSocket, "ACK\n", sizeof("ACK\n") - 1);
+    if (RT_FAILURE(rc))
+        LogRel(("Migration: RTTcpWrite(,ACK,) -> %Rrc\n", rc));
+    return rc;
+}
+
+
+static int migrationTcpWriteNACK(MigrationState *pState)
+{
+    int rc = RTTcpWrite(pState->mhSocket, "NACK\n", sizeof("NACK\n") - 1);
+    if (RT_FAILURE(rc))
+        LogRel(("Migration: RTTcpWrite(,NACK,) -> %Rrc\n", rc));
+    return rc;
+}
+
+
+/**
+ * Reads an ACK or NACK.
+ *
+ * @returns S_OK on ACK, E_FAIL+setError() on failure or NACK.
+ * @param   pState              The live migration source state.
+ *
+ * @remarks the setError laziness forces this to be a Console member.
+ */
+HRESULT
+Console::migrationSrcReadACK(MigrationStateSrc *pState)
+{
+    char szMsg[128];
+    int vrc = migrationTcpReadLine(pState, szMsg, sizeof(szMsg));
+    if (RT_FAILURE(vrc))
+        return setError(E_FAIL, tr("Failed reading ACK: %Rrc"), vrc);
+    if (strcmp(szMsg, "ACK\n"))
+    {
+        if (strcmp(szMsg, "NACK\n"))
+            return setError(E_FAIL, "NACK");
+        return setError(E_FAIL, tr("Expected ACK or NACK, got '%s'"), szMsg);
+    }
+    return S_OK;
+}
+
+/**
+ * Submitts a command to the destination and waits for the ACK.
+ *
+ * @returns S_OK on ACKed command, E_FAIL+setError() on failure.
+ *
+ * @param   pState              The live migration source state.
+ * @param   pszCommand          The command.
+ *
+ * @remarks the setError laziness forces this to be a Console member.
+ */
+HRESULT
+Console::migrationSrcSubmitCommand(MigrationStateSrc *pState, const char *pszCommand)
+{
+    size_t cchCommand = strlen(pszCommand);
+    int vrc = RTTcpWrite(pState->mhSocket, pszCommand, cchCommand);
+    if (RT_SUCCESS(vrc))
+        vrc = RTTcpWrite(pState->mhSocket, "\n", sizeof("\n") - 1);
+    if (RT_FAILURE(vrc))
+        return setError(E_FAIL, tr("Failed writing command '%s': %Rrc"), pszCommand, vrc);
+    return migrationSrcReadACK(pState);
+}
+
+
+/**
  * @copydoc SSMSTRMOPS::pfnWrite
  */
 static DECLCALLBACK(int) migrationTcpOpWrite(void *pvUser, uint64_t offStream, const void *pvBuf, size_t cbToWrite)
 {
-    PMIGRATIONSTATE pState = (PMIGRATIONSTATE)pvUser;
-    int rc = RTTcpWrite(pState->hSocket, pvBuf, cbToWrite);
+    MigrationState *pState = (MigrationState *)pvUser;
+    int rc = RTTcpWrite(pState->mhSocket, pvBuf, cbToWrite);
     if (RT_SUCCESS(rc))
     {
-        pState->offStream += cbToWrite;
+        pState->moffStream += cbToWrite;
         return VINF_SUCCESS;
     }
@@ -86,9 +245,9 @@
 static DECLCALLBACK(int) migrationTcpOpRead(void *pvUser, uint64_t offStream, void *pvBuf, size_t cbToRead, size_t *pcbRead)
 {
-    PMIGRATIONSTATE pState = (PMIGRATIONSTATE)pvUser;
-    int rc = RTTcpRead(pState->hSocket, pvBuf, cbToRead, pcbRead);
+    MigrationState *pState = (MigrationState *)pvUser;
+    int rc = RTTcpRead(pState->mhSocket, pvBuf, cbToRead, pcbRead);
     if (RT_SUCCESS(rc))
     {
-        pState->offStream += pcbRead ? *pcbRead : cbToRead;
+        pState->moffStream += pcbRead ? *pcbRead : cbToRead;
         return VINF_SUCCESS;
     }
@@ -111,6 +270,6 @@
 static DECLCALLBACK(uint64_t) migrationTcpOpTell(void *pvUser)
 {
-    PMIGRATIONSTATE pState = (PMIGRATIONSTATE)pvUser;
-    return pState->offStream;
+    MigrationState *pState = (MigrationState *)pvUser;
+    return pState->moffStream;
 }
 
@@ -161,4 +320,104 @@
 
 /**
+ * Do the live migration.
+ *
+ * @returns VBox status code.
+ * @param   pState              The migration state.
+ */
+HRESULT
+Console::migrationSrc(MigrationStateSrc *pState)
+{
+    AutoCaller autoCaller(this);
+    CheckComRCReturnRC(autoCaller.rc());
+
+    /*
+     * Wait for Console::Migrate to change the state.
+     */
+    { AutoWriteLock autoLock(); }
+
+    /*
+     * Try connect to the destination machine.
+     * (Note. The caller cleans up mhSocket, so we can return without worries.)
+     */
+    int vrc = RTTcpClientConnect(pState->mstrHostname.c_str(), pState->muPort, &pState->mhSocket);
+    if (RT_SUCCESS(vrc))
+        return setError(E_FAIL, tr("Failed to connect to port %u on '%s': %Rrc"),
+                        pState->muPort, pState->mstrHostname.c_str(), vrc);
+
+    /* Read and check the welcome message. */
+    char szLine[RT_MAX(128, sizeof(g_szWelcome))];
+    vrc = RTTcpRead(pState->mhSocket, szLine, sizeof(g_szWelcome) - 1, NULL);
+    if (RT_FAILURE(vrc))
+        return setError(E_FAIL, tr("Failed to read welcome message: %Rrc"), vrc);
+    if (!strcmp(szLine, g_szWelcome))
+        return setError(E_FAIL, tr("Unexpected welcome '%s'"), szLine);
+
+    /* password */
+    pState->mstrPassword.append('\n');
+    vrc = RTTcpWrite(pState->mhSocket, pState->mstrPassword.c_str(), pState->mstrPassword.length());
+    if (RT_FAILURE(vrc))
+        return setError(E_FAIL, tr("Failed to send password: %Rrc"), vrc);
+
+    /* ACK */
+    HRESULT hrc = migrationSrcReadACK(pState);
+    if (FAILED(hrc))
+        return hrc;
+
+    /*
+     * Do compatability checks of the VM config and the host hardware.
+     */
+    /** @todo later */
+
+    /*
+     * Start loading the state.
+     */
+    hrc = migrationSrcSubmitCommand(pState, "load");
+    if (FAILED(hrc))
+        return hrc;
+
+    void *pvUser = static_cast<void *>(static_cast<MigrationState *>(pState));
+    vrc = VMR3Migrate(pState->mpVM, &g_migrationTcpOps, pvUser, NULL/** @todo progress*/, pvUser);
+    if (vrc)
+        return setError(E_FAIL, tr("VMR3Migrate -> %Rrc"), vrc);
+
+    hrc = migrationSrcReadACK(pState);
+    if (FAILED(hrc))
+        return hrc;
+
+    /*
+     * State fun? Automatic power off?
+     */
+
+    return S_OK;
+}
+
+
+/**
+ * Static thread method wrapper.
+ *
+ * @returns VINF_SUCCESS (ignored).
+ * @param   hThread             The thread.
+ * @param   pvUser              Pointer to a MigrationStateSrc instance.
+ */
+/*static*/ DECLCALLBACK(int)
+Console::migrationSrcThreadWrapper(RTTHREAD hThread, void *pvUser)
+{
+    MigrationStateSrc *pState = (MigrationStateSrc *)pvUser;
+
+    HRESULT hrc = pState->mptrConsole->migrationSrc(pState);
+    pState->mptrProgress->notifyComplete(hrc);
+
+    if (pState->mhSocket != NIL_RTSOCKET)
+    {
+        RTTcpClientClose(pState->mhSocket);
+        pState->mhSocket = NIL_RTSOCKET;
+    }
+    delete pState;
+
+    return VINF_SUCCESS;
+}
+
+
+/**
  * Start live migration to the specified target.
  *
@@ -174,10 +433,55 @@
 {
     /*
-     * Validate parameters.
-     */
-
-    /*
-     * Try change the state, create a progress object and spawn a worker thread.
-     */
+     * Validate parameters, check+hold object status, write lock the object
+     * and validate the state.
+     */
+    CheckComArgOutPointerValid(aProgress);
+    CheckComArgStrNotEmptyOrNull(aHostname);
+    CheckComArgNotNull(aHostname);
+    CheckComArgExprMsg(aPort, aPort > 0 && aPort <= 65535, ("is %u", aPort));
+
+    AutoCaller autoCaller(this);
+    CheckComRCReturnRC(autoCaller.rc());
+
+    AutoWriteLock autoLock(this);
+    LogFlowThisFunc(("mMachineState=%d\n", mMachineState));
+
+    switch (mMachineState)
+    {
+        case MachineState_Running:
+        case MachineState_Paused:
+            break;
+
+        default:
+            return setError(VBOX_E_INVALID_VM_STATE,
+                tr("Invalid machine state: %s (must be Running, Paused or Stuck)"),
+                Global::stringifyMachineState(mMachineState));
+    }
+
+
+    /*
+     * Create a progress object, spawn a worker thread and change the state.
+     * Note! The thread won't start working until we release the lock.
+     */
+    LogFlowThisFunc(("Initiating LIVE MIGRATION request...\n"));
+
+    ComObjPtr<Progress> ptrMigrateProgress;
+    HRESULT hrc = ptrMigrateProgress.createObject();
+    CheckComRCReturnRC(hrc);
+    hrc = ptrMigrateProgress->init(static_cast<IConsole *>(this),
+                                   Bstr(tr("Live Migration")),
+                                   TRUE /*aCancelable*/);
+    CheckComRCReturnRC(hrc);
+
+    MigrationStateSrc *pState = new MigrationStateSrc(this, mpVM);
+    pState->mstrPassword = aPassword;
+    pState->mstrHostname = aHostname;
+    pState->muPort       = aPort;
+    pState->mptrProgress = ptrMigrateProgress;
+
+    int vrc = RTThreadCreate(NULL, Console::migrationSrcThreadWrapper, pState, 0 /*cbStack*/,
+                             RTTHREADTYPE_EMULATION, 0 /*fFlags*/, "Migrate");
+    if (RT_SUCCESS(vrc))
+        delete pState;
 
     return E_FAIL;
@@ -187,5 +491,5 @@
 /**
  * Creates a TCP server that listens for the source machine and passes control
- * over to Console::migrationServeConnection().
+ * over to Console::migrationDstServeConnection().
  *
  * @returns VBox status code.
@@ -196,5 +500,5 @@
  */
 int
-Console::migrationLoadRemote(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask)
+Console::migrationDst(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask)
 {
     /*
@@ -211,5 +515,4 @@
         return VERR_GENERAL_FAILURE;
     Utf8Str strPassword(bstrPassword);
-    strPassword.append('\n');           /* always ends with a newline. */
 
     Utf8Str strBind("");
@@ -220,8 +523,8 @@
      * Create the TCP server.
      */
-    int rc;
+    int vrc;
     PRTTCPSERVER hServer;
     if (uPort)
-        rc = RTTcpServerCreateEx(pszBindAddress, uPort, &hServer);
+        vrc = RTTcpServerCreateEx(pszBindAddress, uPort, &hServer);
     else
     {
@@ -229,9 +532,9 @@
         {
             uPort = RTRandU32Ex(cTries >= 8192 ? 49152 : 1024, 65534);
-            rc = RTTcpServerCreateEx(pszBindAddress, uPort, &hServer);
-            if (rc != VERR_NET_ADDRESS_IN_USE)
+            vrc = RTTcpServerCreateEx(pszBindAddress, uPort, &hServer);
+            if (vrc != VERR_NET_ADDRESS_IN_USE)
                 break;
         }
-        if (RT_SUCCESS(rc))
+        if (RT_SUCCESS(vrc))
         {
             HRESULT hrc = pMachine->COMSETTER(LiveMigrationPort)(uPort);
@@ -243,6 +546,6 @@
         }
     }
-    if (RT_FAILURE(rc))
-        return rc;
+    if (RT_FAILURE(vrc))
+        return vrc;
 
     /*
@@ -250,27 +553,21 @@
      */
     RTTIMERLR hTimerLR;
-    rc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, migrationTimeout, hServer);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTTimerLRStart(hTimerLR, 5*60*UINT64_C(1000000000) /*ns*/);
-        if (RT_SUCCESS(rc))
+    vrc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, migrationTimeout, hServer);
+    if (RT_SUCCESS(vrc))
+    {
+        vrc = RTTimerLRStart(hTimerLR, 5*60*UINT64_C(1000000000) /*ns*/);
+        if (RT_SUCCESS(vrc))
         {
             /*
              * Do the job, when it returns we're done.
              */
-            MIGRATIONSTATE State;
-            State.pConsole      = this;
-            State.pMachine      = pMachine;
-            State.pVM           = pVM;
-            State.pszPassword   = strPassword.c_str();
-            State.hSocket       = NIL_RTSOCKET;
-            State.offStream     = UINT64_MAX / 2;
-            State.rc            = VINF_SUCCESS;
-
-            rc = RTTcpServerListen(hServer, Console::migrationServeConnection, &State);
-            if (rc == VERR_TCP_SERVER_STOP)
-                rc = State.rc;
-            if (RT_FAILURE(rc))
-                LogRel(("Migration: RTTcpServerListen -> %Rrc\n", rc));
+            MigrationStateDst State(this, pVM, pMachine);
+            State.mstrPassword = strPassword;
+
+            vrc = RTTcpServerListen(hServer, Console::migrationDstServeConnection, &State);
+            if (vrc == VERR_TCP_SERVER_STOP)
+                vrc = State.mRc;
+            if (RT_FAILURE(vrc))
+                LogRel(("Migration: RTTcpServerListen -> %Rrc\n", vrc));
         }
 
@@ -279,45 +576,5 @@
     RTTcpServerDestroy(hServer);
 
-    return rc;
-}
-
-
-/**
- * Reads a string from the socket.
- *
- * @returns VBox status code.
- *
- * @param   Sock        The socket.
- * @param   pszBuf      The output buffer.
- * @param   cchBuf      The size of the output buffer.
- *
- */
-static int migrationReadLine(RTSOCKET Sock, char *pszBuf, size_t cchBuf)
-{
-    char *pszStart = pszBuf;
-    AssertReturn(cchBuf > 1, VERR_INTERNAL_ERROR);
-
-    /* dead simple (stupid) approach. */
-    for (;;)
-    {
-        char ch;
-        int rc = RTTcpRead(Sock, &ch, sizeof(ch), NULL);
-        if (RT_FAILURE(rc))
-        {
-            LogRel(("Migration: RTTcpRead -> %Rrc while reading string ('%s')\n", rc, pszStart));
-            return rc;
-        }
-        if (    ch == '\n'
-            ||  ch == '\0')
-            return VINF_SUCCESS;
-        if (cchBuf <= 1)
-        {
-            LogRel(("Migration: String buffer overflow: '%s'\n", pszStart));
-            return VERR_BUFFER_OVERFLOW;
-        }
-        *pszBuf++ = ch;
-        *pszBuf   = '\0';
-        cchBuf--;
-    }
+    return vrc;
 }
 
@@ -325,72 +582,87 @@
 /**
  * @copydoc FNRTTCPSERVE
- * VERR_TCP_SERVER_STOP
  */
 /*static*/ DECLCALLBACK(int)
-Console::migrationServeConnection(RTSOCKET Sock, void *pvUser)
-{
-    PMIGRATIONSTATE pState   = (PMIGRATIONSTATE)pvUser;
-    Console        *pConsole = pState->pConsole;
-    IMachine       *pMachine = pState->pMachine;
+Console::migrationDstServeConnection(RTSOCKET Sock, void *pvUser)
+{
+    MigrationStateDst *pState   = (MigrationStateDst *)pvUser;
 
     /*
      * Say hello.
      */
-    int rc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1);
-    if (RT_FAILURE(rc))
-    {
-        LogRel(("Migration: Failed to write welcome message: %Rrc\n", rc));
+    int vrc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1);
+    if (RT_FAILURE(vrc))
+    {
+        LogRel(("Migration: Failed to write welcome message: %Rrc\n", vrc));
         return VINF_SUCCESS;
     }
 
     /*
-     * Password (includes '\n', see migrationLoadRemote).  If it's right, tell
+     * Password (includes '\n', see migrationDst).  If it's right, tell
      * the TCP server to stop listening (frees up host resources and makes sure
      * this is the last connection attempt).
      */
-    const char *pszPassword = pState->pszPassword;
+    pState->mstrPassword.append('\n');
+    const char *pszPassword = pState->mstrPassword.c_str();
     unsigned    off = 0;
     while (pszPassword[off])
     {
         char ch;
-        rc = RTTcpRead(Sock, &ch, sizeof(ch), NULL);
-        if (RT_FAILURE(rc))
+        vrc = RTTcpRead(Sock, &ch, sizeof(ch), NULL);
+        if (    RT_FAILURE(vrc)
+            ||  pszPassword[off] != ch)
+        {
+            if (RT_FAILURE(vrc))
+                LogRel(("Migration: Password read failure (off=%u): %Rrc\n", off, vrc));
+            else
+                LogRel(("Migration: Invalid password (off=%u)\n", off));
+            migrationTcpWriteNACK(pState);
+            return VINF_SUCCESS;
+        }
+        off++;
+    }
+    vrc = migrationTcpWriteACK(pState);
+    if (RT_FAILURE(vrc))
+        return vrc;
+    RTTcpServerShutdown((PRTTCPSERVER)pvUser);
+
+    /*
+     * Command processing loop.
+     */
+    pState->mhSocket = Sock;
+    for (;;)
+    {
+        char szCmd[128];
+        vrc = migrationTcpReadLine(pState, szCmd, sizeof(szCmd));
+        if (RT_FAILURE(vrc))
             break;
-        if (pszPassword[off] != ch)
-        {
-            LogRel(("Migration: Invalid password (off=%u)\n", off));
-            return VINF_SUCCESS;
-        }
-        off++;
-    }
-
-    RTTcpServerShutdown((PRTTCPSERVER)pvUser);
-
-    /*
-     * Command processing loop.
-     */
-    pState->hSocket = Sock;
-    for (;;)
-    {
-        char szCmd[128];
-        rc = migrationReadLine(Sock, szCmd, sizeof(szCmd));
-        if (RT_FAILURE(rc))
-            break;
 
         if (!strcmp(szCmd, "load"))
         {
-            pState->offStream = 0;
-            rc = VMR3LoadFromStream(pState->pVM, &g_migrationTcpOps, pState,
-                                    Console::stateProgressCallback, pState->pvVMCallbackTask);
-            if (RT_FAILURE(rc))
+            vrc = migrationTcpWriteACK(pState);
+            if (RT_FAILURE(vrc))
+                break;
+
+            pState->moffStream = 0;
+            void *pvUser = static_cast<void *>(static_cast<MigrationState *>(pState));
+            vrc = VMR3LoadFromStream(pState->mpVM, &g_migrationTcpOps, pvUser,
+                                     Console::stateProgressCallback, pState->mpvVMCallbackTask);
+            if (RT_FAILURE(vrc))
             {
-                LogRel(("Migration: VMR3LoadFromStream -> %Rrc\n", rc));
+                LogRel(("Migration: VMR3LoadFromStream -> %Rrc\n", vrc));
                 break;
             }
+
+            vrc = migrationTcpWriteACK(pState);
+            if (RT_FAILURE(vrc))
+                break;
         }
         /** @todo implement config verification and hardware compatability checks. Or
          *        maybe leave part of these to the saved state machinery? */
         else if (!strcmp(szCmd, "done"))
+        {
+            migrationTcpWriteACK(pState);
             break;
+        }
         else
         {
@@ -399,5 +671,5 @@
         }
     }
-    pState->hSocket = NIL_RTSOCKET;
+    pState->mhSocket = NIL_RTSOCKET;
 
     return VERR_TCP_SERVER_STOP;
Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 23662)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 23663)
@@ -6746,5 +6746,5 @@
                 else if (task->mLiveMigrationTarget)
                     /* -> ConsoleImpl-LiveMigration.cpp */
-                    vrc = console->migrationLoadRemote(pVM, pMachine, static_cast<VMProgressTask*>(task.get()));
+                    vrc = console->migrationDst(pVM, pMachine, static_cast<VMProgressTask*>(task.get()));
                 else if (task->mStartPaused)
                     /* done */
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 23662)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 23663)
@@ -34,4 +34,5 @@
 class Display;
 class MachineDebugger;
+class MigrationStateSrc;
 class OUSBDevice;
 class RemoteUSBDevice;
@@ -515,6 +516,10 @@
     /** @name Live migration support
      * @{ */
-    int                         migrationLoadRemote(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask);
-    static DECLCALLBACK(int)    migrationServeConnection(RTSOCKET Sock, void *pvUser);
+    static DECLCALLBACK(int)    migrationSrcThreadWrapper(RTTHREAD hThread, void *pvUser);
+    HRESULT                     migrationSrc(MigrationStateSrc *pState);
+    HRESULT                     migrationSrcReadACK(MigrationStateSrc *pState);
+    HRESULT                     migrationSrcSubmitCommand(MigrationStateSrc *pState, const char *pszCommand);
+    int                         migrationDst(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask);
+    static DECLCALLBACK(int)    migrationDstServeConnection(RTSOCKET Sock, void *pvUser);
     /** @} */
 
