summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMR3/FTM.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMR3/FTM.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMR3/FTM.cpp')
-rw-r--r--src/VBox/VMM/VMMR3/FTM.cpp127
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);