Index: /trunk/src/VBox/Main/ConsoleImpl-LiveMigration.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl-LiveMigration.cpp	(revision 23668)
+++ /trunk/src/VBox/Main/ConsoleImpl-LiveMigration.cpp	(revision 23669)
@@ -60,4 +60,5 @@
     RTSOCKET            mhSocket;
     uint64_t            moffStream;
+    bool volatile       mfStopReading;
     /** @} */
 
@@ -67,4 +68,5 @@
         , mhSocket(NIL_RTSOCKET)
         , moffStream(UINT64_MAX / 2)
+        , mfStopReading(false)
     {
     }
@@ -98,4 +100,5 @@
     IMachine           *mpMachine;
     void               *mpvVMCallbackTask;
+    PRTTCPSERVER        mhServer;
     int                 mRc;
 
@@ -104,4 +107,5 @@
         , mpMachine(pMachine)
         , mpvVMCallbackTask(NULL)
+        , mhServer(NULL)
         , mRc(VINF_SUCCESS)
     {
@@ -164,4 +168,5 @@
     if (RT_FAILURE(rc))
         LogRel(("Migration: RTTcpWrite(,ACK,) -> %Rrc\n", rc));
+    RTTcpFlush(pState->mhSocket);
     return rc;
 }
@@ -173,4 +178,5 @@
     if (RT_FAILURE(rc))
         LogRel(("Migration: RTTcpWrite(,NACK,) -> %Rrc\n", rc));
+    RTTcpFlush(pState->mhSocket);
     return rc;
 }
@@ -182,9 +188,10 @@
  * @returns S_OK on ACK, E_FAIL+setError() on failure or NACK.
  * @param   pState              The live migration source state.
+ * @param   pszNAckMsg          Optional NACK message.
  *
  * @remarks the setError laziness forces this to be a Console member.
  */
 HRESULT
-Console::migrationSrcReadACK(MigrationStateSrc *pState)
+Console::migrationSrcReadACK(MigrationStateSrc *pState, const char *pszNAckMsg /*= NULL*/)
 {
     char szMsg[128];
@@ -192,8 +199,8 @@
     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");
+    if (strcmp(szMsg, "ACK"))
+    {
+        if (!strcmp(szMsg, "NACK"))
+            return setError(E_FAIL, pszNAckMsg ? pszNAckMsg : "NACK");
         return setError(E_FAIL, tr("Expected ACK or NACK, got '%s'"), szMsg);
     }
@@ -246,11 +253,21 @@
 {
     MigrationState *pState = (MigrationState *)pvUser;
-    int rc = RTTcpRead(pState->mhSocket, pvBuf, cbToRead, pcbRead);
-    if (RT_SUCCESS(rc))
-    {
-        pState->moffStream += pcbRead ? *pcbRead : cbToRead;
-        return VINF_SUCCESS;
-    }
-    return rc;
+
+    for (;;)
+    {
+        int rc = RTTcpSelectOne(pState->mhSocket, 30); /** @todo fix this polling mess. */
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTTcpRead(pState->mhSocket, pvBuf, cbToRead, pcbRead);
+            if (RT_FAILURE(rc))
+                return rc;
+            pState->moffStream += pcbRead ? *pcbRead : cbToRead;
+            return VINF_SUCCESS;
+        }
+        if (rc != VERR_TIMEOUT)
+            return rc;
+        if (pState->mfStopReading)
+            return VERR_EOF;
+    }
 }
 
@@ -289,4 +306,6 @@
 static DECLCALLBACK(int) migrationTcpOpClose(void *pvUser)
 {
+    MigrationState *pState = (MigrationState *)pvUser;
+    ASMAtomicWriteBool(&pState->mfStopReading, true);
     return VINF_SUCCESS;
 }
@@ -336,4 +355,11 @@
     { AutoWriteLock autoLock(); }
 
+    BOOL fCanceled = TRUE;
+    HRESULT hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCanceled);
+    if (FAILED(hrc))
+        return hrc;
+    if (fCanceled)
+        return setError(E_FAIL, tr("canceled"));
+
     /*
      * Try connect to the destination machine.
@@ -341,5 +367,5 @@
      */
     int vrc = RTTcpClientConnect(pState->mstrHostname.c_str(), pState->muPort, &pState->mhSocket);
-    if (RT_SUCCESS(vrc))
+    if (RT_FAILURE(vrc))
         return setError(E_FAIL, tr("Failed to connect to port %u on '%s': %Rrc"),
                         pState->muPort, pState->mstrHostname.c_str(), vrc);
@@ -360,5 +386,5 @@
 
     /* ACK */
