Page 1 of 1

All about VDIs

PostPosted: 20. Jul 2008, 01:46
by TerryE
This tutorial is an experiment to see if forum users find it useful to have a single collected reference for some common questions that visitors ask about VDIs, their internals and their use. The tutorial is currently in DRAFT, so don't take the content as full gospel until it has had some level of review from the other VBox "power users" who visit the forum. You will find this topic is locked so that only forum moderators can change the content or add additional Qs. However, if you want to discuss this; recommend corrections or challenge the content; suggest new questions within this general VDI umbrella then you can do so on Discuss All about VDIs. If you want to suggest other possible tutorials or discuss the whole approach the you can do so on Discussion on New Tutorials.

PostPosted: 20. Jul 2008, 01:49
by TerryE
Q: How are VDI files structured?

A: All VDIs essentially have the same structure. The VDI has four sections:
  • A Standard header descriptor [512 bytes]
  • An image block map. If the (maximum) size of the virtual HDD is N MByte, then this map is 4N bytes long.
  • Block alignment padding. The header format allows for padding between the image block map and the image blocks, and (as of version 1.6.2) the CreateVDI function adds padding after the map to ensure that the first image block begins on a 512byte sector boundary. Since the allocation unit on both NTFS and Ext3 file systems is 4096 bytes, you will therefore get slightly better performance (typically a few %) if you make your VDIs (1024N – 128) MByte long.
  • Up to N x 1MByte image blocks.

PostPosted: 20. Jul 2008, 01:52
by TerryE
Q: What’s in the Header Descriptor

A: Here is a hexadecimal dump of a typical VDI header. Note that this for the current VBox VDI version (1.1):
Code: Select all   Expand viewCollapse view
0000      3C 3C 3C 20 53 75 6E 20 78 56 4D 20 56 69 72 74    <<< Sun xVM Virt
0010      75 61 6C 42 6F 78 20 44 69 73 6B 20 49 6D 61 67    ualBox Disk Imag
0020      65 20 3E 3E 3E 0A 00 00 00 00 00 00 00 00 00 00    e >>>
0030      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0040      7F 10 DA BE                                        Image Signature
                      01 00 01 00                            Version 1.1
                                  90 01 00 00                Size of Header(0x190)
                                              01 00 00 00    Image Type (Dynamic VDI)
0050      00 00 00 00                                        Image Flags
                      00 00 00 00 00 00 00 00 00 00 00 00    Image Description
0060-001F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0150      00 00 00 00
                      00 02 00 00                            offsetBlocks
                                  00 20 00 00                offsetData
                                              00 00 00 00    #Cylinders (0)
0160      00 00 00 00                                        #Heads (0)
                      00 00 00 00                            #Sectors (0)
                                  00 02 00 00                SectorSize (512)
                                              00 00 00 00     -- unused --
0170      00 00 00 78 00 00 00 00                            DiskSize (Bytes)
                                  00 00 10 00                BlockSize
                                              00 00 00 00    Block Extra Data (0)
0180      80 07 00 00                                        #BlocksInHDD
                      0B 02 00 00                            #BlocksAllocated
                                  5A 08 62 27 A8 B6 69 44    UUID of this VDI
0190      A1 57 E2 B2 43 A5 8F CB
                                  0C 5C B1 E3 C5 73 ED 40    UUID of last SNAP
01A0      AE F7 06 D6 20 69 0C 96
                                  00 00 00 00 00 00 00 00    UUID link
01B0      00 00 00 00 00 00 00 00
                                  00 00 00 00 00 00 00 00    UUID Parent
01C0      00 00 00 00 00 00 00 00
                                  CF 03 00 00 00 00 00 00    -- garbage / unused --
01D0      3F 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00    -- garbage / unused --
01E0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    -- unused --
01F0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    -- unused –

Also note that multi-byte values are “little-endian” that is the bytes are least significant first, so the blockSize = “00 00 10 00” = 0x100000 = 1 Mbyte.

As VDI does not embed its filename, so you are free to change the name of unregistered VDIs. (If you change the name of registered VDIs without manually editing your VirtualBox and Machine XML registries, your machines can become unloadable). However the VDI does embed its UUID and up to three other UUIDs which are discussed in a later Q.

PostPosted: 20. Jul 2008, 01:54
by TerryE
Q. So how are virtual bytes in my Virtual HDD mapped into physical bytes in my VDI?

A: The underlying virtual HDD is divided into 1 Mbyte pages. These are mapped onto image blocks in the VDI. Remember that the zeroth image block starts at an offset and that all image blocks are 1Mbyte long. Any virtual HDD byte address is converted into a block number and block offset. The block number is then mapped to a physical image block in the VDI file by means of the image block mapping table, so for byte Z in the virtual HDD:
  • Hsize = 512 + 4N + (508 + 4N) mod 512
  • Zblock = int( Z / BlockSize )
  • Zoffset = Z mod BlockSize
  • Fblock = IndexMap[Zblock]
  • Fposition = Hsize + ( Fblock * BlockSize ) + ZOffset
However the VDI can be sparse. What this means is that zero blocks (that is 1Mbytes of 0x00) may not be allocated. In such a case, the image map entry is set to -1, and this tells the driver that the corresponding block is not allocated. Reading from an unallocated block returns zeros. If you write to an unallocated block then a new block is allocated at the end of the VDI with the rest of it filled with zeros. Note that this map is small in size (40 Kbytes in the case of a 10 GByte VDI), so all such VDI maps and VDI header info are cached into the VMM memory, so this translation of virtual addresses into physical addresses does not incur additional read/write operations except in the relatively rare case where the I/O transfer cuts across a 1Mbyte boundary).
  • In the case of a dynamic VDI (Type 1) as “new” 1Mbyte blocks in the virtual HDD are written to, these are mapped to new 1Mbyte blocks which are allocated at the end of the VDI file; that is a dynamic VDI is initially ordered in chronological not physical order. The initial size of an N Mbyte dynamic VDI is 512+4N+F bytes with all N image map entries set to -1. F = (508+4N) mod 512, that is the packing necessary to round up to a sector boundary.

  • In the case of a static (Type 2) VDI all blocks are pre-allocated so no dynamic allocation is necessary. The create utility also writes zeros to the entire file because many file systems themselves adopt a just-in-time allocation policy. The initial size of an N Mbyte static VDI is 512+4N+F+1048576N bytes, where F is as in the dynamic case.
The pros and cons of deciding whether choosing whether to use a static or dynamic VDI are complex. Static drives are fragmentation free at a file level, and since you also take the ‘pain’ of file allocation up-front in one hit, you know that you aren’t going to have continuous growth of your VDIs slowly filling up your host file system. VirtualBox recommend the use of static VDIs primarily because fragmentation can degrade performance. I personally disagree and prefer using dynamic VDIs myself for the following reasons:
  • If you are going to use your VDI as an immutable drive or a baseline for snapshots, then there is little point in allocating space that is never going to be written to, so why waste the HDD space?

  • As long as your process for creating the disk in the first place is not too fragmented then the more compact dynamic VDI will actually give you better performance. (I now defragment the dynamic VDIs that I am going to use, and I’ve posted the utility I use in this topic: Example VDI Defragmentation Utility.)

PostPosted: 20. Jul 2008, 01:56
by TerryE
Q. So what about snapshots? How do they work?

Technically, a snapshot records an entire VM state, which including all attached drives, however most people do also use the word as a synonym for "delta image", "difference image" or "child image" when discussing the role of a single VDI in a snapshot chain, other than the base VDI.

A: A snapshot allows you to establish a baseline of your HDDs, which you can then roll back to at a later stage. These can be very useful for testing out new options and installations because you know that you can trivially roll back to the snapshot point. (As I discussed later, they can also significantly reduce the size of working backups.) When you take a snapshot, the current (in the snapshot chain) VDI is "frozen" and a new delta VDI is added.

The snapshot has the same format and is initialised in the same way as a normal dynamic VDI. When the guest VM OS wants to read from the disk, the VirtualBox VM monitor (VMM) process in the host has to map this to a read from a VDI host file. All such read operations first index into the current snapshot's image map and if the map entry exists, then the corresponding image block is used. In the case of a "miss", the same read process is repeated on the parent VDI/snapshot index map, and so on up the snapshot chain until the block is found. If no match is found (i.e. the block has never been written to since the VM was created) then it is treated as a read from an uninitialized area of the disk, and artbitrary content is returned.

In the case of a write, the data is always written to a block in the current snapshot. If there is a "miss" on the current index map, a new block is allocated in the current snapshot and the new data is stored there. Over time therefore the writes to the current snapshot will hide the older writes in previous snapshot layers. The following figure gives a simple example of how this all maps out:
Code: Select all   Expand viewCollapse view
             < - - - - -Block Map - - - - - >   Block Order
             0         1         2         3      on VDI
Snapshot 1:  AB-FOG---CIJD--EM----NKL----H---  ABCDEFGHIJKLMN
Snapshot 2:  ---f----bc---d--e-----a------g--  abcdefg
Current:     -----3--1------0------245-------  012345
Source File: 11-213--321112-32----1333---12-- 
Block:       AB-fO3--1cIJDd-0e----N245---Hg-

                              Figure 1

This example has a 32Mb initial dynamic VDI. At the time of the first snapshot 14 blocks have been allocated, and 18 are still zero/unallocated. A snapshot is then taken and another 7 blocks are written to (4 of which supersede the original VDI) and then a second snapshot with another six blocks. Whilst the guest OS 'sees' a single 32Mb disk, the VMM has to read from one of the three different VDIs, and the final physical block order is pretty randomised compare to the logical block sequence.
Code: Select all   Expand viewCollapse view
VDI chain
   UUID       Location            Date of  Size  UUID Links in Snapshot Header
                                  Snapshot   Mb    This   Last   Link  Parent
 {UUID-5} jeosLAMPsys.vdi           19/07/2008 587   UUID-5 UUID-7 000000 000000
 {UUID-6} Snapshots/{UUID-6}.vdi 24/07/2008  29   UUID-6 UUID-8 UUID-5 UUID-7
 {UUID-4} Snapshots/{UUID-4}.vdi 26/07/2008  12   UUID-4 UUID-9 UUID-6 UUID-8
VM Details in jeosLAMP.vbox
    name="Snapshot 1"
      name="Snapshot 2"
                              Figure 2

As you can see from the above example, the snapshots form an ordered chain. The four UUIDs in the snapshot headers are used to link the snapshots logically so that the VBoxManager and the VirtualBox GUI can build and check the integrity of the chain to be used for a given VDI. (The UUIDs are just random unique hex fingerprints, e.g. {ca788f17-f54f-417f-b666-3016a2472159}, so I have replaced them by UUID-N in this example to make it more readable). The VMM also uses the VM's "media registry" (stored in the <vmname>.vbox file) which also references the savestate files and snapshots by UUID for each disk. (I have again included a simplified extract in the above). Hence the snapshots and VDIs include double linked references by UUID and in the registry. If any of these get out of sync then your VM will not load. Whilst it is possible to patch up broken chains, VirtualBox does not currently include any repair utilities, and so any repair has to be done manually by editing the .vbox file and the header of files of the VDIs. This is not a task for the novice or the faint-hearted - so it's a good idea to make backups of VMs, especially if they use snapshots - or any similar delta scheme e.g. immutable drives or linked clones.

Removing a snapshot can be done in one of two ways:

  • If you Restore to an earlier snapshot state then all snapshot data which came after that earlier state is deleted and lost forever.
  • If you Delete an earlier snapshot then this can be seen as deleting the ability to revert to that old moment in time. No data is lost from the later snapshot states (at the implementation level, data is first merged into the next snapshot and then the now redundant intermediate file is deleted). The only exception is if you delete the current state, which is treated as equivalent to reverting to the newest-but-one state.

PostPosted: 20. Jul 2008, 01:57
by TerryE
Q. So what are Immutable and Writethrough drives? How do they work?

A: A drive can be designated as normal (the default), immutable or writethrough when it is registered through the VBoxManage registerimage disk command. An immutable drive is a special delta drive that is constructed much as a snapshot in that the VDI file is opened readonly (and for that reason can be used by multiple VMs), but as far as the guest OS is concerned the drive is read/write with any writes going to a machine-specific delta VDI, much the same as a current snapshot. The unique characteristic of an immutable drive is that these delta VDIs are discarded on the next VM power-up and hence the drive reverts to its initial state, with all changes lost. Note that immutable drives are preserved through the snapshot process if the snapshot is taken when the guest is not powered down.

An example use of a immutable disk could be where your system is spread over a system disk and a user data disk. If you make the system disk immutable, then each time you reboot, the system disk is returned to its clean state, but the user data persists. This means that any virus or other configuration change cannot persist on the system disk (but by the same reason, there is little point in your guest being configured for automatic OS update as any updates will also be lost on reboot!)

You mark a drive as writethrough when you want to indicate that the drive is not to involved in snapshots: if you snapshot the VM the other drives will have new delta states created, but writethrough drives will be skipped. A scenario where you might use write-through drives is one where you wanted to test an application and frequently needed to roll-back by reverting snapshots. Here you might configure your test system over 3 drives:
  • An immutable system disk
  • A normal application disk
  • A write-through audit and results disk.
Remember that the normal / immutable / write-through status is at the virtual drive (VDI) level. You cannot ‘mix and match’ at the partition level.

Also note that this write-through concept has nothing to do with the sync and dirsync options that some Linux file systems support.

PostPosted: 20. Jul 2008, 01:58
by TerryE
Q: Why do dynamic VDIs grow far more than the used space?

A: Think about the design objectives of the writers of file systems. These include things like being able to allocate files to the file system flexibly, to be able to append data to files, to be able to index into files, and to have file I/O as efficient as is practical. They use various types of allocation structures and regimes to ensure flexibility and try to minimise file fragmentation so that I/O is efficient. One of the ways that this is done is by spreading the files over the file system. Indeed, the idea of scrunching all of the files into one small region would be an anathema to most file system developers. So recall how space is allocated on a dynamic VDI: each time the file system touches any bytes in a new 1 Mbyte image block, then the full 1Mbyte block is allocated. It stays allocated even if the file is deleted and the space return to some “free pool”. So if you have a 20 GByte partition, over time the file system will touch every 1 MByte block, and therefore the VDI will grow to 20 GBytes even if you actually only use 5 GByte.

If you typically only use 5 GBytes in your partition with its sometimes growing up to 8 GBytes, say, and you don't want it to occupy more than 10 GBytes on your host then don't make your partition bigger than 10 GBytes! OK, so many would then say “but I want to allocate 20 GBytes for growth capacity”. My response here would be either to use LVM if you are an advanced user, or to reserve say 100% space between your partitions. Remember that this dead space will only take up 4 bytes per Gbyte. You can then easily resize your partitions when you require (as discussed in a later question).

PostPosted: 20. Jul 2008, 02:02
by TerryE
Q: How can I reduce the size of a dynamic VDI on disk?

A: There are two approaches to cleaning up and reducing the size of the file system stored on a dynamic VDI. The first is what I call in-place and the second is by doing a file system copy. This answer addresses the first of these.

You must prepare the file system before you attempt to reduce its size, otherwise the benefit will be minimal. First, clear out any obvious garbage files that are lying around; for example empty your wastebasket and Internet caches; clean up any temporary folders and files that you no longer need. In the case of NTFS and FAT file systems, you should run a defragment utility, because this not only reduces file fragmentation but also free space fragmentation.

You then need to use a utility to zero the free space within the file system (remember that in general free space will not be zero, because it will contain data blocks that have been used and recycled to the file system). This utility must understand the structure of the file system and in particular its free-space maps, and be able to bypass the high level file-system I/O functions to write directly to the disk at a block level, without compromising its integrity. It is therefore OS specific.

The best tool to use for NTFS under a Windows guest OS is the System Internals (now part of Microsoft) tool sdelete (Microsoft SysInternals File Utillities). You run this at the command prompt with the -c option to tell sdelete to clear the unused space, hence the following command cleans out the C and D partitions:
Code: Select all   Expand viewCollapse view
sdelete -c C
sdelete -c D

In the case of Linux, a good utility for ext2, ext3 and ext4 file systems is zerofree written by Ron Yorston and available on his website:zerofree. The easiest way to use this utility is to keep a copy in /usr/bin on each system image. Some distributions such as Ubuntu now include this so you can install it in your Ubuntu guest by running sudo apt-get install zerofree. To zero out the file systems, you boot your system in init 1 mode (typically the second option on most grub-loader menus); then remount your file systems read-only (as zerofree will only clear out read-only file systems); and then run zerofree on each partition, for example the following clears my system and application disks:
Code: Select all   Expand viewCollapse view
mount -n -o remount,ro -t ext2 /dev/sda1 /
mount -n -o remount,ro -t ext2 /dev/sdb1 /var
zerofree /dev/sda1
zerofree /dev/sdb1

The safest thing to do immediately following these commands is to shutdown / reboot your VM after scheduling a boot-time file system check. Then shutdown your VB. You can then execute VBoxManage modifyvdi xxxx.vdi --compact command from your host OS where xxxx.vdi is your dynamic VDI. (I find that the easiest thing to do is to cd to my VDI directory first so I don't have to bother with pathnames in the command).

Compacting a dynamic VDI is done in place in a two pass algorithm. First all blocks are scanned and any that are entirely zero are freed; this creates holes in the physical allocation. So if the image contained 110 blocks and 10 were tagged as zero, then the new image should contain 100 blocks. The second phase copies any blocks above the 100 high-water mark into the now vacant blocks below the mark. The block map is then updated and the VDI file truncated to the new length. This process minimises the amount of temporary disk required, but it does have the disadvantage that the compaction process further shuffles block order.

Note: mpack's unofficial CloneVDI tool (see sticky in Windows Hosts) can also be used to compact VDIs, and does not require that first sdelete/zerofree preprocessing pass, hence is normally considerably quicker in use, in addition to being able to compact e.g. unpartitioned areas of the disk which sdelete can't reach. Although a 32bit Windows app, it is known to run well in the Wine GUI platform for Linux and OS X.

PostPosted: 20. Jul 2008, 02:04
by TerryE
Q: How do I get the best performance out of my VDIs?

A: In general you will get the best performance if your VDI is stored on contiguous blocks on the file system, with the individual 1 MByte allocation blocks within the file also contiguous. (This is what I think of as an unfragmented VDI). Also minimise the number of snapshots that you use. Any contiguous blocks can then be read from the file system without having to do extra HDD seeks. So why am I concerned so much about I/O operations? Whilst CPU speeds have increased by perhaps four orders of magnitude in the last few decades, physical aspects such as the rotation speed of disks and track-to-track seek times have only doubled or thereabouts. So what this means is that the relative consequence of file and file system fragmentation has increased over the decades. Your CPU can now spend tens of millions of CPU cycles waiting for a physical disk to move into position to start an I/O operation.

Unfortunately file fragmentation is a necessary evil that rises from the need to have flexibility in allocating your files, and being able to increase your files in size when necessary, though modest levels of fragmentation produce very little perceivable performance impact. In the case of the Microsoft Windows OSs, the fragmentation within NTFS and the FAT file systems is so bad (certainly compared to the Linux file systems) that Microsoft have had to include a basic defragmenting utility in their OSs, and there is a sufficient market demand to sustain the more sophisticated third-party defragmenting utilities that are also available. Wise Windows users defragment regularly, and novice users just end up waiting around saying “Why is my disk becoming so slow”.

The allocation strategies within Linux file systems are a lot better at mitigating the impacts of fragmentation, so most Linux users aren't aware of this is an issue. Nonetheless, Linux file systems can still badly defragment over years, especially if you allow the file system utilisation to climb much over 80%.

With VDIs, you have one or more file systems embedded within a single VDI container, and in the case of dynamic VDIs and snapshots, you face a triple fragmentation whammy:
  • The guest OS file system can fragment.
  • The block allocation scheme within VDIs introduces another level of fragmentation.
  • The host file system can also fragment its allocation of the VDI.
The net result of this is that unless you actively manage your fragmentation at all three levels, your PC might end up doing twice as many I/Os as the equivalent native OS installation, and therefore run at half the speed on an I/O bound application. Remember that dynamic VDIs initially order the 1 MByte image blocks in chronological allocation order. If you are compacting your drives, and using snapshots which you roll forward, this slowly shuffles this block order over time, so the order of the 1 MByte blocks can get quite randomised.

By its nature a dynamic VDI will slowly grow over time. This type of slow file growth is something that neither Ext3 nor NTFS handles very well and tends to cause fragmentation. In the case of Windows NTFS hosted VDIs, there is an excellent Microsoft SysInternal utility called contig which analyses and calls the internal NT API to defragment individual files. This is great for making sure that individual VDIs are not too fragmented.

The simple way to avoid such internal fragmentation within the VDI is to use a static format. However, as I mentioned above, as long as you keep your VDIs reasonably defragmented as well as the file system that contains them, the performance reductions are marginal, even compared to using raw image VMDKs within VirtualBox.

PostPosted: 20. Jul 2008, 02:05
by TerryE
Q: Where is the best place to keep my VDIs?

The best place to keep your VDI's is inside the VM home folder. This ensures that sometime down the road when you want to make a backup of your VM, all you need to do is copy the entire VM folder to secondary storage, and you don't need to remember that "oh yeah, I stored its data drive on this other partition over here". If you are concerned about the size of the VDI then it's better to move the entire VM folder to a larger partition, rather than split up the file set. For details read Howto: Move a VM.

Remember that, whatever location you use, the filesystem must be able to cope with very large files. This generally rules out the use of FAT/FAT32 formatted removable drives.

Lastly note that only the current VDI files are opened read-write, so in the case of snapshotted systems and immutable drives the base VDI is opened read only. This means that you can not only share mutable drives across VMs but that you can also mount them from read-only file systems such as CD-ROMs.

PostPosted: 20. Jul 2008, 02:07
by TerryE
Q: How can I resize the partitions inside my VDI?

A: For all non-experts I have a standard answer, and that is to use a Gparted liveCD. At the time of posting you can download this from Gparted on SourceForge. This is a reasonably large download (90 MByte), but you only need to download it once and keep it in a central directory (I have a VirtualBox/ISO in which I store my ISOs). You simply attach this ISO as your CD in the interactive GUI and temporarily change the boot order to boot from CD first. The default liveCD configuration boots happily under VirtualBox. You have to answer a couple of questions to choose the correct keyboard and language but after that you will be presented with a simple Windows interface that any Windows, Mac or Linux user will be familiar with. The Gparted online documentation includes a couple of step-by-step introductions for beginners to show how to use it, so there is little point in my covering this ground here. Note that this latest version handles most file system formats automatically (including Ext2, Ext3, FAT16, FAT32, JFS, NTFS, ReiserFS, XFS). See the Gparted->Show Features option for more details. So even though this is a Linux CD,
    you can still use it to resize and to copy NTFS volumes.
The tedious bit is then getting the new partition to boot properly. Unfortunately the bootstrap process is quite complex and works differently for the Linux (grub) and NT boot processes. You need to integrate the bootstrap loader that is located in the MBR with an OS-specific secondary bootstrap in the filesystem. For Windows, the easiest way is to boot from your Windows media into recovery console, then do
Code: Select all   Expand viewCollapse view
and this will fix up the MBR. For Linux, I boot off the old system image mount the new image and use the grub-install --root-directory option to create a grub loader on the new drive. Once you’ve cracked this for your OS, you can quickly get this down to a routine process, but there are enough complications here to merit a separate topic in its own right.

Also note that since the Gparted utility copies only allocated blocks (that is it doesn't copy file-system free space) and also copies in partition block order, this process can be used to create optimally ordered dynamic VDIs if you copy from an existing VDI to a new blank one.

PostPosted: 20. Jul 2008, 02:08
by TerryE
Q: How do I backup my VDIs?

Perhaps before answering this Q, I need to emphasise a simple truth here: if you don't want to lose data then you must backup. Disks can fail; host OSs and PCs can fail; guest OSs , VMs, VirtualBox itself, and guest apps can all fail. One outcome of any of these is that you might just lose access to your data. You need to have a recovery strategy in place in the case of such failure that is matched to the value of your data.

A: Remember that VDIs are just disk drives as far as the guest system is concerned, so one option is to use whatever guest based backup that you are comfortable with. For example with one of my LAMP systems I have an automatic script which dumps the database, diffs it against a weekly baseline and compresses the diff file. It also does a compressed tarball of any changed files in the www hierarchy since the last dump. These are then pulled to an offsite server. This runs every night and takes about a min to save the entire LAMP stack. It doesn’t need any bouncing of VMs or stopping of the applications.

The alternative is that you can savestate your VM and backup your VDIs at a file level in the host OS. Use of snapshots can help you here. If you have a file system that is reasonably stable then use clean up process discussed above and then snapshot it. The base VDI is now fixed and only needs to be backed up once. All changes will be written to the delta VDI in the Machine Snapshots directory, and this is typically a lot smaller than the base snapshot, so future backups will be smaller because they can skip backing up the base VDI.

Use your favourite compression tool to backup the delta VDIs. Gzip is fast but its compression isn’t too great. WinZIP in windows is comparable. 7-Zip gives far better compression but is a lot slower and CPU intensive. A good time to do this is overnight, then you can use high compression algorithms to minimise backup space. Make sure to back any files such as the machine.xml so that you can recover the directory hierarchies if you need to.

What I now do is to use the rsync utility to update on off machine copy of the VDI. This is very efficient since only updated blocks get copied and the content is compressed before transfer over the network.

From time to time (say once a month in the case of a system that you are actively adding to), after doing the backup, take the system down for maintenance; delete any snapshots to roll forward to a single current VDI; and clean it up using the process described above. You can script most of this. What this does is to establish a new baseline VDI that you can backup from. Use snapshots sparingly and only for a reason. I have been contacted by a number of users who have a VM with a long snapshot chain that has become corrupted. Be warned. I myself use snapshots frequently, but avoid the snapshot chain getting longer than base + 2 snapshots. If you do this you need to be careful so that you can reconstruct the Snapshot chains if you need to restore and this will be the topic of a separate post.

If you can’t take your VMs offline for long then one good trick is to start a new snapshot. Only the latest snapshot VDIs are opened R/W, so you can then backup the second to last whilst still using the VM. To resync, you savestate, delete the second last snapshot which in effect merges its content into latest; and resume the VM. This takes minutes rather than the compress which can take hours.

Now that I have switched from Windows to Linux for my host of preference, I now use a more advanced technique based on hosting my VDIs on a LVM partition. My backup utility uses a VBoxManage guestcontrol execute command to sync the guest file system and then established a temporary readonly snapshot. I then use rsync to mirror this frozen copy of the VM to a separate host before releasing the snapshot. This gives me the ability to hot-copy any VM.