VirtualBox

Ticket #5582 (reopened enhancement)

Opened 7 years ago

Last modified 12 days ago

Suggestion: allow disk image data to be aligned in VDI files, for optimal use with SSDs

Reported by: Donuts Owned by:
Priority: minor Component: other
Version: VirtualBox 3.0.12 Keywords:
Cc: Guest type: other
Host type: other

Description (last modified by aeichner) (diff)

First, see this blog post which has some background information:  http://thunk.org/tytso/blog/2009/02/20/aligning-filesystems-to-an-ssds-erase-block-size/

In summary, the smallest chunk of data that SSDs (solid-state flash drives) can write is larger than the 512-byte size that the SSD emulates/fakes for the host computer. The smallest chunk size might be 4KB, for example. If filesystem writes are not aligned to 4KB boundaries performance will suffer, especially for first-generation SSDs.

For example, if the host computer writes 4KB to (512-byte) sectors 63 to 70, the SSD will read the 4KB corresponding to sectors 56-63, update the sector 63 data and write it to flash. Similarly with the 4KB block corresponding to sectors 64-71. This read-modify-write causes more wear on the SSD.

Windows XP and earlier (and probably most non-Windows partitioning software) by default creates the first partition starting at (512-byte) sector 63. That is an "odd" alignment, not aligned on a 1KB boundary let alone 4KB or more.

What does this have to do with VirtualBox? My suggestion is that the VDI format be updated to allow the user to specify the alignment of the data. VirtualBox would add a few sectors worth of padding before the actual data. For use with SSDs, the user could set the alignment so sector 63 is on a 4KB boundary in the VDI file. The fixed-size VDI header appears to be $600 bytes long, so an extra $C00 bytes padding would be needed in that case. Doing that might also be a minor performance win for conventional hard drives, if the host filesystem uses a 4KB cluster size. Of course the exact amount of padding to use needs to be user-configurable; for a Vista VDI it would be $A00 bytes.

Change History

comment:1 Changed 7 years ago by Donuts

I have posted instructions on how to manually add padding to a new (dynamically-expanding) VDI file to  http://forums.virtualbox.org/viewtopic.php?f=1&t=25336

Contrary to what I wrote about SSDs above, this is also relevant to conventional hard disks. The issue is that the guest filesystem clusters (typically 4KB) may not be aligned on a cluster boundary in the host partition.

comment:2 Changed 12 days ago by aeichner

  • Status changed from new to closed
  • Resolution set to fixed
  • Description modified (diff)

VDI images are aligned to a 1MB boundary which should be enough for the near future. Additionally the alignment for VDI images can be set by the user with vbox-img when creating a base image. Closing as fixed.

comment:3 Changed 12 days ago by Donuts

  • Status changed from closed to reopened
  • Resolution fixed deleted

I'm marking this as reopened for a couple of reasons:

  • It doesn't seem to be possible, as far as I can tell, to have vbox-img use the specific alignment required. For a given --dataalignment argument, the actual aligment seems to vary depending on the VDI capacity.
  • There's no way in the VirtualBox GUI to achieve that either.

To solve this issue there should be a way to tell vbox-img to align sector data to offset X modulo Y bytes. For the partition-starts-at-sector-63 case, to align the guest partition on a multiple of 1MB, sector data needs to begin at a byte offset which is (1048576 - 32256) modulo 1048576 in the VDI file.

The --dataalignment argument could be modified to take two numbers, modulo and offset. So the user could specify --dataalignment 1048576,-32256 for the desired result.

As you say, disk sector data begins at a 1MB boundary in the VDI file by default. But that doesn't help the common case where Windows XP (and presumably earlier OSes back to MS-DOS) by default create a partition which begins at sector 63. That's what you get when you install XP to a blank/empty disk.

In that case, for optimal performance guest sector 63 (i.e. byte offset 32256) needs to start at a multiple of 4KB in the VDI file (or a larger alignment like 8KB or even 1MB). In other words, guest sector data should start at a (multiple of 4KB/8KB/1MB/whatever) MINUS 32256 bytes.

I tried using vbox-img to create VDI files using various values for the --dataalignment argument, but didn't manage to get the correct alignment for a VDI which is going to have a partition that starts at sector 63. By luck I could get sector 63 to be 4KB-aligned, but not 1MB.

For example:

$ vbox-img createbase --filename blah1GB_3584.vdi --size 1073741824 --dataalignment 3584
$ vbox-img info --filename blah1GB_3584.vdi 
--- Dumping VD Disk, Images=1
Dumping VD image "blah1GB_3584.vdi" (Backend=VDI)
Dumping VDI image "blah1GB_3584.vdi" mode=r/o uOpenFlags=9 File=0x00000000a41780
Header: Version=00010001 Type=1 Flags=0 Size=1073741824
Header: cbBlock=1048576 cbBlockExtra=0 cBlocks=1024 cBlocksAllocated=0
Header: offBlocks=512 offData=4608
Header: Geometry: C/H/S=0/0/0 cbSector=512
...
Image:  fFlags=00000000 offStartBlocks=512 offStartData=4608
Image:  uBlockMask=000FFFFF cbTotalBlockData=1048576 uShiftOffset2Index=20 offStartBlockData=0

In that case sector data starts at offset 4608, meaning guest sector 63 will be at byte offset 4608+32256 = 36864 = 0x9000. That's 4KB-aligned.

Now create a 4GB VDI using the same --dataalignment value:

$ vbox-img createbase --filename blah4GB_3584.vdi --size 4294967296 --dataalignment 3584
$ vbox-img info --filename blah4GB_3584.vdi 
--- Dumping VD Disk, Images=1
Dumping VD image "blah4GB_3584.vdi" (Backend=VDI)
Dumping VDI image "blah4GB_3584.vdi" mode=r/o uOpenFlags=9 File=0x000000016ec780
Header: Version=00010001 Type=1 Flags=0 Size=4294967296
Header: cbBlock=1048576 cbBlockExtra=0 cBlocks=4096 cBlocksAllocated=0
Header: offBlocks=512 offData=16896
Header: Geometry: C/H/S=0/0/0 cbSector=512
...
Image:  fFlags=00000000 offStartBlocks=512 offStartData=16896
Image:  uBlockMask=000FFFFF cbTotalBlockData=1048576 uShiftOffset2Index=20 offStartBlockData=0

Here sector data starts at offset 16896, meaning guest sector 63 is at byte offset 16896+32256 = 0xC000. Again 4KB-aligned (in fact 16KB-aligned).

But how would I create a VDI where sector data is aligned to a (multiple of 1MB)-32256? Try using --dataalignment 1016320 to create a 1GB VDI:

$ vbox-img createbase --filename blah1GB_1016320.vdi --size 1073741824 --dataalignment 1016320
$ vbox-img info --filename blah1GB_1016320.vdi
--- Dumping VD Disk, Images=1
Dumping VD image "blah1GB_1016320.vdi" (Backend=VDI)
Dumping VDI image "blah1GB_1016320.vdi" mode=r/o uOpenFlags=9 File=0x00000001ac9780
Header: Version=00010001 Type=1 Flags=0 Size=1073741824
Header: cbBlock=1048576 cbBlockExtra=0 cBlocks=1024 cBlocksAllocated=0
Header: offBlocks=512 offData=4608
Header: Geometry: C/H/S=0/0/0 cbSector=512
...
Image:  fFlags=00000000 offStartBlocks=512 offStartData=4608
Image:  uBlockMask=000FFFFF cbTotalBlockData=1048576 uShiftOffset2Index=20 offStartBlockData=0

For some reason sector data starts at offset 4608 (same as with --dataalignment 3584), even though I specified --dataalignment 1016320. So sector 63 data will start at byte offset 0x9000; that's 4KB-aligned but not 1MB.

Now use same --dataalignment 1016320 to create a 10GB VDI:

$ vbox-img createbase --filename blah10GB_1016320.vdi --size 10737418240 --dataalignment 1016320
$ vbox-img info --filename blah10GB_1016320.vdi
--- Dumping VD Disk, Images=1
Dumping VD image "blah10GB_1016320.vdi" (Backend=VDI)
Dumping VDI image "blah10GB_1016320.vdi" mode=r/o uOpenFlags=9 File=0x000000015c2790
Header: Version=00010001 Type=1 Flags=0 Size=10737418240
Header: cbBlock=1048576 cbBlockExtra=0 cBlocks=10240 cBlocksAllocated=0
Header: offBlocks=512 offData=1057280
Header: Geometry: C/H/S=0/0/0 cbSector=512
...
Image:  fFlags=00000000 offStartBlocks=512 offStartData=1057280
Image:  uBlockMask=000FFFFF cbTotalBlockData=1048576 uShiftOffset2Index=20 offStartBlockData=0

There the sector 63 data will be at byte offset 1057280+32256 = 0x10A000; again 4KB-aligned but not 1MB-aligned.

If it is actually possible to have sector 63 be 1MB-aligned, it seems figuring out the value to use for --dataalignment is trial-and-error, and the correct value to use will depend on the VDI capacity.

Note: See TracTickets for help on using tickets.

www.oracle.com
ContactPrivacy policyTerms of Use