- Timestamp:
- Aug 14, 2008 12:06:14 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxHDD-new.h
r11353 r11421 224 224 /** Capabilities of the backend (a combination of the VD_CAP_* flags). */ 225 225 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; 226 230 } VDBACKENDINFO, *PVDBACKENDINFO; 227 231 -
trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
r11353 r11421 67 67 } RAWIMAGE, *PRAWIMAGE; 68 68 69 /******************************************************************************* 70 * Static Variables * 71 *******************************************************************************/ 72 73 /** NULL-terminated array of supported file extensions. */ 74 static 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 }; 69 81 70 82 /******************************************************************************* … … 1058 1070 /* uBackendCaps */ 1059 1071 VD_CAP_CREATE_FIXED | VD_CAP_FILE, 1072 /* papszFileExtensions */ 1073 s_apszRawFileExtensions, 1060 1074 /* pfnCheckIfValid */ 1061 1075 rawCheckIfValid, -
trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp
r11353 r11421 649 649 pEntries[cEntries].pszBackend = pszName; 650 650 pEntries[cEntries].uBackendCaps = aBackends[i]->uBackendCaps; 651 pEntries[cEntries].papszFileExtensions = aBackends[i]->papszFileExtensions; 651 652 cEntries++; 652 653 if (cEntries >= cEntriesAlloc) … … 737 738 pEntries[cEntries].pszBackend = pszName; 738 739 pEntries[cEntries].uBackendCaps = pBackend->uBackendCaps; 740 pEntries[cEntries].papszFileExtensions = pBackend->papszFileExtensions; 739 741 cEntries++; 740 742 if (cEntries >= cEntriesAlloc) … … 751 753 } 752 754 } 755 if (rc == VERR_NO_MORE_FILES) 756 rc = VINF_SUCCESS; 753 757 RTStrFree(pszPluginFilter); 754 758 if (pPluginDirEntry) … … 2891 2895 pBackendInfo->pszBackend = RTStrDup(pImage->Backend->pszBackendName); 2892 2896 pBackendInfo->uBackendCaps = pImage->Backend->uBackendCaps; 2897 pBackendInfo->papszFileExtensions = pImage->Backend->papszFileExtensions; 2893 2898 rc = VINF_SUCCESS; 2894 2899 } -
trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h
r11353 r11421 55 55 */ 56 56 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; 57 64 58 65 /** -
trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
r11353 r11421 37 37 38 38 #define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M 39 40 /******************************************************************************* 41 * Static Variables * 42 *******************************************************************************/ 43 44 /** NULL-terminated array of supported file extensions. */ 45 static const char *const s_apszVdiFileExtensions[] = 46 { 47 "vdi", 48 NULL 49 }; 39 50 40 51 /******************************************************************************* … … 1796 1807 VD_CAP_UUID | VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC 1797 1808 | VD_CAP_CREATE_SPLIT_2G | VD_CAP_DIFF | VD_CAP_FILE, 1809 /* papszFileExtensions */ 1810 s_apszVdiFileExtensions, 1798 1811 /* pfnCheckIfValid */ 1799 1812 vdiCheckIfValid, -
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r11353 r11421 409 409 } VMDKIMAGE; 410 410 411 411 /******************************************************************************* 412 * Static Variables * 413 *******************************************************************************/ 414 415 /** NULL-terminated array of supported file extensions. */ 416 static const char *const s_apszVmdkFileExtensions[] = 417 { 418 "vmdk", 419 NULL 420 }; 421 412 422 /******************************************************************************* 413 423 * Internal Functions * … … 5153 5163 VD_CAP_UUID | VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC 5154 5164 | VD_CAP_CREATE_SPLIT_2G | VD_CAP_DIFF | VD_CAP_FILE |VD_CAP_ASYNC, 5165 /* papszFileExtensions */ 5166 s_apszVmdkFileExtensions, 5155 5167 /* pfnCheckIfValid */ 5156 5168 vmdkCheckIfValid, -
trunk/src/VBox/Devices/Storage/testcase/Makefile.kmk
r10041 r11421 59 59 60 60 # 61 # Basic testcase for the VD code.61 # Basic testcases for the VD code. 62 62 # 63 63 ifdef VBOX_WITH_TESTCASES 64 PROGRAMS += tstVD 64 PROGRAMS += tstVD tstVD-2 65 65 ifeq ($(KBUILD_TARGET),l4) 66 66 tstVD_TEMPLATE = VBOXLNXHOSTR3EXE 67 tstVD-2_TEMPLATE = VBOXLNXHOSTR3EXE 67 68 else 68 69 tstVD_TEMPLATE = VBOXR3TSTEXE 70 tstVD-2_TEMPLATE = VBOXR3TSTEXE 69 71 endif 70 72 tstVD_LIBS = $(vditool_LIBS) 73 tstVD-2_LIBS = $(vditool_LIBS) 71 74 tstVD_SOURCES = tstVD.cpp 75 tstVD-2_SOURCES = tstVD-2.cpp 72 76 endif 73 77 -
trunk/src/VBox/Devices/Storage/testcase/tstVD-2.cpp
r11406 r11421 1 1 /** @file 2 2 * 3 * Simple VBox HDD container test utility. 3 * Simple VBox HDD container test utility. Only fast tests. 4 4 */ 5 5 … … 38 38 39 39 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) 40 static int tstVDBackendInfo(void) 53 41 { 54 42 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; 60 46 61 47 #define CHECK(str) \ … … 64 50 RTPrintf("%s rc=%Vrc\n", str, rc); \ 65 51 if (VBOX_FAILURE(rc)) \ 66 { \67 VDCloseAll(pVD); \68 52 return rc; \ 69 } \70 53 } while (0) 71 54 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()"); 76 57 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++) 224 59 { 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) 304 63 { 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) 340 66 { 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++; 352 71 } 353 pMergeSegment++; 72 if (papsz == aVDInfo[i].papszFileExtensions) 73 RTPrintf("<EMPTY>"); 74 RTPrintf("\n"); 354 75 } 355 76 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"); 416 78 } 417 79 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 else479 {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 CHECK538 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);617 80 #undef CHECK 618 81 return 0; … … 624 87 int rc; 625 88 626 uint32_t u32Seed = 0; // Means choose random 89 RTR3Init(); 90 RTPrintf("tstVD-2: TESTING...\n"); 627 91 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(); 655 93 if (VBOX_FAILURE(rc)) 656 94 { 657 RTPrintf("tstVD : dynamic VDI createtest failed! rc=%Vrc\n", rc);95 RTPrintf("tstVD-2: getting backend info test failed! rc=%Vrc\n", rc); 658 96 g_cErrors++; 659 97 } 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 #endif742 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");769 98 770 99 /* … … 772 101 */ 773 102 if (!g_cErrors) 774 RTPrintf("tstVD : SUCCESS\n");103 RTPrintf("tstVD-2: SUCCESS\n"); 775 104 else 776 RTPrintf("tstVD : FAILURE - %d errors\n", g_cErrors);105 RTPrintf("tstVD-2: FAILURE - %d errors\n", g_cErrors); 777 106 778 107 return !!g_cErrors; -
trunk/src/testcase/tstRunTestcases.cpp
-
Property svn:eol-style
set to
native
r10915 r11421 53 53 "testcase/tstVD", 54 54 #endif 55 "testcase/tstVD-2", 55 56 "testcase/tstFileLock", 56 57 "testcase/tstCritSect", -
Property svn:eol-style
set to
Note:
See TracChangeset
for help on using the changeset viewer.