-    HRESULT hrc = migrationSrcReadACK(pState);
+    hrc = migrationSrcReadACK(pState, tr("Invalid password"));
     if (FAILED(hrc))
         return hrc;
@@ -407,4 +433,36 @@
     HRESULT hrc = pState->mptrConsole->migrationSrc(pState);
     pState->mptrProgress->notifyComplete(hrc);
+
+    if (    FAILED(hrc)
+        &&  pState->mptrConsole->mMachineState == MachineState_Saving)
+    {
+        VMSTATE enmVMState = VMR3GetState(pState->mpVM);
+        switch (enmVMState)
+        {
+            case VMSTATE_RUNNING:
+            case VMSTATE_RUNNING_LS:
+            case VMSTATE_DEBUGGING:
+            case VMSTATE_DEBUGGING_LS:
+            case VMSTATE_POWERING_OFF:
+            case VMSTATE_POWERING_OFF_LS:
+            case VMSTATE_RESETTING:
+            case VMSTATE_RESETTING_LS:
+                pState->mptrConsole->setMachineState(MachineState_Running);
+                break;
+            case VMSTATE_GURU_MEDITATION:
+            case VMSTATE_GURU_MEDITATION_LS:
+                pState->mptrConsole->setMachineState(MachineState_Stuck);
+                break;
+            default:
+                AssertMsgFailed(("%s\n", VMR3GetStateName(enmVMState)));
+            case VMSTATE_SUSPENDED:
+            case VMSTATE_SUSPENDED_LS:
+            case VMSTATE_SUSPENDING:
+            case VMSTATE_SUSPENDING_LS:
+            case VMSTATE_SUSPENDING_EXT_LS:
+                pState->mptrConsole->setMachineState(MachineState_Paused);
+                break;
+        }
+    }
 
     if (pState->mhSocket != NIL_RTSOCKET)
@@ -480,10 +538,21 @@
     pState->mptrProgress = ptrMigrateProgress;
 
-    int vrc = RTThreadCreate(NULL, Console::migrationSrcThreadWrapper, pState, 0 /*cbStack*/,
+    int vrc = RTThreadCreate(NULL, Console::migrationSrcThreadWrapper, (void *)pState, 0 /*cbStack*/,
                              RTTHREADTYPE_EMULATION, 0 /*fFlags*/, "Migrate");
     if (RT_SUCCESS(vrc))
+    {
+        hrc = setMachineState(MachineState_Saving);
+        if (SUCCEEDED(hrc))
+            ptrMigrateProgress.queryInterfaceTo(aProgress);
+        else
+            ptrMigrateProgress->Cancel();
+    }
+    else
+    {
         delete pState;
-
-    return E_FAIL;
+        hrc = setError(E_FAIL, tr("RTThreadCreate -> %Rrc"), vrc);
+    }
+
+    return hrc;
 }
 
@@ -496,9 +565,11 @@
  * @param   pVM                 The VM handle
  * @param   pMachine            The IMachine for the virtual machine.
+ * @param   fStartPaused        Whether to start it in the Paused (true) or
+ *                              Running (false) state,
  * @param   pvVMCallbackTask    The callback task pointer for
  *                              stateProgressCallback().
  */
 int
-Console::migrationDst(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask)
+Console::migrationDst(PVM pVM, IMachine *pMachine, bool fStartPaused, void *pvVMCallbackTask)
 {
     /*
@@ -515,8 +586,10 @@
         return VERR_GENERAL_FAILURE;
     Utf8Str strPassword(bstrPassword);
+    strPassword.append('\n');           /* To simplify password checking. */
 
     Utf8Str strBind("");
     /** @todo Add a bind address property. */
     const char *pszBindAddress = strBind.isEmpty() ? NULL : strBind.c_str();
+
 
     /*
@@ -563,11 +636,22 @@
              */
             MigrationStateDst State(this, pVM, pMachine);
-            State.mstrPassword = strPassword;
+            State.mstrPassword      = strPassword;
+            State.mhServer          = hServer;
+            State.mpvVMCallbackTask = pvVMCallbackTask;
 
             vrc = RTTcpServerListen(hServer, Console::migrationDstServeConnection, &State);
             if (vrc == VERR_TCP_SERVER_STOP)
                 vrc = State.mRc;
-            if (RT_FAILURE(vrc))
+            if (RT_SUCCESS(vrc))
+            {
+                if (fStartPaused)
+                    setMachineState(MachineState_Paused);
+                else
+                    vrc = VMR3Resume(pVM);
+            }
+            else
+            {
                 LogRel(("Migration: RTTcpServerListen -> %Rrc\n", vrc));
+            }
         }
 
