Changeset 24874 in vbox
- Timestamp:
- Nov 23, 2009 3:37:58 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
-
include/VBox/ssm.h (modified) (2 diffs)
-
include/VBox/vmapi.h (modified) (1 diff)
-
src/VBox/Frontends/VBoxManage/VBoxManage.cpp (modified) (3 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp (modified) (1 diff)
-
src/VBox/Main/ConsoleImplTeleporter.cpp (modified) (6 diffs)
-
src/VBox/Main/idl/VirtualBox.xidl (modified) (2 diffs)
-
src/VBox/Main/include/ConsoleImpl.h (modified) (1 diff)
-
src/VBox/VMM/PGM.cpp (modified) (1 diff)
-
src/VBox/VMM/PGMInternal.h (modified) (1 diff)
-
src/VBox/VMM/PGMSavedState.cpp (modified) (10 diffs)
-
src/VBox/VMM/SSM.cpp (modified) (6 diffs)
-
src/VBox/VMM/VM.cpp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/ssm.h
r24843 r24874 1001 1001 VMMR3DECL(int) SSMR3DeregisterExternal(PVM pVM, const char *pszName); 1002 1002 VMMR3DECL(int) SSMR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser); 1003 VMMR3_INT_DECL(int) SSMR3LiveSave(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOps, 1004 SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, PSSMHANDLE *ppSSM); 1003 VMMR3_INT_DECL(int) SSMR3LiveSave(PVM pVM, uint32_t cMsMaxDowntime, 1004 const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOps, 1005 SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, 1006 PSSMHANDLE *ppSSM); 1005 1007 VMMR3_INT_DECL(int) SSMR3LiveDoStep1(PSSMHANDLE pSSM); 1006 1008 VMMR3_INT_DECL(int) SSMR3LiveDoStep2(PSSMHANDLE pSSM); … … 1016 1018 VMMR3DECL(SSMAFTER) SSMR3HandleGetAfter(PSSMHANDLE pSSM); 1017 1019 VMMR3DECL(bool) SSMR3HandleIsLiveSave(PSSMHANDLE pSSM); 1020 VMMR3DECL(uint32_t) SSMR3HandleMaxDowntime(PSSMHANDLE pSSM); 1018 1021 VMMR3DECL(uint32_t) SSMR3HandleHostBits(PSSMHANDLE pSSM); 1019 1022 VMMR3DECL(uint32_t) SSMR3HandleRevision(PSSMHANDLE pSSM); -
trunk/include/VBox/vmapi.h
r24740 r24874 337 337 338 338 VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser); 339 VMMR3DECL(int) VMR3Teleport(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended);339 VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended); 340 340 VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); 341 341 VMMR3DECL(int) VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r24493 r24874 1296 1296 { 1297 1297 Bstr bstrHostname; 1298 uint32_t uPort = UINT32_MAX; 1298 uint32_t uMaxDowntime = 250 /*ms*/; 1299 uint32_t uPort = UINT32_MAX; 1299 1300 Bstr bstrPassword(""); 1300 1301 static const RTGETOPTDEF s_aTeleportOptions[] = 1301 1302 { 1302 { "--hostname", 'h', RTGETOPT_REQ_STRING }, /** @todo RTGETOPT_FLAG_MANDATORY */ 1303 { "--host", 'h', RTGETOPT_REQ_STRING }, /** @todo RTGETOPT_FLAG_MANDATORY */ 1304 { "--hostname", 'h', RTGETOPT_REQ_STRING }, /** @todo remove this */ 1305 { "--maxdowntime", 'd', RTGETOPT_REQ_UINT32 }, 1303 1306 { "--port", 'p', RTGETOPT_REQ_UINT32 }, /** @todo RTGETOPT_FLAG_MANDATORY */ 1304 1307 { "--password", 'P', RTGETOPT_REQ_STRING } … … 1314 1317 { 1315 1318 case 'h': bstrHostname = Value.psz; break; 1319 case 'd': uMaxDowntime = Value.u32; break; 1316 1320 case 'p': uPort = Value.u32; break; 1317 1321 case 'P': bstrPassword = Value.psz; break; … … 1326 1330 1327 1331 ComPtr<IProgress> progress; 1328 CHECK_ERROR_BREAK(console, Teleport(bstrHostname, uPort, bstrPassword, progress.asOutParam()));1332 CHECK_ERROR_BREAK(console, Teleport(bstrHostname, uPort, bstrPassword, uMaxDowntime, progress.asOutParam())); 1329 1333 showProgress(progress); 1330 1334 -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
r24864 r24874 309 309 " setcredentials <username> <password> <domain>\n" 310 310 " [--allowlocallogon <yes|no>] |\n" 311 " teleport --host name<name> --port <port>\n"312 " [-- password password]\n"311 " teleport --host <name> --port <port>\n" 312 " [--maxdowntime <msec>] [--password password]\n" 313 313 "\n"); 314 314 } -
trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
r24770 r24874 92 92 Utf8Str mstrHostname; 93 93 uint32_t muPort; 94 uint32_t mcMsMaxDowntime; 94 95 MachineState_T menmOldMachineState; 95 96 bool mfSuspendedByUs; … … 99 100 : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/) 100 101 , muPort(UINT32_MAX) 102 , mcMsMaxDowntime(250) 101 103 , menmOldMachineState(enmOldMachineState) 102 104 , mfSuspendedByUs(false) … … 640 642 641 643 void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState)); 642 vrc = VMR3Teleport(pState->mpVM, &g_teleporterTcpOps, pvUser, teleporterProgressCallback, pvUser, &pState->mfSuspendedByUs); 644 vrc = VMR3Teleport(pState->mpVM, pState->mcMsMaxDowntime, 645 &g_teleporterTcpOps, pvUser, 646 teleporterProgressCallback, pvUser, 647 &pState->mfSuspendedByUs); 643 648 if (RT_FAILURE(vrc)) 644 649 return setError(E_FAIL, tr("VMR3Teleport -> %Rrc"), vrc); … … 854 859 * @returns COM status code. 855 860 * 856 * @param aHostname The name of the target host. 857 * @param aPort The TCP port number. 858 * @param aPassword The password. 859 * @param aProgress Where to return the progress object. 861 * @param aHostname The name of the target host. 862 * @param aPort The TCP port number. 863 * @param aPassword The password. 864 * @param aMaxDowntime Max allowed "downtime" in milliseconds. 865 * @param aProgress Where to return the progress object. 860 866 */ 861 867 STDMETHODIMP 862 Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, IProgress **aProgress)868 Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress) 863 869 { 864 870 /* … … 870 876 CheckComArgNotNull(aHostname); 871 877 CheckComArgExprMsg(aPort, aPort > 0 && aPort <= 65535, ("is %u", aPort)); 878 CheckComArgExprMsg(aMaxDowntime, aMaxDowntime > 0, ("is %u", aMaxDowntime)); 872 879 873 880 AutoCaller autoCaller(this); … … 903 910 904 911 TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM, ptrProgress, mMachineState); 905 pState->mstrPassword = aPassword; 906 pState->mstrHostname = aHostname; 907 pState->muPort = aPort; 912 pState->mstrPassword = aPassword; 913 pState->mstrHostname = aHostname; 914 pState->muPort = aPort; 915 pState->mcMsMaxDowntime = aMaxDowntime; 908 916 909 917 void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState)); -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r24865 r24874 6442 6442 <interface 6443 6443 name="IConsole" extends="$unknown" 6444 uuid=" 55dd56a5-1d1d-4d81-b742-b082b9571be6"6444 uuid="6375231a-c17c-464b-92cb-ae9e128d71c3" 6445 6445 wsmap="managed" 6446 6446 > … … 7147 7147 <param name="password" type="wstring" dir="in"> 7148 7148 <desc>The password.</desc> 7149 </param> 7150 <param name="maxDowntime" type="unsigned long" dir="in"> 7151 <desc> 7152 The maximum allowed downtime given as milliseconds. 0 is not a valid 7153 value. Recommended value: 250 ms. 7154 7155 The higher the value is, the greater the chance for a successful 7156 teleportation. A small value may easily result in the teleportation 7157 process taking hours and eventually fail. 7158 7159 <note> 7160 The current implementation treats this a guideline, not as an 7161 absolute rule. 7162 </note> 7163 </desc> 7149 7164 </param> 7150 7165 <param name="progress" type="IProgress" dir="return"> -
trunk/src/VBox/Main/include/ConsoleImpl.h
r24703 r24874 147 147 STDMETHOD(DeleteSnapshot)(IN_BSTR aId, IProgress **aProgress); 148 148 STDMETHOD(RestoreSnapshot)(ISnapshot *aSnapshot, IProgress **aProgress); 149 STDMETHOD(Teleport)(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, IProgress **aProgress);149 STDMETHOD(Teleport)(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress); 150 150 STDMETHOD(RegisterCallback) (IConsoleCallback *aCallback); 151 151 STDMETHOD(UnregisterCallback)(IConsoleCallback *aCallback); -
trunk/src/VBox/VMM/PGM.cpp
r24797 r24874 1581 1581 STAM_REL_REG_USED(pVM, &pPGM->LiveSave.cDirtyPagesLong, STAMTYPE_U32, "/PGM/LiveSave/cDirtyPagesLong", STAMUNIT_COUNT, "Longer term dirty page average."); 1582 1582 STAM_REL_REG_USED(pVM, &pPGM->LiveSave.cDirtyPagesShort, STAMTYPE_U32, "/PGM/LiveSave/cDirtyPagesShort", STAMUNIT_COUNT, "Short term dirty page average."); 1583 STAM_REL_REG_USED(pVM, &pPGM->LiveSave.cPagesPerSecond, STAMTYPE_U32, "/PGM/LiveSave/cPagesPerSecond", STAMUNIT_COUNT, "Pages per second."); 1584 STAM_REL_REG_USED(pVM, &pPGM->LiveSave.cSavedPages, STAMTYPE_U64, "/PGM/LiveSave/cSavedPages", STAMUNIT_COUNT, "The total number of saved pages."); 1583 1585 STAM_REL_REG_USED(pVM, &pPGM->LiveSave.Ram.cReadyPages, STAMTYPE_U32, "/PGM/LiveSave/Ram/cReadPages", STAMUNIT_COUNT, "RAM: Ready pages."); 1584 1586 STAM_REL_REG_USED(pVM, &pPGM->LiveSave.Ram.cDirtyPages, STAMTYPE_U32, "/PGM/LiveSave/Ram/cDirtyPages", STAMUNIT_COUNT, "RAM: Dirty pages."); -
trunk/src/VBox/VMM/PGMInternal.h
r24807 r24874 2754 2754 /** Long term dirty page average. */ 2755 2755 uint32_t cDirtyPagesLong; 2756 /** The number of saved pages. This is used to get some kind of estimate of the 2757 * link speed so we can decide when we're done. It is reset after the first 2758 * 7 passes so the speed estimate doesn't get inflated by the initial set of 2759 * zero pages. */ 2760 uint64_t cSavedPages; 2761 /** The nanosecond timestamp when cSavedPages was 0. */ 2762 uint64_t uSaveStartNS; 2763 /** Pages per second (for statistics). */ 2764 uint32_t cPagesPerSecond; 2765 uint32_t cAlignment; 2756 2766 } LiveSave; 2757 2767 -
trunk/src/VBox/VMM/PGMSavedState.cpp
r24808 r24874 437 437 pVM->pgm.s.LiveSave.Rom.cDirtyPages--; 438 438 pVM->pgm.s.LiveSave.Rom.cReadyPages++; 439 pVM->pgm.s.LiveSave.cSavedPages++; 439 440 } 440 441 } … … 502 503 pVM->pgm.s.LiveSave.Rom.cReadyPages++; 503 504 pVM->pgm.s.LiveSave.Rom.cDirtyPages--; 505 pVM->pgm.s.LiveSave.cSavedPages++; 504 506 } 505 507 pgmUnlock(pVM); … … 880 882 } 881 883 u8Type = paLSPages[iPage].fZero ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 884 pVM->pgm.s.LiveSave.cSavedPages++; 882 885 } 883 886 … … 957 960 if (u8Type == PGM_STATE_REC_MMIO2_ZERO) 958 961 pVM->pgm.s.LiveSave.Mmio2.cZeroPages++; 962 pVM->pgm.s.LiveSave.cSavedPages++; 959 963 iPageLast = iPage; 960 964 } … … 1608 1612 pVM->pgm.s.LiveSave.Ram.cZeroPages++; 1609 1613 pVM->pgm.s.LiveSave.Ram.cDirtyPages--; 1614 pVM->pgm.s.LiveSave.cSavedPages++; 1610 1615 } 1611 1616 if (idRamRangesGen != pVM->pgm.s.idRamRangesGen) … … 1723 1728 return rc; 1724 1729 } 1730 /* 1731 * Reset the page-per-second estimate to avoid inflation by the initial 1732 * load of zero pages. pgmR3LiveVote ASSUMES this is done at pass 7. 1733 */ 1734 else if (uPass == 7) 1735 { 1736 pVM->pgm.s.LiveSave.cSavedPages = 0; 1737 pVM->pgm.s.LiveSave.uSaveStartNS = RTTimeNanoTS(); 1738 } 1725 1739 1726 1740 /* … … 1768 1782 1769 1783 /* update history. */ 1784 pgmLock(pVM); 1785 uint32_t const cWrittenToPages = pVM->pgm.s.cWrittenToPages; 1786 pgmUnlock(pVM); 1770 1787 uint32_t i = pVM->pgm.s.LiveSave.iDirtyPagesHistory; 1771 1788 pVM->pgm.s.LiveSave.acDirtyPagesHistory[i] = pVM->pgm.s.LiveSave.Rom.cDirtyPages 1772 1789 + pVM->pgm.s.LiveSave.Mmio2.cDirtyPages 1773 + pVM->pgm.s.LiveSave.Ram.cDirtyPages; 1790 + pVM->pgm.s.LiveSave.Ram.cDirtyPages 1791 + cWrittenToPages; 1774 1792 pVM->pgm.s.LiveSave.iDirtyPagesHistory = (i + 1) % cHistoryEntries; 1775 1793 … … 1794 1812 pVM->pgm.s.LiveSave.cDirtyPagesLong = cDirtyPagesLong; 1795 1813 1814 /* estimate the speed */ 1815 uint64_t cNsElapsed = RTTimeNanoTS() - pVM->pgm.s.LiveSave.uSaveStartNS; 1816 uint32_t cPagesPerSecond = (uint32_t)( pVM->pgm.s.LiveSave.cSavedPages 1817 / ((long double)cNsElapsed / 1000000000.0) ); 1818 pVM->pgm.s.LiveSave.cPagesPerSecond = cPagesPerSecond; 1819 1796 1820 /* 1797 1821 * Try make a decision. 1798 1822 */ 1799 /** @todo take the count dirtied write-monitored page into account here. */1800 1823 if (cDirtyPagesShort <= cDirtyPagesLong) 1801 1824 { 1802 if ( cDirtyPagesShort <= 128 1803 && cDirtyPagesLong <= 1024) 1804 return VINF_SUCCESS; 1805 if (cDirtyPagesLong <= 256) 1806 return VINF_SUCCESS; 1807 /* !! hack !! */ 1808 if ( cDirtyPagesShort <= 512 1809 && cDirtyPagesLong <= 640 1810 && uPass >= 1024) 1811 return VINF_SUCCESS; 1812 if ( cDirtyPagesShort <= 896 1813 && cDirtyPagesLong <= 1024 1814 && uPass >= 2048) 1815 return VINF_SUCCESS; 1816 if ( cDirtyPagesShort <= 1512 1817 && cDirtyPagesLong <= 1536 1818 && uPass >= 4096) 1819 return VINF_SUCCESS; 1820 if ( cDirtyPagesLong <= 4096 1821 && uPass >= 8192) 1822 return VINF_SUCCESS; 1825 if (uPass > 10) 1826 { 1827 uint32_t cMsLeftShort = (uint32_t)(cDirtyPagesShort / (long double)cPagesPerSecond * 1000.0); 1828 uint32_t cMsLeftLong = (uint32_t)(cDirtyPagesLong / (long double)cPagesPerSecond * 1000.0); 1829 uint32_t cMsMaxDowntime = SSMR3HandleMaxDowntime(pSSM); 1830 if (cMsMaxDowntime < 32) 1831 cMsMaxDowntime = 32; 1832 if ( ( cMsLeftLong <= cMsMaxDowntime 1833 && cMsLeftShort < cMsMaxDowntime) 1834 || cMsLeftShort < cMsMaxDowntime / 2 1835 ) 1836 { 1837 Log(("pgmR3LiveVote: VINF_SUCCESS - pass=%d cDirtyPagesShort=%u|%ums cDirtyPagesLong=%u|%ums cMsMaxDowntime=%u\n", 1838 uPass, cDirtyPagesShort, cMsLeftShort, cDirtyPagesLong, cMsLeftLong, cMsMaxDowntime)); 1839 return VINF_SUCCESS; 1840 } 1841 } 1842 else 1843 { 1844 if ( ( cDirtyPagesShort <= 128 1845 && cDirtyPagesLong <= 1024) 1846 || cDirtyPagesLong <= 256 1847 ) 1848 { 1849 Log(("pgmR3LiveVote: VINF_SUCCESS - pass=%d cDirtyPagesShort=%u cDirtyPagesLong=%u\n", uPass, cDirtyPagesShort, cDirtyPagesLong)); 1850 return VINF_SUCCESS; 1851 } 1852 } 1823 1853 } 1824 1854 return VINF_SSM_VOTE_FOR_ANOTHER_PASS; … … 1867 1897 pVM->pgm.s.LiveSave.acDirtyPagesHistory[i] = UINT32_MAX / 2; 1868 1898 pVM->pgm.s.LiveSave.iDirtyPagesHistory = 0; 1899 pVM->pgm.s.LiveSave.cSavedPages = 0; 1900 pVM->pgm.s.LiveSave.uSaveStartNS = RTTimeNanoTS(); 1901 pVM->pgm.s.LiveSave.cPagesPerSecond = 8192; 1869 1902 1870 1903 /* … … 2980 3013 return SSMR3RegisterInternal(pVM, "pgm", 1, PGM_SAVED_STATE_VERSION, (size_t)cbRam + sizeof(PGM), 2981 3014 pgmR3LivePrep, pgmR3LiveExec, pgmR3LiveVote, 2982 NULL, pgmR3SaveExec, pgmR3SaveDone,2983 pgmR3LoadPrep, pgmR3Load, NULL);2984 } 2985 3015 NULL, pgmR3SaveExec, pgmR3SaveDone, 3016 pgmR3LoadPrep, pgmR3Load, NULL); 3017 } 3018 -
trunk/src/VBox/VMM/SSM.cpp
r24846 r24874 504 504 /** Data buffer. */ 505 505 uint8_t abDataBuffer[4096]; 506 /** The maximum downtime given as milliseconds. */ 507 uint32_t cMsMaxDowntime; 506 508 } Write; 507 509 … … 4604 4606 return VERR_NO_MEMORY; 4605 4607 4606 pSSM->pVM = pVM; 4607 pSSM->enmOp = SSMSTATE_INVALID; 4608 pSSM->enmAfter = enmAfter; 4609 pSSM->fCancelled = SSMHANDLE_OK; 4610 pSSM->rc = VINF_SUCCESS; 4611 pSSM->cbUnitLeftV1 = 0; 4612 pSSM->offUnit = UINT64_MAX; 4613 pSSM->fLiveSave = false; 4614 pSSM->pfnProgress = pfnProgress; 4615 pSSM->pvUser = pvProgressUser; 4616 pSSM->uPercent = 0; 4617 pSSM->offEstProgress = 0; 4618 pSSM->cbEstTotal = 0; 4619 pSSM->offEst = 0; 4620 pSSM->offEstUnitEnd = 0; 4621 pSSM->uPercentPrepare = 0; 4622 pSSM->uPercentDone = 0; 4623 pSSM->pszFilename = pszFilename; 4624 pSSM->u.Write.offDataBuffer = 0; 4608 pSSM->pVM = pVM; 4609 pSSM->enmOp = SSMSTATE_INVALID; 4610 pSSM->enmAfter = enmAfter; 4611 pSSM->fCancelled = SSMHANDLE_OK; 4612 pSSM->rc = VINF_SUCCESS; 4613 pSSM->cbUnitLeftV1 = 0; 4614 pSSM->offUnit = UINT64_MAX; 4615 pSSM->fLiveSave = false; 4616 pSSM->pfnProgress = pfnProgress; 4617 pSSM->pvUser = pvProgressUser; 4618 pSSM->uPercent = 0; 4619 pSSM->offEstProgress = 0; 4620 pSSM->cbEstTotal = 0; 4621 pSSM->offEst = 0; 4622 pSSM->offEstUnitEnd = 0; 4623 pSSM->uPercentPrepare = 0; 4624 pSSM->uPercentDone = 0; 4625 pSSM->pszFilename = pszFilename; 4626 pSSM->u.Write.offDataBuffer = 0; 4627 pSSM->u.Write.cMsMaxDowntime = UINT32_MAX; 4625 4628 4626 4629 int rc; … … 5097 5100 * 5098 5101 * @param pVM The VM handle. 5102 * @param cMsMaxDowntime The maximum downtime given as milliseconds. 5099 5103 * @param pszFilename Name of the file to save the state in. This string 5100 5104 * must remain valid until SSMR3LiveDone is called. … … 5109 5113 * @thread EMT0 5110 5114 */ 5111 VMMR3_INT_DECL(int) SSMR3LiveSave(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, 5112 SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, PSSMHANDLE *ppSSM) 5113 { 5114 LogFlow(("SSMR3LiveSave: pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p\n", 5115 pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser)); 5115 VMMR3_INT_DECL(int) SSMR3LiveSave(PVM pVM, uint32_t cMsMaxDowntime, 5116 const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, 5117 SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, 5118 PSSMHANDLE *ppSSM) 5119 { 5120 LogFlow(("SSMR3LiveSave: cMsMaxDowntime=%u pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p\n", 5121 cMsMaxDowntime, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser)); 5116 5122 VM_ASSERT_EMT0(pVM); 5117 5123 … … 5148 5154 if (RT_FAILURE(rc)) 5149 5155 return rc; 5150 pSSM->uPercentPrepare = 20; /** @todo fix these. */ 5151 pSSM->uPercentDone = 2; 5152 pSSM->fLiveSave = true; 5156 pSSM->uPercentPrepare = 20; /** @todo fix these. */ 5157 pSSM->uPercentDone = 2; 5158 pSSM->fLiveSave = true; 5159 pSSM->u.Write.cMsMaxDowntime = cMsMaxDowntime; 5153 5160 5154 5161 /* … … 8645 8652 8646 8653 /** 8654 * Gets the maximum downtime for a live operation. 8655 * 8656 * @returns The max downtime in milliseconds. Can be anything from 0 thru 8657 * UINT32_MAX. 8658 * 8659 * @param pSSM The saved state handle. 8660 */ 8661 VMMR3DECL(uint32_t) SSMR3HandleMaxDowntime(PSSMHANDLE pSSM) 8662 { 8663 SSM_ASSERT_VALID_HANDLE(pSSM); 8664 if (pSSM->enmOp <= SSMSTATE_SAVE_DONE) 8665 return pSSM->u.Write.cMsMaxDowntime; 8666 return UINT32_MAX; 8667 } 8668 8669 8670 /** 8647 8671 * Gets the host bit count of a saved state. 8648 8672 * -
trunk/src/VBox/VMM/VM.cpp
r24785 r24874 1585 1585 * 1586 1586 * @param pVM The VM handle. 1587 * @param cMsMaxDowntime The maximum downtime given as milliseconds. 1587 1588 * @param pszFilename The name of the file. NULL if pStreamOps is used. 1588 1589 * @param pStreamOps The stream methods. NULL if pszFilename is used. … … 1595 1596 * @thread EMT 1596 1597 */ 1597 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,1598 static DECLCALLBACK(int) vmR3Save(PVM pVM, uint32_t cMsMaxDowntime, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, 1598 1599 SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, PSSMHANDLE *ppSSM) 1599 1600 { 1600 LogFlow(("vmR3Save: pVM=%p pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p ppSSM=%p\n",1601 pVM, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser, ppSSM));1601 LogFlow(("vmR3Save: pVM=%p cMsMaxDowntime=%u pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p ppSSM=%p\n", 1602 pVM, cMsMaxDowntime, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser, ppSSM)); 1602 1603 1603 1604 /* … … 1629 1630 if (enmAfter == SSMAFTER_TELEPORT) 1630 1631 pVM->vm.s.fTeleportedAndNotFullyResumedYet = true; 1631 rc = SSMR3LiveSave(pVM, pszFilename, pStreamOps, pvStreamOpsUser,1632 rc = SSMR3LiveSave(pVM, cMsMaxDowntime, pszFilename, pStreamOps, pvStreamOpsUser, 1632 1633 enmAfter, pfnProgress, pvProgressUser, ppSSM); 1633 1634 /* (We're not subject to cancellation just yet.) */ … … 1645 1646 * 1646 1647 * @param pVM The VM handle. 1648 * @param cMsMaxDowntime The maximum downtime given as milliseconds. 1647 1649 * @param pszFilename The name of the file. NULL if pStreamOps is used. 1648 1650 * @param pStreamOps The stream methods. NULL if pszFilename is used. … … 1655 1657 * @thread Non-EMT 1656 1658 */ 1657 static int vmR3SaveTeleport(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, 1659 static int vmR3SaveTeleport(PVM pVM, uint32_t cMsMaxDowntime, 1660 const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, 1658 1661 SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended) 1659 1662 { … … 1663 1666 PSSMHANDLE pSSM; 1664 1667 int rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/, 1665 (PFNRT)vmR3Save, 8, pVM, pszFilename, pStreamOps, pvStreamOpsUser,1668 (PFNRT)vmR3Save, 9, pVM, cMsMaxDowntime, pszFilename, pStreamOps, pvStreamOpsUser, 1666 1669 enmAfter, pfnProgress, pvProgressUser, &pSSM); 1667 1670 if ( RT_SUCCESS(rc) … … 1756 1759 bool fSuspended = false; /** @todo need this for live snapshots. */ 1757 1760 SSMAFTER enmAfter = fContinueAfterwards ? SSMAFTER_CONTINUE : SSMAFTER_DESTROY; 1758 int rc = vmR3SaveTeleport(pVM, pszFilename, NULL /*pStreamOps*/, NULL /*pvStreamOpsUser*/, 1761 int rc = vmR3SaveTeleport(pVM, 250 /*cMsMaxDowntime*/, 1762 pszFilename, NULL /*pStreamOps*/, NULL /*pvStreamOpsUser*/, 1759 1763 enmAfter, pfnProgress, pvUser, &fSuspended); 1760 1764 LogFlow(("VMR3Save: returns %Rrc\n", rc)); … … 1769 1773 * 1770 1774 * @param pVM The VM which state should be saved. 1775 * @param cMsMaxDowntime The maximum downtime given as milliseconds. 1771 1776 * @param pStreamOps The stream methods. 1772 1777 * @param pvStreamOpsUser The user argument to the stream methods. … … 1780 1785 * RunningLS+SuspeningLS+SuspendedLS+Saving+Suspended. 1781 1786 */ 1782 VMMR3DECL(int) VMR3Teleport(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,1787 VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsMaxDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, 1783 1788 PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended) 1784 1789 { 1785 LogFlow(("VMR3Teleport: pVM=%p pStreamOps=%p pvStreamOps=%p pfnProgress=%p pvProgressUser=%p\n",1786 pVM, pStreamOps, pvStreamOpsUser, pfnProgress, pvProgressUser));1790 LogFlow(("VMR3Teleport: pVM=%p cMsMaxDowntime=%u pStreamOps=%p pvStreamOps=%p pfnProgress=%p pvProgressUser=%p\n", 1791 pVM, cMsMaxDowntime, pStreamOps, pvStreamOpsUser, pfnProgress, pvProgressUser)); 1787 1792 1788 1793 /* … … 1799 1804 * Join paths with VMR3Save. 1800 1805 */ 1801 int rc = vmR3SaveTeleport(pVM, NULL /*pszFilename*/, pStreamOps, pvStreamOpsUser, 1806 int rc = vmR3SaveTeleport(pVM, cMsMaxDowntime, 1807 NULL /*pszFilename*/, pStreamOps, pvStreamOpsUser, 1802 1808 SSMAFTER_TELEPORT, pfnProgress, pvProgressUser, pfSuspended); 1803 1809 LogFlow(("VMR3Teleport: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended));
Note:
See TracChangeset
for help on using the changeset viewer.

