diff options
Diffstat (limited to 'src/VBox/VMM/VMMR3/FTM.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMR3/FTM.cpp | 127 |
1 files changed, 68 insertions, 59 deletions
diff --git a/src/VBox/VMM/VMMR3/FTM.cpp b/src/VBox/VMM/VMMR3/FTM.cpp index ef9e468a..2318f910 100644 --- a/src/VBox/VMM/VMMR3/FTM.cpp +++ b/src/VBox/VMM/VMMR3/FTM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -20,15 +20,18 @@ * Header Files * *******************************************************************************/ #define LOG_GROUP LOG_GROUP_FTM +#include <VBox/vmm/ftm.h> +#include <VBox/vmm/em.h> +#include <VBox/vmm/pdm.h> +#include <VBox/vmm/pgm.h> +#include <VBox/vmm/ssm.h> +#include <VBox/vmm/vmm.h> #include "FTMInternal.h" #include <VBox/vmm/vm.h> -#include <VBox/vmm/vmm.h> +#include <VBox/vmm/uvm.h> #include <VBox/err.h> #include <VBox/param.h> -#include <VBox/vmm/ssm.h> #include <VBox/log.h> -#include <VBox/vmm/pgm.h> -#include <VBox/vmm/pdm.h> #include <iprt/assert.h> #include <iprt/thread.h> @@ -39,10 +42,9 @@ #include <iprt/semaphore.h> #include <iprt/asm.h> -#include "internal/vm.h" -#include "internal/em.h" #include "internal/pgm.h" + /******************************************************************************* * Structures and Typedefs * *******************************************************************************/ @@ -100,7 +102,7 @@ static DECLCALLBACK(int) ftmR3PageTreeDestroyCallback(PAVLGCPHYSNODECORE pBaseNo * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(int) FTMR3Init(PVM pVM) +VMMR3_INT_DECL(int) FTMR3Init(PVM pVM) { /* * Assert alignment and sizes. @@ -156,7 +158,7 @@ VMMR3DECL(int) FTMR3Init(PVM pVM) * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(int) FTMR3Term(PVM pVM) +VMMR3_INT_DECL(int) FTMR3Term(PVM pVM) { if (pVM->ftm.s.hShutdownEvent != NIL_RTSEMEVENT) { @@ -195,7 +197,7 @@ VMMR3DECL(int) FTMR3Term(PVM pVM) static int ftmR3TcpWriteACK(PVM pVM) { - int rc = RTTcpWrite(pVM->ftm.s.hSocket, "ACK\n", sizeof("ACK\n") - 1); + int rc = RTTcpWrite(pVM->ftm.s.hSocket, RT_STR_TUPLE("ACK\n")); if (RT_FAILURE(rc)) { LogRel(("FTSync: RTTcpWrite(,ACK,) -> %Rrc\n", rc)); @@ -283,7 +285,7 @@ static int ftmR3TcpReadACK(PVM pVM, const char *pszWhich, const char *pszNAckMsg if (!strcmp(szMsg, "ACK")) return VINF_SUCCESS; - if (!strncmp(szMsg, "NACK=", sizeof("NACK=") - 1)) + if (!strncmp(szMsg, RT_STR_TUPLE("NACK="))) { char *pszMsgText = strchr(szMsg, ';'); if (pszMsgText) @@ -331,7 +333,7 @@ static int ftmR3TcpReadACK(PVM pVM, const char *pszWhich, const char *pszNAckMsg */ static int ftmR3TcpSubmitCommand(PVM pVM, const char *pszCommand, bool fWaitForAck = true) { - int rc = RTTcpSgWriteL(pVM->ftm.s.hSocket, 2, pszCommand, strlen(pszCommand), "\n", sizeof("\n") - 1); + int rc = RTTcpSgWriteL(pVM->ftm.s.hSocket, 2, pszCommand, strlen(pszCommand), RT_STR_TUPLE("\n")); if (RT_FAILURE(rc)) return rc; if (!fWaitForAck) @@ -635,7 +637,7 @@ static int ftmR3PerformFullSync(PVM pVM) { bool fSuspended = false; - int rc = VMR3Suspend(pVM); + int rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_FTM_SYNC); AssertRCReturn(rc, rc); STAM_REL_COUNTER_INC(&pVM->ftm.s.StatFullSync); @@ -653,7 +655,7 @@ static int ftmR3PerformFullSync(PVM pVM) AssertRC(rc); pVM->ftm.s.fDeltaLoadSaveActive = false; - rc = VMR3SaveFT(pVM, &g_ftmR3TcpOps, pVM, &fSuspended, false /* fSkipStateChanges */); + rc = VMR3SaveFT(pVM->pUVM, &g_ftmR3TcpOps, pVM, &fSuspended, false /* fSkipStateChanges */); AssertRC(rc); rc = ftmR3TcpReadACK(pVM, "full-sync-complete"); @@ -665,7 +667,7 @@ static int ftmR3PerformFullSync(PVM pVM) rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3WriteProtectMemory, 1, pVM); AssertRCReturn(rc, rc); - rc = VMR3Resume(pVM); + rc = VMR3Resume(pVM->pUVM, VMRESUMEREASON_FTM_SYNC); AssertRC(rc); return rc; @@ -714,6 +716,7 @@ static DECLCALLBACK(int) ftmR3SyncDirtyPage(PVM pVM, RTGCPHYS GCPhys, uint8_t *p break; case PGMPAGETYPE_MMIO2_ALIAS_MMIO: + case PGMPAGETYPE_SPECIAL_ALIAS_MMIO: AssertFailed(); break; @@ -1088,7 +1091,7 @@ static DECLCALLBACK(int) ftmR3StandbyServeConnection(RTSOCKET Sock, void *pvUser pVM->ftm.s.syncstate.fEndOfStream = false; pVM->ftm.s.fDeltaLoadSaveActive = (fFullSync == false); - rc = VMR3LoadFromStreamFT(pVM, &g_ftmR3TcpOps, pVM); + rc = VMR3LoadFromStreamFT(pVM->pUVM, &g_ftmR3TcpOps, pVM); pVM->ftm.s.fDeltaLoadSaveActive = false; RTSocketRelease(pVM->ftm.s.hSocket); AssertRC(rc); @@ -1123,7 +1126,7 @@ static DECLCALLBACK(int) ftmR3StandbyServeConnection(RTSOCKET Sock, void *pvUser * * @returns VBox status code. * - * @param pVM Pointer to the VM. + * @param pUVM The user mode VM handle. * @param fMaster FT master or standby * @param uInterval FT sync interval * @param pszAddress Standby VM address @@ -1134,9 +1137,12 @@ static DECLCALLBACK(int) ftmR3StandbyServeConnection(RTSOCKET Sock, void *pvUser * @vmstate Created * @vmstateto PoweringOn+Running (master), PoweringOn+Running_FT (standby) */ -VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword) +VMMR3DECL(int) FTMR3PowerOn(PUVM pUVM, bool fMaster, unsigned uInterval, + const char *pszAddress, unsigned uPort, const char *pszPassword) { - int rc = VINF_SUCCESS; + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; + VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); VMSTATE enmVMState = VMR3GetState(pVM); AssertMsgReturn(enmVMState == VMSTATE_CREATED, @@ -1154,7 +1160,7 @@ VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const cha if (pszPassword) pVM->ftm.s.pszPassword = RTStrDup(pszPassword); - rc = RTSemEventCreate(&pVM->ftm.s.hShutdownEvent); + int rc = RTSemEventCreate(&pVM->ftm.s.hShutdownEvent); if (RT_FAILURE(rc)) return rc; @@ -1174,36 +1180,35 @@ VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const cha } /** @todo might need to disable page fusion as well */ - return VMR3PowerOn(pVM); + return VMR3PowerOn(pVM->pUVM); } - else - { - /* standby */ - rc = RTThreadCreate(NULL, ftmR3StandbyThread, pVM, - 0, RTTHREADTYPE_DEFAULT, 0, "ftmStandby"); - if (RT_FAILURE(rc)) - return rc; - rc = RTTcpServerCreateEx(pszAddress, uPort, &pVM->ftm.s.standby.hServer); - if (RT_FAILURE(rc)) - return rc; - pVM->ftm.s.fIsStandbyNode = true; - rc = RTTcpServerListen(pVM->ftm.s.standby.hServer, ftmR3StandbyServeConnection, pVM); - /** @todo deal with the exit code to check if we should activate this standby VM. */ - if (pVM->ftm.s.fActivateStandby) - { - /** @todo fallover. */ - } + /* standby */ + rc = RTThreadCreate(NULL, ftmR3StandbyThread, pVM, + 0, RTTHREADTYPE_DEFAULT, 0, "ftmStandby"); + if (RT_FAILURE(rc)) + return rc; - if (pVM->ftm.s.standby.hServer) - { - RTTcpServerDestroy(pVM->ftm.s.standby.hServer); - pVM->ftm.s.standby.hServer = NULL; - } - if (rc == VERR_TCP_SERVER_SHUTDOWN) - rc = VINF_SUCCESS; /* ignore this error; the standby process was cancelled. */ + rc = RTTcpServerCreateEx(pszAddress, uPort, &pVM->ftm.s.standby.hServer); + if (RT_FAILURE(rc)) + return rc; + pVM->ftm.s.fIsStandbyNode = true; + + rc = RTTcpServerListen(pVM->ftm.s.standby.hServer, ftmR3StandbyServeConnection, pVM); + /** @todo deal with the exit code to check if we should activate this standby VM. */ + if (pVM->ftm.s.fActivateStandby) + { + /** @todo fallover. */ + } + + if (pVM->ftm.s.standby.hServer) + { + RTTcpServerDestroy(pVM->ftm.s.standby.hServer); + pVM->ftm.s.standby.hServer = NULL; } + if (rc == VERR_TCP_SERVER_SHUTDOWN) + rc = VINF_SUCCESS; /* ignore this error; the standby process was cancelled. */ return rc; } @@ -1212,10 +1217,13 @@ VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const cha * * @returns VBox status code. * - * @param pVM Pointer to the VM. + * @param pUVM The user mode VM handle. */ -VMMR3DECL(int) FTMR3CancelStandby(PVM pVM) +VMMR3DECL(int) FTMR3CancelStandby(PUVM pUVM) { + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; + VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); AssertReturn(!pVM->fFaultTolerantMaster, VERR_NOT_SUPPORTED); Assert(pVM->ftm.s.standby.hServer); @@ -1266,7 +1274,7 @@ static DECLCALLBACK(VBOXSTRICTRC) ftmR3SetCheckpointRendezvous(PVM pVM, PVMCPU p AssertRC(rc); pVM->ftm.s.fDeltaLoadSaveActive = true; - rc = VMR3SaveFT(pVM, &g_ftmR3TcpOps, pVM, &fSuspended, true /* fSkipStateChanges */); + rc = VMR3SaveFT(pVM->pUVM, &g_ftmR3TcpOps, pVM, &fSuspended, true /* fSkipStateChanges */); pVM->ftm.s.fDeltaLoadSaveActive = false; AssertRC(rc); @@ -1301,7 +1309,7 @@ static DECLCALLBACK(VBOXSTRICTRC) ftmR3SetCheckpointRendezvous(PVM pVM, PVMCPU p * @param pVM Pointer to the VM. * @param enmCheckpoint Checkpoint type */ -VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmCheckpoint) +VMMR3_INT_DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmCheckpoint) { int rc; @@ -1310,17 +1318,18 @@ VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmCheckpoint) switch (enmCheckpoint) { - case FTMCHECKPOINTTYPE_NETWORK: - STAM_REL_COUNTER_INC(&pVM->ftm.s.StatCheckpointNetwork); - break; + case FTMCHECKPOINTTYPE_NETWORK: + STAM_REL_COUNTER_INC(&pVM->ftm.s.StatCheckpointNetwork); + break; - case FTMCHECKPOINTTYPE_STORAGE: - STAM_REL_COUNTER_INC(&pVM->ftm.s.StatCheckpointStorage); - break; + case FTMCHECKPOINTTYPE_STORAGE: + STAM_REL_COUNTER_INC(&pVM->ftm.s.StatCheckpointStorage); + break; - default: - break; + default: + AssertMsgFailedReturn(("%d\n", enmCheckpoint), VERR_INVALID_PARAMETER); } + pVM->ftm.s.fCheckpointingActive = true; if (VM_IS_EMT(pVM)) { @@ -1329,13 +1338,13 @@ VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmCheckpoint) /* We must take special care here as the memory sync is competing with us and requires a responsive EMT. */ while ((rc = PDMCritSectTryEnter(&pVM->ftm.s.CritSect)) == VERR_SEM_BUSY) { - if (VM_FF_ISPENDING(pVM, VM_FF_EMT_RENDEZVOUS)) + if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS)) { rc = VMMR3EmtRendezvousFF(pVM, pVCpu); AssertRC(rc); } - if (VM_FF_ISPENDING(pVM, VM_FF_REQUEST)) + if (VM_FF_IS_PENDING(pVM, VM_FF_REQUEST)) { rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY, true /*fPriorityOnly*/); AssertRC(rc); |