@@ -586,5 +670,6 @@
 Console::migrationDstServeConnection(RTSOCKET Sock, void *pvUser)
 {
-    MigrationStateDst *pState   = (MigrationStateDst *)pvUser;
+    MigrationStateDst *pState = (MigrationStateDst *)pvUser;
+    pState->mhSocket = Sock;
 
     /*
@@ -603,5 +688,4 @@
      * this is the last connection attempt).
      */
-    pState->mstrPassword.append('\n');
     const char *pszPassword = pState->mstrPassword.c_str();
     unsigned    off = 0;
@@ -625,10 +709,9 @@
     if (RT_FAILURE(vrc))
         return vrc;
-    RTTcpServerShutdown((PRTTCPSERVER)pvUser);
+    RTTcpServerShutdown(pState->mhServer);
 
     /*
      * Command processing loop.
      */
-    pState->mhSocket = Sock;
     for (;;)
     {
@@ -671,6 +754,6 @@
         }
     }
+
     pState->mhSocket = NIL_RTSOCKET;
-
     return VERR_TCP_SERVER_STOP;
 }
Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 23668)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 23669)
@@ -4614,4 +4614,14 @@
     }
 
+    /* test and clear the LiveMigrationTarget property  */
+    BOOL fLiveMigrationTarget;
+    rc = mMachine->COMGETTER(LiveMigrationTarget)(&fLiveMigrationTarget);
+    CheckComRCReturnRC(rc);
+    if (fLiveMigrationTarget)
+    {
+        rc = mMachine->COMSETTER(LiveMigrationTarget)(FALSE);
+        CheckComRCReturnRC(rc);
+    }
+
     /* create a progress object to track progress of this operation */
     ComObjPtr<Progress> powerupProgress;
@@ -4620,4 +4630,6 @@
     if (mMachineState == MachineState_Saved)
         progressDesc = tr("Restoring virtual machine");
+    else if (fLiveMigrationTarget)
+        progressDesc = tr("Migrating virtual machine");
     else
         progressDesc = tr("Starting virtual machine");
@@ -4638,13 +4650,5 @@
     if (mMachineState == MachineState_Saved)
         task->mSavedStateFile = savedStateFile;
-
-    /* test and clear the LiveMigrationTarget property  */
-    rc = mMachine->COMGETTER(LiveMigrationTarget)(&task->mLiveMigrationTarget);
-    CheckComRCReturnRC(rc);
-    if (task->mLiveMigrationTarget)
-    {
-        rc = mMachine->COMSETTER(LiveMigrationTarget)(FALSE);
-        CheckComRCReturnRC(rc);
-    }
+    task->mLiveMigrationTarget = fLiveMigrationTarget;
 
     /* Reset differencing hard disks for which autoReset is true */
@@ -4726,5 +4730,6 @@
      * any error reporting and appropriate state change! */
 
-    if (mMachineState == MachineState_Saved)
+    if (   mMachineState == MachineState_Saved
+        || fLiveMigrationTarget)
         setMachineState(MachineState_Restoring);
     else
@@ -6743,6 +6748,11 @@
                 }
                 else if (task->mLiveMigrationTarget)
+                {
                     /* -> ConsoleImpl-LiveMigration.cpp */
-                    vrc = console->migrationDst(pVM, pMachine, static_cast<VMProgressTask*>(task.get()));
+                    vrc = console->migrationDst(pVM, pMachine, task->mStartPaused,
+                                                static_cast<VMProgressTask*>(task.get()));
+                    if (RT_FAILURE(vrc))
+                        VMR3PowerOff(pVM);
+                }
                 else if (task->mStartPaused)
                     /* done */
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 23668)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 23669)
@@ -518,7 +518,7 @@
     static DECLCALLBACK(int)    migrationSrcThreadWrapper(RTTHREAD hThread, void *pvUser);
     HRESULT                     migrationSrc(MigrationStateSrc *pState);
-    HRESULT                     migrationSrcReadACK(MigrationStateSrc *pState);
+    HRESULT                     migrationSrcReadACK(MigrationStateSrc *pState, const char *pszNAckMsg = NULL);
     HRESULT                     migrationSrcSubmitCommand(MigrationStateSrc *pState, const char *pszCommand);
-    int                         migrationDst(PVM pVM, IMachine *pMachine, void *pvVMCallbackTask);
+    int                         migrationDst(PVM pVM, IMachine *pMachine, bool fStartPaused, void *pvVMCallbackTask);
     static DECLCALLBACK(int)    migrationDstServeConnection(RTSOCKET Sock, void *pvUser);
     /** @} */
