VirtualBox

Changeset 24874 in vbox


Ignore:
Timestamp:
Nov 23, 2009 3:37:58 PM (15 years ago)
Author:
vboxsync
Message:

Main,VMM,VBoxManage: Added a parameter to IConsole::Teleport for specifying a max downtime and made PGM compare this against a rough estimate of the time it would take to deal with the rest of the pages.

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/ssm.h

    r24843 r24874  
    10011001VMMR3DECL(int)          SSMR3DeregisterExternal(PVM pVM, const char *pszName);
    10021002VMMR3DECL(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);
     1003VMMR3_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);
    10051007VMMR3_INT_DECL(int)     SSMR3LiveDoStep1(PSSMHANDLE pSSM);
    10061008VMMR3_INT_DECL(int)     SSMR3LiveDoStep2(PSSMHANDLE pSSM);
     
    10161018VMMR3DECL(SSMAFTER)     SSMR3HandleGetAfter(PSSMHANDLE pSSM);
    10171019VMMR3DECL(bool)         SSMR3HandleIsLiveSave(PSSMHANDLE pSSM);
     1020VMMR3DECL(uint32_t)     SSMR3HandleMaxDowntime(PSSMHANDLE pSSM);
    10181021VMMR3DECL(uint32_t)     SSMR3HandleHostBits(PSSMHANDLE pSSM);
    10191022VMMR3DECL(uint32_t)     SSMR3HandleRevision(PSSMHANDLE pSSM);
  • trunk/include/VBox/vmapi.h

    r24740 r24874  
    337337
    338338VMMR3DECL(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);
     339VMMR3DECL(int)  VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended);
    340340VMMR3DECL(int)  VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
    341341VMMR3DECL(int)  VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r24493 r24874  
    12961296        {
    12971297            Bstr        bstrHostname;
    1298             uint32_t    uPort = UINT32_MAX;
     1298            uint32_t    uMaxDowntime = 250 /*ms*/;
     1299            uint32_t    uPort        = UINT32_MAX;
    12991300            Bstr        bstrPassword("");
    13001301            static const RTGETOPTDEF s_aTeleportOptions[] =
    13011302            {
    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 },
    13031306                { "--port",        'p', RTGETOPT_REQ_UINT32 }, /** @todo RTGETOPT_FLAG_MANDATORY */
    13041307                { "--password",    'P', RTGETOPT_REQ_STRING }
     
    13141317                {
    13151318                    case 'h': bstrHostname  = Value.psz; break;
     1319                    case 'd': uMaxDowntime  = Value.u32; break;
    13161320                    case 'p': uPort         = Value.u32; break;
    13171321                    case 'P': bstrPassword  = Value.psz; break;
     
    13261330
    13271331            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()));
    13291333            showProgress(progress);
    13301334
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r24864 r24874  
    309309                 "                            setcredentials <username> <password> <domain>\n"
    310310                 "                                           [--allowlocallogon <yes|no>] |\n"
    311                  "                            teleport --hostname <name> --port <port>\n"
    312                  "                                   [--password password]\n"
     311                 "                            teleport --host <name> --port <port>\n"
     312                 "                                   [--maxdowntime <msec>] [--password password]\n"
    313313                 "\n");
    314314    }
  • trunk/src/VBox/Main/ConsoleImplTeleporter.cpp

    r24770 r24874  
    9292    Utf8Str             mstrHostname;
    9393    uint32_t            muPort;
     94    uint32_t            mcMsMaxDowntime;
    9495    MachineState_T      menmOldMachineState;
    9596    bool                mfSuspendedByUs;
     
    99100        : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/)
    100101        , muPort(UINT32_MAX)
     102        , mcMsMaxDowntime(250)
    101103        , menmOldMachineState(enmOldMachineState)
    102104        , mfSuspendedByUs(false)
     
    640642
    641643    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);
    643648    if (RT_FAILURE(vrc))
    644649        return setError(E_FAIL, tr("VMR3Teleport -> %Rrc"), vrc);
     
    854859 * @returns COM status code.
    855860 *
    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.
    860866 */
    861867STDMETHODIMP
    862 Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, IProgress **aProgress)
     868Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress)
    863869{
    864870    /*
     
    870876    CheckComArgNotNull(aHostname);
    871877    CheckComArgExprMsg(aPort, aPort > 0 && aPort <= 65535, ("is %u", aPort));
     878    CheckComArgExprMsg(aMaxDowntime, aMaxDowntime > 0, ("is %u", aMaxDowntime));
    872879
    873880    AutoCaller autoCaller(this);
     
    903910
    904911    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;
    908916
    909917    void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r24865 r24874  
    64426442  <interface
    64436443     name="IConsole" extends="$unknown"
    6444      uuid="55dd56a5-1d1d-4d81-b742-b082b9571be6"
     6444     uuid="6375231a-c17c-464b-92cb-ae9e128d71c3"
    64456445     wsmap="managed"
    64466446     >
     
    71477147      <param name="password" type="wstring" dir="in">
    71487148        <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>
    71497164      </param>
    71507165      <param name="progress" type="IProgress" dir="return">
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r24703 r24874  
    147147    STDMETHOD(DeleteSnapshot)(IN_BSTR aId, IProgress **aProgress);
    148148    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);
    150150    STDMETHOD(RegisterCallback) (IConsoleCallback *aCallback);
    151151    STDMETHOD(UnregisterCallback)(IConsoleCallback *aCallback);
  • trunk/src/VBox/VMM/PGM.cpp

    r24797 r24874  
    15811581    STAM_REL_REG_USED(pVM, &pPGM->LiveSave.cDirtyPagesLong,      STAMTYPE_U32,     "/PGM/LiveSave/cDirtyPagesLong",      STAMUNIT_COUNT,     "Longer term dirty page average.");
    15821582    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.");
    15831585    STAM_REL_REG_USED(pVM, &pPGM->LiveSave.Ram.cReadyPages,      STAMTYPE_U32,     "/PGM/LiveSave/Ram/cReadPages",       STAMUNIT_COUNT,     "RAM: Ready pages.");
    15841586    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  
    27542754        /** Long term dirty page average. */
    27552755        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;
    27562766    } LiveSave;
    27572767
  • trunk/src/VBox/VMM/PGMSavedState.cpp

    r24808 r24874  
    437437                pVM->pgm.s.LiveSave.Rom.cDirtyPages--;
    438438                pVM->pgm.s.LiveSave.Rom.cReadyPages++;
     439                pVM->pgm.s.LiveSave.cSavedPages++;
    439440            }
    440441        }
     
    502503                        pVM->pgm.s.LiveSave.Rom.cReadyPages++;
    503504                        pVM->pgm.s.LiveSave.Rom.cDirtyPages--;
     505                        pVM->pgm.s.LiveSave.cSavedPages++;
    504506                    }
    505507                    pgmUnlock(pVM);
     
    880882                    }
    881883                    u8Type = paLSPages[iPage].fZero ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW;
     884                    pVM->pgm.s.LiveSave.cSavedPages++;
    882885                }
    883886
     
    957960                if (u8Type == PGM_STATE_REC_MMIO2_ZERO)
    958961                    pVM->pgm.s.LiveSave.Mmio2.cZeroPages++;
     962                pVM->pgm.s.LiveSave.cSavedPages++;
    959963                iPageLast = iPage;
    960964            }
     
    16081612                            pVM->pgm.s.LiveSave.Ram.cZeroPages++;
    16091613                        pVM->pgm.s.LiveSave.Ram.cDirtyPages--;
     1614                        pVM->pgm.s.LiveSave.cSavedPages++;
    16101615                    }
    16111616                    if (idRamRangesGen != pVM->pgm.s.idRamRangesGen)
     
    17231728            return rc;
    17241729    }
     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    }
    17251739
    17261740    /*
     
    17681782
    17691783    /* update history. */
     1784    pgmLock(pVM);
     1785    uint32_t const cWrittenToPages = pVM->pgm.s.cWrittenToPages;
     1786    pgmUnlock(pVM);
    17701787    uint32_t i = pVM->pgm.s.LiveSave.iDirtyPagesHistory;
    17711788    pVM->pgm.s.LiveSave.acDirtyPagesHistory[i] = pVM->pgm.s.LiveSave.Rom.cDirtyPages
    17721789                                               + pVM->pgm.s.LiveSave.Mmio2.cDirtyPages
    1773                                                + pVM->pgm.s.LiveSave.Ram.cDirtyPages;
     1790                                               + pVM->pgm.s.LiveSave.Ram.cDirtyPages
     1791                                               + cWrittenToPages;
    17741792    pVM->pgm.s.LiveSave.iDirtyPagesHistory = (i + 1) % cHistoryEntries;
    17751793
     
    17941812    pVM->pgm.s.LiveSave.cDirtyPagesLong = cDirtyPagesLong;
    17951813
     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
    17961820    /*
    17971821     * Try make a decision.
    17981822     */
    1799     /** @todo take the count dirtied write-monitored page into account here. */
    18001823    if (cDirtyPagesShort <= cDirtyPagesLong)
    18011824    {
    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        }
    18231853    }
    18241854    return VINF_SSM_VOTE_FOR_ANOTHER_PASS;
     
    18671897        pVM->pgm.s.LiveSave.acDirtyPagesHistory[i] = UINT32_MAX / 2;
    18681898    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;
    18691902
    18701903    /*
     
    29803013    return SSMR3RegisterInternal(pVM, "pgm", 1, PGM_SAVED_STATE_VERSION, (size_t)cbRam + sizeof(PGM),
    29813014                                 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  
    504504            /** Data buffer. */
    505505            uint8_t         abDataBuffer[4096];
     506            /** The maximum downtime given as milliseconds. */
     507            uint32_t        cMsMaxDowntime;
    506508        } Write;
    507509
     
    46044606        return VERR_NO_MEMORY;
    46054607
    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;
    46254628
    46264629    int rc;
     
    50975100 *
    50985101 * @param   pVM             The VM handle.
     5102 * @param   cMsMaxDowntime  The maximum downtime given as milliseconds.
    50995103 * @param   pszFilename     Name of the file to save the state in. This string
    51005104 *                          must remain valid until SSMR3LiveDone is called.
     
    51095113 * @thread  EMT0
    51105114 */
    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));
     5115VMMR3_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));
    51165122    VM_ASSERT_EMT0(pVM);
    51175123
     
    51485154    if (RT_FAILURE(rc))
    51495155        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;
    51535160
    51545161    /*
     
    86458652
    86468653/**
     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 */
     8661VMMR3DECL(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/**
    86478671 * Gets the host bit count of a saved state.
    86488672 *
  • trunk/src/VBox/VMM/VM.cpp

    r24785 r24874  
    15851585 *
    15861586 * @param   pVM             The VM handle.
     1587 * @param   cMsMaxDowntime  The maximum downtime given as milliseconds.
    15871588 * @param   pszFilename     The name of the file.  NULL if pStreamOps is used.
    15881589 * @param   pStreamOps      The stream methods.  NULL if pszFilename is used.
     
    15951596 * @thread  EMT
    15961597 */
    1597 static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
     1598static DECLCALLBACK(int) vmR3Save(PVM pVM, uint32_t cMsMaxDowntime, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
    15981599                                  SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, PSSMHANDLE *ppSSM)
    15991600{
    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));
    16021603
    16031604    /*
     
    16291630        if (enmAfter == SSMAFTER_TELEPORT)
    16301631            pVM->vm.s.fTeleportedAndNotFullyResumedYet = true;
    1631         rc = SSMR3LiveSave(pVM, pszFilename, pStreamOps, pvStreamOpsUser,
     1632        rc = SSMR3LiveSave(pVM, cMsMaxDowntime, pszFilename, pStreamOps, pvStreamOpsUser,
    16321633                           enmAfter, pfnProgress, pvProgressUser, ppSSM);
    16331634        /* (We're not subject to cancellation just yet.) */
     
    16451646 *
    16461647 * @param   pVM             The VM handle.
     1648 * @param   cMsMaxDowntime      The maximum downtime given as milliseconds.
    16471649 * @param   pszFilename     The name of the file.  NULL if pStreamOps is used.
    16481650 * @param   pStreamOps      The stream methods.  NULL if pszFilename is used.
     
    16551657 * @thread  Non-EMT
    16561658 */
    1657 static int vmR3SaveTeleport(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
     1659static int vmR3SaveTeleport(PVM pVM, uint32_t cMsMaxDowntime,
     1660                            const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
    16581661                            SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended)
    16591662{
     
    16631666    PSSMHANDLE pSSM;
    16641667    int rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/,
    1665                               (PFNRT)vmR3Save, 8, pVM, pszFilename, pStreamOps, pvStreamOpsUser,
     1668                              (PFNRT)vmR3Save, 9, pVM, cMsMaxDowntime, pszFilename, pStreamOps, pvStreamOpsUser,
    16661669                              enmAfter, pfnProgress, pvProgressUser, &pSSM);
    16671670    if (    RT_SUCCESS(rc)
     
    17561759    bool fSuspended = false; /** @todo need this for live snapshots. */
    17571760    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*/,
    17591763                              enmAfter, pfnProgress, pvUser, &fSuspended);
    17601764    LogFlow(("VMR3Save: returns %Rrc\n", rc));
     
    17691773 *
    17701774 * @param   pVM                 The VM which state should be saved.
     1775 * @param   cMsMaxDowntime      The maximum downtime given as milliseconds.
    17711776 * @param   pStreamOps          The stream methods.
    17721777 * @param   pvStreamOpsUser     The user argument to the stream methods.
     
    17801785 *              RunningLS+SuspeningLS+SuspendedLS+Saving+Suspended.
    17811786 */
    1782 VMMR3DECL(int) VMR3Teleport(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
     1787VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsMaxDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
    17831788                            PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended)
    17841789{
    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));
    17871792
    17881793    /*
     
    17991804     * Join paths with VMR3Save.
    18001805     */
    1801     int rc = vmR3SaveTeleport(pVM, NULL /*pszFilename*/, pStreamOps, pvStreamOpsUser,
     1806    int rc = vmR3SaveTeleport(pVM, cMsMaxDowntime,
     1807                              NULL /*pszFilename*/, pStreamOps, pvStreamOpsUser,
    18021808                              SSMAFTER_TELEPORT, pfnProgress, pvProgressUser, pfSuspended);
    18031809    LogFlow(("VMR3Teleport: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended));
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette