Changeset 38413 in vbox
- Timestamp:
- Aug 11, 2011 11:18:44 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73451
- Location:
- trunk/src/VBox/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/Parallels.cpp
r37739 r38413 412 412 } 413 413 414 /** 415 * Internal: Create a parallels image. 416 */ 417 static int parallelsCreateImage(PPARALLELSIMAGE pImage, uint64_t cbSize, 418 unsigned uImageFlags, const char *pszComment, 419 PCVDGEOMETRY pPCHSGeometry, 420 PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags, 421 PFNVDPROGRESS pfnProgress, void *pvUser, 422 unsigned uPercentStart, unsigned uPercentSpan) 423 { 424 int rc = VINF_SUCCESS; 425 int32_t fOpen; 426 427 if (uImageFlags & VD_IMAGE_FLAGS_FIXED) 428 { 429 rc = parallelsError(pImage, VERR_VD_INVALID_TYPE, RT_SRC_POS, N_("Parallels: cannot create fixed image '%s'. Create a raw image"), pImage->pszFilename); 430 goto out; 431 } 432 433 pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY; 434 pImage->uImageFlags = uImageFlags; 435 pImage->PCHSGeometry = *pPCHSGeometry; 436 pImage->LCHSGeometry = *pLCHSGeometry; 437 438 if (!pImage->PCHSGeometry.cCylinders) 439 { 440 /* Set defaults. */ 441 pImage->PCHSGeometry.cSectors = 63; 442 pImage->PCHSGeometry.cHeads = 16; 443 pImage->PCHSGeometry.cCylinders = pImage->cbSize / (512 * pImage->PCHSGeometry.cSectors * pImage->PCHSGeometry.cHeads); 444 } 445 446 pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR); 447 if (pImage->pInterfaceError) 448 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 449 450 /* Get I/O interface. */ 451 pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsImage, VDINTERFACETYPE_IOINT); 452 AssertPtrReturn(pImage->pInterfaceIO, VERR_INVALID_PARAMETER); 453 pImage->pInterfaceIOCallbacks = VDGetInterfaceIOInt(pImage->pInterfaceIO); 454 AssertPtrReturn(pImage->pInterfaceIOCallbacks, VERR_INVALID_PARAMETER); 455 456 /* Create image file. */ 457 fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */); 458 rc = parallelsFileOpen(pImage, pImage->pszFilename, fOpen); 459 if (RT_FAILURE(rc)) 460 { 461 rc = parallelsError(pImage, rc, RT_SRC_POS, N_("Parallels: cannot create image '%s'"), pImage->pszFilename); 462 goto out; 463 } 464 465 if (RT_SUCCESS(rc) && pfnProgress) 466 pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100); 467 468 /* Setup image state. */ 469 pImage->cbSize = cbSize; 470 pImage->cAllocationBitmapEntries = cbSize / 512 / pImage->PCHSGeometry.cSectors; 471 if (pImage->cAllocationBitmapEntries * pImage->PCHSGeometry.cSectors * 512 < cbSize) 472 pImage->cAllocationBitmapEntries++; 473 pImage->fAllocationBitmapChanged = true; 474 pImage->cbFileCurrent = sizeof(ParallelsHeader) + pImage->cAllocationBitmapEntries * sizeof(uint32_t); 475 /* Round to next sector boundary. */ 476 pImage->cbFileCurrent += 512 - pImage->cbFileCurrent % 512; 477 Assert(!(pImage->cbFileCurrent % 512)); 478 pImage->pAllocationBitmap = (uint32_t *)RTMemAllocZ(pImage->cAllocationBitmapEntries * sizeof(uint32_t)); 479 if (!pImage->pAllocationBitmap) 480 rc = VERR_NO_MEMORY; 481 482 if (RT_SUCCESS(rc)) 483 { 484 ParallelsHeader Header; 485 486 memcpy(Header.HeaderIdentifier, PARALLELS_HEADER_MAGIC, sizeof(Header.HeaderIdentifier)); 487 Header.uVersion = RT_H2LE_U32(PARALLELS_DISK_VERSION); 488 Header.cHeads = RT_H2LE_U32(pImage->PCHSGeometry.cHeads); 489 Header.cCylinders = RT_H2LE_U32(pImage->PCHSGeometry.cCylinders); 490 Header.cSectorsPerTrack = RT_H2LE_U32(pImage->PCHSGeometry.cSectors); 491 Header.cEntriesInAllocationBitmap = RT_H2LE_U32(pImage->cAllocationBitmapEntries); 492 Header.cSectors = RT_H2LE_U32(pImage->cbSize / 512); 493 memset(Header.Padding, 0, sizeof(Header.Padding)); 494 495 /* Write header and allocation bitmap. */ 496 rc = parallelsFileSetSize(pImage, pImage->cbFileCurrent); 497 if (RT_SUCCESS(rc)) 498 rc = parallelsFileWriteSync(pImage, 0, &Header, sizeof(Header), NULL); 499 if (RT_SUCCESS(rc)) 500 rc = parallelsFlushImage(pImage); /* Writes the allocation bitmap. */ 501 } 502 503 out: 504 if (RT_SUCCESS(rc) && pfnProgress) 505 pfnProgress(pvUser, uPercentStart + uPercentSpan); 506 507 if (RT_FAILURE(rc)) 508 parallelsFreeImage(pImage, rc != VERR_ALREADY_EXISTS); 509 return rc; 510 } 414 511 415 512 /** @copydoc VBOXHDDBACKEND::pfnCheckIfValid */ … … 502 599 } 503 600 504 /** @todo r=klaus why this duplicate check, async is not claimed... */505 if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)506 {507 rc = VERR_NOT_SUPPORTED;508 goto out;509 }510 511 601 pImage = (PPARALLELSIMAGE)RTMemAllocZ(sizeof(PARALLELSIMAGE)); 512 602 if (!pImage) … … 543 633 PVDINTERFACE pVDIfsOperation, void **ppBackendData) 544 634 { 545 LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData)); 546 int rc = VERR_NOT_IMPLEMENTED; 547 635 LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p", 636 pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData)); 637 int rc = VINF_SUCCESS; 638 PPARALLELSIMAGE pImage; 639 640 PFNVDPROGRESS pfnProgress = NULL; 641 void *pvUser = NULL; 642 PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation, 643 VDINTERFACETYPE_PROGRESS); 644 PVDINTERFACEPROGRESS pCbProgress = NULL; 645 if (pIfProgress) 646 { 647 pCbProgress = VDGetInterfaceProgress(pIfProgress); 648 if (pCbProgress) 649 pfnProgress = pCbProgress->pfnProgress; 650 pvUser = pIfProgress->pvUser; 651 } 652 653 /* Check open flags. All valid flags are supported. */ 654 if (uOpenFlags & ~VD_OPEN_FLAGS_MASK) 655 { 656 rc = VERR_INVALID_PARAMETER; 657 goto out; 658 } 659 660 /* Check remaining arguments. */ 661 if ( !VALID_PTR(pszFilename) 662 || !*pszFilename 663 || !VALID_PTR(pPCHSGeometry) 664 || !VALID_PTR(pLCHSGeometry)) 665 { 666 rc = VERR_INVALID_PARAMETER; 667 goto out; 668 } 669 670 pImage = (PPARALLELSIMAGE)RTMemAllocZ(sizeof(PARALLELSIMAGE)); 671 if (!pImage) 672 { 673 rc = VERR_NO_MEMORY; 674 goto out; 675 } 676 pImage->pszFilename = pszFilename; 677 pImage->pStorage = NULL; 678 pImage->pVDIfsDisk = pVDIfsDisk; 679 pImage->pVDIfsImage = pVDIfsImage; 680 681 rc = parallelsCreateImage(pImage, cbSize, uImageFlags, pszComment, 682 pPCHSGeometry, pLCHSGeometry, uOpenFlags, 683 pfnProgress, pvUser, uPercentStart, uPercentSpan); 684 if (RT_SUCCESS(rc)) 685 { 686 /* So far the image is opened in read/write mode. Make sure the 687 * image is opened in read-only mode if the caller requested that. */ 688 if (uOpenFlags & VD_OPEN_FLAGS_READONLY) 689 { 690 parallelsFreeImage(pImage, false); 691 rc = parallelsOpenImage(pImage, uOpenFlags); 692 if (RT_FAILURE(rc)) 693 { 694 RTMemFree(pImage); 695 goto out; 696 } 697 } 698 *ppBackendData = pImage; 699 } 700 else 701 RTMemFree(pImage); 702 703 out: 548 704 LogFlowFunc(("returns %Rrc\n", rc)); 549 705 return rc; … … 612 768 /** @copydoc VBOXHDDBACKEND::pfnRead */ 613 769 static int parallelsRead(void *pBackendData, uint64_t uOffset, void *pvBuf, 614 size_t cbBuf, size_t *pcbActuallyRead) 615 { 616 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbBuf=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbBuf, pcbActuallyRead)); 770 size_t cbToRead, size_t *pcbActuallyRead) 771 { 772 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", 773 pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead)); 617 774 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 618 775 int rc = VINF_SUCCESS; 619 uint64_t uSector;620 uint64_t uOffsetInFile;621 uint32_t iIndexInAllocationTable;622 776 623 777 AssertPtr(pImage); 624 778 Assert(uOffset % 512 == 0); 625 Assert(cb Buf% 512 == 0);779 Assert(cbToRead % 512 == 0); 626 780 627 781 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 628 { 629 rc = parallelsFileReadSync(pImage, uOffset, pvBuf, cbBuf, NULL); 630 } 631 else 632 { 782 rc = parallelsFileReadSync(pImage, uOffset, pvBuf, cbToRead, NULL); 783 else 784 { 785 uint64_t uSector; 786 uint32_t iIndexInAllocationTable; 787 788 /* Calculate offset in the real file. */ 789 uSector = uOffset / 512; 790 791 /* One chunk in the file is always one track big. */ 792 iIndexInAllocationTable = (uint32_t)(uSector / pImage->PCHSGeometry.cSectors); 793 uSector = uSector % pImage->PCHSGeometry.cSectors; 794 795 Assert(iIndexInAllocationTable < pImage->cAllocationBitmapEntries); 796 797 cbToRead = RT_MIN(cbToRead, (pImage->PCHSGeometry.cSectors - uSector)*512); 798 799 LogFlowFunc(("AllocationBitmap[%u]=%u uSector=%u cbToRead=%zu cAllocationBitmapEntries=%u\n", 800 iIndexInAllocationTable, pImage->pAllocationBitmap[iIndexInAllocationTable], 801 uSector, cbToRead, pImage->cAllocationBitmapEntries)); 802 803 if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0) 804 rc = VERR_VD_BLOCK_FREE; 805 else 806 { 807 uint64_t uOffsetInFile = ((uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 808 809 LogFlowFunc(("uOffsetInFile=%llu\n", uOffsetInFile)); 810 rc = parallelsFileReadSync(pImage, uOffsetInFile, pvBuf, cbToRead, NULL); 811 } 812 } 813 814 if ( ( RT_SUCCESS(rc) 815 || rc == VERR_VD_BLOCK_FREE) 816 && pcbActuallyRead) 817 *pcbActuallyRead = cbToRead; 818 819 LogFlowFunc(("returns %Rrc\n", rc)); 820 return rc; 821 } 822 823 /** @copydoc VBOXHDDBACKEND::pfnWrite */ 824 static int parallelsWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf, 825 size_t cbToWrite, size_t *pcbWriteProcess, 826 size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite) 827 { 828 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p\n", 829 pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess)); 830 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 831 int rc = VINF_SUCCESS; 832 833 AssertPtr(pImage); 834 Assert(uOffset % 512 == 0); 835 Assert(cbToWrite % 512 == 0); 836 837 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 838 rc = parallelsFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL); 839 else 840 { 841 uint64_t uSector; 842 uint64_t uOffsetInFile; 843 uint32_t iIndexInAllocationTable; 844 633 845 /* Calculate offset in the real file. */ 634 846 uSector = uOffset / 512; … … 637 849 uSector = uSector % pImage->PCHSGeometry.cSectors; 638 850 639 cbBuf = RT_MIN(cbBuf, (pImage->PCHSGeometry.cSectors - uSector)*512); 851 Assert(iIndexInAllocationTable < pImage->cAllocationBitmapEntries); 852 853 cbToWrite = RT_MIN(cbToWrite, (pImage->PCHSGeometry.cSectors - uSector)*512); 854 855 LogFlowFunc(("AllocationBitmap[%u]=%u uSector=%u cbToWrite=%zu cAllocationBitmapEntries=%u\n", 856 iIndexInAllocationTable, pImage->pAllocationBitmap[iIndexInAllocationTable], 857 uSector, cbToWrite, pImage->cAllocationBitmapEntries)); 640 858 641 859 if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0) 642 860 { 643 rc = VERR_VD_BLOCK_FREE; 861 if ( cbToWrite == pImage->PCHSGeometry.cSectors * 512 862 && !(fWrite & VD_WRITE_NO_ALLOC)) 863 { 864 /* Stay on the safe side. Do not run the risk of confusing the higher 865 * level, as that can be pretty lethal to image consistency. */ 866 *pcbPreRead = 0; 867 *pcbPostRead = 0; 868 869 /* Allocate new chunk in the file. */ 870 AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n")); 871 pImage->pAllocationBitmap[iIndexInAllocationTable] = (uint32_t)(pImage->cbFileCurrent / 512); 872 pImage->cbFileCurrent += pImage->PCHSGeometry.cSectors * 512; 873 pImage->fAllocationBitmapChanged = true; 874 875 uOffsetInFile = (uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] * 512; 876 877 LogFlowFunc(("uOffsetInFile=%llu\n", uOffsetInFile)); 878 879 /* 880 * Write the new block at the current end of the file. 881 */ 882 rc = parallelsFileWriteSync(pImage, uOffsetInFile, pvBuf, cbToWrite, 883 NULL); 884 } 885 else 886 { 887 /* Trying to do a partial write to an unallocated cluster. Don't do 888 * anything except letting the upper layer know what to do. */ 889 *pcbPreRead = uSector * 512; 890 *pcbPostRead = (pImage->PCHSGeometry.cSectors * 512) - cbToWrite - *pcbPreRead; 891 rc = VERR_VD_BLOCK_FREE; 892 } 644 893 } 645 894 else 646 895 { 647 uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 648 rc = parallelsFileReadSync(pImage, uOffsetInFile, pvBuf, cbBuf, NULL); 649 } 650 } 651 652 if ( RT_SUCCESS(rc) 653 || rc == VERR_VD_BLOCK_FREE) 654 { 655 if (pcbActuallyRead) 656 *pcbActuallyRead = cbBuf; 657 658 Log2(("parallelsRead: off=%#llx pvBuf=%p cbBuf=%d\n" 659 "%.*Rhxd\n", 660 uOffset, pvBuf, cbBuf, cbBuf, pvBuf)); 661 } 662 663 LogFlowFunc(("returns %Rrc\n", rc)); 664 return rc; 665 } 666 667 /** @copydoc VBOXHDDBACKEND::pfnWrite */ 668 static int parallelsWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf, 669 size_t cbBuf, size_t *pcbWriteProcess, 670 size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite) 671 { 672 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbBuf=%zu pcbWriteProcess=%#p\n", pBackendData, uOffset, pvBuf, cbBuf, pcbWriteProcess)); 673 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 674 int rc = VINF_SUCCESS; 675 uint64_t uSector; 676 uint64_t uOffsetInFile; 677 uint32_t iIndexInAllocationTable; 678 679 AssertPtr(pImage); 680 Assert(uOffset % 512 == 0); 681 Assert(cbBuf % 512 == 0); 682 683 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 684 { 685 rc = parallelsFileWriteSync(pImage, uOffset, pvBuf, cbBuf, NULL); 686 } 687 else 688 { 689 /** Calculate offset in the real file. */ 690 uSector = uOffset / 512; 691 /** One chunk in the file is always one track big. */ 692 iIndexInAllocationTable = (uint32_t)(uSector / pImage->PCHSGeometry.cSectors); 693 uSector = uSector % pImage->PCHSGeometry.cSectors; 694 695 cbBuf = RT_MIN(cbBuf, (pImage->PCHSGeometry.cSectors - uSector)*512); 696 697 if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0) 698 { 699 /* Allocate new chunk in the file. */ 700 AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n")); 701 pImage->pAllocationBitmap[iIndexInAllocationTable] = (uint32_t)(pImage->cbFileCurrent / 512); 702 pImage->cbFileCurrent += pImage->PCHSGeometry.cSectors * 512; 703 pImage->fAllocationBitmapChanged = true; 704 705 uint8_t *pNewBlock = (uint8_t *)RTMemAllocZ(pImage->PCHSGeometry.cSectors * 512); 706 707 if (!pNewBlock) 708 { 709 rc = VERR_NO_MEMORY; 710 goto out; 711 } 712 713 uOffsetInFile = (uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] * 512; 714 memcpy(pNewBlock + (uOffset - ((uint64_t)iIndexInAllocationTable * pImage->PCHSGeometry.cSectors * 512)), 715 pvBuf, cbBuf); 716 717 /* 718 * Write the new block at the current end of the file. 719 */ 720 rc = parallelsFileWriteSync(pImage, uOffsetInFile, pNewBlock, 721 pImage->PCHSGeometry.cSectors * 512, 722 NULL); 723 724 RTMemFree(pNewBlock); 725 } 726 else 727 { 728 uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 729 rc = parallelsFileWriteSync(pImage, uOffsetInFile, pvBuf, cbBuf, NULL); 896 uOffsetInFile = ((uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 897 898 LogFlowFunc(("uOffsetInFile=%llu\n", uOffsetInFile)); 899 rc = parallelsFileWriteSync(pImage, uOffsetInFile, pvBuf, cbToWrite, NULL); 730 900 } 731 901 } 732 902 733 903 if (pcbWriteProcess) 734 *pcbWriteProcess = cbBuf; 735 736 /* Stay on the safe side. Do not run the risk of confusing the higher 737 * level, as that can be pretty lethal to image consistency. */ 738 *pcbPreRead = 0; 739 *pcbPostRead = 0; 904 *pcbWriteProcess = cbToWrite; 740 905 741 906 out: … … 961 1126 962 1127 /* Image must be opened and the new flags must be valid. */ 963 /** @todo r=klaus add VD_OPEN_FLAGS_ASYNC_IO when async io has been tested */ 964 if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL))) 1128 if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_ASYNC_IO))) 965 1129 { 966 1130 rc = VERR_INVALID_PARAMETER; … … 1310 1474 NULL, NULL); 1311 1475 } 1476 1477 *pcbPreRead = 0; 1478 *pcbPostRead = 0; 1312 1479 } 1313 1480 else … … 1348 1515 sizeof(VBOXHDDBACKEND), 1349 1516 /* uBackendCaps */ 1350 VD_CAP_FILE | VD_CAP_ASYNC | VD_CAP_VFS ,1517 VD_CAP_FILE | VD_CAP_ASYNC | VD_CAP_VFS | VD_CAP_CREATE_DYNAMIC | VD_CAP_DIFF, 1351 1518 /* paFileExtensions */ 1352 1519 s_aParallelsFileExtensions, -
trunk/src/VBox/Storage/testcase/tstVDIo.vd
r38204 r38413 64 64 destroydisk name=test 65 65 66 # Parallels disk 67 print msg=Testing_Parallels 68 createdisk name=test verify=yes 69 create disk=test mode=base name=tstShared.hdd type=dynamic backend=Parallels size=200M 70 io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=100 71 io disk=test async=yes max-reqs=32 mode=seq blocksize=64k off=0-200M size=200M writes=0 72 create disk=test mode=diff name=tstShared2.hdd type=dynamic backend=Parallels size=200M 73 io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50 74 create disk=test mode=diff name=tstShared3.hdd type=dynamic backend=Parallels size=200M 75 io disk=test async=yes max-reqs=32 mode=rnd blocksize=64k off=0-200M size=200M writes=50 76 close disk=test mode=single delete=yes 77 close disk=test mode=single delete=yes 78 close disk=test mode=single delete=yes 79 destroydisk name=test 80 66 81 iorngdestroy 67 82
Note:
See TracChangeset
for help on using the changeset viewer.