VirtualBox

Changeset 11421 in vbox for trunk


Ignore:
Timestamp:
Aug 14, 2008 12:06:14 PM (16 years ago)
Author:
vboxsync
Message:

Storage/VBoxHDD-new: Added backend info, listing the supported file extensions. Implemented a testcase anf fixed a small bug which it found.

Location:
trunk
Files:
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxHDD-new.h

    r11353 r11421  
    224224    /** Capabilities of the backend (a combination of the VD_CAP_* flags). */
    225225    uint64_t uBackendCaps;
     226    /** Pointer to a NULL-terminated array of strings, containing the supported
     227     * file extensions. Note that some backends do not work on files, so this
     228     * pointer may just contain NULL. */
     229    const char * const *papszFileExtensions;
    226230} VDBACKENDINFO, *PVDBACKENDINFO;
    227231
  • trunk/src/VBox/Devices/Storage/RawHDDCore.cpp

    r11353 r11421  
    6767} RAWIMAGE, *PRAWIMAGE;
    6868
     69/*******************************************************************************
     70*   Static Variables                                                           *
     71*******************************************************************************/
     72
     73/** NULL-terminated array of supported file extensions. */
     74static const char *const s_apszRawFileExtensions[] =
     75{
     76    /** @todo At the monment this backend doesn't claim any extensions, but it might
     77     * be useful to add a few later. However this needs careful testing, as the
     78     * CheckIfValid function never returns success. */
     79    NULL
     80};
    6981
    7082/*******************************************************************************
     
    10581070    /* uBackendCaps */
    10591071    VD_CAP_CREATE_FIXED | VD_CAP_FILE,
     1072    /* papszFileExtensions */
     1073    s_apszRawFileExtensions,
    10601074    /* pfnCheckIfValid */
    10611075    rawCheckIfValid,
  • trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp

    r11353 r11421  
    649649            pEntries[cEntries].pszBackend = pszName;
    650650            pEntries[cEntries].uBackendCaps = aBackends[i]->uBackendCaps;
     651            pEntries[cEntries].papszFileExtensions = aBackends[i]->papszFileExtensions;
    651652            cEntries++;
    652653            if (cEntries >= cEntriesAlloc)
     
    737738                        pEntries[cEntries].pszBackend = pszName;
    738739                        pEntries[cEntries].uBackendCaps = pBackend->uBackendCaps;
     740                        pEntries[cEntries].papszFileExtensions = pBackend->papszFileExtensions;
    739741                        cEntries++;
    740742                        if (cEntries >= cEntriesAlloc)
     
    751753            }
    752754        }
     755        if (rc == VERR_NO_MORE_FILES)
     756            rc = VINF_SUCCESS;
    753757        RTStrFree(pszPluginFilter);
    754758        if (pPluginDirEntry)
     
    28912895            pBackendInfo->pszBackend = RTStrDup(pImage->Backend->pszBackendName);
    28922896            pBackendInfo->uBackendCaps = pImage->Backend->uBackendCaps;
     2897            pBackendInfo->papszFileExtensions = pImage->Backend->papszFileExtensions;
    28932898            rc = VINF_SUCCESS;
    28942899        }
  • trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h

    r11353 r11421  
    5555     */
    5656    uint64_t uBackendCaps;
     57
     58    /**
     59     * Pointer to a NULL-terminated array of strings, containing the supported
     60     * file extensions. Note that some backends do not work on files, so this
     61     * pointer may just contain NULL.
     62     */
     63    const char * const *papszFileExtensions;
    5764
    5865    /**
  • trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp

    r11353 r11421  
    3737
    3838#define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M
     39
     40/*******************************************************************************
     41*   Static Variables                                                           *
     42*******************************************************************************/
     43
     44/** NULL-terminated array of supported file extensions. */
     45static const char *const s_apszVdiFileExtensions[] =
     46{
     47    "vdi",
     48    NULL
     49};
    3950
    4051/*******************************************************************************
     
    17961807      VD_CAP_UUID | VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC
    17971808    | VD_CAP_CREATE_SPLIT_2G | VD_CAP_DIFF | VD_CAP_FILE,
     1809    /* papszFileExtensions */
     1810    s_apszVdiFileExtensions,
    17981811    /* pfnCheckIfValid */
    17991812    vdiCheckIfValid,
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r11353 r11421  
    409409} VMDKIMAGE;
    410410
    411 
     411/*******************************************************************************
     412 *   Static Variables                                                           *
     413 *******************************************************************************/
     414
     415/** NULL-terminated array of supported file extensions. */
     416static const char *const s_apszVmdkFileExtensions[] =
     417{
     418    "vmdk",
     419    NULL
     420};
     421       
    412422/*******************************************************************************
    413423*   Internal Functions                                                         *
     
    51535163      VD_CAP_UUID | VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC
    51545164    | VD_CAP_CREATE_SPLIT_2G | VD_CAP_DIFF | VD_CAP_FILE |VD_CAP_ASYNC,
     5165    /* papszFileExtensions */
     5166    s_apszVmdkFileExtensions,
    51555167    /* pfnCheckIfValid */
    51565168    vmdkCheckIfValid,
  • trunk/src/VBox/Devices/Storage/testcase/Makefile.kmk

    r10041 r11421  
    5959
    6060#
    61 # Basic testcase for the VD code.
     61# Basic testcases for the VD code.
    6262#
    6363ifdef VBOX_WITH_TESTCASES
    64  PROGRAMS += tstVD
     64 PROGRAMS += tstVD tstVD-2
    6565 ifeq ($(KBUILD_TARGET),l4)
    6666  tstVD_TEMPLATE = VBOXLNXHOSTR3EXE
     67  tstVD-2_TEMPLATE = VBOXLNXHOSTR3EXE
    6768 else
    6869  tstVD_TEMPLATE = VBOXR3TSTEXE
     70  tstVD-2_TEMPLATE = VBOXR3TSTEXE
    6971 endif
    7072 tstVD_LIBS     = $(vditool_LIBS)
     73 tstVD-2_LIBS     = $(vditool_LIBS)
    7174 tstVD_SOURCES  = tstVD.cpp
     75 tstVD-2_SOURCES  = tstVD-2.cpp
    7276endif
    7377
  • trunk/src/VBox/Devices/Storage/testcase/tstVD-2.cpp

    r11406 r11421  
    11/** @file
    22 *
    3  * Simple VBox HDD container test utility.
     3 * Simple VBox HDD container test utility. Only fast tests.
    44 */
    55
     
    3838
    3939
    40 static void tstVDError(void *pvUser, int rc, RT_SRC_POS_DECL,
    41                        const char *pszFormat, va_list va)
    42 {
    43     g_cErrors++;
    44     RTPrintf("tstVD: Error %Vrc at %s:%u (%s): ", rc, RT_SRC_POS_ARGS);
    45     RTPrintfV(pszFormat, va);
    46     RTPrintf("\n");
    47 }
    48 
    49 
    50 static int tstVDCreateDelete(const char *pszBackend, const char *pszFilename,
    51                              uint64_t cbSize, VDIMAGETYPE enmType,
    52                              unsigned uFlags, bool fDelete)
     40static int tstVDBackendInfo(void)
    5341{
    5442    int rc;
    55     PVBOXHDD pVD = NULL;
    56     PDMMEDIAGEOMETRY PCHS = { 0, 0, 0 };
    57     PDMMEDIAGEOMETRY LCHS = { 0, 0, 0 };
    58     VDINTERFACE      VDIError;
    59     VDINTERFACEERROR VDIErrorCallbacks;
     43#define MAX_BACKENDS 100
     44    VDBACKENDINFO aVDInfo[MAX_BACKENDS];
     45    unsigned cEntries;
    6046
    6147#define CHECK(str) \
     
    6450        RTPrintf("%s rc=%Vrc\n", str, rc); \
    6551        if (VBOX_FAILURE(rc)) \
    66         { \
    67             VDCloseAll(pVD); \
    6852            return rc; \
    69         } \
    7053    } while (0)
    7154
    72     /* Create error interface. */
    73     VDIErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
    74     VDIErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
    75     VDIErrorCallbacks.pfnError = tstVDError;
     55    rc = VDBackendInfo(MAX_BACKENDS, aVDInfo, &cEntries);
     56    CHECK("VDBackendInfo()");
    7657
    77     rc = VDInterfaceCreate(&VDIError, "tstVD_Error", VDINTERFACETYPE_ERROR, &VDIErrorCallbacks,
    78                            NULL, NULL);
    79     AssertRC(rc);
    80 
    81     rc = VDCreate(&VDIError, &pVD);
    82     CHECK("VDCreate()");
    83 
    84     rc = VDCreateBase(pVD, pszBackend, pszFilename, enmType, cbSize,
    85                       uFlags, "Test image", &PCHS, &LCHS, NULL,
    86                       VD_OPEN_FLAGS_NORMAL, NULL, NULL);
    87     CHECK("VDCreateBase()");
    88 
    89     VDDumpImages(pVD);
    90 
    91     VDClose(pVD, fDelete);
    92 #undef CHECK
    93     return 0;
    94 }
    95 
    96 
    97 #undef RTDECL
    98 #define RTDECL(x) static x
    99 
    100 /* Start of IPRT code */
    101 
    102 /**
    103  * The following code is based on the work of George Marsaglia
    104  * taken from
    105  * http://groups.google.ws/group/comp.sys.sun.admin/msg/7c667186f6cbf354
    106  * and
    107  * http://groups.google.ws/group/comp.lang.c/msg/0e170777c6e79e8d
    108  */
    109 
    110 /*
    111 A C version of a very very good 64-bit RNG is given below.
    112 You should be able to adapt it to your particular needs.
    113 
    114 It is based on the complimentary-multiple-with-carry
    115 sequence
    116          x(n)=a*x(n-4)+carry mod 2^64-1,
    117 which works as follows:
    118 Assume a certain multiplier 'a' and a base 'b'.
    119 Given a current x value and a current carry 'c',
    120 form:               t=a*x+c
    121 Then the new carry is     c=floor(t/b)
    122 and the new x value is    x = b-1-(t mod b).
    123 
    124 
    125 Ordinarily, for 32-bit mwc or cmwc sequences, the
    126 value t=a*x+c can be formed in 64 bits, then the new c
    127 is the top and the new x the bottom 32 bits (with a little
    128 fiddling when b=2^32-1 and cmwc rather than mwc.)
    129 
    130 
    131 To generate 64-bit x's, it is difficult to form
    132 t=a*x+c in 128 bits then get the new c and new x
    133 from the the top and bottom halves.
    134 But if 'a' has a special form, for example,
    135 a=2^62+2^47+2 and b=2^64-1, then the new c and
    136 the new x can be formed with shifts, tests and +/-'s,
    137 again with a little fiddling because b=2^64-1 rather
    138 than 2^64.   (The latter is not an optimal choice because,
    139 being a square, it cannot be a primitive root of the
    140 prime a*b^k+1, where 'k' is the 'lag':
    141         x(n)=a*x(n-k)+carry mod b.)
    142 But the multiplier a=2^62+2^47+2 makes a*b^4+1 a prime for
    143 which b=2^64-1 is a primitive root, and getting  the new x and
    144 new c  can be done with arithmetic on integers the size of x.
    145 */
    146 
    147 struct RndCtx
    148 {
    149     uint64_t x;
    150     uint64_t y;
    151     uint64_t z;
    152     uint64_t w;
    153     uint64_t c;
    154     uint32_t u32x;
    155     uint32_t u32y;
    156 };
    157 typedef struct RndCtx RNDCTX;
    158 typedef RNDCTX *PRNDCTX;
    159 
    160 /**
    161  * Initialize seeds.
    162  *
    163  * @remarks You should choose ANY 4 random 64-bit
    164  * seeds x,y,z,w < 2^64-1 and a random seed c in
    165  * 0<= c < a = 2^62+2^47+2.
    166  * There are P=(2^62+2^46+2)*(2^64-1)^4 > 2^318 possible choices
    167  * for seeds, the period of the RNG.
    168  */
    169 RTDECL(int) RTPRandInit(PRNDCTX pCtx, uint32_t u32Seed)
    170 {
    171     if (u32Seed == 0)
    172         u32Seed = (uint32_t)(ASMReadTSC() >> 8);
    173     /* Zero is not a good seed. */
    174     if (u32Seed == 0)
    175         u32Seed = 362436069;
    176     pCtx->x = u32Seed;
    177     pCtx->y = 17280675555674358941ULL;
    178     pCtx->z = 6376492577913983186ULL;
    179     pCtx->w = 9064188857900113776ULL;
    180     pCtx->c = 123456789;
    181     pCtx->u32x = 2282008;
    182     pCtx->u32y = u32Seed;
    183     return VINF_SUCCESS;
    184 }
    185 
    186 RTDECL(uint32_t) RTPRandGetSeedInfo(PRNDCTX pCtx)
    187 {
    188     return pCtx->u32y;
    189 }
    190 
    191 /**
    192  * Generate a 64-bit unsigned random number.
    193  *
    194  * @returns The pseudo random number.
    195  */
    196 RTDECL(uint64_t) RTPRandU64(PRNDCTX pCtx)
    197 {
    198     uint64_t t;
    199     t = (pCtx->x<<47) + (pCtx->x<<62) + (pCtx->x<<1);
    200     t += pCtx->c; t+= (t < pCtx->c);
    201     pCtx->c = (t<pCtx->c) + (pCtx->x>>17) + (pCtx->x>>2) + (pCtx->x>>63);
    202     pCtx->x = pCtx->y;  pCtx->y = pCtx->z ; pCtx->z = pCtx->w;
    203     return (pCtx->w = ~(t + pCtx->c)-1);
    204 }
    205 
    206 /**
    207  * Generate a 64-bit unsigned pseudo random number in the set
    208  * [u64First..u64Last].
    209  *
    210  * @returns The pseudo random number.
    211  * @param   u64First    First number in the set.
    212  * @param   u64Last     Last number in the set.
    213  */
    214 RTDECL(uint64_t) RTPRandU64Ex(PRNDCTX pCtx, uint64_t u64First, uint64_t u64Last)
    215 {
    216     if (u64First == 0 && u64Last == UINT64_MAX)
    217         return RTPRandU64(pCtx);
    218 
    219     uint64_t u64Tmp;
    220     uint64_t u64Range = u64Last - u64First + 1;
    221     uint64_t u64Scale = UINT64_MAX / u64Range;
    222 
    223     do
     58    for (unsigned i=0; i < cEntries; i++)
    22459    {
    225         u64Tmp = RTPRandU64(pCtx) / u64Scale;
    226     } while (u64Tmp >= u64Range);
    227     return u64First + u64Tmp;
    228 }
    229 
    230 /**
    231  * Generate a 32-bit unsigned random number.
    232  *
    233  * @returns The pseudo random number.
    234  */
    235 RTDECL(uint32_t) RTPRandU32(PRNDCTX pCtx)
    236 {
    237     return ( pCtx->u32x = 69069 * pCtx->u32x + 123,
    238              pCtx->u32y ^= pCtx->u32y<<13,
    239              pCtx->u32y ^= pCtx->u32y>>17,
    240              pCtx->u32y ^= pCtx->u32y<<5,
    241              pCtx->u32x + pCtx->u32y );
    242 }
    243 
    244 /**
    245  * Generate a 32-bit unsigned pseudo random number in the set
    246  * [u32First..u32Last].
    247  *
    248  * @returns The pseudo random number.
    249  * @param   u32First    First number in the set.
    250  * @param   u32Last     Last number in the set.
    251  */
    252 RTDECL(uint32_t) RTPRandU32Ex(PRNDCTX pCtx, uint32_t u32First, uint32_t u32Last)
    253 {
    254     if (u32First == 0 && u32Last == UINT32_MAX)
    255         return RTPRandU32(pCtx);
    256 
    257     uint32_t u32Tmp;
    258     uint32_t u32Range = u32Last - u32First + 1;
    259     uint32_t u32Scale = UINT32_MAX / u32Range;
    260 
    261     do
    262     {
    263         u32Tmp = RTPRandU32(pCtx) / u32Scale;
    264     } while (u32Tmp >= u32Range);
    265     return u32First + u32Tmp;
    266 }
    267 
    268 /* End of IPRT code */
    269 
    270 struct Segment
    271 {
    272     uint64_t u64Offset;
    273     uint32_t u32Length;
    274     uint32_t u8Value;
    275 };
    276 typedef struct Segment *PSEGMENT;
    277 
    278 static void initializeRandomGenerator(PRNDCTX pCtx, uint32_t u32Seed)
    279 {
    280     int rc = RTPRandInit(pCtx, u32Seed);
    281     if (VBOX_FAILURE(rc))
    282         RTPrintf("ERROR: Failed to initialize random generator. RC=%Vrc\n", rc);
    283     else
    284     {
    285         RTPrintf("INFO: Random generator seed used: %x\n", RTPRandGetSeedInfo(pCtx));
    286         RTLogPrintf("INFO: Random generator seed used: %x\n", RTPRandGetSeedInfo(pCtx));
    287     }
    288 }
    289 
    290 static int compareSegments(const void *left, const void *right)
    291 {
    292     /* Note that no duplicates are allowed in the array being sorted. */
    293     return ((PSEGMENT)left)->u64Offset < ((PSEGMENT)right)->u64Offset ? -1 : 1;
    294 }
    295 
    296 static void generateRandomSegments(PRNDCTX pCtx, PSEGMENT pSegment, uint32_t nSegments, uint32_t u32MaxSegmentSize, uint64_t u64DiskSize, uint32_t u32SectorSize, uint8_t u8ValueLow, uint8_t u8ValueHigh)
    297 {
    298     uint32_t i;
    299     /* Generate segment offsets. */
    300     for (i = 0; i < nSegments; i++)
    301     {
    302         bool fDuplicateFound;
    303         do
     60        RTPrintf("Backend %u: name=%s capabilities=%#06x extensions=",
     61                 i, aVDInfo[i].pszBackend, aVDInfo[i].uBackendCaps);
     62        if (aVDInfo[i].papszFileExtensions)
    30463        {
    305             pSegment[i].u64Offset = RTPRandU64Ex(pCtx, 0, u64DiskSize / u32SectorSize - 1) * u32SectorSize;
    306             fDuplicateFound = false;
    307             for (uint32_t j = 0; j < i; j++)
    308                 if (pSegment[i].u64Offset == pSegment[j].u64Offset)
    309                 {
    310                     fDuplicateFound = true;
    311                     break;
    312                 }
    313         } while (fDuplicateFound);
    314     }
    315     /* Sort in offset-ascending order. */
    316     qsort(pSegment, nSegments, sizeof(*pSegment), compareSegments);
    317     /* Put a sentinel at the end. */
    318     pSegment[nSegments].u64Offset = u64DiskSize;
    319     pSegment[nSegments].u32Length = 0;
    320     /* Generate segment lengths and values. */
    321     for (i = 0; i < nSegments; i++)
    322     {
    323         pSegment[i].u32Length = RTPRandU32Ex(pCtx, 1, RT_MIN(pSegment[i+1].u64Offset - pSegment[i].u64Offset,
    324                                                              u32MaxSegmentSize) / u32SectorSize) * u32SectorSize;
    325         Assert(pSegment[i].u32Length <= u32MaxSegmentSize);
    326         pSegment[i].u8Value  = RTPRandU32Ex(pCtx, (uint32_t)u8ValueLow, (uint32_t)u8ValueHigh);
    327     }
    328 }
    329 
    330 static void mergeSegments(PSEGMENT pBaseSegment, PSEGMENT pDiffSegment, PSEGMENT pMergeSegment, uint32_t u32MaxLength)
    331 {
    332     while (pBaseSegment->u32Length > 0 || pDiffSegment->u32Length > 0)
    333     {
    334         if (pBaseSegment->u64Offset < pDiffSegment->u64Offset)
    335         {
    336             *pMergeSegment = *pBaseSegment;
    337             if (pMergeSegment->u64Offset + pMergeSegment->u32Length <= pDiffSegment->u64Offset)
    338                 pBaseSegment++;
    339             else
     64            const char *const *papsz = aVDInfo[i].papszFileExtensions;
     65            while (*papsz != NULL)
    34066            {
    341                 pMergeSegment->u32Length = pDiffSegment->u64Offset - pMergeSegment->u64Offset;
    342                 Assert(pMergeSegment->u32Length <= u32MaxLength);
    343                 if (pBaseSegment->u64Offset + pBaseSegment->u32Length >
    344                     pDiffSegment->u64Offset + pDiffSegment->u32Length)
    345                 {
    346                     pBaseSegment->u32Length -= pDiffSegment->u64Offset + pDiffSegment->u32Length - pBaseSegment->u64Offset;
    347                     Assert(pBaseSegment->u32Length <= u32MaxLength);
    348                     pBaseSegment->u64Offset = pDiffSegment->u64Offset + pDiffSegment->u32Length;
    349                 }
    350                 else
    351                     pBaseSegment++;
     67                if (papsz != aVDInfo[i].papszFileExtensions)
     68                    RTPrintf(",");
     69                RTPrintf("%s", *papsz);
     70                papsz++;
    35271            }
    353             pMergeSegment++;
     72            if (papsz == aVDInfo[i].papszFileExtensions)
     73                RTPrintf("<EMPTY>");
     74            RTPrintf("\n");
    35475        }
    35576        else
    356         {
    357             *pMergeSegment = *pDiffSegment;
    358             if (pMergeSegment->u64Offset + pMergeSegment->u32Length <= pBaseSegment->u64Offset)
    359             {
    360                 pDiffSegment++;
    361                 pMergeSegment++;
    362             }
    363             else
    364             {
    365                 if (pBaseSegment->u64Offset + pBaseSegment->u32Length > pDiffSegment->u64Offset + pDiffSegment->u32Length)
    366                 {
    367                     pBaseSegment->u32Length -= pDiffSegment->u64Offset + pDiffSegment->u32Length - pBaseSegment->u64Offset;
    368                     Assert(pBaseSegment->u32Length <= u32MaxLength);
    369                     pBaseSegment->u64Offset = pDiffSegment->u64Offset + pDiffSegment->u32Length;
    370                     pDiffSegment++;
    371                     pMergeSegment++;
    372                 }
    373                 else
    374                     pBaseSegment++;
    375             }
    376         }
    377     }
    378 }
    379 
    380 static void writeSegmentsToDisk(PVBOXHDD pVD, void *pvBuf, PSEGMENT pSegment)
    381 {
    382     while (pSegment->u32Length)
    383     {
    384         //memset((uint8_t*)pvBuf + pSegment->u64Offset, pSegment->u8Value, pSegment->u32Length);
    385         memset(pvBuf, pSegment->u8Value, pSegment->u32Length);
    386         VDWrite(pVD, pSegment->u64Offset, pvBuf, pSegment->u32Length);
    387         pSegment++;
    388     }
    389 }
    390 
    391 static int readAndCompareSegments(PVBOXHDD pVD, void *pvBuf, PSEGMENT pSegment)
    392 {
    393     while (pSegment->u32Length)
    394     {
    395         int rc = VDRead(pVD, pSegment->u64Offset, pvBuf, pSegment->u32Length);
    396         if (VBOX_FAILURE(rc))
    397         {
    398             RTPrintf("ERROR: Failed to read from virtual disk\n");
    399             return rc;
    400         }
    401         else
    402         {
    403             for (unsigned i = 0; i < pSegment->u32Length; i++)
    404                 if (((uint8_t*)pvBuf)[i] != pSegment->u8Value)
    405                 {
    406                     RTPrintf("ERROR: Segment at %Lx of %x bytes is corrupt at offset %x (found %x instead of %x)\n",
    407                              pSegment->u64Offset, pSegment->u32Length, i, ((uint8_t*)pvBuf)[i],
    408                              pSegment->u8Value);
    409                     RTLogPrintf("ERROR: Segment at %Lx of %x bytes is corrupt at offset %x (found %x instead of %x)\n",
    410                              pSegment->u64Offset, pSegment->u32Length, i, ((uint8_t*)pvBuf)[i],
    411                              pSegment->u8Value);
    412                     return VERR_INTERNAL_ERROR;
    413                 }
    414         }
    415         pSegment++;
     77            RTPrintf("<NONE>\n");
    41678    }
    41779
    418     return VINF_SUCCESS;
    419 }
    420 
    421 static int tstVDOpenCreateWriteMerge(const char *pszBackend,
    422                                      const char *pszBaseFilename,
    423                                      const char *pszDiffFilename,
    424                                      uint32_t u32Seed)
    425 {
    426     int rc;
    427     PVBOXHDD pVD = NULL;
    428     char *pszFormat;
    429     PDMMEDIAGEOMETRY PCHS = { 0, 0, 0 };
    430     PDMMEDIAGEOMETRY LCHS = { 0, 0, 0 };
    431     uint64_t u64DiskSize  = 1000 * _1M;
    432     uint32_t u32SectorSize = 512;
    433     VDINTERFACE      VDIError;
    434     VDINTERFACEERROR VDIErrorCallbacks;
    435 
    436 #define CHECK(str) \
    437     do \
    438     { \
    439         RTPrintf("%s rc=%Vrc\n", str, rc); \
    440         if (VBOX_FAILURE(rc)) \
    441         { \
    442             VDCloseAll(pVD); \
    443             return rc; \
    444         } \
    445     } while (0)
    446 
    447     /* Create error interface. */
    448     VDIErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
    449     VDIErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
    450     VDIErrorCallbacks.pfnError = tstVDError;
    451 
    452     rc = VDInterfaceCreate(&VDIError, "tstVD_Error", VDINTERFACETYPE_ERROR, &VDIErrorCallbacks,
    453                            NULL, NULL);
    454     AssertRC(rc);
    455 
    456 
    457     rc = VDCreate(&VDIError, &pVD);
    458     CHECK("VDCreate()");
    459 
    460     RTFILE File;
    461     rc = RTFileOpen(&File, pszBaseFilename, RTFILE_O_READ);
    462     if (VBOX_SUCCESS(rc))
    463     {
    464         RTFileClose(File);
    465         rc = VDGetFormat(pszBaseFilename, &pszFormat);
    466         RTPrintf("VDGetFormat() pszFormat=%s rc=%Vrc\n", pszFormat, rc);
    467         if (VBOX_SUCCESS(rc) && strcmp(pszFormat, pszBackend))
    468         {
    469             rc = VERR_GENERAL_FAILURE;
    470             RTPrintf("VDGetFormat() returned incorrect backend name\n");
    471         }
    472         RTStrFree(pszFormat);
    473         CHECK("VDGetFormat()");
    474 
    475         rc = VDOpen(pVD, pszBackend, pszBaseFilename, VD_OPEN_FLAGS_NORMAL);
    476         CHECK("VDOpen()");
    477     }
    478     else
    479     {
    480         rc = VDCreateBase(pVD, pszBackend, pszBaseFilename,
    481                           VD_IMAGE_TYPE_NORMAL, u64DiskSize,
    482                           VD_IMAGE_FLAGS_NONE, "Test image",
    483                           &PCHS, &LCHS, NULL, VD_OPEN_FLAGS_NORMAL,
    484                           NULL, NULL);
    485         CHECK("VDCreateBase()");
    486     }
    487 
    488     int nSegments = 100;
    489     /* Allocate one extra element for a sentinel. */
    490     PSEGMENT paBaseSegments  = (PSEGMENT)RTMemAllocZ(sizeof(struct Segment) * (nSegments + 1));
    491     PSEGMENT paDiffSegments  = (PSEGMENT)RTMemAllocZ(sizeof(struct Segment) * (nSegments + 1));
    492     PSEGMENT paMergeSegments = (PSEGMENT)RTMemAllocZ(sizeof(struct Segment) * (nSegments + 1) * 3);
    493 
    494     void *pvBuf = RTMemAlloc(_1M);
    495 
    496     RNDCTX ctx;
    497     initializeRandomGenerator(&ctx, u32Seed);
    498     generateRandomSegments(&ctx, paBaseSegments, nSegments, _1M, u64DiskSize, u32SectorSize, 0u, 127u);
    499     generateRandomSegments(&ctx, paDiffSegments, nSegments, _1M, u64DiskSize, u32SectorSize, 128u, 255u);
    500 
    501     /*PSEGMENT pSegment;
    502     RTPrintf("Base segments:\n");
    503     for (pSegment = paBaseSegments; pSegment->u32Length; pSegment++)
    504         RTPrintf("off: %08Lx len: %05x val: %02x\n", pSegment->u64Offset, pSegment->u32Length, pSegment->u8Value);*/
    505     writeSegmentsToDisk(pVD, pvBuf, paBaseSegments);
    506 
    507     rc = VDCreateDiff(pVD, pszBackend, pszDiffFilename,
    508                       VD_IMAGE_FLAGS_NONE, "Test diff image", NULL,
    509                       VD_OPEN_FLAGS_NORMAL, NULL, NULL);
    510     CHECK("VDCreateDiff()");
    511 
    512     /*RTPrintf("\nDiff segments:\n");
    513     for (pSegment = paDiffSegments; pSegment->u32Length; pSegment++)
    514         RTPrintf("off: %08Lx len: %05x val: %02x\n", pSegment->u64Offset, pSegment->u32Length, pSegment->u8Value);*/
    515     writeSegmentsToDisk(pVD, pvBuf, paDiffSegments);
    516 
    517     VDDumpImages(pVD);
    518 
    519     RTPrintf("Merging diff into base..\n");
    520     rc = VDMerge(pVD, (unsigned)-1, 0, NULL, NULL);
    521     CHECK("VDMerge()");
    522 
    523     mergeSegments(paBaseSegments, paDiffSegments, paMergeSegments, _1M);
    524     /*RTPrintf("\nMerged segments:\n");
    525     for (pSegment = paMergeSegments; pSegment->u32Length; pSegment++)
    526         RTPrintf("off: %08Lx len: %05x val: %02x\n", pSegment->u64Offset, pSegment->u32Length, pSegment->u8Value);*/
    527     rc = readAndCompareSegments(pVD, pvBuf, paMergeSegments);
    528     CHECK("readAndCompareSegments()");
    529 
    530     RTMemFree(paMergeSegments);
    531     RTMemFree(paDiffSegments);
    532     RTMemFree(paBaseSegments);
    533 
    534     VDDumpImages(pVD);
    535 
    536     VDCloseAll(pVD);
    537 #undef CHECK
    538     return 0;
    539 }
    540 
    541 static int tstVDCreateWriteOpenRead(const char *pszBackend,
    542                                     const char *pszFilename,
    543                                     uint32_t u32Seed)
    544 {
    545     int rc;
    546     PVBOXHDD pVD = NULL;
    547     PDMMEDIAGEOMETRY PCHS = { 0, 0, 0 };
    548     PDMMEDIAGEOMETRY LCHS = { 0, 0, 0 };
    549     uint64_t u64DiskSize  = 1000 * _1M;
    550     uint32_t u32SectorSize = 512;
    551     VDINTERFACE      VDIError;
    552     VDINTERFACEERROR VDIErrorCallbacks;
    553 
    554 #define CHECK(str) \
    555     do \
    556     { \
    557         RTPrintf("%s rc=%Vrc\n", str, rc); \
    558         if (VBOX_FAILURE(rc)) \
    559         { \
    560             VDCloseAll(pVD); \
    561             return rc; \
    562         } \
    563     } while (0)
    564 
    565     /* Create error interface. */
    566     VDIErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
    567     VDIErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
    568     VDIErrorCallbacks.pfnError = tstVDError;
    569 
    570     rc = VDInterfaceCreate(&VDIError, "tstVD_Error", VDINTERFACETYPE_ERROR, &VDIErrorCallbacks,
    571                            NULL, NULL);
    572     AssertRC(rc);
    573 
    574 
    575     rc = VDCreate(&VDIError, &pVD);
    576     CHECK("VDCreate()");
    577 
    578     RTFILE File;
    579     rc = RTFileOpen(&File, pszFilename, RTFILE_O_READ);
    580     if (VBOX_SUCCESS(rc))
    581     {
    582         RTFileClose(File);
    583         RTFileDelete(pszFilename);
    584     }
    585 
    586     rc = VDCreateBase(pVD, pszBackend, pszFilename,
    587                       VD_IMAGE_TYPE_NORMAL, u64DiskSize,
    588                       VD_IMAGE_FLAGS_NONE, "Test image",
    589                       &PCHS, &LCHS, NULL, VD_OPEN_FLAGS_NORMAL,
    590                       NULL, NULL);
    591     CHECK("VDCreateBase()");
    592 
    593     int nSegments = 100;
    594     /* Allocate one extra element for a sentinel. */
    595     PSEGMENT paSegments  = (PSEGMENT)RTMemAllocZ(sizeof(struct Segment) * (nSegments + 1));
    596 
    597     void *pvBuf = RTMemAlloc(_1M);
    598 
    599     RNDCTX ctx;
    600     initializeRandomGenerator(&ctx, u32Seed);
    601     generateRandomSegments(&ctx, paSegments, nSegments, _1M, u64DiskSize, u32SectorSize, 0u, 127u);
    602     /*for (PSEGMENT pSegment = paSegments; pSegment->u32Length; pSegment++)
    603         RTPrintf("off: %08Lx len: %05x val: %02x\n", pSegment->u64Offset, pSegment->u32Length, pSegment->u8Value);*/
    604 
    605     writeSegmentsToDisk(pVD, pvBuf, paSegments);
    606 
    607     VDCloseAll(pVD);
    608 
    609     rc = VDOpen(pVD, pszBackend, pszFilename, VD_OPEN_FLAGS_NORMAL);
    610     CHECK("VDOpen()");
    611     rc = readAndCompareSegments(pVD, pvBuf, paSegments);
    612     CHECK("readAndCompareSegments()");
    613 
    614     RTMemFree(paSegments);
    615 
    616     VDCloseAll(pVD);
    61780#undef CHECK
    61881    return 0;
     
    62487    int rc;
    62588
    626     uint32_t u32Seed = 0; // Means choose random
     89    RTR3Init();
     90    RTPrintf("tstVD-2: TESTING...\n");
    62791
    628     if (argc > 1)
    629         if (sscanf(argv[1], "%x", &u32Seed) != 1)
    630         {
    631             RTPrintf("ERROR: Invalid parameter %s. Valid usage is %s <32-bit seed>.\n",
    632                      argv[1], argv[0]);
    633             return 1;
    634         }
    635 
    636     RTR3Init();
    637     RTPrintf("tstVD: TESTING...\n");
    638 
    639     /*
    640      * Clean up potential leftovers from previous unsuccessful runs.
    641      */
    642     RTFileDelete("tmpVDCreate.vdi");
    643     RTFileDelete("tmpVDCreate.vmdk");
    644     RTFileDelete("tmpVDCreate.vhd");
    645     RTFileDelete("tmpVDBase.vdi");
    646     RTFileDelete("tmpVDDiff.vdi");
    647     RTFileDelete("tmpVDBase.vmdk");
    648     RTFileDelete("tmpVDDiff.vmdk");
    649     RTFileDelete("tmpVDBase.vhd");
    650     RTFileDelete("tmpVDDiff.vhd");
    651 #if 1
    652     rc = tstVDCreateDelete("VDI", "tmpVDCreate.vdi", 2 * _4G,
    653                            VD_IMAGE_TYPE_NORMAL, VD_IMAGE_FLAGS_NONE,
    654                            true);
     92    rc = tstVDBackendInfo();
    65593    if (VBOX_FAILURE(rc))
    65694    {
    657         RTPrintf("tstVD: dynamic VDI create test failed! rc=%Vrc\n", rc);
     95        RTPrintf("tstVD-2: getting backend info test failed! rc=%Vrc\n", rc);
    65896        g_cErrors++;
    65997    }
    660     rc = tstVDCreateDelete("VDI", "tmpVDCreate.vdi", 2 * _4G,
    661                            VD_IMAGE_TYPE_FIXED, VD_IMAGE_FLAGS_NONE,
    662                            true);
    663     if (VBOX_FAILURE(rc))
    664     {
    665         RTPrintf("tstVD: fixed VDI create test failed! rc=%Vrc\n", rc);
    666         g_cErrors++;
    667     }
    668     rc = tstVDCreateDelete("VMDK", "tmpVDCreate.vmdk", 2 * _4G,
    669                            VD_IMAGE_TYPE_NORMAL, VD_IMAGE_FLAGS_NONE,
    670                            true);
    671     if (VBOX_FAILURE(rc))
    672     {
    673         RTPrintf("tstVD: dynamic VMDK create test failed! rc=%Vrc\n", rc);
    674         g_cErrors++;
    675     }
    676     rc = tstVDCreateDelete("VMDK", "tmpVDCreate.vmdk", 2 * _4G,
    677                            VD_IMAGE_TYPE_NORMAL, VD_VMDK_IMAGE_FLAGS_SPLIT_2G,
    678                            true);
    679     if (VBOX_FAILURE(rc))
    680     {
    681         RTPrintf("tstVD: dynamic split VMDK create test failed! rc=%Vrc\n", rc);
    682         g_cErrors++;
    683     }
    684     rc = tstVDCreateDelete("VMDK", "tmpVDCreate.vmdk", 2 * _4G,
    685                            VD_IMAGE_TYPE_FIXED, VD_IMAGE_FLAGS_NONE,
    686                            true);
    687     if (VBOX_FAILURE(rc))
    688     {
    689         RTPrintf("tstVD: fixed VMDK create test failed! rc=%Vrc\n", rc);
    690         g_cErrors++;
    691     }
    692     rc = tstVDCreateDelete("VMDK", "tmpVDCreate.vmdk", 2 * _4G,
    693                            VD_IMAGE_TYPE_FIXED, VD_VMDK_IMAGE_FLAGS_SPLIT_2G,
    694                            true);
    695     if (VBOX_FAILURE(rc))
    696     {
    697         RTPrintf("tstVD: fixed split VMDK create test failed! rc=%Vrc\n", rc);
    698         g_cErrors++;
    699     }
    700     rc = tstVDCreateDelete("VHD", "tmpVDCreate.vhd", 2 * _4G,
    701                            VD_IMAGE_TYPE_NORMAL, VD_IMAGE_FLAGS_NONE,
    702                            true);
    703     if (VBOX_FAILURE(rc))
    704     {
    705         RTPrintf("tstVD: dynamic VHD create test failed! rc=%Vrc\n", rc);
    706         g_cErrors++;
    707     }
    708     rc = tstVDCreateDelete("VHD", "tmpVDCreate.vhd", 2 * _4G,
    709                            VD_IMAGE_TYPE_FIXED, VD_IMAGE_FLAGS_NONE,
    710                            true);
    711     if (VBOX_FAILURE(rc))
    712     {
    713         RTPrintf("tstVD: fixed VHD create test failed! rc=%Vrc\n", rc);
    714         g_cErrors++;
    715     }
    716 
    717     rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", u32Seed);
    718     if (VBOX_FAILURE(rc))
    719     {
    720         RTPrintf("tstVD: VDI test failed (new image)! rc=%Vrc\n", rc);
    721         g_cErrors++;
    722     }
    723     rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", u32Seed);
    724     if (VBOX_FAILURE(rc))
    725     {
    726         RTPrintf("tstVD: VDI test failed (existing image)! rc=%Vrc\n", rc);
    727         g_cErrors++;
    728     }
    729     rc = tstVDOpenCreateWriteMerge("VMDK", "tmpVDBase.vmdk", "tmpVDDiff.vmdk", u32Seed);
    730     if (VBOX_FAILURE(rc))
    731     {
    732         RTPrintf("tstVD: VMDK test failed (new image)! rc=%Vrc\n", rc);
    733         g_cErrors++;
    734     }
    735     rc = tstVDOpenCreateWriteMerge("VMDK", "tmpVDBase.vmdk", "tmpVDDiff.vmdk", u32Seed);
    736     if (VBOX_FAILURE(rc))
    737     {
    738         RTPrintf("tstVD: VMDK test failed (existing image)! rc=%Vrc\n", rc);
    739         g_cErrors++;
    740     }
    741 #endif
    742 
    743     rc = tstVDCreateWriteOpenRead("VHD", "tmpVDCreate.vhd", u32Seed);
    744     if (VBOX_FAILURE(rc))
    745     {
    746         RTPrintf("tstVD: VHD test failed (creating image)! rc=%Vrc\n", rc);
    747         g_cErrors++;
    748     }
    749 
    750     rc = tstVDOpenCreateWriteMerge("VHD", "tmpVDBase.vhd", "tmpVDDiff.vhd", u32Seed);
    751     if (VBOX_FAILURE(rc))
    752     {
    753         RTPrintf("tstVD: VHD test failed (existing image)! rc=%Vrc\n", rc);
    754         g_cErrors++;
    755     }
    756 
    757     /*
    758      * Clean up any leftovers.
    759      */
    760     RTFileDelete("tmpVDCreate.vdi");
    761     RTFileDelete("tmpVDCreate.vmdk");
    762     RTFileDelete("tmpVDCreate.vhd");
    763     RTFileDelete("tmpVDBase.vdi");
    764     RTFileDelete("tmpVDDiff.vdi");
    765     RTFileDelete("tmpVDBase.vmdk");
    766     RTFileDelete("tmpVDDiff.vmdk");
    767     RTFileDelete("tmpVDBase.vhd");
    768     RTFileDelete("tmpVDDiff.vhd");
    76998
    77099    /*
     
    772101     */
    773102    if (!g_cErrors)
    774         RTPrintf("tstVD: SUCCESS\n");
     103        RTPrintf("tstVD-2: SUCCESS\n");
    775104    else
    776         RTPrintf("tstVD: FAILURE - %d errors\n", g_cErrors);
     105        RTPrintf("tstVD-2: FAILURE - %d errors\n", g_cErrors);
    777106
    778107    return !!g_cErrors;
  • trunk/src/testcase/tstRunTestcases.cpp

    • Property svn:eol-style set to native
    r10915 r11421  
    5353    "testcase/tstVD",
    5454#endif
     55    "testcase/tstVD-2",
    5556    "testcase/tstFileLock",
    5657    "testcase/tstCritSect",
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