VirtualBox

Changeset 30396 in vbox


Ignore:
Timestamp:
Jun 23, 2010 3:26:41 PM (14 years ago)
Author:
vboxsync
Message:

Teleportation: Make the progress bar move during teleportation. The completion percentage calculation in PGM isn't all that great yet, but that can be fixed later.

Location:
trunk
Files:
6 edited

Legend:

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

    r28800 r30396  
    11651165VMMR3DECL(uint32_t)     SSMR3HandleVersion(PSSMHANDLE pSSM);
    11661166VMMR3DECL(const char *) SSMR3HandleHostOSAndArch(PSSMHANDLE pSSM);
    1167 VMMR3_INT_DECL(int)     SSMR3SetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr);
     1167VMMR3_INT_DECL(int)     SSMR3HandleSetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr);
     1168VMMR3DECL(void)         SSMR3HandleReportLivePercent(PSSMHANDLE pSSM, unsigned uPercent);
    11681169VMMR3DECL(int)          SSMR3Cancel(PVM pVM);
    11691170
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp

    r29979 r30396  
    822822            static const RTGETOPTDEF s_aTeleportOptions[] =
    823823            {
    824                 { "--host",        'h', RTGETOPT_REQ_STRING }, /** @todo RTGETOPT_FLAG_MANDATORY */
    825                 { "--hostname",    'h', RTGETOPT_REQ_STRING }, /** @todo remove this */
    826                 { "--maxdowntime", 'd', RTGETOPT_REQ_UINT32 },
    827                 { "--port",        'p', RTGETOPT_REQ_UINT32 }, /** @todo RTGETOPT_FLAG_MANDATORY */
    828                 { "--password",    'P', RTGETOPT_REQ_STRING },
    829                 { "--timeout",     't', RTGETOPT_REQ_UINT32 }
     824                { "--host",              'h', RTGETOPT_REQ_STRING }, /** @todo RTGETOPT_FLAG_MANDATORY */
     825                { "--hostname",          'h', RTGETOPT_REQ_STRING }, /** @todo remove this */
     826                { "--maxdowntime",       'd', RTGETOPT_REQ_UINT32 },
     827                { "--port",              'p', RTGETOPT_REQ_UINT32 }, /** @todo RTGETOPT_FLAG_MANDATORY */
     828                { "--password",          'P', RTGETOPT_REQ_STRING },
     829                { "--timeout",           't', RTGETOPT_REQ_UINT32 },
     830                { "--detailed-progress", 'D', RTGETOPT_REQ_NOTHING }
    830831            };
    831832            RTGETOPTSTATE GetOptState;
     
    840841                    case 'h': bstrHostname  = Value.psz; break;
    841842                    case 'd': uMaxDowntime  = Value.u32; break;
     843                    case 'D': g_fDetailedProgress = true; break;
    842844                    case 'p': uPort         = Value.u32; break;
    843845                    case 'P': bstrPassword  = Value.psz; break;
  • trunk/src/VBox/Main/ProgressImpl.cpp

    r29989 r30396  
    977977    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    978978
    979     AssertReturn(aPercent <= 100, E_INVALIDARG);
     979    AssertMsgReturn(aPercent <= 100, ("%u\n", aPercent), E_INVALIDARG);
    980980
    981981    checkForAutomaticTimeout();
  • trunk/src/VBox/VMM/CPUM.cpp

    r30316 r30396  
    20852085         */
    20862086        if (uVersion == CPUM_SAVED_STATE_VERSION_VER1_6)
    2087             SSMR3SetGCPtrSize(pSSM, sizeof(RTGCPTR32));
     2087            SSMR3HandleSetGCPtrSize(pSSM, sizeof(RTGCPTR32));
    20882088        else if (uVersion <= CPUM_SAVED_STATE_VERSION_VER3_0)
    2089             SSMR3SetGCPtrSize(pSSM, HC_ARCH_BITS == 32 ? sizeof(RTGCPTR32) : sizeof(RTGCPTR));
     2089            SSMR3HandleSetGCPtrSize(pSSM, HC_ARCH_BITS == 32 ? sizeof(RTGCPTR32) : sizeof(RTGCPTR));
    20902090
    20912091        /*
  • trunk/src/VBox/VMM/PGMSavedState.cpp

    r30326 r30396  
    18901890        }
    18911891    }
     1892
     1893    /*
     1894     * Come up with a completion percentage.  Currently this is a simple
     1895     * dirty page (long term) vs. total pages ratio + some pass trickery.
     1896     */
     1897    unsigned uPctDirty = cDirtyPagesLong
     1898                       / (long double)(pVM->pgm.s.cAllPages - pVM->pgm.s.LiveSave.cIgnoredPages - pVM->pgm.s.cZeroPages);
     1899    if (uPctDirty <= 100)
     1900        SSMR3HandleReportLivePercent(pSSM, RT_MIN(100 - uPctDirty, uPass * 2));
     1901    else
     1902        AssertMsgFailed(("uPctDirty=%u cDirtyPagesLong=%#x cAllPages=%#x cIgnoredPages=%#x cZeroPages=%#x\n",
     1903                         uPctDirty, cDirtyPagesLong, pVM->pgm.s.cAllPages, pVM->pgm.s.LiveSave.cIgnoredPages, pVM->pgm.s.cZeroPages));
     1904
    18921905    return VINF_SSM_VOTE_FOR_ANOTHER_PASS;
    18931906}
  • trunk/src/VBox/VMM/SSM.cpp

    r30111 r30396  
    55
    66/*
    7  * Copyright (C) 2006-2009 Oracle Corporation
     7 * Copyright (C) 2006-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    485485    /** End of current unit in the estimated file. */
    486486    uint64_t                offEstUnitEnd;
    487     /** the amount of % we reserve for the 'prepare' phase */
     487    /** The amount of % we reserve for the 'live' stage */
     488    unsigned                uPercentLive;
     489    /** The amount of % we reserve for the 'prepare' phase */
    488490    unsigned                uPercentPrepare;
    489     /** the amount of % we reserve for the 'done' stage */
     491    /** The amount of % we reserve for the 'done' stage */
    490492    unsigned                uPercentDone;
     493    /** The lowest value reported via SSMR3HandleReportLivePercent during one
     494     * vote run. */
     495    unsigned                uReportedLivePercent;
    491496    /** The filename, NULL if remote stream. */
    492497    const char             *pszFilename;
     
    872877static DECLCALLBACK(int)    ssmR3SelfSaveExec(PVM pVM, PSSMHANDLE pSSM);
    873878static DECLCALLBACK(int)    ssmR3SelfLoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
     879static DECLCALLBACK(int)    ssmR3LiveControlLoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
    874880static int                  ssmR3Register(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore, PSSMUNIT *ppUnit);
     881static int                  ssmR3LiveControlEmit(PSSMHANDLE pSSM, long double lrdPct, uint32_t uPass);
    875882#endif
    876883
     
    916923                                   NULL /*pfnSavePrep*/, ssmR3SelfSaveExec, NULL /*pfnSaveDone*/,
    917924                                   NULL /*pfnSavePrep*/, ssmR3SelfLoadExec, NULL /*pfnSaveDone*/);
     925    if (RT_SUCCESS(rc))
     926        rc = SSMR3RegisterInternal(pVM, "SSMLiveControl", 0 /*uInstance*/, 1 /*uVersion*/, 1 /*cbGuess*/,
     927                                   NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/,     NULL /*pfnLiveVote*/,
     928                                   NULL /*pfnSavePrep*/, NULL /*pfnSaveExec*/,     NULL /*pfnSaveDone*/,
     929                                   NULL /*pfnSavePrep*/, ssmR3LiveControlLoadExec, NULL /*pfnSaveDone*/);
    918930
    919931    /*
     
    10401052    }
    10411053    return VINF_SUCCESS;
     1054}
     1055
     1056
     1057/**
     1058 * Load exec callback for the special live save state unit that tracks the
     1059 * progress of a live save.
     1060 *
     1061 * This is saved by ssmR3LiveControlEmit().
     1062 *
     1063 * @returns VBox status code.
     1064 * @param   pVM             Pointer to the shared VM structure.
     1065 * @param   pSSM            The SSM handle.
     1066 * @param   uVersion        The version (1).
     1067 * @param   uPass           The pass.
     1068 */
     1069static DECLCALLBACK(int) ssmR3LiveControlLoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     1070{
     1071    AssertLogRelMsgReturn(uVersion == 1, ("%d", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     1072
     1073    uint16_t uPartsPerTenThousand;
     1074    int rc = SSMR3GetU16(pSSM, &uPartsPerTenThousand);
     1075    if (RT_SUCCESS(rc))
     1076    {
     1077        /* Scale it down to fit in our exec range. */
     1078        unsigned uPct = (unsigned)(  (long double)uPartsPerTenThousand / 100
     1079                                   * (100 - pSSM->uPercentPrepare - pSSM->uPercentDone) / 100)
     1080                      + pSSM->uPercentPrepare;
     1081        if (uPct != pSSM->uPercent)
     1082        {
     1083            AssertMsg(uPct < 100, ("uPct=%d uPartsPerTenThousand=%d uPercentPrepare=%d uPercentDone=%d\n", uPct, uPartsPerTenThousand, pSSM->uPercentPrepare, pSSM->uPercentDone));
     1084            pSSM->uPercent = uPct;
     1085            if (pSSM->pfnProgress)
     1086                pSSM->pfnProgress(pVM, RT_MIN(uPct, 100 - pSSM->uPercentDone), pSSM->pvUser);
     1087        }
     1088    }
     1089    return rc;
    10421090}
    10431091
     
    28922940
    28932941/**
    2894  * Works the progress calculation.
     2942 * Works the progress calculation for non-live saves and restores.
    28952943 *
    28962944 * @param   pSSM        The SSM handle.
    2897  * @param   cbAdvance   Number of bytes to advance
    2898  */
    2899 static void ssmR3Progress(PSSMHANDLE pSSM, uint64_t cbAdvance)
    2900 {
    2901     /* Can't advance it beyond the estimated end of the unit. */
    2902     uint64_t cbLeft = pSSM->offEstUnitEnd - pSSM->offEst;
    2903     if (cbAdvance > cbLeft)
    2904         cbAdvance = cbLeft;
    2905     pSSM->offEst += cbAdvance;
    2906 
    2907     /* uPercentPrepare% prepare, xx% exec, uPercentDone% done+crc */
    2908     while (   pSSM->offEst >= pSSM->offEstProgress
    2909            && pSSM->uPercent <= 100-pSSM->uPercentDone)
    2910     {
    2911         if (pSSM->pfnProgress)
    2912             pSSM->pfnProgress(pSSM->pVM, pSSM->uPercent, pSSM->pvUser);
    2913         pSSM->uPercent++;
    2914         pSSM->offEstProgress = (pSSM->uPercent - pSSM->uPercentPrepare) * pSSM->cbEstTotal
    2915                              / (100 - pSSM->uPercentDone - pSSM->uPercentPrepare);
     2945 * @param   cbAdvance   Number of bytes to advance (with in the current unit).
     2946 */
     2947static void ssmR3ProgressByByte(PSSMHANDLE pSSM, uint64_t cbAdvance)
     2948{
     2949    if (!pSSM->fLiveSave)
     2950    {
     2951        /* Can't advance it beyond the estimated end of the unit. */
     2952        uint64_t cbLeft = pSSM->offEstUnitEnd - pSSM->offEst;
     2953        if (cbAdvance > cbLeft)
     2954            cbAdvance = cbLeft;
     2955        pSSM->offEst += cbAdvance;
     2956
     2957        /* uPercentPrepare% prepare, xx% exec, uPercentDone% done+crc. This is not
     2958           quite right for live save, but the non-live stage there is very short. */
     2959        while (   pSSM->offEst >= pSSM->offEstProgress
     2960               && pSSM->uPercent <= 100 - pSSM->uPercentDone)
     2961        {
     2962            if (pSSM->pfnProgress)
     2963                pSSM->pfnProgress(pSSM->pVM, pSSM->uPercent, pSSM->pvUser);
     2964            pSSM->uPercent++;
     2965            pSSM->offEstProgress = (pSSM->uPercent - pSSM->uPercentPrepare - pSSM->uPercentLive) * pSSM->cbEstTotal
     2966                                 / (100 - pSSM->uPercentDone - pSSM->uPercentPrepare - pSSM->uPercentLive);
     2967        }
    29162968    }
    29172969}
     
    31513203    if (RT_SUCCESS(rc))
    31523204        rc = ssmR3DataWriteRaw(pSSM, pSSM->u.Write.abDataBuffer, cb);
    3153     ssmR3Progress(pSSM, cb);
     3205    ssmR3ProgressByByte(pSSM, cb);
    31543206    return rc;
    31553207}
     
    32133265
    32143266                pSSM->offUnit += cbRec;
    3215                 ssmR3Progress(pSSM, SSM_ZIP_BLOCK_SIZE);
     3267                ssmR3ProgressByByte(pSSM, SSM_ZIP_BLOCK_SIZE);
    32163268
    32173269                /* advance */
     
    32363288
    32373289                /* advance */
    3238                 ssmR3Progress(pSSM, SSM_ZIP_BLOCK_SIZE);
     3290                ssmR3ProgressByByte(pSSM, SSM_ZIP_BLOCK_SIZE);
    32393291                if (cbBuf == SSM_ZIP_BLOCK_SIZE)
    32403292                    return VINF_SUCCESS;
     
    32503302                if (RT_SUCCESS(rc))
    32513303                    rc = ssmR3DataWriteRaw(pSSM, pvBuf, cbBuf);
    3252                 ssmR3Progress(pSSM, cbBuf);
     3304                ssmR3ProgressByByte(pSSM, cbBuf);
    32533305                break;
    32543306            }
     
    40614113
    40624114/**
     4115 * Emits a SSMLiveControl unit with a new progress report.
     4116 *
     4117 * @returns VBox status code.
     4118 * @param   pSSM                    The saved state handle.
     4119 * @param   lrdPct                  The progress of the the live save.
     4120 * @param   uPass                   The current pass.
     4121 */
     4122static int ssmR3LiveControlEmit(PSSMHANDLE pSSM, long double lrdPct, uint32_t uPass)
     4123{
     4124    AssertMsg(lrdPct <= 100.0, ("%u\n", lrdPct * 100));
     4125
     4126    /*
     4127     * Make sure we're in one of the two EXEC states or we may fail.
     4128     */
     4129    SSMSTATE enmSavedState = pSSM->enmOp;
     4130    if (enmSavedState == SSMSTATE_LIVE_VOTE)
     4131        pSSM->enmOp = SSMSTATE_LIVE_EXEC;
     4132    else if (enmSavedState == SSMSTATE_SAVE_DONE)
     4133        pSSM->enmOp = SSMSTATE_SAVE_EXEC;
     4134
     4135    /*
     4136     * Write the unit header.
     4137     */
     4138    SSMFILEUNITHDRV2 UnitHdr;
     4139    memcpy(&UnitHdr.szMagic[0], SSMFILEUNITHDR_MAGIC, sizeof(UnitHdr.szMagic));
     4140    UnitHdr.offStream       = ssmR3StrmTell(&pSSM->Strm);
     4141    UnitHdr.u32CurStreamCRC = ssmR3StrmCurCRC(&pSSM->Strm);
     4142    UnitHdr.u32CRC          = 0;
     4143    UnitHdr.u32Version      = 1;
     4144    UnitHdr.u32Instance     = 0;
     4145    UnitHdr.u32Pass         = uPass;
     4146    UnitHdr.fFlags          = 0;
     4147    UnitHdr.cbName          = sizeof("SSMLiveControl");
     4148    memcpy(&UnitHdr.szName[0], "SSMLiveControl", UnitHdr.cbName);
     4149    UnitHdr.u32CRC          = RTCrc32(&UnitHdr, RT_OFFSETOF(SSMFILEUNITHDRV2, szName[UnitHdr.cbName]));
     4150    Log(("SSM: Unit at %#9llx: '%s', instance %u, pass %#x, version %u\n",
     4151         UnitHdr.offStream, UnitHdr.szName, UnitHdr.u32Instance, UnitHdr.u32Pass, UnitHdr.u32Version));
     4152    int rc = ssmR3StrmWrite(&pSSM->Strm, &UnitHdr, RT_OFFSETOF(SSMFILEUNITHDRV2, szName[UnitHdr.cbName]));
     4153    if (RT_SUCCESS(rc))
     4154    {
     4155        /*
     4156         * Write the payload.
     4157         */
     4158        ssmR3DataWriteBegin(pSSM);
     4159
     4160        uint16_t u16PartsPerTenThousand = (uint16_t)(lrdPct * (100 - pSSM->uPercentDone));
     4161        AssertMsg(u16PartsPerTenThousand <= 10000, ("%u\n", u16PartsPerTenThousand));
     4162        ssmR3DataWrite(pSSM, &u16PartsPerTenThousand, sizeof(u16PartsPerTenThousand));
     4163
     4164        rc = ssmR3DataFlushBuffer(pSSM); /* will return SSMHANDLE::rc if it is set */
     4165        if (RT_SUCCESS(rc))
     4166        {
     4167            /*
     4168             * Write the termination record and flush the compression stream.
     4169             */
     4170            SSMRECTERM TermRec;
     4171            TermRec.u8TypeAndFlags   = SSM_REC_FLAGS_FIXED | SSM_REC_FLAGS_IMPORTANT | SSM_REC_TYPE_TERM;
     4172            TermRec.cbRec            = sizeof(TermRec) - 2;
     4173            if (pSSM->Strm.fChecksummed)
     4174            {
     4175                TermRec.fFlags       = SSMRECTERM_FLAGS_CRC32;
     4176                TermRec.u32StreamCRC = RTCrc32Finish(RTCrc32Process(ssmR3StrmCurCRC(&pSSM->Strm), &TermRec, 2));
     4177            }
     4178            else
     4179            {
     4180                TermRec.fFlags       = 0;
     4181                TermRec.u32StreamCRC = 0;
     4182            }
     4183            TermRec.cbUnit           = pSSM->offUnit + sizeof(TermRec);
     4184            rc = ssmR3DataWriteRaw(pSSM, &TermRec, sizeof(TermRec));
     4185            if (RT_SUCCESS(rc))
     4186                rc = ssmR3DataWriteFinish(pSSM);
     4187            if (RT_SUCCESS(rc))
     4188            {
     4189                pSSM->enmOp = enmSavedState;
     4190                return rc;
     4191            }
     4192        }
     4193    }
     4194
     4195    LogRel(("SSM: Failed to write live control unit. rc=%Rrc\n", rc));
     4196    if (RT_SUCCESS_NP(pSSM->rc))
     4197        pSSM->rc = rc;
     4198    pSSM->enmOp = enmSavedState;
     4199    return rc;
     4200}
     4201
     4202
     4203/**
    40634204 * Do the pfnSaveDone run.
    40644205 *
     
    43384479
    43394480/**
     4481 * Works the progress calculation during the exec part of a live save.
     4482 *
     4483 * @param   pSSM        The SSM handle.
     4484 * @param   iUnit       The current unit number.
     4485 */
     4486static void ssmR3ProgressByUnit(PSSMHANDLE pSSM, uint32_t iUnit)
     4487{
     4488    if (pSSM->fLiveSave)
     4489    {
     4490        unsigned    uPctExec = iUnit * 100 / pSSM->pVM->ssm.s.cUnits;
     4491        unsigned    cPctExec = 100 - pSSM->uPercentDone - pSSM->uPercentPrepare - pSSM->uPercentLive;
     4492        long double lrdPct   = (long double)uPctExec * cPctExec / 100 + pSSM->uPercentPrepare + pSSM->uPercentLive;
     4493        unsigned    uPct     = (unsigned)lrdPct;
     4494        if (uPct != pSSM->uPercent)
     4495        {
     4496            ssmR3LiveControlEmit(pSSM, lrdPct, SSM_PASS_FINAL);
     4497            pSSM->uPercent =  uPct;
     4498            pSSM->pfnProgress(pSSM->pVM, uPct, pSSM->pvUser);
     4499        }
     4500    }
     4501}
     4502
     4503
     4504/**
    43404505 * Do the pfnSaveExec run.
    43414506 *
     
    43504515    pSSM->rc = VINF_SUCCESS;
    43514516    pSSM->enmOp = SSMSTATE_SAVE_EXEC;
    4352     for (PSSMUNIT pUnit = pVM->ssm.s.pHead; pUnit; pUnit = pUnit->pNext)
     4517    unsigned iUnit = 0;
     4518    for (PSSMUNIT pUnit = pVM->ssm.s.pHead; pUnit; pUnit = pUnit->pNext, iUnit++)
    43534519    {
    43544520        /*
     
    43564522         * make sure to keep the progress indicator up to date.
    43574523         */
     4524        ssmR3ProgressByUnit(pSSM, iUnit);
    43584525        pSSM->offEstUnitEnd += pUnit->cbGuess;
    43594526        if (!pUnit->u.Common.pfnSaveExec)
     
    43614528            pUnit->fCalled = true;
    43624529            if (pUnit->cbGuess)
    4363                 ssmR3Progress(pSSM, pSSM->offEstUnitEnd - pSSM->offEst);
     4530                ssmR3ProgressByByte(pSSM, pSSM->offEstUnitEnd - pSSM->offEst);
    43644531            continue;
    43654532        }
     
    44634630         * Advance the progress indicator to the end of the current unit.
    44644631         */
    4465         ssmR3Progress(pSSM, pSSM->offEstUnitEnd - pSSM->offEst);
     4632        ssmR3ProgressByByte(pSSM, pSSM->offEstUnitEnd - pSSM->offEst);
    44664633    } /* for each unit */
    4467 
     4634    ssmR3ProgressByUnit(pSSM, pVM->ssm.s.cUnits);
    44684635
    44694636    /* (progress should be pending 99% now) */
    4470     AssertMsg(   pSSM->uPercent == (101 - pSSM->uPercentDone)
    4471               || pSSM->fLiveSave, ("%d\n", pSSM->uPercent));
     4637    AssertMsg(   pSSM->uPercent == 101 - pSSM->uPercentDone
     4638              || pSSM->uPercent == 100 - pSSM->uPercentDone,
     4639              ("%d\n", pSSM->uPercent));
    44724640    return VINF_SUCCESS;
    44734641}
     
    45284696     */
    45294697    if (pSSM->pfnProgress)
    4530         pSSM->pfnProgress(pVM, pSSM->uPercentPrepare-1, pSSM->pvUser);
    4531     pSSM->uPercent = pSSM->uPercentPrepare;
     4698        pSSM->pfnProgress(pVM, pSSM->uPercentPrepare + pSSM->uPercentLive - 1, pSSM->pvUser);
     4699    pSSM->uPercent = pSSM->uPercentPrepare + pSSM->uPercentLive;
    45324700
    45334701    return VINF_SUCCESS;
     
    46874855    pSSM->offEst                    = 0;
    46884856    pSSM->offEstUnitEnd             = 0;
     4857    pSSM->uPercentLive              = 0;
    46894858    pSSM->uPercentPrepare           = 0;
    46904859    pSSM->uPercentDone              = 0;
     4860    pSSM->uReportedLivePercent      = 0;
    46914861    pSSM->pszFilename               = pszFilename;
    46924862    pSSM->u.Write.offDataBuffer     = 0;
     
    47474917    if (RT_FAILURE(rc))
    47484918        return rc;
     4919    pSSM->uPercentLive    = 0;
    47494920    pSSM->uPercentPrepare = 20;
    47504921    pSSM->uPercentDone    = 2;
     
    47684939
    47694940/**
     4941 * Used by PGM to report the completion percentage of the live stage during the
     4942 * vote run.
     4943 *
     4944 * @param   pSSM                The saved state handle.
     4945 * @param   uPercent            The completion percentage.
     4946 */
     4947VMMR3DECL(void) SSMR3HandleReportLivePercent(PSSMHANDLE pSSM, unsigned uPercent)
     4948{
     4949    AssertMsgReturnVoid(pSSM->enmOp == SSMSTATE_LIVE_VOTE, ("%d\n", pSSM->enmOp));
     4950    AssertReturnVoid(uPercent <= 100);
     4951    if (uPercent < pSSM->uReportedLivePercent)
     4952        pSSM->uReportedLivePercent = uPercent;
     4953}
     4954
     4955
     4956/**
    47704957 * Calls pfnLiveVote for all units.
    47714958 *
     
    47844971    pSSM->rc = VINF_SUCCESS;
    47854972    pSSM->enmOp = SSMSTATE_LIVE_VOTE;
     4973
     4974    unsigned uPrevPrecent = pSSM->uReportedLivePercent;
     4975    pSSM->uReportedLivePercent = 101;
     4976
    47864977    for (PSSMUNIT pUnit = pVM->ssm.s.pHead; pUnit; pUnit = pUnit->pNext)
    47874978    {
     
    48375028    }
    48385029    if (rcRet == VINF_SUCCESS)
     5030    {
    48395031        LogRel(("SSM: Step 1 completed after pass %u.\n", uPass));
     5032        pSSM->uReportedLivePercent = 100;
     5033    }
     5034    else
     5035    {
     5036        /*
     5037         * Work the progress callback.
     5038         */
     5039        if (pSSM->uReportedLivePercent > 100)
     5040            pSSM->uReportedLivePercent = 0;
     5041        if (   pSSM->uReportedLivePercent != uPrevPrecent
     5042            && pSSM->pfnProgress
     5043            && pSSM->uPercentLive)
     5044        {
     5045            long double lrdPct = (long double)pSSM->uReportedLivePercent * pSSM->uPercentLive / 100;
     5046            unsigned    uPct   = (unsigned)lrdPct;
     5047            if (uPct != pSSM->uPercent)
     5048            {
     5049                ssmR3LiveControlEmit(pSSM, lrdPct, uPass);
     5050                pSSM->uPercent = uPct;
     5051                pSSM->pfnProgress(pVM, uPct, pSSM->pvUser);
     5052            }
     5053        }
     5054    }
    48405055    return rcRet;
    48415056}
     
    52075422    if (RT_FAILURE(rc))
    52085423        return rc;
    5209     pSSM->uPercentPrepare        = 20; /** @todo fix these. */
     5424    pSSM->uPercentLive           = 93;
     5425    pSSM->uPercentPrepare        = 2;
    52105426    pSSM->uPercentDone           = 2;
    52115427    pSSM->fLiveSave              = true;
     
    53025518            if (pcbRead)
    53035519                *pcbRead = cbRead;
    5304             ssmR3Progress(pSSM, cbRead);
     5520            ssmR3ProgressByByte(pSSM, cbRead);
    53055521            return VINF_SUCCESS;
    53065522        }
     
    54155631    {
    54165632        pSSM->offUnit += cbToRead;
    5417         ssmR3Progress(pSSM, cbToRead);
     5633        ssmR3ProgressByByte(pSSM, cbToRead);
    54185634        return VINF_SUCCESS;
    54195635    }
     
    54825698    {
    54835699        pSSM->offUnit += cbCompr;
    5484         ssmR3Progress(pSSM, cbCompr);
     5700        ssmR3ProgressByByte(pSSM, cbCompr);
    54855701    }
    54865702    else
     
    66706886 *          format isn't 1.1 the call will be ignored.
    66716887 */
    6672 VMMR3_INT_DECL(int) SSMR3SetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr)
     6888VMMR3_INT_DECL(int) SSMR3HandleSetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr)
    66736889{
    66746890    Assert(cbGCPtr == sizeof(RTGCPTR32) || cbGCPtr == sizeof(RTGCPTR64));
     
    73987614     * Initialize the handle.
    73997615     */
    7400     pSSM->pVM               = pVM;
    7401     pSSM->enmOp             = SSMSTATE_INVALID;
    7402     pSSM->enmAfter          = SSMAFTER_INVALID;
    7403     pSSM->fCancelled        = SSMHANDLE_OK;
    7404     pSSM->rc                = VINF_SUCCESS;
    7405     pSSM->cbUnitLeftV1      = 0;
    7406     pSSM->offUnit           = UINT64_MAX;
    7407     pSSM->fLiveSave         = false;
    7408     pSSM->pfnProgress       = NULL;
    7409     pSSM->pvUser            = NULL;
    7410     pSSM->uPercent          = 0;
    7411     pSSM->offEstProgress    = 0;
    7412     pSSM->cbEstTotal        = 0;
    7413     pSSM->offEst            = 0;
    7414     pSSM->offEstUnitEnd     = 0;
    7415     pSSM->uPercentPrepare   = 5;
    7416     pSSM->uPercentDone      = 2;
    7417     pSSM->pszFilename       = pszFilename;
     7616    pSSM->pVM                   = pVM;
     7617    pSSM->enmOp                 = SSMSTATE_INVALID;
     7618    pSSM->enmAfter              = SSMAFTER_INVALID;
     7619    pSSM->fCancelled            = SSMHANDLE_OK;
     7620    pSSM->rc                    = VINF_SUCCESS;
     7621    pSSM->cbUnitLeftV1          = 0;
     7622    pSSM->offUnit               = UINT64_MAX;
     7623    pSSM->fLiveSave             = false;
     7624    pSSM->pfnProgress           = NULL;
     7625    pSSM->pvUser                = NULL;
     7626    pSSM->uPercent              = 0;
     7627    pSSM->offEstProgress        = 0;
     7628    pSSM->cbEstTotal            = 0;
     7629    pSSM->offEst                = 0;
     7630    pSSM->offEstUnitEnd         = 0;
     7631    pSSM->uPercentLive          = 0;
     7632    pSSM->uPercentPrepare       = 5;
     7633    pSSM->uPercentDone          = 2;
     7634    pSSM->uReportedLivePercent  = 0;
     7635    pSSM->pszFilename           = pszFilename;
    74187636
    74197637    pSSM->u.Read.pZipDecompV1   = NULL;
     
    75587776                    Log(("SSM: EndOfFile: offset %#9llx size %9d\n", offUnit, UnitHdr.cbUnit));
    75597777                    /* Complete the progress bar (pending 99% afterwards). */
    7560                     ssmR3Progress(pSSM, pSSM->cbEstTotal - pSSM->offEst);
     7778                    ssmR3ProgressByByte(pSSM, pSSM->cbEstTotal - pSSM->offEst);
    75617779                    break;
    75627780                }
     
    76527870                                Log(("SSM: Unit '%s' left %lld bytes unread!\n", pszName, -i64Diff));
    76537871                                rc = ssmR3StrmSkipTo(&pSSM->Strm, offUnit + UnitHdr.cbUnit);
    7654                                 ssmR3Progress(pSSM, offUnit + UnitHdr.cbUnit - pSSM->offEst);
     7872                                ssmR3ProgressByByte(pSSM, offUnit + UnitHdr.cbUnit - pSSM->offEst);
    76557873                            }
    76567874                            else if (i64Diff > 0)
     
    78498067             */
    78508068            Log(("SSM: Unit at %#9llx: END UNIT\n", offUnit));
    7851             ssmR3Progress(pSSM, pSSM->cbEstTotal - pSSM->offEst);
    7852 
     8069            ssmR3ProgressByByte(pSSM, pSSM->cbEstTotal - pSSM->offEst);
    78538070            return ssmR3LoadDirectoryAndFooter(pSSM);
    78548071        }
     
    80038220        ssmR3SetCancellable(pVM, &Handle, true);
    80048221
    8005         Handle.enmAfter     = enmAfter;
    8006         Handle.pfnProgress  = pfnProgress;
    8007         Handle.pvUser       = pvProgressUser;
     8222        Handle.enmAfter         = enmAfter;
     8223        Handle.pfnProgress      = pfnProgress;
     8224        Handle.pvUser           = pvProgressUser;
     8225        Handle.uPercentLive     = 0;
     8226        Handle.uPercentPrepare  = 2;
     8227        Handle.uPercentDone     = 2;
    80088228
    80098229        if (Handle.u.Read.u16VerMajor)
     
    80698289        }
    80708290
    8071         /* pending 2% */
     8291        /* end of prepare % */
    80728292        if (pfnProgress)
    8073             pfnProgress(pVM, Handle.uPercentPrepare-1, pvProgressUser);
     8293            pfnProgress(pVM, Handle.uPercentPrepare - 1, pvProgressUser);
    80748294        Handle.uPercent      = Handle.uPercentPrepare;
    80758295        Handle.cbEstTotal    = Handle.u.Read.cbLoadFile;
     
    80928312            AssertMsg(   Handle.fLiveSave
    80938313                      || RT_FAILURE(rc)
    8094                       || Handle.uPercent == (101-Handle.uPercentDone), ("%d\n", Handle.uPercent));
     8314                      || Handle.uPercent == 101 - Handle.uPercentDone, ("%d\n", Handle.uPercent));
    80958315        }
    80968316
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