VirtualBox

Changeset 21858 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 28, 2009 7:27:08 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
50494
Message:

SSM: optimized checksumming.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/SSM-new.cpp

    r21856 r21858  
    231231/** @name SSMRECTERM::fFlags
    232232 * @{ */
    233 /** There is CRC-32 for the data. */
     233/** There is a CRC-32 value for the stream. */
    234234#define SSMRECTERM_FLAGS_CRC32                  UINT16_C(0x0001)
    235235/** @} */
     
    294294    /** The current uncompressed offset into the data unit. */
    295295    uint64_t        offUnit;
    296     /** Whether we're checksumming the unit or not. */
    297     bool            fUnitChecksummed;
    298     /** The unit CRC. */
    299     uint32_t        u32UnitCRC;
    300296
    301297    /** Pointer to the progress callback function. */
     
    526522     * This is mainly intended for sanity checking. */
    527523    uint64_t        offStream;
     524    /** The CRC-in-progress value this unit starts at. */
     525    uint32_t        u32CurStreamCRC;
    528526    /** The checksum of this structure, including the whole name.
    529527     * Calculated with this field set to zero.  */
     
    542540    char            szName[SSM_MAX_NAME_SIZE];
    543541} SSMFILEUNITHDR;
    544 AssertCompileMemberOffset(SSMFILEUNITHDR, szName, 40);
     542AssertCompileMemberOffset(SSMFILEUNITHDR, szName, 44);
    545543AssertCompileMemberSize(SSMFILEUNITHDR, szMagic, sizeof(SSMFILEUNITHDR_MAGIC));
    546544AssertCompileMemberSize(SSMFILEUNITHDR, szMagic, sizeof(SSMFILEUNITHDR_END));
     
    583581    /** Flags, see SSMRECTERM_FLAGS_CRC32. */
    584582    uint16_t        fFlags;
    585     /** The checksum of the data up to the start of this record. */
    586     uint32_t        u32CRC;
     583    /** The checksum of the stream up to the start of this record. */
     584    uint32_t        u32StreamCRC;
    587585    /** The length of this data unit in bytes (including this record). */
    588586    uint64_t        cbUnit;
     
    15281526    Handle.cbUnitLeftV1     = 0;
    15291527    Handle.offUnit          = UINT64_MAX;
    1530     Handle.fUnitChecksummed = false;
    1531     Handle.u32UnitCRC       = 0;
    15321528    Handle.pfnProgress      = pfnProgress;
    15331529    Handle.pvUser           = pvUser;
     
    16571653                 */
    16581654                memcpy(&u.UnitHdr.szMagic[0], SSMFILEUNITHDR_MAGIC, sizeof(u.UnitHdr.szMagic));
    1659                 u.UnitHdr.offStream   = pUnit->offStream;
    1660                 u.UnitHdr.u32CRC      = 0;
    1661                 u.UnitHdr.u32Version  = pUnit->u32Version;
    1662                 u.UnitHdr.u32Instance = pUnit->u32Instance;
    1663                 u.UnitHdr.u32Phase    = SSM_PHASE_FINAL;
    1664                 u.UnitHdr.fFlags      = 0;
    1665                 u.UnitHdr.cbName      = (uint32_t)pUnit->cchName + 1;
     1655                u.UnitHdr.offStream       = pUnit->offStream;
     1656                if (Handle.fChecksummed)
     1657                    ssmR3StrmFlush(&Handle);
     1658                u.UnitHdr.u32CurStreamCRC = Handle.u32StreamCRC;
     1659                u.UnitHdr.u32CRC          = 0;
     1660                u.UnitHdr.u32Version      = pUnit->u32Version;
     1661                u.UnitHdr.u32Instance     = pUnit->u32Instance;
     1662                u.UnitHdr.u32Phase        = SSM_PHASE_FINAL;
     1663                u.UnitHdr.fFlags          = 0;
     1664                u.UnitHdr.cbName          = (uint32_t)pUnit->cchName + 1;
    16661665                memcpy(&u.UnitHdr.szName[0], &pUnit->szName[0], u.UnitHdr.cbName);
    1667                 u.UnitHdr.u32CRC      = RTCrc32(&u.UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[u.UnitHdr.cbName]));
     1666                u.UnitHdr.u32CRC          = RTCrc32(&u.UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[u.UnitHdr.cbName]));
    16681667                Log(("SSM: Unit at %#9llx: '%s', instance %u, phase %#x, version %u\n",
    16691668                     u.UnitHdr.offStream, u.UnitHdr.szName, u.UnitHdr.u32Instance, u.UnitHdr.u32Phase, u.UnitHdr.u32Version));
     
    17021701                        TermRec.u8TypeAndFlags = SSM_REC_FLAGS_FIXED | SSM_REC_FLAGS_IMPORTANT | SSM_REC_TYPE_TERM;
    17031702                        TermRec.cbRec       = sizeof(TermRec) - 2;
    1704                         if (Handle.fUnitChecksummed)
     1703                        if (Handle.fChecksummed)
    17051704                        {
    1706                             TermRec.fFlags  = SSMRECTERM_FLAGS_CRC32;
    1707                             TermRec.u32CRC  = RTCrc32Finish(Handle.u32UnitCRC);
     1705                            TermRec.fFlags       = SSMRECTERM_FLAGS_CRC32;
     1706                            TermRec.u32StreamCRC = RTCrc32Finish(Handle.u32StreamCRC);
    17081707                        }
    17091708                        else
    17101709                        {
    1711                             TermRec.fFlags  = 0;
    1712                             TermRec.u32CRC = 0;
     1710                            TermRec.fFlags       = 0;
     1711                            TermRec.u32StreamCRC = 0;
    17131712                        }
    17141713                        TermRec.cbUnit      = Handle.offUnit + sizeof(TermRec);
     
    17171716                            rc = ssmR3DataWriteFinish(&Handle);
    17181717                        if (RT_SUCCESS(rc))
    1719                         {
    17201718                            Handle.offUnit     = UINT64_MAX;
    1721                             Handle.u32UnitCRC  = 0;
    1722                         }
    17231719                        else
    17241720                        {
     
    17901786            /* Write the end unit. */
    17911787            memcpy(&u.UnitHdr.szMagic[0], SSMFILEUNITHDR_END, sizeof(u.UnitHdr.szMagic));
    1792             u.UnitHdr.offStream   = ssmR3StrmTell(&Handle);
    1793             u.UnitHdr.u32Version  = 0;
    1794             u.UnitHdr.u32Instance = 0;
    1795             u.UnitHdr.u32Phase    = SSM_PHASE_FINAL;
    1796             u.UnitHdr.fFlags      = 0;
    1797             u.UnitHdr.cbName      = 0;
    1798             u.UnitHdr.u32CRC      = 0;
    1799             u.UnitHdr.u32CRC      = RTCrc32(&u.UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[0]));
     1788            u.UnitHdr.offStream       = ssmR3StrmTell(&Handle);
     1789            u.UnitHdr.u32CurStreamCRC = Handle.u32StreamCRC;
     1790            u.UnitHdr.u32CRC          = 0;
     1791            u.UnitHdr.u32Version      = 0;
     1792            u.UnitHdr.u32Instance     = 0;
     1793            u.UnitHdr.u32Phase        = SSM_PHASE_FINAL;
     1794            u.UnitHdr.fFlags          = 0;
     1795            u.UnitHdr.cbName          = 0;
     1796            u.UnitHdr.u32CRC          = RTCrc32(&u.UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[0]));
    18001797            Log(("SSM: Unit at %#9llx: END UNIT\n", u.UnitHdr.offStream));
    18011798            rc = ssmR3StrmWrite(&Handle,  &u.UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[0]));
     
    19101907
    19111908/**
    1912  * Validates the integrity of a saved state file.
     1909 * Validates the integrity of a saved state file, it also initializes
     1910 * u32StreamCRC for v2.0+.
    19131911 *
    19141912 * @returns VBox status.
     
    19951993        }
    19961994
     1995        if (fChecksummed && fChecksumOnRead)
     1996            pSSM->u32StreamCRC = RTCrc32Process(RTCrc32Start(), &uHdr, pSSM->u.Read.cbFileHdr);
     1997
    19971998        /*
    19981999         * Read and validate the footer.
     
    20412042         */
    20422043        if (    fChecksummed
    2043             &&  fChecksumIt)
     2044            &&  fChecksumIt
     2045            &&  !fChecksumOnRead)
    20442046        {
    20452047            rc = RTFileSeek(pSSM->hFile, 0, RTFILE_SEEK_BEGIN, NULL);
     
    21932195    pSSM->cbUnitLeftV1     = 0;
    21942196    pSSM->offUnit          = UINT64_MAX;
    2195     pSSM->fUnitChecksummed = 0;
    2196     pSSM->u32UnitCRC       = 0;
    21972197    pSSM->pfnProgress      = NULL;
    21982198    pSSM->pvUser           = NULL;
     
    24602460         * Read the unit header and check its integrity.
    24612461         */
    2462         uint64_t        offUnit = ssmR3StrmTell(pSSM);
     2462        uint64_t        offUnit         = ssmR3StrmTell(pSSM);
     2463        uint32_t        u32CurStreamCRC = pSSM->u32StreamCRC;
    24632464        SSMFILEUNITHDR  UnitHdr;
    24642465        int rc = ssmR3StrmRead(pSSM, &UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName));
     
    24972498            return VERR_SSM_INTEGRITY;
    24982499        }
     2500        AssertLogRelMsgReturn(UnitHdr.u32CurStreamCRC == u32CurStreamCRC || !pSSM->fChecksummed,
     2501                              ("Unit at %#llx (%lld): Stream CRC mismatch: %08x, correct is %08x\n", offUnit, offUnit, UnitHdr.u32CurStreamCRC, u32CurStreamCRC), VERR_SSM_INTEGRITY);
    24992502        AssertLogRelMsgReturn(!UnitHdr.fFlags, ("Unit at %#llx (%lld): fFlags=%08x\n", offUnit, offUnit, UnitHdr.fFlags), VERR_SSM_INTEGRITY);
    25002503        if (!memcmp(&UnitHdr.szMagic[0], SSMFILEUNITHDR_END,   sizeof(UnitHdr.szMagic)))
     
    28112814     * Try open the file and validate it.
    28122815     */
    2813     int rc = ssmR3OpenFile(NULL, pszFilename, true /*fChecksumIt*/, false /*fChecksumOnRead*/, pSSM);
     2816    int rc = ssmR3OpenFile(NULL, pszFilename, false /*fChecksumIt*/, true /*fChecksumOnRead*/, pSSM);
    28142817    if (RT_SUCCESS(rc))
    28152818    {
     
    30083011                AssertLogRelRCReturn(rc, rc);
    30093012
     3013                if (pSSM->fChecksummed)
     3014                    pSSM->u32StreamCRC = RTCrc32Process(UnitHdr.u32CurStreamCRC, &UnitHdr, cbUnitHdr);
     3015
    30103016                ssmR3DataReadBeginV2(pSSM);
    30113017                return VINF_SUCCESS;
     
    31333139static void ssmR3DataWriteBegin(PSSMHANDLE pSSM)
    31343140{
    3135     pSSM->offUnit           = 0;
    3136     if (pSSM->fUnitChecksummed)
    3137         pSSM->u32UnitCRC    = RTCrc32Start();
     3141    pSSM->offUnit = 0;
    31383142}
    31393143
     
    31573161    if (RT_FAILURE(pSSM->rc))
    31583162        return pSSM->rc;
    3159 
    3160     /*
    3161      * Do the stream checksumming before we write the data.
    3162      */
    3163     if (pSSM->fUnitChecksummed)
    3164         pSSM->u32UnitCRC = RTCrc32Process(pSSM->u32UnitCRC, pvBuf, cbBuf);
    31653163
    31663164    /*
     
    40434041
    40444042/**
    4045  * Read reader that does the decompression and keeps the offset and CRC members
    4046  * up to date.
     4043 * Read reader that keep works the progress indicator and unit offset.
    40474044 *
    40484045 * Does not set SSM::rc.
     
    40604057    {
    40614058        pSSM->offUnit += cbToRead;
    4062         if (pSSM->fUnitChecksummed)
    4063             pSSM->u32UnitCRC = RTCrc32Process(pSSM->u32UnitCRC, pvBuf, cbToRead);
    4064 
    40654059        ssmR3Progress(pSSM, cbToRead);
    40664060        return VINF_SUCCESS;
     
    41584152     * Read the two mandatory bytes.
    41594153     */
    4160     uint32_t u32UnitCRC = pSSM->u32UnitCRC;
     4154    uint32_t u32StreamCRC = pSSM->u32StreamCRC;
    41614155    uint8_t  abHdr[8];
    41624156    int rc = ssmR3DataReadV2Raw(pSSM, abHdr, 2);
     
    41884182        AssertLogRelMsgReturn(!(TermRec.fFlags & ~SSMRECTERM_FLAGS_CRC32), ("%#x\n", TermRec.fFlags), VERR_SSM_INTEGRITY);
    41894183        if (!(TermRec.fFlags & SSMRECTERM_FLAGS_CRC32))
    4190             AssertLogRelMsgReturn(TermRec.u32CRC == 0, ("%#x\n", TermRec.u32CRC), VERR_SSM_INTEGRITY);
    4191         else if (pSSM->fUnitChecksummed)
    4192         {
    4193             u32UnitCRC = RTCrc32Finish(u32UnitCRC);
    4194             AssertLogRelMsgReturn(TermRec.u32CRC == u32UnitCRC, ("%#x, %#x\n", TermRec.u32CRC, u32UnitCRC), VERR_SSM_INTEGRITY_CRC);
     4184            AssertLogRelMsgReturn(TermRec.u32StreamCRC == 0, ("%#x\n", TermRec.u32StreamCRC), VERR_SSM_INTEGRITY);
     4185        else if (pSSM->fChecksummed)
     4186        {
     4187            u32StreamCRC = RTCrc32Finish(u32StreamCRC);
     4188            AssertLogRelMsgReturn(TermRec.u32StreamCRC == u32StreamCRC, ("%#x, %#x\n", TermRec.u32StreamCRC, u32StreamCRC), VERR_SSM_INTEGRITY_CRC);
    41954189        }
    41964190
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