VirtualBox

Changeset 35789 in vbox for trunk/src


Ignore:
Timestamp:
Jan 31, 2011 3:25:22 PM (14 years ago)
Author:
vboxsync
Message:

Storage/tstVDIo: Updates + sample script which is a replacement of tstVDShareable

Location:
trunk/src/VBox/Storage/testcase
Files:
1 added
1 edited

Legend:

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

    r35671 r35789  
    1717 */
    1818#define LOGGROUP LOGGROUP_DEFAULT
     19#define RTMEM_WRAP_TO_EF_APIS
    1920#include <VBox/vd.h>
    2021#include <VBox/err.h>
     
    4647    /** Memory file baking the file. */
    4748    PVDMEMDISK     pMemDisk;
     49    /** Flag whether the file is read locked. */
     50    bool           fReadLock;
     51    /** Flag whether the file is write locked. */
     52    bool           fWriteLock;
     53} VDFILE, *PVDFILE;
     54
     55/**
     56 * VD storage object.
     57 */
     58typedef struct VDSTORAGE
     59{
     60    /** Pointer to the file. */
     61    PVDFILE        pFile;
    4862    /** Completion callback of the VD layer. */
    4963    PFNVDCOMPLETED pfnComplete;
    50 } VDFILE, *PVDFILE;
     64} VDSTORAGE, *PVDSTORAGE;
     65
     66/**
     67 * A virtual disk.
     68 */
     69typedef struct VDDISK
     70{
     71    /** List node. */
     72    RTLISTNODE     ListNode;
     73    /** Name of the disk handle for identification. */
     74    char          *pszName;
     75    /** HDD handle to operate on. */
     76    PVBOXHDD       pVD;
     77    /** Physical CHS Geometry. */
     78    VDGEOMETRY     PhysGeom;
     79    /** Logical CHS geometry. */
     80    VDGEOMETRY     LogicalGeom;
     81} VDDISK, *PVDDISK;
    5182
    5283/**
     
    5586typedef struct VDTESTGLOB
    5687{
    57     /** HDD handle to operate on. */
    58     PVBOXHDD         pVD;
     88    /** List of active virtual disks. */
     89    RTLISTNODE       ListDisks;
    5990    /** Head of the active file list. */
    6091    RTLISTNODE       ListFiles;
     
    73104    /** Pointer to the per image interface list. */
    74105    PVDINTERFACE     pInterfacesImages;
    75     /** Physical CHS Geometry. */
    76     VDGEOMETRY       PhysGeom;
    77     /** Logical CHS geometry. */
    78     VDGEOMETRY       LogicalGeom;
    79106    /** I/O RNG handle. */
    80107    PVDIORND         pIoRnd;
     
    136163    union
    137164    {
    138         /** Next offset for seuential access. */
     165        /** Next offset for sequential access. */
    139166        uint64_t    offNext;
    140167        /** Data for random acess. */
     
    251278static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    252279static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
     280static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
     281static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
     282static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs);
    253283
    254284/* create action */
    255285const VDSCRIPTARGDESC g_aArgCreate[] =
    256286{
    257     /* pcszName chId enmType                          fFlags */
    258     {"mode",    'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    259     {"name",    'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    260     {"backend", 'b', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    261     {"size",    's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
     287    /* pcszName    chId enmType                          fFlags */
     288    {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     289    {"mode",       'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     290    {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     291    {"type",       't', VDSCRIPTARGTYPE_STRING,          0},
     292    {"backend",    'b', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     293    {"size",       's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}
    262294};
    263295
     
    265297const VDSCRIPTARGDESC g_aArgOpen[] =
    266298{
    267     /* pcszName chId enmType                             fFlags */
    268     {"name",    'n', VDSCRIPTARGTYPE_STRING,             VDSCRIPTARGDESC_FLAG_MANDATORY},
    269     {"backend", 'b', VDSCRIPTARGTYPE_STRING,             VDSCRIPTARGDESC_FLAG_MANDATORY}
     299    /* pcszName    chId enmType                          fFlags */
     300    {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     301    {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     302    {"backend",    'b', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     303    {"shareable",  's', VDSCRIPTARGTYPE_BOOL,            0},
     304    {"readonly",   'r', VDSCRIPTARGTYPE_BOOL,            0}
    270305};
    271306
    272 /* write action */
     307/* I/O action */
    273308const VDSCRIPTARGDESC g_aArgIo[] =
    274309{
    275310    /* pcszName    chId enmType                          fFlags */
     311    {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
    276312    {"async",      'a', VDSCRIPTARGTYPE_BOOL,            0},
    277313    {"max-reqs",   'l', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0},
     
    280316    {"blocksize",  'b', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    281317    {"off",        'o', VDSCRIPTARGTYPE_UNSIGNED_RANGE,  VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    282     {"reads",      'r', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},
    283318    {"writes",     'w', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
    284319};
     
    287322const VDSCRIPTARGDESC g_aArgFlush[] =
    288323{
    289     /* pcszName  chId enmType                            fFlags */
    290     {"async",    'a', VDSCRIPTARGTYPE_BOOL,              0}
     324    /* pcszName    chId enmType                          fFlags */
     325    {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     326    {"async",      'a', VDSCRIPTARGTYPE_BOOL,            0}
    291327};
    292328
     
    294330const VDSCRIPTARGDESC g_aArgMerge[] =
    295331{
    296     /* pcszName  chId enmType                            fFlags */
    297     {"forward",  'f', VDSCRIPTARGTYPE_BOOL,              VDSCRIPTARGDESC_FLAG_MANDATORY}
     332    /* pcszName    chId enmType                          fFlags */
     333    {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     334    {"forward",    'f', VDSCRIPTARGTYPE_BOOL,            VDSCRIPTARGDESC_FLAG_MANDATORY}
    298335};
    299336
     
    301338const VDSCRIPTARGDESC g_aArgClose[] =
    302339{
    303     /* pcszName  chId enmType                            fFlags */
    304     {"mode",     'm', VDSCRIPTARGTYPE_STRING,            VDSCRIPTARGDESC_FLAG_MANDATORY},
    305     {"delete",   'd', VDSCRIPTARGTYPE_BOOL,              VDSCRIPTARGDESC_FLAG_MANDATORY}
     340    /* pcszName    chId enmType                          fFlags */
     341    {"disk",       'd', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     342    {"mode",       'm', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     343    {"delete",     'r', VDSCRIPTARGTYPE_BOOL,            VDSCRIPTARGDESC_FLAG_MANDATORY}
    306344};
    307345
     
    309347const VDSCRIPTARGDESC g_aArgIoRngCreate[] =
    310348{
    311     /* pcszName  chId enmType                            fFlags */
    312     {"size",     'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER,  VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
    313     {"seed",     's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER,  VDSCRIPTARGDESC_FLAG_MANDATORY}
     349    /* pcszName    chId enmType                          fFlags */
     350    {"size",       'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},
     351    {"seed",       's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
    314352};
    315353
     
    317355const VDSCRIPTARGDESC g_aArgSleep[] =
    318356{
    319     /* pcszName  chId enmType                            fFlags */
    320     {"time",     't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER,   VDSCRIPTARGDESC_FLAG_MANDATORY},
     357    /* pcszName    chId enmType                          fFlags */
     358    {"time",       't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY}
    321359};
    322360
     
    324362const VDSCRIPTARGDESC g_aArgDumpFile[] =
    325363{
    326     /* pcszName  chId enmType                            fFlags */
    327     {"file",     'f', VDSCRIPTARGTYPE_STRING,            VDSCRIPTARGDESC_FLAG_MANDATORY},
    328     {"path",     'p', VDSCRIPTARGTYPE_STRING,            VDSCRIPTARGDESC_FLAG_MANDATORY},
     364    /* pcszName    chId enmType                          fFlags */
     365    {"file",       'f', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     366    {"path",       'p', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     367};
     368
     369/* Create virtual disk handle */
     370const VDSCRIPTARGDESC g_aArgCreateDisk[] =
     371{
     372    /* pcszName    chId enmType                          fFlags */
     373    {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     374};
     375
     376/* Create virtual disk handle */
     377const VDSCRIPTARGDESC g_aArgDestroyDisk[] =
     378{
     379    /* pcszName    chId enmType                          fFlags */
     380    {"name",       'n', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
     381};
     382
     383/* Compare virtual disks */
     384const VDSCRIPTARGDESC g_aArgCompareDisks[] =
     385{
     386    /* pcszName    chId enmType                          fFlags */
     387    {"disk1",      '1', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY},
     388    {"disk2",      '2', VDSCRIPTARGTYPE_STRING,          VDSCRIPTARGDESC_FLAG_MANDATORY}
    329389};
    330390
     
    341401    {"iorngdestroy", NULL,                0,                               vdScriptHandlerIoRngDestroy},
    342402    {"sleep",        g_aArgSleep,         RT_ELEMENTS(g_aArgSleep),        vdScriptHandlerSleep},
    343     {"dumpfile",     g_aArgDumpFile,      RT_ELEMENTS(g_aArgDumpFile),     vdScriptHandlerDumpFile}
     403    {"dumpfile",     g_aArgDumpFile,      RT_ELEMENTS(g_aArgDumpFile),     vdScriptHandlerDumpFile},
     404    {"createdisk",   g_aArgCreateDisk,    RT_ELEMENTS(g_aArgCreateDisk),   vdScriptHandlerCreateDisk},
     405    {"destroydisk",  g_aArgDestroyDisk,   RT_ELEMENTS(g_aArgDestroyDisk),  vdScriptHandlerDestroyDisk},
     406    {"comparedisks", g_aArgCompareDisks,  RT_ELEMENTS(g_aArgCompareDisks), vdScriptHandlerCompareDisks}
    344407};
    345408
     
    363426static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, uint64_t cbIo,
    364427                           size_t cbBlkSize, uint64_t offStart, uint64_t offEnd,
    365                            unsigned uWriteChance, unsigned uReadChance);
     428                           unsigned uWriteChance);
    366429static bool tstVDIoTestRunning(PVDIOTEST pIoTest);
    367430static void tstVDIoTestDestroy(PVDIOTEST pIoTest);
     
    370433static void tstVDIoTestReqComplete(void *pvUser1, void *pvUser2, int rcReq);
    371434
     435static PVDDISK tstVDIoGetDiskByName(PVDTESTGLOB pGlob, const char *pcszDisk);
     436
    372437static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
    373438{
     
    376441    const char *pcszBackend = NULL;
    377442    const char *pcszImage = NULL;
     443    const char *pcszDisk = NULL;
     444    PVDDISK pDisk = NULL;
    378445    bool fBase = false;
     446    bool fDynamic = true;
    379447
    380448    for (unsigned i = 0; i < cScriptArgs; i++)
     
    382450        switch (paScriptArgs[i].chId)
    383451        {
     452            case 'd':
     453            {
     454                pcszDisk = paScriptArgs[i].u.pcszString;
     455                break;
     456            }
    384457            case 'm':
    385458            {
     
    410483                break;
    411484            }
     485            case 't':
     486            {
     487                if (!RTStrICmp(paScriptArgs[i].u.pcszString, "fixed"))
     488                    fDynamic = false;
     489                else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "dynamic"))
     490                    fDynamic = true;
     491                else
     492                {
     493                    RTPrintf("Invalid image type '%s' given\n", paScriptArgs[i].u.pcszString);
     494                    rc = VERR_INVALID_PARAMETER;
     495                }
     496                break;
     497            }
    412498            default:
    413499                AssertMsgFailed(("Invalid argument given!\n"));
     
    420506    if (RT_SUCCESS(rc))
    421507    {
    422         if (fBase)
    423             rc = VDCreateBase(pGlob->pVD, pcszBackend, pcszImage, cbSize, 0, NULL,
    424                               &pGlob->PhysGeom, &pGlob->LogicalGeom,
    425                               NULL, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages, NULL);
     508        pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     509        if (pDisk)
     510        {
     511            unsigned fImageFlags = VD_IMAGE_FLAGS_NONE;
     512
     513            if (!fDynamic)
     514                fImageFlags |= VD_IMAGE_FLAGS_FIXED;
     515
     516            if (fBase)
     517                rc = VDCreateBase(pDisk->pVD, pcszBackend, pcszImage, cbSize, fImageFlags, NULL,
     518                                  &pDisk->PhysGeom, &pDisk->LogicalGeom,
     519                                  NULL, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages, NULL);
     520            else
     521                rc = VDCreateDiff(pDisk->pVD, pcszBackend, pcszImage, fImageFlags, NULL, NULL, NULL, VD_OPEN_FLAGS_ASYNC_IO,
     522                                  pGlob->pInterfacesImages, NULL);
     523        }
    426524        else
    427             rc = VDCreateDiff(pGlob->pVD, pcszBackend, pcszImage, 0, NULL, NULL, NULL, VD_OPEN_FLAGS_ASYNC_IO,
    428                               pGlob->pInterfacesImages, NULL);
     525            rc = VERR_NOT_FOUND;
    429526    }
    430527
     
    437534    const char *pcszBackend = NULL;
    438535    const char *pcszImage = NULL;
     536    const char *pcszDisk = NULL;
     537    PVDDISK pDisk = NULL;
     538    bool fShareable = false;
     539    bool fReadonly = false;
    439540
    440541    for (unsigned i = 0; i < cScriptArgs; i++)
     
    442543        switch (paScriptArgs[i].chId)
    443544        {
     545            case 'd':
     546            {
     547                pcszDisk = paScriptArgs[i].u.pcszString;
     548                break;
     549            }
    444550            case 'n':
    445551            {
     
    450556            {
    451557                pcszBackend = paScriptArgs[i].u.pcszString;
     558                break;
     559            }
     560            case 's':
     561            {
     562                fShareable = paScriptArgs[i].u.fFlag;
     563                break;
     564            }
     565            case 'r':
     566            {
     567                fReadonly = paScriptArgs[i].u.fFlag;
    452568                break;
    453569            }
     
    462578    if (RT_SUCCESS(rc))
    463579    {
    464         rc = VDOpen(pGlob->pVD, pcszBackend, pcszImage, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages);
     580        pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     581        if (pDisk)
     582        {
     583            unsigned fOpenFlags = VD_OPEN_FLAGS_ASYNC_IO;
     584
     585            if (fShareable)
     586                fOpenFlags |= VD_OPEN_FLAGS_SHAREABLE;
     587            if (fReadonly)
     588                fOpenFlags |= VD_OPEN_FLAGS_READONLY;
     589
     590            rc = VDOpen(pDisk->pVD, pcszBackend, pcszImage, fOpenFlags, pGlob->pInterfacesImages);
     591        }
     592        else
     593            rc = VERR_NOT_FOUND;
    465594    }
    466595
     
    481610    unsigned cMaxReqs = 0;
    482611    uint8_t uWriteChance = 0;
    483     uint8_t uReadChance = 0;
    484 
    485     offEnd = VDGetSize(pGlob->pVD, VD_LAST_IMAGE);
    486     if (offEnd == 0)
    487         return VERR_INVALID_STATE;
    488     cbIo = offEnd;
     612    const char *pcszDisk = NULL;
     613    PVDDISK pDisk = NULL;
    489614
    490615    for (unsigned i = 0; i < cScriptArgs; i++)
     
    492617        switch (paScriptArgs[i].chId)
    493618        {
     619            case 'd':
     620            {
     621                pcszDisk = paScriptArgs[i].u.pcszString;
     622                break;
     623            }
    494624            case 'a':
    495625            {
     
    531661                break;
    532662            }
    533             case 'r':
    534             {
    535                 uReadChance = (uint8_t)paScriptArgs[i].u.u64;
    536                 break;
    537             }
    538663            case 'w':
    539664            {
     
    551676    if (RT_SUCCESS(rc))
    552677    {
     678        pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     679        if (!pDisk)
     680            rc = VERR_NOT_FOUND;
     681    }
     682
     683    if (RT_SUCCESS(rc))
     684    {
     685        /* Set defaults if not set by the user. */
     686        if (offStart == 0 && offEnd == 0)
     687        {
     688            offEnd = VDGetSize(pDisk->pVD, VD_LAST_IMAGE);
     689            if (offEnd == 0)
     690                return VERR_INVALID_STATE;
     691        }
     692
     693        if (!cbIo)
     694            cbIo = offEnd;
     695    }
     696
     697    if (RT_SUCCESS(rc))
     698    {
    553699        VDIOTEST IoTest;
    554700
    555         rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance, uReadChance);
     701        rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance);
    556702        if (RT_SUCCESS(rc))
    557703        {
     
    601747                                        case VDIOREQTXDIR_READ:
    602748                                        {
    603                                             rc = VDRead(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
     749                                            rc = VDRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
    604750                                            break;
    605751                                        }
    606752                                        case VDIOREQTXDIR_WRITE:
    607753                                        {
    608                                             rc = VDWrite(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
     754                                            rc = VDWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);
    609755                                            break;
    610756                                        }
    611757                                        case VDIOREQTXDIR_FLUSH:
    612758                                        {
    613                                             rc = VDFlush(pGlob->pVD);
     759                                            rc = VDFlush(pDisk->pVD);
    614760                                            break;
    615761                                        }
     
    624770                                        case VDIOREQTXDIR_READ:
    625771                                        {
    626                                             rc = VDAsyncRead(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
     772                                            rc = VDAsyncRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
    627773                                                             tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
    628774                                            break;
     
    630776                                        case VDIOREQTXDIR_WRITE:
    631777                                        {
    632                                             rc = VDAsyncWrite(pGlob->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
     778                                            rc = VDAsyncWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,
    633779                                                              tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
    634780                                            break;
     
    636782                                        case VDIOREQTXDIR_FLUSH:
    637783                                        {
    638                                             rc = VDAsyncFlush(pGlob->pVD, tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
     784                                            rc = VDAsyncFlush(pDisk->pVD, tstVDIoTestReqComplete, &paIoReq[idx], EventSem);
    639785                                            break;
    640786                                        }
     
    715861    int rc = VINF_SUCCESS;
    716862    bool fAsync = false;
    717 
    718     if (cScriptArgs == 1 && paScriptArgs[0].chId == 'a')
    719         fAsync = paScriptArgs[0].u.fFlag;
    720 
    721     if (fAsync)
    722     {
    723         /** @todo  */
    724         rc = VERR_NOT_IMPLEMENTED;
    725     }
    726     else
    727         rc = VDFlush(pGlob->pVD);
     863    const char *pcszDisk = NULL;
     864    PVDDISK pDisk = NULL;
     865
     866    for (unsigned i = 0; i < cScriptArgs; i++)
     867    {
     868        switch (paScriptArgs[i].chId)
     869        {
     870            case 'd':
     871            {
     872                pcszDisk = paScriptArgs[i].u.pcszString;
     873                break;
     874            }
     875            case 'a':
     876            {
     877                fAsync = paScriptArgs[i].u.fFlag;
     878                break;
     879            }
     880
     881            default:
     882                AssertMsgFailed(("Invalid argument given!\n"));
     883        }
     884
     885        if (RT_FAILURE(rc))
     886            break;
     887    }
     888
     889    if (RT_SUCCESS(rc))
     890    {
     891        pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     892        if (!pDisk)
     893            rc = VERR_NOT_FOUND;
     894        else if (fAsync)
     895        {
     896            /** @todo  */
     897            rc = VERR_NOT_IMPLEMENTED;
     898        }
     899        else
     900            rc = VDFlush(pDisk->pVD);
     901    }
    728902
    729903    return rc;
     
    740914    bool fAll = false;
    741915    bool fDelete = false;
     916    const char *pcszDisk = NULL;
     917    PVDDISK pDisk = NULL;
    742918
    743919    for (unsigned i = 0; i < cScriptArgs; i++)
     
    745921        switch (paScriptArgs[i].chId)
    746922        {
     923            case 'd':
     924            {
     925                pcszDisk = paScriptArgs[i].u.pcszString;
     926                break;
     927            }
    747928            case 'm':
    748929            {
     
    758939                break;
    759940            }
    760             case 'd':
     941            case 'r':
    761942            {
    762943                fDelete = paScriptArgs[i].u.fFlag;
     
    781962    if (RT_SUCCESS(rc))
    782963    {
    783         if (fAll)
    784             rc = VDCloseAll(pGlob->pVD);
     964        pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     965        if (pDisk)
     966        {
     967            if (fAll)
     968                rc = VDCloseAll(pDisk->pVD);
     969            else
     970                rc = VDClose(pDisk->pVD, fDelete);
     971        }
    785972        else
    786             rc = VDClose(pGlob->pVD, fDelete);
     973            rc = VERR_NOT_FOUND;
    787974    }
    788975    return rc;
     
    9101097}
    9111098
     1099static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
     1100{
     1101    int rc = VINF_SUCCESS;
     1102    const char *pcszDisk = NULL;
     1103    PVDDISK pDisk = NULL;
     1104
     1105    for (unsigned i = 0; i < cScriptArgs; i++)
     1106    {
     1107        switch (paScriptArgs[i].chId)
     1108        {
     1109            case 'n':
     1110            {
     1111                pcszDisk = paScriptArgs[i].u.pcszString;
     1112                break;
     1113            }
     1114            default:
     1115                AssertMsgFailed(("Invalid argument given!\n"));
     1116        }
     1117    }
     1118
     1119    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     1120    if (pDisk)
     1121        rc = VERR_ALREADY_EXISTS;
     1122    else
     1123    {
     1124        pDisk = (PVDDISK)RTMemAllocZ(sizeof(VDDISK));
     1125        if (pDisk)
     1126        {
     1127            pDisk->pszName = RTStrDup(pcszDisk);
     1128            if (pDisk->pszName)
     1129            {
     1130                rc = VDCreate(pGlob->pInterfacesDisk, VDTYPE_HDD, &pDisk->pVD);
     1131
     1132                if (RT_SUCCESS(rc))
     1133                    RTListAppend(&pGlob->ListDisks, &pDisk->ListNode);
     1134                else
     1135                    RTStrFree(pDisk->pszName);
     1136            }
     1137            else
     1138                rc = VERR_NO_MEMORY;
     1139
     1140            if (RT_FAILURE(rc))
     1141                RTMemFree(pDisk);
     1142        }
     1143        else
     1144            rc = VERR_NO_MEMORY;
     1145    }
     1146    return rc;
     1147}
     1148
     1149static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
     1150{
     1151    int rc = VINF_SUCCESS;
     1152    const char *pcszDisk = NULL;
     1153    PVDDISK pDisk = NULL;
     1154
     1155    for (unsigned i = 0; i < cScriptArgs; i++)
     1156    {
     1157        switch (paScriptArgs[i].chId)
     1158        {
     1159            case 'n':
     1160            {
     1161                pcszDisk = paScriptArgs[i].u.pcszString;
     1162                break;
     1163            }
     1164            default:
     1165                AssertMsgFailed(("Invalid argument given!\n"));
     1166        }
     1167    }
     1168
     1169    pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk);
     1170    if (pDisk)
     1171    {
     1172        RTListNodeRemove(&pDisk->ListNode);
     1173        VDDestroy(pDisk->pVD);
     1174        RTStrFree(pDisk->pszName);
     1175        RTMemFree(pDisk);
     1176    }
     1177    else
     1178        rc = VERR_NOT_FOUND;
     1179
     1180    return rc;
     1181}
     1182
     1183static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs)
     1184{
     1185    int rc = VINF_SUCCESS;
     1186    const char *pcszDisk1 = NULL;
     1187    PVDDISK pDisk1 = NULL;
     1188    const char *pcszDisk2 = NULL;
     1189    PVDDISK pDisk2 = NULL;
     1190
     1191    for (unsigned i = 0; i < cScriptArgs; i++)
     1192    {
     1193        switch (paScriptArgs[i].chId)
     1194        {
     1195            case '1':
     1196            {
     1197                pcszDisk1 = paScriptArgs[i].u.pcszString;
     1198                break;
     1199            }
     1200            case '2':
     1201            {
     1202                pcszDisk2 = paScriptArgs[i].u.pcszString;
     1203                break;
     1204            }
     1205            default:
     1206                AssertMsgFailed(("Invalid argument given!\n"));
     1207        }
     1208    }
     1209
     1210    pDisk1 = tstVDIoGetDiskByName(pGlob, pcszDisk1);
     1211    pDisk2 = tstVDIoGetDiskByName(pGlob, pcszDisk2);
     1212
     1213    if (pDisk1 && pDisk2)
     1214    {
     1215        uint8_t *pbBuf1 = (uint8_t *)RTMemAllocZ(16 * _1M);
     1216        uint8_t *pbBuf2 = (uint8_t *)RTMemAllocZ(16 * _1M);
     1217        if (pbBuf1 && pbBuf2)
     1218        {
     1219            uint64_t cbDisk1, cbDisk2;
     1220            uint64_t uOffCur = 0;
     1221
     1222            cbDisk1 = VDGetSize(pDisk1->pVD, VD_LAST_IMAGE);
     1223            cbDisk2 = VDGetSize(pDisk2->pVD, VD_LAST_IMAGE);
     1224
     1225            if (cbDisk1 != cbDisk2)
     1226                RTPrintf("Disks differ in size %llu vs %llu\n", cbDisk1, cbDisk2);
     1227            else
     1228            {
     1229                while (uOffCur < cbDisk1)
     1230                {
     1231                    size_t cbRead = RT_MIN(cbDisk1, 16 * _1M);
     1232
     1233                    rc = VDRead(pDisk1->pVD, uOffCur, pbBuf1, cbRead);
     1234                    if (RT_SUCCESS(rc))
     1235                        rc = VDRead(pDisk2->pVD, uOffCur, pbBuf2, cbRead);
     1236
     1237                    if (RT_SUCCESS(rc))
     1238                    {
     1239                        if (memcmp(pbBuf1, pbBuf2, cbRead))
     1240                        {
     1241                            RTPrintf("Disks differ at offset %llu\n", uOffCur);
     1242                            rc = VERR_DEV_IO_ERROR;
     1243                            break;
     1244                        }
     1245                    }
     1246                    else
     1247                    {
     1248                        RTPrintf("Reading one disk at offset %llu failed\n", uOffCur);
     1249                        break;
     1250                    }
     1251
     1252                    uOffCur += cbRead;
     1253                    cbDisk1 -= cbRead;
     1254                }
     1255            }
     1256            RTMemFree(pbBuf1);
     1257            RTMemFree(pbBuf2);
     1258        }
     1259        else
     1260        {
     1261            if (pbBuf1)
     1262                RTMemFree(pbBuf1);
     1263            if (pbBuf2)
     1264                RTMemFree(pbBuf2);
     1265            rc = VERR_NO_MEMORY;
     1266        }
     1267    }
     1268    else
     1269        rc = VERR_NOT_FOUND;
     1270
     1271    return rc;
     1272}
     1273
    9121274static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation,
    9131275                                         uint32_t fOpen,
     
    9191281    bool fFound = false;
    9201282
     1283    /*
     1284     * Some backends use ./ for paths, strip it.
     1285     * @todo: Implement proper directory support for the
     1286     * memory filesystem.
     1287     */
     1288    if (   strlen(pszLocation) >= 2
     1289        && *pszLocation == '.'
     1290        && pszLocation[1] == '/')
     1291        pszLocation += 2;
     1292
    9211293    /* Check if the file exists. */
    9221294    PVDFILE pIt = NULL;
     
    9301302    }
    9311303
    932     if (fFound && pIt->pfnComplete)
    933         rc = VERR_FILE_LOCK_FAILED;
    934     else if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE)
     1304    if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE)
    9351305    {
    9361306        /* If the file exists delete the memory disk. */
     
    9431313            if (pIt)
    9441314            {
    945                 pIt->pfnComplete = pfnCompleted;
    946                 pIt->pszName     = RTStrDup(pszLocation);
     1315                pIt->pszName = RTStrDup(pszLocation);
    9471316
    9481317                if (pIt->pszName)
     
    9701339        if (!fFound)
    9711340            rc = VERR_FILE_NOT_FOUND;
    972         else
    973             pIt->pfnComplete = pfnCompleted;
    9741341    }
    9751342    else
     
    9791346    {
    9801347        AssertPtr(pIt);
    981         *ppStorage = pIt;
     1348        PVDSTORAGE pStorage = (PVDSTORAGE)RTMemAllocZ(sizeof(VDSTORAGE));
     1349        if (!pStorage)
     1350            rc = VERR_NO_MEMORY;
     1351
     1352        pStorage->pFile = pIt;
     1353        pStorage->pfnComplete = pfnCompleted;
     1354        *ppStorage = pStorage;
    9821355    }
    9831356
     
    9871360static DECLCALLBACK(int) tstVDIoFileClose(void *pvUser, void *pStorage)
    9881361{
    989     PVDFILE pFile = (PVDFILE)pStorage;
    990 
    991     /* Mark as not busy. */
    992     pFile->pfnComplete = NULL;
     1362    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
     1363
     1364    RTMemFree(pIoStorage);
    9931365    return VINF_SUCCESS;
    9941366}
     
    10761448static DECLCALLBACK(int) tstVDIoFileGetSize(void *pvUser, void *pStorage, uint64_t *pcbSize)
    10771449{
    1078     PVDFILE pFile = (PVDFILE)pStorage;
    1079 
    1080     return VDMemDiskGetSize(pFile->pMemDisk, pcbSize);
     1450    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
     1451
     1452    return VDMemDiskGetSize(pIoStorage->pFile->pMemDisk, pcbSize);
    10811453}
    10821454
    10831455static DECLCALLBACK(int) tstVDIoFileSetSize(void *pvUser, void *pStorage, uint64_t cbSize)
    10841456{
    1085     PVDFILE pFile = (PVDFILE)pStorage;
    1086 
    1087     return VDMemDiskSetSize(pFile->pMemDisk, cbSize);
     1457    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
     1458
     1459    return VDMemDiskSetSize(pIoStorage->pFile->pMemDisk, cbSize);
    10881460}
    10891461
     
    10921464{
    10931465    int rc = VINF_SUCCESS;
    1094     PVDFILE pFile = (PVDFILE)pStorage;
     1466    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
    10951467
    10961468    RTSGBUF SgBuf;
     
    11001472    Seg.cbSeg = cbBuffer;
    11011473    RTSgBufInit(&SgBuf, &Seg, 1);
    1102     rc = VDMemDiskWrite(pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
     1474    rc = VDMemDiskWrite(pIoStorage->pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
    11031475    if (RT_SUCCESS(rc) && pcbWritten)
    11041476        *pcbWritten = cbBuffer;
     
    11111483{
    11121484    int rc = VINF_SUCCESS;
    1113     PVDFILE pFile = (PVDFILE)pStorage;
     1485    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
    11141486
    11151487    RTSGBUF SgBuf;
     
    11191491    Seg.cbSeg = cbBuffer;
    11201492    RTSgBufInit(&SgBuf, &Seg, 1);
    1121     rc = VDMemDiskRead(pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
     1493    rc = VDMemDiskRead(pIoStorage->pFile->pMemDisk, uOffset, cbBuffer, &SgBuf);
    11221494    if (RT_SUCCESS(rc) && pcbRead)
    11231495        *pcbRead = cbBuffer;
     
    11391511    int rc = VINF_SUCCESS;
    11401512    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    1141     PVDFILE pFile = (PVDFILE)pStorage;
    1142 
    1143     rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pFile->pMemDisk, VDIOTXDIR_READ, uOffset,
    1144                                 cbRead, paSegments, cSegments, pFile->pfnComplete, pvCompletion);
     1513    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
     1514
     1515    rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_READ, uOffset,
     1516                                cbRead, paSegments, cSegments, pIoStorage->pfnComplete, pvCompletion);
    11451517    if (RT_SUCCESS(rc))
    11461518        rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     
    11561528    int rc = VINF_SUCCESS;
    11571529    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    1158     PVDFILE pFile = (PVDFILE)pStorage;
    1159 
    1160     rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pFile->pMemDisk, VDIOTXDIR_WRITE, uOffset,
    1161                                 cbWrite, paSegments, cSegments, pFile->pfnComplete, pvCompletion);
     1530    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
     1531
     1532    rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_WRITE, uOffset,
     1533                                cbWrite, paSegments, cSegments, pIoStorage->pfnComplete, pvCompletion);
    11621534    if (RT_SUCCESS(rc))
    11631535        rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     
    11711543    int rc = VINF_SUCCESS;
    11721544    PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser;
    1173     PVDFILE pFile = (PVDFILE)pStorage;
    1174 
    1175     rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pFile->pMemDisk, VDIOTXDIR_FLUSH, 0,
    1176                                 0, NULL, 0, pFile->pfnComplete, pvCompletion);
     1545    PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage;
     1546
     1547    rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_FLUSH, 0,
     1548                                0, NULL, 0, pIoStorage->pfnComplete, pvCompletion);
    11771549    if (RT_SUCCESS(rc))
    11781550        rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     
    11831555static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, uint64_t cbIo,
    11841556                           size_t cbBlkSize, uint64_t offStart, uint64_t offEnd,
    1185                            unsigned uWriteChance, unsigned uReadChance)
     1557                           unsigned uWriteChance)
    11861558{
    11871559    int rc = VINF_SUCCESS;
     
    13031675                if (!pIoTest->u.Rnd.cBlocksLeft)
    13041676                {
    1305                     /* New round, clear everthing. */
     1677                    /* New round, clear everything. */
    13061678                    ASMBitClearRange(pIoTest->u.Rnd.pbMapAccessed, 0, pIoTest->u.Rnd.cBlocks);
    13071679                    pIoTest->u.Rnd.cBlocksLeft = pIoTest->u.Rnd.cBlocks;
     
    13461718
    13471719/**
     1720 * Returns the disk handle by name or NULL if not found
     1721 *
     1722 * @returns Disk handle or NULL if the disk could not be found.
     1723 *
     1724 * @param pGlob    Global test state.
     1725 * @param pcszDisk Name of the disk to get.
     1726 */
     1727static PVDDISK tstVDIoGetDiskByName(PVDTESTGLOB pGlob, const char *pcszDisk)
     1728{
     1729    PVDDISK pIt = NULL;
     1730    bool fFound = false;
     1731
     1732    LogFlowFunc(("pGlob=%#p pcszDisk=%s\n", pGlob, pcszDisk));
     1733
     1734    RTListForEach(&pGlob->ListDisks, pIt, VDDISK, ListNode)
     1735    {
     1736        if (!RTStrCmp(pIt->pszName, pcszDisk))
     1737        {
     1738            fFound = true;
     1739            break;
     1740        }
     1741    }
     1742
     1743    LogFlowFunc(("return %#p\n", fFound ? pIt : NULL));
     1744    return fFound ? pIt : NULL;
     1745}
     1746
     1747/**
    13481748 * Skips the characters until the given character is reached.
    13491749 *
     
    13961796
    13971797    return psz;
     1798}
     1799
     1800/**
     1801 * Returns true if the first character of the given string
     1802 * contains a character marking a line end (comment or \0
     1803 * terminator).
     1804 *
     1805 * @returns true if the line contains no more characters of
     1806 *          interest and false otherwise.
     1807 *
     1808 * @param psz    The string to check for.
     1809 */
     1810static bool tstVDIoIsLineEnd(const char *psz)
     1811{
     1812    return *psz == '\0' || *psz == '#';
    13981813}
    13991814
     
    16202035
    16212036    while (    psz
    1622            && *psz != '\0')
     2037           && !tstVDIoIsLineEnd(psz))
    16232038    {
    16242039        const char *pcszName = psz;
    16252040
    16262041        psz = tstVDIoScriptSkipUntil(psz, '=');
    1627         if (psz != '\0')
     2042        if (!tstVDIoIsLineEnd(psz))
    16282043        {
    16292044            *psz = '\0'; /* Overwrite */
     
    16322047
    16332048            psz = tstVDIoScriptSkipNonSpace(psz);
    1634             if (psz != '\0')
     2049            if (!tstVDIoIsLineEnd(psz))
    16352050            {
    16362051                *psz = '\0'; /* Overwrite */
    16372052                psz++;
    16382053                psz = tstVDIoScriptSkipSpace(psz);
    1639 
    1640                 /* We have the name and value pair now. */
    1641                 bool fMandatory = false; /* Shut up gcc */
    1642                 rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory);
    1643                 if (RT_SUCCESS(rc))
    1644                 {
    1645                     if (fMandatory)
    1646                         cMandatoryArgsReq--;
    1647                     cScriptArgs++;
    1648                 }
    1649             }
    1650             else
     2054            }
     2055
     2056            pcszValue = tstVDIoScriptSkipSpace((char *)pcszValue);
     2057            if (*pcszValue == '\0')
    16512058            {
    16522059                RTPrintf("Value missing for argument '%s'\n", pcszName);
    16532060                rc = VERR_INVALID_STATE;
    16542061                break;
     2062            }
     2063
     2064            /* We have the name and value pair now. */
     2065            bool fMandatory = false; /* Shut up gcc */
     2066            rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory);
     2067            if (RT_SUCCESS(rc))
     2068            {
     2069                if (fMandatory)
     2070                    cMandatoryArgsReq--;
     2071                cScriptArgs++;
    16552072            }
    16562073        }
     
    17032120            /* Skip space */
    17042121            psz = tstVDIoScriptSkipSpace(psz);
    1705             if (psz != '\0')
     2122            if (!tstVDIoIsLineEnd(psz))
    17062123            {
    17072124                PCVDSCRIPTACTION pVDScriptAction = NULL;
     
    17112128
    17122129                psz = tstVDIoScriptSkipNonSpace(psz);
    1713                 if (psz != '\0')
     2130                if (!tstVDIoIsLineEnd(psz))
    17142131                {
    17152132                    Assert(RT_C_IS_SPACE(*psz));
     
    17632180                }
    17642181            }
    1765             else
    1766             {
    1767                 RTPrintf("Missing action name\n");
    1768                 rc = VERR_INVALID_STATE;
    1769             }
     2182            /* else empty line, just continue */
    17702183        }
    17712184    } while(RT_SUCCESS(rc));
     
    17942207    memset(&GlobTest, 0, sizeof(VDTESTGLOB));
    17952208    RTListInit(&GlobTest.ListFiles);
     2209    RTListInit(&GlobTest.ListDisks);
    17962210
    17972211    rc = RTStrmOpen(pcszFilename, "r", &pScriptStrm);
     
    18332247        if (RT_SUCCESS(rc))
    18342248        {
    1835             rc = VDCreate(GlobTest.pInterfacesDisk, VDTYPE_HDD, &GlobTest.pVD);
    1836             if (RT_SUCCESS(rc))
    1837             {
    1838                 /* Execute the script. */
    1839                 rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest);
    1840                 if (RT_FAILURE(rc))
    1841                 {
    1842                     RTPrintf("Executing the script stream failed rc=%Rrc\n", rc);
    1843                 }
    1844             }
    1845             else
    1846                 RTPrintf("Failed to create disk container rc=%Rrc\n", rc);
     2249            /* Execute the script. */
     2250            rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest);
     2251            if (RT_FAILURE(rc))
     2252            {
     2253                RTPrintf("Executing the script stream failed rc=%Rrc\n", rc);
     2254            }
    18472255            VDIoBackendMemDestroy(GlobTest.pIoBackend);
    18482256        }
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