VirtualBox

Changeset 36134 in vbox


Ignore:
Timestamp:
Mar 2, 2011 11:31:06 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
70311
Message:

tstVDIo: Add simple data verification.

Location:
trunk/src/VBox/Storage/testcase
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/testcase/VDMemDisk.cpp

    r35596 r36134  
    338338}
    339339
     340int VDMemDiskCmp(PVDMEMDISK pMemDisk, uint64_t off, size_t cbCmp, PRTSGBUF pSgBuf)
     341{
     342    LogFlowFunc(("pMemDisk=%#p off=%llx cbCmp=%u pSgBuf=%#p\n",
     343                 pMemDisk, off, cbCmp, pSgBuf));
     344
     345    /* Compare data */
     346    size_t   cbLeft   = cbCmp;
     347    uint64_t offCurr  = off;
     348
     349    while (cbLeft)
     350    {
     351        PVDMEMDISKSEG pSeg = (PVDMEMDISKSEG)RTAvlrU64Get(pMemDisk->pTreeSegments, offCurr);
     352        size_t cbRange  = 0;
     353        bool fCmp       = false;
     354        unsigned offSeg = 0;
     355
     356        if (!pSeg)
     357        {
     358            /* Get next segment */
     359            pSeg = (PVDMEMDISKSEG)RTAvlrU64GetBestFit(pMemDisk->pTreeSegments, offCurr, true);
     360            if (!pSeg)
     361            {
     362                /* No data in the tree for this read. Assume everything is ok. */
     363                cbRange = cbLeft;
     364            }
     365            else if (offCurr + cbLeft <= pSeg->Core.Key)
     366                cbRange = cbLeft;
     367            else
     368                cbRange = pSeg->Core.Key - offCurr;
     369        }
     370        else
     371        {
     372            fCmp    = true;
     373            offSeg  = offCurr - pSeg->Core.Key;
     374            cbRange = RT_MIN(cbLeft, (size_t)(pSeg->Core.KeyLast + 1 - offCurr));
     375        }
     376
     377        if (fCmp)
     378        {
     379            RTSGSEG Seg;
     380            RTSGBUF SgBufCmp;
     381            size_t cbOff = 0;
     382            int rc = 0;
     383
     384            Seg.cbSeg = cbRange;
     385            Seg.pvSeg = (uint8_t *)pSeg->pvSeg + offSeg;
     386
     387            RTSgBufInit(&SgBufCmp, &Seg, 1);
     388            rc = RTSgBufCmpEx(pSgBuf, &SgBufCmp, cbRange, &cbOff, true);
     389            if (rc)
     390                return rc;
     391        }
     392        else
     393            RTSgBufAdvance(pSgBuf, cbRange);
     394
     395        offCurr += cbRange;
     396        cbLeft  -= cbRange;
     397    }
     398
     399    return 0;
     400}
     401
  • trunk/src/VBox/Storage/testcase/VDMemDisk.h

    r35471 r36134  
    115115int VDMemDiskReadFromFile(PVDMEMDISK pMemDisk, const char *pcszFilename);
    116116
     117/**
     118 * Compares the given range of the memory disk with a provided S/G buffer.
     119 *
     120 * @returns whatever memcmp returns.
     121 *
     122 * @param   pMemDisk   The memory disk handle.
     123 * @param   off        Where to start comparing.
     124 * @param   cbCmp      How many bytes to compare.
     125 * @param   pSgBuf     The S/G buffer to compare with.
     126 */
     127int VDMemDiskCmp(PVDMEMDISK pMemDisk, uint64_t off, size_t cbCmp, PRTSGBUF pSgBuf);
     128
    117129#endif /* __VDMemDisk_h__ */
  • trunk/src/VBox/Storage/testcase/tstVDIo.cpp

    r36131 r36134  
    3131#include <iprt/thread.h>
    3232#include <iprt/rand.h>
     33#include <iprt/critsect.h>
    3334
    3435#include "VDMemDisk.h"
     
    7576    /** HDD handle to operate on. */
    7677    PVBOXHDD       pVD;
     78    /** Memory disk used for data verification. */
     79    PVDMEMDISK     pMemDiskVerify;
     80    /** Critical section to serialize access to the memory disk. */
     81    RTCRITSECT     CritSectVerify;
    7782    /** Physical CHS Geometry. */
    7883    VDGEOMETRY     PhysGeom;
     
    139144    /** Buffer to use for reads. */
    140145    void          *pvBufRead;
     146    /** Opaque user data. */
     147    void          *pvUser;
    141148} VDIOREQ, *PVDIOREQ;
    142149
     
    373380{
    374381    /* pcszName    chId enmType                          fFlags */
    375     {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     382    {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     383    {"verify",     'v', VDSCRIPTARGTYPE_BOOL,            0}
    376384};
    377385
     
    440448static void tstVDIoTestDestroy(PVDIOTEST pIoTest);
    441449static bool tstVDIoTestReqOutstanding(PVDIOREQ pIoReq);
    442 static int  tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq);
     450static int  tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq, void *pvUser);
    443451static void tstVDIoTestReqComplete(void *pvUser1, void *pvUser2, int rcReq);
    444452
     
    746754                        if (!tstVDIoTestReqOutstanding(&paIoReq[idx]))
    747755                        {
    748                             rc = tstVDIoTestReqInit(&IoTest, &paIoReq[idx]);
     756                            rc = tstVDIoTestReqInit(&IoTest, &paIoReq[idx], pDisk);
    749757                            AssertRC(rc);
    750758
     
    758766                                        {
    759767                                            rc = VDRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
     768
     769                                            if (RT_SUCCESS(rc)
     770                                                && pDisk->pMemDiskVerify)
     771                                            {
     772                                                RTSGBUF SgBuf;
     773                                                RTSgBufInit(&SgBuf, &paIoReq[idx].DataSeg, 1);
     774
     775                                                if (VDMemDiskCmp(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq, &SgBuf))
     776                                                {
     777                                                    RTPrintf("Corrupted disk at offset %llu!\n", paIoReq[idx].off);
     778                                                    rc = VERR_INVALID_STATE;
     779                                                }
     780                                            }
    760781                                            break;
    761782                                        }
     
    763784                                        {
    764785                                            rc = VDWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
     786
     787                                            if (RT_SUCCESS(rc)
     788                                                && pDisk->pMemDiskVerify)
     789                                            {
     790                                                RTSGBUF SgBuf;
     791                                                RTSgBufInit(&SgBuf, &paIoReq[idx].DataSeg, 1);
     792                                                rc = VDMemDiskWrite(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq, &SgBuf);
     793                                            }
    765794                                            break;
    766795                                        }
     
    805834                                    else if (rc == VINF_VD_ASYNC_IO_FINISHED)
    806835                                    {
     836                                        switch (paIoReq[idx].enmTxDir)
     837                                        {
     838                                            case VDIOREQTXDIR_READ:
     839                                            {
     840                                                rc = VDAsyncRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
     841                                                                 tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
     842                                                if (pDisk->pMemDiskVerify)
     843                                                {
     844                                                    RTCritSectEnter(&pDisk->CritSectVerify);
     845                                                    RTSgBufReset(&paIoReq[idx].SgBuf);
     846
     847                                                    if (VDMemDiskCmp(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq,
     848                                                                     &paIoReq[idx].SgBuf))
     849                                                    {
     850                                                        RTPrintf("Corrupted disk at offset %llu!\n", paIoReq[idx].off);
     851                                                        rc = VERR_INVALID_STATE;
     852                                                    }
     853                                                    RTCritSectLeave(&pDisk->CritSectVerify);
     854                                                }
     855                                            }
     856                                            case VDIOREQTXDIR_WRITE:
     857                                            {
     858                                                rc = VDAsyncWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
     859                                                                  tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
     860
     861                                                if (pDisk->pMemDiskVerify)
     862                                                {
     863                                                    RTCritSectEnter(&pDisk->CritSectVerify);
     864                                                    RTSgBufReset(&paIoReq[idx].SgBuf);
     865
     866                                                    rc = VDMemDiskWrite(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq,
     867                                                                        &paIoReq[idx].SgBuf);
     868                                                    RTCritSectLeave(&pDisk->CritSectVerify);
     869                                                }
     870                                                break;
     871                                            }
     872                                            case VDIOREQTXDIR_FLUSH:
     873                                                break;
     874                                        }
     875
    807876                                        ASMAtomicXchgBool(&paIoReq[idx].fOutstanding, false);
    808                                         rc = VINF_SUCCESS;
     877                                        if (rc != VERR_INVALID_STATE)
     878                                            rc = VINF_SUCCESS;
    809879                                    }
    810880                                }
     
    11381208    const char *pcszDisk = NULL;
    11391209    PVDDISK pDisk = NULL;
     1210    bool fVerify = false;
    11401211
    11411212    for (unsigned i = 0; i < cScriptArgs; i++)
     
    11461217            {
    11471218                pcszDisk = paScriptArgs[i].u.pcszString;
     1219                break;
     1220            }
     1221            case 'v':
     1222            {
     1223                fVerify = paScriptArgs[i].u.fFlag;
    11481224                break;
    11491225            }
     
    11641240            if (pDisk->pszName)
    11651241            {
    1166                 rc = VDCreate(pGlob->pInterfacesDisk, VDTYPE_HDD, &pDisk->pVD);
     1242                rc = VINF_SUCCESS;
     1243
     1244                if (fVerify)
     1245                {
     1246                    rc = VDMemDiskCreate(&pDisk->pMemDiskVerify, 0 /* Growing */);
     1247                    if (RT_SUCCESS(rc))
     1248                    {
     1249                        rc = RTCritSectInit(&pDisk->CritSectVerify);
     1250                        if (RT_FAILURE(rc))
     1251                            VDMemDiskDestroy(pDisk->pMemDiskVerify);
     1252                    }
     1253                }
    11671254
    11681255                if (RT_SUCCESS(rc))
    1169                     RTListAppend(&pGlob->ListDisks, &pDisk->ListNode);
    1170                 else
    1171                     RTStrFree(pDisk->pszName);
     1256                {
     1257                    rc = VDCreate(pGlob->pInterfacesDisk, VDTYPE_HDD, &pDisk->pVD);
     1258
     1259                    if (RT_SUCCESS(rc))
     1260                        RTListAppend(&pGlob->ListDisks, &pDisk->ListNode);
     1261                    else
     1262                    {
     1263                        if (fVerify)
     1264                        {
     1265                            RTCritSectDelete(&pDisk->CritSectVerify);
     1266                            VDMemDiskDestroy(pDisk->pMemDiskVerify);
     1267                        }
     1268                        RTStrFree(pDisk->pszName);
     1269                    }
     1270                }
    11721271            }
    11731272            else
     
    12081307        RTListNodeRemove(&pDisk->ListNode);
    12091308        VDDestroy(pDisk->pVD);
     1309        if (pDisk->pMemDiskVerify)
     1310        {
     1311            VDMemDiskDestroy(pDisk->pMemDiskVerify);
     1312            RTCritSectDelete(&pDisk->CritSectVerify);
     1313        }
    12101314        RTStrFree(pDisk->pszName);
    12111315        RTMemFree(pDisk);
     
    16831787}
    16841788
    1685 static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq)
     1789static int tstVDIoTestReqInit(PVDIOTEST pIoTest, PVDIOREQ pIoReq, void *pvUser)
    16861790{
    16871791    int rc = VINF_SUCCESS;
     
    17641868                }
    17651869            }
     1870            pIoReq->pvUser = pvUser;
    17661871            pIoReq->fOutstanding = true;
    17671872        }
     
    17771882    PVDIOREQ pIoReq = (PVDIOREQ)pvUser1;
    17781883    RTSEMEVENT hEventSem = (RTSEMEVENT)pvUser2;
     1884    PVDDISK pDisk = (PVDDISK)pIoReq->pvUser;
     1885
     1886    if (pDisk->pMemDiskVerify)
     1887    {
     1888        switch (pIoReq->enmTxDir)
     1889        {
     1890            case VDIOREQTXDIR_READ:
     1891            {
     1892                RTCritSectEnter(&pDisk->CritSectVerify);
     1893                RTSgBufReset(&pIoReq->SgBuf);
     1894
     1895                if (VDMemDiskCmp(pDisk->pMemDiskVerify, pIoReq->off, pIoReq->cbReq,
     1896                                 &pIoReq->SgBuf))
     1897                    RTPrintf("Corrupted disk at offset %llu!\n", pIoReq->off);
     1898                RTCritSectLeave(&pDisk->CritSectVerify);
     1899            }
     1900            case VDIOREQTXDIR_WRITE:
     1901            {
     1902                RTCritSectEnter(&pDisk->CritSectVerify);
     1903                RTSgBufReset(&pIoReq->SgBuf);
     1904
     1905                int rc = VDMemDiskWrite(pDisk->pMemDiskVerify, pIoReq->off, pIoReq->cbReq,
     1906                                        &pIoReq->SgBuf);
     1907                AssertRC(rc);
     1908                RTCritSectLeave(&pDisk->CritSectVerify);
     1909                break;
     1910            }
     1911            case VDIOREQTXDIR_FLUSH:
     1912                break;
     1913        }
     1914    }
    17791915
    17801916    ASMAtomicXchgBool(&pIoReq->fOutstanding, false);
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