- Timestamp:
- Jan 31, 2011 3:25:22 PM (14 years ago)
- Location:
- trunk/src/VBox/Storage/testcase
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/testcase/tstVDIo.cpp
r35671 r35789 17 17 */ 18 18 #define LOGGROUP LOGGROUP_DEFAULT 19 #define RTMEM_WRAP_TO_EF_APIS 19 20 #include <VBox/vd.h> 20 21 #include <VBox/err.h> … … 46 47 /** Memory file baking the file. */ 47 48 PVDMEMDISK pMemDisk; 49 /** Flag whether the file is read locked. */ 50 bool fReadLock; 51 /** Flag whether the file is write locked. */ 52 bool fWriteLock; 53 } VDFILE, *PVDFILE; 54 55 /** 56 * VD storage object. 57 */ 58 typedef struct VDSTORAGE 59 { 60 /** Pointer to the file. */ 61 PVDFILE pFile; 48 62 /** Completion callback of the VD layer. */ 49 63 PFNVDCOMPLETED pfnComplete; 50 } VDFILE, *PVDFILE; 64 } VDSTORAGE, *PVDSTORAGE; 65 66 /** 67 * A virtual disk. 68 */ 69 typedef struct VDDISK 70 { 71 /** List node. */ 72 RTLISTNODE ListNode; 73 /** Name of the disk handle for identification. */ 74 char *pszName; 75 /** HDD handle to operate on. */ 76 PVBOXHDD pVD; 77 /** Physical CHS Geometry. */ 78 VDGEOMETRY PhysGeom; 79 /** Logical CHS geometry. */ 80 VDGEOMETRY LogicalGeom; 81 } VDDISK, *PVDDISK; 51 82 52 83 /** … … 55 86 typedef struct VDTESTGLOB 56 87 { 57 /** HDD handle to operate on. */58 PVBOXHDD pVD;88 /** List of active virtual disks. */ 89 RTLISTNODE ListDisks; 59 90 /** Head of the active file list. */ 60 91 RTLISTNODE ListFiles; … … 73 104 /** Pointer to the per image interface list. */ 74 105 PVDINTERFACE pInterfacesImages; 75 /** Physical CHS Geometry. */76 VDGEOMETRY PhysGeom;77 /** Logical CHS geometry. */78 VDGEOMETRY LogicalGeom;79 106 /** I/O RNG handle. */ 80 107 PVDIORND pIoRnd; … … 136 163 union 137 164 { 138 /** Next offset for se uential access. */165 /** Next offset for sequential access. */ 139 166 uint64_t offNext; 140 167 /** Data for random acess. */ … … 251 278 static DECLCALLBACK(int) vdScriptHandlerSleep(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs); 252 279 static DECLCALLBACK(int) vdScriptHandlerDumpFile(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs); 280 static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs); 281 static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs); 282 static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs); 253 283 254 284 /* create action */ 255 285 const VDSCRIPTARGDESC g_aArgCreate[] = 256 286 { 257 /* pcszName chId enmType fFlags */ 258 {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 259 {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 260 {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 261 {"size", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}, 287 /* pcszName chId enmType fFlags */ 288 {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 289 {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 290 {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 291 {"type", 't', VDSCRIPTARGTYPE_STRING, 0}, 292 {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 293 {"size", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX} 262 294 }; 263 295 … … 265 297 const VDSCRIPTARGDESC g_aArgOpen[] = 266 298 { 267 /* pcszName chId enmType fFlags */ 268 {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 269 {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY} 299 /* pcszName chId enmType fFlags */ 300 {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 301 {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 302 {"backend", 'b', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 303 {"shareable", 's', VDSCRIPTARGTYPE_BOOL, 0}, 304 {"readonly", 'r', VDSCRIPTARGTYPE_BOOL, 0} 270 305 }; 271 306 272 /* writeaction */307 /* I/O action */ 273 308 const VDSCRIPTARGDESC g_aArgIo[] = 274 309 { 275 310 /* pcszName chId enmType fFlags */ 311 {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 276 312 {"async", 'a', VDSCRIPTARGTYPE_BOOL, 0}, 277 313 {"max-reqs", 'l', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, 0}, … … 280 316 {"blocksize", 'b', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}, 281 317 {"off", 'o', VDSCRIPTARGTYPE_UNSIGNED_RANGE, VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}, 282 {"reads", 'r', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},283 318 {"writes", 'w', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY} 284 319 }; … … 287 322 const VDSCRIPTARGDESC g_aArgFlush[] = 288 323 { 289 /* pcszName chId enmType fFlags */ 290 {"async", 'a', VDSCRIPTARGTYPE_BOOL, 0} 324 /* pcszName chId enmType fFlags */ 325 {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 326 {"async", 'a', VDSCRIPTARGTYPE_BOOL, 0} 291 327 }; 292 328 … … 294 330 const VDSCRIPTARGDESC g_aArgMerge[] = 295 331 { 296 /* pcszName chId enmType fFlags */ 297 {"forward", 'f', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY} 332 /* pcszName chId enmType fFlags */ 333 {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 334 {"forward", 'f', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY} 298 335 }; 299 336 … … 301 338 const VDSCRIPTARGDESC g_aArgClose[] = 302 339 { 303 /* pcszName chId enmType fFlags */ 304 {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 305 {"delete", 'd', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY} 340 /* pcszName chId enmType fFlags */ 341 {"disk", 'd', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 342 {"mode", 'm', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 343 {"delete", 'r', VDSCRIPTARGTYPE_BOOL, VDSCRIPTARGDESC_FLAG_MANDATORY} 306 344 }; 307 345 … … 309 347 const VDSCRIPTARGDESC g_aArgIoRngCreate[] = 310 348 { 311 /* pcszName chId enmTypefFlags */312 {"size", 'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER,VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX},313 {"seed", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER,VDSCRIPTARGDESC_FLAG_MANDATORY}349 /* pcszName chId enmType fFlags */ 350 {"size", 'd', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY | VDSCRIPTARGDESC_FLAG_SIZE_SUFFIX}, 351 {"seed", 's', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY} 314 352 }; 315 353 … … 317 355 const VDSCRIPTARGDESC g_aArgSleep[] = 318 356 { 319 /* pcszName chId enmTypefFlags */320 {"time", 't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY},357 /* pcszName chId enmType fFlags */ 358 {"time", 't', VDSCRIPTARGTYPE_UNSIGNED_NUMBER, VDSCRIPTARGDESC_FLAG_MANDATORY} 321 359 }; 322 360 … … 324 362 const VDSCRIPTARGDESC g_aArgDumpFile[] = 325 363 { 326 /* pcszName chId enmType fFlags */ 327 {"file", 'f', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 328 {"path", 'p', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 364 /* pcszName chId enmType fFlags */ 365 {"file", 'f', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 366 {"path", 'p', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY} 367 }; 368 369 /* Create virtual disk handle */ 370 const VDSCRIPTARGDESC g_aArgCreateDisk[] = 371 { 372 /* pcszName chId enmType fFlags */ 373 {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY} 374 }; 375 376 /* Create virtual disk handle */ 377 const VDSCRIPTARGDESC g_aArgDestroyDisk[] = 378 { 379 /* pcszName chId enmType fFlags */ 380 {"name", 'n', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY} 381 }; 382 383 /* Compare virtual disks */ 384 const VDSCRIPTARGDESC g_aArgCompareDisks[] = 385 { 386 /* pcszName chId enmType fFlags */ 387 {"disk1", '1', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY}, 388 {"disk2", '2', VDSCRIPTARGTYPE_STRING, VDSCRIPTARGDESC_FLAG_MANDATORY} 329 389 }; 330 390 … … 341 401 {"iorngdestroy", NULL, 0, vdScriptHandlerIoRngDestroy}, 342 402 {"sleep", g_aArgSleep, RT_ELEMENTS(g_aArgSleep), vdScriptHandlerSleep}, 343 {"dumpfile", g_aArgDumpFile, RT_ELEMENTS(g_aArgDumpFile), vdScriptHandlerDumpFile} 403 {"dumpfile", g_aArgDumpFile, RT_ELEMENTS(g_aArgDumpFile), vdScriptHandlerDumpFile}, 404 {"createdisk", g_aArgCreateDisk, RT_ELEMENTS(g_aArgCreateDisk), vdScriptHandlerCreateDisk}, 405 {"destroydisk", g_aArgDestroyDisk, RT_ELEMENTS(g_aArgDestroyDisk), vdScriptHandlerDestroyDisk}, 406 {"comparedisks", g_aArgCompareDisks, RT_ELEMENTS(g_aArgCompareDisks), vdScriptHandlerCompareDisks} 344 407 }; 345 408 … … 363 426 static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, uint64_t cbIo, 364 427 size_t cbBlkSize, uint64_t offStart, uint64_t offEnd, 365 unsigned uWriteChance , unsigned uReadChance);428 unsigned uWriteChance); 366 429 static bool tstVDIoTestRunning(PVDIOTEST pIoTest); 367 430 static void tstVDIoTestDestroy(PVDIOTEST pIoTest); … … 370 433 static void tstVDIoTestReqComplete(void *pvUser1, void *pvUser2, int rcReq); 371 434 435 static PVDDISK tstVDIoGetDiskByName(PVDTESTGLOB pGlob, const char *pcszDisk); 436 372 437 static DECLCALLBACK(int) vdScriptHandlerCreate(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs) 373 438 { … … 376 441 const char *pcszBackend = NULL; 377 442 const char *pcszImage = NULL; 443 const char *pcszDisk = NULL; 444 PVDDISK pDisk = NULL; 378 445 bool fBase = false; 446 bool fDynamic = true; 379 447 380 448 for (unsigned i = 0; i < cScriptArgs; i++) … … 382 450 switch (paScriptArgs[i].chId) 383 451 { 452 case 'd': 453 { 454 pcszDisk = paScriptArgs[i].u.pcszString; 455 break; 456 } 384 457 case 'm': 385 458 { … … 410 483 break; 411 484 } 485 case 't': 486 { 487 if (!RTStrICmp(paScriptArgs[i].u.pcszString, "fixed")) 488 fDynamic = false; 489 else if (!RTStrICmp(paScriptArgs[i].u.pcszString, "dynamic")) 490 fDynamic = true; 491 else 492 { 493 RTPrintf("Invalid image type '%s' given\n", paScriptArgs[i].u.pcszString); 494 rc = VERR_INVALID_PARAMETER; 495 } 496 break; 497 } 412 498 default: 413 499 AssertMsgFailed(("Invalid argument given!\n")); … … 420 506 if (RT_SUCCESS(rc)) 421 507 { 422 if (fBase) 423 rc = VDCreateBase(pGlob->pVD, pcszBackend, pcszImage, cbSize, 0, NULL, 424 &pGlob->PhysGeom, &pGlob->LogicalGeom, 425 NULL, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages, NULL); 508 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 509 if (pDisk) 510 { 511 unsigned fImageFlags = VD_IMAGE_FLAGS_NONE; 512 513 if (!fDynamic) 514 fImageFlags |= VD_IMAGE_FLAGS_FIXED; 515 516 if (fBase) 517 rc = VDCreateBase(pDisk->pVD, pcszBackend, pcszImage, cbSize, fImageFlags, NULL, 518 &pDisk->PhysGeom, &pDisk->LogicalGeom, 519 NULL, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages, NULL); 520 else 521 rc = VDCreateDiff(pDisk->pVD, pcszBackend, pcszImage, fImageFlags, NULL, NULL, NULL, VD_OPEN_FLAGS_ASYNC_IO, 522 pGlob->pInterfacesImages, NULL); 523 } 426 524 else 427 rc = VDCreateDiff(pGlob->pVD, pcszBackend, pcszImage, 0, NULL, NULL, NULL, VD_OPEN_FLAGS_ASYNC_IO, 428 pGlob->pInterfacesImages, NULL); 525 rc = VERR_NOT_FOUND; 429 526 } 430 527 … … 437 534 const char *pcszBackend = NULL; 438 535 const char *pcszImage = NULL; 536 const char *pcszDisk = NULL; 537 PVDDISK pDisk = NULL; 538 bool fShareable = false; 539 bool fReadonly = false; 439 540 440 541 for (unsigned i = 0; i < cScriptArgs; i++) … … 442 543 switch (paScriptArgs[i].chId) 443 544 { 545 case 'd': 546 { 547 pcszDisk = paScriptArgs[i].u.pcszString; 548 break; 549 } 444 550 case 'n': 445 551 { … … 450 556 { 451 557 pcszBackend = paScriptArgs[i].u.pcszString; 558 break; 559 } 560 case 's': 561 { 562 fShareable = paScriptArgs[i].u.fFlag; 563 break; 564 } 565 case 'r': 566 { 567 fReadonly = paScriptArgs[i].u.fFlag; 452 568 break; 453 569 } … … 462 578 if (RT_SUCCESS(rc)) 463 579 { 464 rc = VDOpen(pGlob->pVD, pcszBackend, pcszImage, VD_OPEN_FLAGS_ASYNC_IO, pGlob->pInterfacesImages); 580 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 581 if (pDisk) 582 { 583 unsigned fOpenFlags = VD_OPEN_FLAGS_ASYNC_IO; 584 585 if (fShareable) 586 fOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; 587 if (fReadonly) 588 fOpenFlags |= VD_OPEN_FLAGS_READONLY; 589 590 rc = VDOpen(pDisk->pVD, pcszBackend, pcszImage, fOpenFlags, pGlob->pInterfacesImages); 591 } 592 else 593 rc = VERR_NOT_FOUND; 465 594 } 466 595 … … 481 610 unsigned cMaxReqs = 0; 482 611 uint8_t uWriteChance = 0; 483 uint8_t uReadChance = 0; 484 485 offEnd = VDGetSize(pGlob->pVD, VD_LAST_IMAGE); 486 if (offEnd == 0) 487 return VERR_INVALID_STATE; 488 cbIo = offEnd; 612 const char *pcszDisk = NULL; 613 PVDDISK pDisk = NULL; 489 614 490 615 for (unsigned i = 0; i < cScriptArgs; i++) … … 492 617 switch (paScriptArgs[i].chId) 493 618 { 619 case 'd': 620 { 621 pcszDisk = paScriptArgs[i].u.pcszString; 622 break; 623 } 494 624 case 'a': 495 625 { … … 531 661 break; 532 662 } 533 case 'r':534 {535 uReadChance = (uint8_t)paScriptArgs[i].u.u64;536 break;537 }538 663 case 'w': 539 664 { … … 551 676 if (RT_SUCCESS(rc)) 552 677 { 678 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 679 if (!pDisk) 680 rc = VERR_NOT_FOUND; 681 } 682 683 if (RT_SUCCESS(rc)) 684 { 685 /* Set defaults if not set by the user. */ 686 if (offStart == 0 && offEnd == 0) 687 { 688 offEnd = VDGetSize(pDisk->pVD, VD_LAST_IMAGE); 689 if (offEnd == 0) 690 return VERR_INVALID_STATE; 691 } 692 693 if (!cbIo) 694 cbIo = offEnd; 695 } 696 697 if (RT_SUCCESS(rc)) 698 { 553 699 VDIOTEST IoTest; 554 700 555 rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance , uReadChance);701 rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance); 556 702 if (RT_SUCCESS(rc)) 557 703 { … … 601 747 case VDIOREQTXDIR_READ: 602 748 { 603 rc = VDRead(p Glob->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);749 rc = VDRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq); 604 750 break; 605 751 } 606 752 case VDIOREQTXDIR_WRITE: 607 753 { 608 rc = VDWrite(p Glob->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq);754 rc = VDWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].DataSeg.pvSeg, paIoReq[idx].cbReq); 609 755 break; 610 756 } 611 757 case VDIOREQTXDIR_FLUSH: 612 758 { 613 rc = VDFlush(p Glob->pVD);759 rc = VDFlush(pDisk->pVD); 614 760 break; 615 761 } … … 624 770 case VDIOREQTXDIR_READ: 625 771 { 626 rc = VDAsyncRead(p Glob->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,772 rc = VDAsyncRead(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf, 627 773 tstVDIoTestReqComplete, &paIoReq[idx], EventSem); 628 774 break; … … 630 776 case VDIOREQTXDIR_WRITE: 631 777 { 632 rc = VDAsyncWrite(p Glob->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf,778 rc = VDAsyncWrite(pDisk->pVD, paIoReq[idx].off, paIoReq[idx].cbReq, &paIoReq[idx].SgBuf, 633 779 tstVDIoTestReqComplete, &paIoReq[idx], EventSem); 634 780 break; … … 636 782 case VDIOREQTXDIR_FLUSH: 637 783 { 638 rc = VDAsyncFlush(p Glob->pVD, tstVDIoTestReqComplete, &paIoReq[idx], EventSem);784 rc = VDAsyncFlush(pDisk->pVD, tstVDIoTestReqComplete, &paIoReq[idx], EventSem); 639 785 break; 640 786 } … … 715 861 int rc = VINF_SUCCESS; 716 862 bool fAsync = false; 717 718 if (cScriptArgs == 1 && paScriptArgs[0].chId == 'a') 719 fAsync = paScriptArgs[0].u.fFlag; 720 721 if (fAsync) 722 { 723 /** @todo */ 724 rc = VERR_NOT_IMPLEMENTED; 725 } 726 else 727 rc = VDFlush(pGlob->pVD); 863 const char *pcszDisk = NULL; 864 PVDDISK pDisk = NULL; 865 866 for (unsigned i = 0; i < cScriptArgs; i++) 867 { 868 switch (paScriptArgs[i].chId) 869 { 870 case 'd': 871 { 872 pcszDisk = paScriptArgs[i].u.pcszString; 873 break; 874 } 875 case 'a': 876 { 877 fAsync = paScriptArgs[i].u.fFlag; 878 break; 879 } 880 881 default: 882 AssertMsgFailed(("Invalid argument given!\n")); 883 } 884 885 if (RT_FAILURE(rc)) 886 break; 887 } 888 889 if (RT_SUCCESS(rc)) 890 { 891 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 892 if (!pDisk) 893 rc = VERR_NOT_FOUND; 894 else if (fAsync) 895 { 896 /** @todo */ 897 rc = VERR_NOT_IMPLEMENTED; 898 } 899 else 900 rc = VDFlush(pDisk->pVD); 901 } 728 902 729 903 return rc; … … 740 914 bool fAll = false; 741 915 bool fDelete = false; 916 const char *pcszDisk = NULL; 917 PVDDISK pDisk = NULL; 742 918 743 919 for (unsigned i = 0; i < cScriptArgs; i++) … … 745 921 switch (paScriptArgs[i].chId) 746 922 { 923 case 'd': 924 { 925 pcszDisk = paScriptArgs[i].u.pcszString; 926 break; 927 } 747 928 case 'm': 748 929 { … … 758 939 break; 759 940 } 760 case ' d':941 case 'r': 761 942 { 762 943 fDelete = paScriptArgs[i].u.fFlag; … … 781 962 if (RT_SUCCESS(rc)) 782 963 { 783 if (fAll) 784 rc = VDCloseAll(pGlob->pVD); 964 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 965 if (pDisk) 966 { 967 if (fAll) 968 rc = VDCloseAll(pDisk->pVD); 969 else 970 rc = VDClose(pDisk->pVD, fDelete); 971 } 785 972 else 786 rc = V DClose(pGlob->pVD, fDelete);973 rc = VERR_NOT_FOUND; 787 974 } 788 975 return rc; … … 910 1097 } 911 1098 1099 static DECLCALLBACK(int) vdScriptHandlerCreateDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs) 1100 { 1101 int rc = VINF_SUCCESS; 1102 const char *pcszDisk = NULL; 1103 PVDDISK pDisk = NULL; 1104 1105 for (unsigned i = 0; i < cScriptArgs; i++) 1106 { 1107 switch (paScriptArgs[i].chId) 1108 { 1109 case 'n': 1110 { 1111 pcszDisk = paScriptArgs[i].u.pcszString; 1112 break; 1113 } 1114 default: 1115 AssertMsgFailed(("Invalid argument given!\n")); 1116 } 1117 } 1118 1119 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 1120 if (pDisk) 1121 rc = VERR_ALREADY_EXISTS; 1122 else 1123 { 1124 pDisk = (PVDDISK)RTMemAllocZ(sizeof(VDDISK)); 1125 if (pDisk) 1126 { 1127 pDisk->pszName = RTStrDup(pcszDisk); 1128 if (pDisk->pszName) 1129 { 1130 rc = VDCreate(pGlob->pInterfacesDisk, VDTYPE_HDD, &pDisk->pVD); 1131 1132 if (RT_SUCCESS(rc)) 1133 RTListAppend(&pGlob->ListDisks, &pDisk->ListNode); 1134 else 1135 RTStrFree(pDisk->pszName); 1136 } 1137 else 1138 rc = VERR_NO_MEMORY; 1139 1140 if (RT_FAILURE(rc)) 1141 RTMemFree(pDisk); 1142 } 1143 else 1144 rc = VERR_NO_MEMORY; 1145 } 1146 return rc; 1147 } 1148 1149 static DECLCALLBACK(int) vdScriptHandlerDestroyDisk(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs) 1150 { 1151 int rc = VINF_SUCCESS; 1152 const char *pcszDisk = NULL; 1153 PVDDISK pDisk = NULL; 1154 1155 for (unsigned i = 0; i < cScriptArgs; i++) 1156 { 1157 switch (paScriptArgs[i].chId) 1158 { 1159 case 'n': 1160 { 1161 pcszDisk = paScriptArgs[i].u.pcszString; 1162 break; 1163 } 1164 default: 1165 AssertMsgFailed(("Invalid argument given!\n")); 1166 } 1167 } 1168 1169 pDisk = tstVDIoGetDiskByName(pGlob, pcszDisk); 1170 if (pDisk) 1171 { 1172 RTListNodeRemove(&pDisk->ListNode); 1173 VDDestroy(pDisk->pVD); 1174 RTStrFree(pDisk->pszName); 1175 RTMemFree(pDisk); 1176 } 1177 else 1178 rc = VERR_NOT_FOUND; 1179 1180 return rc; 1181 } 1182 1183 static DECLCALLBACK(int) vdScriptHandlerCompareDisks(PVDTESTGLOB pGlob, PVDSCRIPTARG paScriptArgs, unsigned cScriptArgs) 1184 { 1185 int rc = VINF_SUCCESS; 1186 const char *pcszDisk1 = NULL; 1187 PVDDISK pDisk1 = NULL; 1188 const char *pcszDisk2 = NULL; 1189 PVDDISK pDisk2 = NULL; 1190 1191 for (unsigned i = 0; i < cScriptArgs; i++) 1192 { 1193 switch (paScriptArgs[i].chId) 1194 { 1195 case '1': 1196 { 1197 pcszDisk1 = paScriptArgs[i].u.pcszString; 1198 break; 1199 } 1200 case '2': 1201 { 1202 pcszDisk2 = paScriptArgs[i].u.pcszString; 1203 break; 1204 } 1205 default: 1206 AssertMsgFailed(("Invalid argument given!\n")); 1207 } 1208 } 1209 1210 pDisk1 = tstVDIoGetDiskByName(pGlob, pcszDisk1); 1211 pDisk2 = tstVDIoGetDiskByName(pGlob, pcszDisk2); 1212 1213 if (pDisk1 && pDisk2) 1214 { 1215 uint8_t *pbBuf1 = (uint8_t *)RTMemAllocZ(16 * _1M); 1216 uint8_t *pbBuf2 = (uint8_t *)RTMemAllocZ(16 * _1M); 1217 if (pbBuf1 && pbBuf2) 1218 { 1219 uint64_t cbDisk1, cbDisk2; 1220 uint64_t uOffCur = 0; 1221 1222 cbDisk1 = VDGetSize(pDisk1->pVD, VD_LAST_IMAGE); 1223 cbDisk2 = VDGetSize(pDisk2->pVD, VD_LAST_IMAGE); 1224 1225 if (cbDisk1 != cbDisk2) 1226 RTPrintf("Disks differ in size %llu vs %llu\n", cbDisk1, cbDisk2); 1227 else 1228 { 1229 while (uOffCur < cbDisk1) 1230 { 1231 size_t cbRead = RT_MIN(cbDisk1, 16 * _1M); 1232 1233 rc = VDRead(pDisk1->pVD, uOffCur, pbBuf1, cbRead); 1234 if (RT_SUCCESS(rc)) 1235 rc = VDRead(pDisk2->pVD, uOffCur, pbBuf2, cbRead); 1236 1237 if (RT_SUCCESS(rc)) 1238 { 1239 if (memcmp(pbBuf1, pbBuf2, cbRead)) 1240 { 1241 RTPrintf("Disks differ at offset %llu\n", uOffCur); 1242 rc = VERR_DEV_IO_ERROR; 1243 break; 1244 } 1245 } 1246 else 1247 { 1248 RTPrintf("Reading one disk at offset %llu failed\n", uOffCur); 1249 break; 1250 } 1251 1252 uOffCur += cbRead; 1253 cbDisk1 -= cbRead; 1254 } 1255 } 1256 RTMemFree(pbBuf1); 1257 RTMemFree(pbBuf2); 1258 } 1259 else 1260 { 1261 if (pbBuf1) 1262 RTMemFree(pbBuf1); 1263 if (pbBuf2) 1264 RTMemFree(pbBuf2); 1265 rc = VERR_NO_MEMORY; 1266 } 1267 } 1268 else 1269 rc = VERR_NOT_FOUND; 1270 1271 return rc; 1272 } 1273 912 1274 static DECLCALLBACK(int) tstVDIoFileOpen(void *pvUser, const char *pszLocation, 913 1275 uint32_t fOpen, … … 919 1281 bool fFound = false; 920 1282 1283 /* 1284 * Some backends use ./ for paths, strip it. 1285 * @todo: Implement proper directory support for the 1286 * memory filesystem. 1287 */ 1288 if ( strlen(pszLocation) >= 2 1289 && *pszLocation == '.' 1290 && pszLocation[1] == '/') 1291 pszLocation += 2; 1292 921 1293 /* Check if the file exists. */ 922 1294 PVDFILE pIt = NULL; … … 930 1302 } 931 1303 932 if (fFound && pIt->pfnComplete) 933 rc = VERR_FILE_LOCK_FAILED; 934 else if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE) 1304 if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE) 935 1305 { 936 1306 /* If the file exists delete the memory disk. */ … … 943 1313 if (pIt) 944 1314 { 945 pIt->pfnComplete = pfnCompleted; 946 pIt->pszName = RTStrDup(pszLocation); 1315 pIt->pszName = RTStrDup(pszLocation); 947 1316 948 1317 if (pIt->pszName) … … 970 1339 if (!fFound) 971 1340 rc = VERR_FILE_NOT_FOUND; 972 else973 pIt->pfnComplete = pfnCompleted;974 1341 } 975 1342 else … … 979 1346 { 980 1347 AssertPtr(pIt); 981 *ppStorage = pIt; 1348 PVDSTORAGE pStorage = (PVDSTORAGE)RTMemAllocZ(sizeof(VDSTORAGE)); 1349 if (!pStorage) 1350 rc = VERR_NO_MEMORY; 1351 1352 pStorage->pFile = pIt; 1353 pStorage->pfnComplete = pfnCompleted; 1354 *ppStorage = pStorage; 982 1355 } 983 1356 … … 987 1360 static DECLCALLBACK(int) tstVDIoFileClose(void *pvUser, void *pStorage) 988 1361 { 989 PVDFILE pFile = (PVDFILE)pStorage; 990 991 /* Mark as not busy. */ 992 pFile->pfnComplete = NULL; 1362 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1363 1364 RTMemFree(pIoStorage); 993 1365 return VINF_SUCCESS; 994 1366 } … … 1076 1448 static DECLCALLBACK(int) tstVDIoFileGetSize(void *pvUser, void *pStorage, uint64_t *pcbSize) 1077 1449 { 1078 PVD FILE pFile = (PVDFILE)pStorage;1079 1080 return VDMemDiskGetSize(p File->pMemDisk, pcbSize);1450 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1451 1452 return VDMemDiskGetSize(pIoStorage->pFile->pMemDisk, pcbSize); 1081 1453 } 1082 1454 1083 1455 static DECLCALLBACK(int) tstVDIoFileSetSize(void *pvUser, void *pStorage, uint64_t cbSize) 1084 1456 { 1085 PVD FILE pFile = (PVDFILE)pStorage;1086 1087 return VDMemDiskSetSize(p File->pMemDisk, cbSize);1457 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1458 1459 return VDMemDiskSetSize(pIoStorage->pFile->pMemDisk, cbSize); 1088 1460 } 1089 1461 … … 1092 1464 { 1093 1465 int rc = VINF_SUCCESS; 1094 PVD FILE pFile = (PVDFILE)pStorage;1466 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1095 1467 1096 1468 RTSGBUF SgBuf; … … 1100 1472 Seg.cbSeg = cbBuffer; 1101 1473 RTSgBufInit(&SgBuf, &Seg, 1); 1102 rc = VDMemDiskWrite(p File->pMemDisk, uOffset, cbBuffer, &SgBuf);1474 rc = VDMemDiskWrite(pIoStorage->pFile->pMemDisk, uOffset, cbBuffer, &SgBuf); 1103 1475 if (RT_SUCCESS(rc) && pcbWritten) 1104 1476 *pcbWritten = cbBuffer; … … 1111 1483 { 1112 1484 int rc = VINF_SUCCESS; 1113 PVD FILE pFile = (PVDFILE)pStorage;1485 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1114 1486 1115 1487 RTSGBUF SgBuf; … … 1119 1491 Seg.cbSeg = cbBuffer; 1120 1492 RTSgBufInit(&SgBuf, &Seg, 1); 1121 rc = VDMemDiskRead(p File->pMemDisk, uOffset, cbBuffer, &SgBuf);1493 rc = VDMemDiskRead(pIoStorage->pFile->pMemDisk, uOffset, cbBuffer, &SgBuf); 1122 1494 if (RT_SUCCESS(rc) && pcbRead) 1123 1495 *pcbRead = cbBuffer; … … 1139 1511 int rc = VINF_SUCCESS; 1140 1512 PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser; 1141 PVD FILE pFile = (PVDFILE)pStorage;1142 1143 rc = VDIoBackendMemTransfer(pGlob->pIoBackend, p File->pMemDisk, VDIOTXDIR_READ, uOffset,1144 cbRead, paSegments, cSegments, p File->pfnComplete, pvCompletion);1513 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1514 1515 rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_READ, uOffset, 1516 cbRead, paSegments, cSegments, pIoStorage->pfnComplete, pvCompletion); 1145 1517 if (RT_SUCCESS(rc)) 1146 1518 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; … … 1156 1528 int rc = VINF_SUCCESS; 1157 1529 PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser; 1158 PVD FILE pFile = (PVDFILE)pStorage;1159 1160 rc = VDIoBackendMemTransfer(pGlob->pIoBackend, p File->pMemDisk, VDIOTXDIR_WRITE, uOffset,1161 cbWrite, paSegments, cSegments, p File->pfnComplete, pvCompletion);1530 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1531 1532 rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_WRITE, uOffset, 1533 cbWrite, paSegments, cSegments, pIoStorage->pfnComplete, pvCompletion); 1162 1534 if (RT_SUCCESS(rc)) 1163 1535 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; … … 1171 1543 int rc = VINF_SUCCESS; 1172 1544 PVDTESTGLOB pGlob = (PVDTESTGLOB)pvUser; 1173 PVD FILE pFile = (PVDFILE)pStorage;1174 1175 rc = VDIoBackendMemTransfer(pGlob->pIoBackend, p File->pMemDisk, VDIOTXDIR_FLUSH, 0,1176 0, NULL, 0, p File->pfnComplete, pvCompletion);1545 PVDSTORAGE pIoStorage = (PVDSTORAGE)pStorage; 1546 1547 rc = VDIoBackendMemTransfer(pGlob->pIoBackend, pIoStorage->pFile->pMemDisk, VDIOTXDIR_FLUSH, 0, 1548 0, NULL, 0, pIoStorage->pfnComplete, pvCompletion); 1177 1549 if (RT_SUCCESS(rc)) 1178 1550 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; … … 1183 1555 static int tstVDIoTestInit(PVDIOTEST pIoTest, PVDTESTGLOB pGlob, bool fRandomAcc, uint64_t cbIo, 1184 1556 size_t cbBlkSize, uint64_t offStart, uint64_t offEnd, 1185 unsigned uWriteChance , unsigned uReadChance)1557 unsigned uWriteChance) 1186 1558 { 1187 1559 int rc = VINF_SUCCESS; … … 1303 1675 if (!pIoTest->u.Rnd.cBlocksLeft) 1304 1676 { 1305 /* New round, clear ever thing. */1677 /* New round, clear everything. */ 1306 1678 ASMBitClearRange(pIoTest->u.Rnd.pbMapAccessed, 0, pIoTest->u.Rnd.cBlocks); 1307 1679 pIoTest->u.Rnd.cBlocksLeft = pIoTest->u.Rnd.cBlocks; … … 1346 1718 1347 1719 /** 1720 * Returns the disk handle by name or NULL if not found 1721 * 1722 * @returns Disk handle or NULL if the disk could not be found. 1723 * 1724 * @param pGlob Global test state. 1725 * @param pcszDisk Name of the disk to get. 1726 */ 1727 static PVDDISK tstVDIoGetDiskByName(PVDTESTGLOB pGlob, const char *pcszDisk) 1728 { 1729 PVDDISK pIt = NULL; 1730 bool fFound = false; 1731 1732 LogFlowFunc(("pGlob=%#p pcszDisk=%s\n", pGlob, pcszDisk)); 1733 1734 RTListForEach(&pGlob->ListDisks, pIt, VDDISK, ListNode) 1735 { 1736 if (!RTStrCmp(pIt->pszName, pcszDisk)) 1737 { 1738 fFound = true; 1739 break; 1740 } 1741 } 1742 1743 LogFlowFunc(("return %#p\n", fFound ? pIt : NULL)); 1744 return fFound ? pIt : NULL; 1745 } 1746 1747 /** 1348 1748 * Skips the characters until the given character is reached. 1349 1749 * … … 1396 1796 1397 1797 return psz; 1798 } 1799 1800 /** 1801 * Returns true if the first character of the given string 1802 * contains a character marking a line end (comment or \0 1803 * terminator). 1804 * 1805 * @returns true if the line contains no more characters of 1806 * interest and false otherwise. 1807 * 1808 * @param psz The string to check for. 1809 */ 1810 static bool tstVDIoIsLineEnd(const char *psz) 1811 { 1812 return *psz == '\0' || *psz == '#'; 1398 1813 } 1399 1814 … … 1620 2035 1621 2036 while ( psz 1622 && *psz != '\0')2037 && !tstVDIoIsLineEnd(psz)) 1623 2038 { 1624 2039 const char *pcszName = psz; 1625 2040 1626 2041 psz = tstVDIoScriptSkipUntil(psz, '='); 1627 if ( psz != '\0')2042 if (!tstVDIoIsLineEnd(psz)) 1628 2043 { 1629 2044 *psz = '\0'; /* Overwrite */ … … 1632 2047 1633 2048 psz = tstVDIoScriptSkipNonSpace(psz); 1634 if ( psz != '\0')2049 if (!tstVDIoIsLineEnd(psz)) 1635 2050 { 1636 2051 *psz = '\0'; /* Overwrite */ 1637 2052 psz++; 1638 2053 psz = tstVDIoScriptSkipSpace(psz); 1639 1640 /* We have the name and value pair now. */ 1641 bool fMandatory = false; /* Shut up gcc */ 1642 rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory); 1643 if (RT_SUCCESS(rc)) 1644 { 1645 if (fMandatory) 1646 cMandatoryArgsReq--; 1647 cScriptArgs++; 1648 } 1649 } 1650 else 2054 } 2055 2056 pcszValue = tstVDIoScriptSkipSpace((char *)pcszValue); 2057 if (*pcszValue == '\0') 1651 2058 { 1652 2059 RTPrintf("Value missing for argument '%s'\n", pcszName); 1653 2060 rc = VERR_INVALID_STATE; 1654 2061 break; 2062 } 2063 2064 /* We have the name and value pair now. */ 2065 bool fMandatory = false; /* Shut up gcc */ 2066 rc = tstVDIoScriptArgumentParse(pVDScriptAction, pcszName, pcszValue, &paScriptArgs[cScriptArgs], &fMandatory); 2067 if (RT_SUCCESS(rc)) 2068 { 2069 if (fMandatory) 2070 cMandatoryArgsReq--; 2071 cScriptArgs++; 1655 2072 } 1656 2073 } … … 1703 2120 /* Skip space */ 1704 2121 psz = tstVDIoScriptSkipSpace(psz); 1705 if ( psz != '\0')2122 if (!tstVDIoIsLineEnd(psz)) 1706 2123 { 1707 2124 PCVDSCRIPTACTION pVDScriptAction = NULL; … … 1711 2128 1712 2129 psz = tstVDIoScriptSkipNonSpace(psz); 1713 if ( psz != '\0')2130 if (!tstVDIoIsLineEnd(psz)) 1714 2131 { 1715 2132 Assert(RT_C_IS_SPACE(*psz)); … … 1763 2180 } 1764 2181 } 1765 else 1766 { 1767 RTPrintf("Missing action name\n"); 1768 rc = VERR_INVALID_STATE; 1769 } 2182 /* else empty line, just continue */ 1770 2183 } 1771 2184 } while(RT_SUCCESS(rc)); … … 1794 2207 memset(&GlobTest, 0, sizeof(VDTESTGLOB)); 1795 2208 RTListInit(&GlobTest.ListFiles); 2209 RTListInit(&GlobTest.ListDisks); 1796 2210 1797 2211 rc = RTStrmOpen(pcszFilename, "r", &pScriptStrm); … … 1833 2247 if (RT_SUCCESS(rc)) 1834 2248 { 1835 rc = VDCreate(GlobTest.pInterfacesDisk, VDTYPE_HDD, &GlobTest.pVD); 1836 if (RT_SUCCESS(rc)) 1837 { 1838 /* Execute the script. */ 1839 rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest); 1840 if (RT_FAILURE(rc)) 1841 { 1842 RTPrintf("Executing the script stream failed rc=%Rrc\n", rc); 1843 } 1844 } 1845 else 1846 RTPrintf("Failed to create disk container rc=%Rrc\n", rc); 2249 /* Execute the script. */ 2250 rc = tstVDIoScriptExecute(pScriptStrm, &GlobTest); 2251 if (RT_FAILURE(rc)) 2252 { 2253 RTPrintf("Executing the script stream failed rc=%Rrc\n", rc); 2254 } 1847 2255 VDIoBackendMemDestroy(GlobTest.pIoBackend); 1848 2256 }
Note:
See TracChangeset
for help on using the changeset viewer.