VirtualBox

Changeset 11421

Show
Ignore:
Timestamp:
08/14/08 14:06:14 (3 months 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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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

    • Property svn:mergeinfo set
    r11353 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", 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy