This is another “how to” tech article, anyone who is not interested in such things may stop reading now.
VirtualBox is a great virtualization software (hypervisor as the lingo currently goes) – I believe it matches up nicely against the current VMWare Workstation line and they offer both an open source version which is free for any use as well as a commercial version (with some added features such as SATA support) that is free for personal use.
VirtualBox allows you to take snapshots of the current VM state so that you can safely return to a previous state of your VM if you messed something up (for example – installed too much software on your Windows XP VM). Unfortunately, unlike what the VirtualBox UI will have you think, the snapshot features allows you to take progressive snapshots but you can’t fork your snapshot tree – you can’t create branches off old snapshots. Snapshots which are not current can be either discarded (have their state merged into another state) or reverted too (discard all the newest data and return to the old state).
Additionally, you can’t copy (clone) VMs with snapshots except copying the oldest state(1).
Still, if you want to keep your old state, and maybe fork some previous snapshots and create something of a real tree structure, there is a round about way to achieve something similar:
Suppose you have created a set of snapshots similar to the screenshot above, and now you want to use “Old State B” as a basis for a new set of snapshots (that will not include the changes in “Old State C”).
In the screenshot below you can see the VirtualBox Media Manager lists the VMs virtual HD with all its snapshots – “Arbel.vdi” is the base snapshot “Old State A”, the next down is “Old State B”, then “C” and finally “Current state”.
Theoretically what you would want to do is to use VirtualBox’s command line management interface to clone the virtual HD state of “Old State B” (UUID 4e1f756e-f158-4c07-bc9a-20261f574730) into a new base HD, like this:
$ VBoxManage clonehd 4e1f756e-f158-4c07-bc9a-20261f574730 .VirtualBox/HardDisks/new-old-state-b.vdi -format VDI -remember
And then create a new VM that you can use for the new set of snapshots (as we said, you can’t actually see a tree of snapshots, but you can represent each branch using its own VM. Not really space efficient, but works).
The problem is that VirtualBox’s
clonehd will not let you clone a snapshot other then the base. This is due to the fact that snapshots are simply “difference lists” between the previous snapshot and the current state. Whenever you take a snapshot VirtualBox will “freeze” the current state as a read-only VDI file and create a new VDI where it will save only the blocks that the VM has written too after the snapshot. In order to clone a snapshot VirtualBox will need to first consolidate all the changes between all the previous snapshots. This functionality apparently is not implemented yet.
What you can do is to clone the base snapshot – this is a normal VDI file that all the snapshot VDIs refer to (and it is read-only with regard to the VM so you can clone it even if the VM is currently running). So I can clone “Old State A”, but not “Old State B”. But what I can do is to force VirtualBox to consolidate “Old State A” and “Old State B” back into the base snapshot (“Arbel.vdi” in the above screenshot) by discarding the base snapshot: open the “Snapshots” tab for the VM whose state you want to clone, select the first snapshot “Old State A” and choose “discard” from the toolbar. What really happens is that VirtualBox pretends to remove “Old State A” but it actually removes “Old State B” after copying all the changes in “B” back into “A”. You now have a base snapshot which contains the state in “Old State B” which you can clone. Do note though that in VDI file terms, the VDI file for “Old State B” (4e1f756e-f158-4c07-bc9a-20261f574730 above) was removed and you need to clone the base VDI, like this:
$ VBoxManage clonehd .VirtualBox/HardDisks/Arbel.vdi .VirtualBox/HardDisks/new-old-state-b.vdi -format VDI -remember
Now you can create a new VM with the “new-old-state-b” VDI as the boot hard disk.
What happened to “Old State A”? Its gone – not there any more. If you want to keep it in case you want to base a new set of snapshots on that, you have to clone it first before discarding it (for the cost of the whole disk space it took, of course).
I do wish though that VirtualBox would offer the ability to manage a tree of snapshots it would make the whole situation much more convenient to work with for QA purposes, and I believe they will offer this capability in the near future as most of the infrastructure seems to be already in place (including the UI to display it 🙂 ). Another tiny feature that I’m missing from VMWare Workstation is “VM groups” to make it easier to manage many VMs – but that is a different story altogether.
Starting with version 3.1, VirtualBox does support a tree of snapshots – it will let you boot to any intermediary snapshot and take new snapshots from that. Which is more or less exactly what I wanted.
Its not entirely trivial to use: to start a VM from an old snapshot, choose the snapshot to use and select “Restore Snapshot” – VirtualBox will then rebase the “current state” on that snapshot by discarding the old “current state” and “forking” a new “current state” from the snapshot you’ve chosen. You can then start the VM based on this new state.