Multiple snapshots in VMware Player

I've seen numerous posts on the web by people asking whether it is possible to keep multiple virtual machine snapshots with VMware Player. The usual answer to this question is “no”. It is true that VMware Player doesn't offer this functionality by itself, because VMware sells this in their commercial products. It is, however, very easy to implement VMware Player snapshots using a source code management system, such as Subversion or git. In the rest of this article I will briefly demonstrate how to do it with svn using an example Fedora virtual machine on one of my Linux boxes.

A word of caution: Please note that this is not a commercial one-click solution for all your problems. If you intend to use this method for jumping back and forth in time between your virtual machine snapshots, you will most probably run into conflicts while trying to commit some of your changes with svn. This means you may easily lose your data if you don't know what you are doing. Use at your own risk!

Preparing the repository and a working copy

To keep track of changes we make to our virtual machine, we first need to create an svn repository. Assuming our repository will reside in /vm/repo/Fedora, we make sure the directory /vm/repo exits and then execute svnadmin to initialize an empty repository:

$ mkdir -p /vm/repo
$ svnadmin create /vm/repo/Fedora
$ █

The repository we created in /vm/repo/Fedora will hold all the snapshots of our virtual machine. However, since svn stores the data in the repository in its own internal format, we cannot access it directly. We need another directory to store a working copy of our virtual machine. Creating a working copy in /vm/work is performed by running svn checkout from our empty repository:

$ mkdir /vm/work
$ cd /vm/work
$ svn checkout file:///vm/repo/Fedora
Checked out revision 0.
$ ls -F
Fedora/
$ █

The initial snapshot

The initial snapshot is very important, because it will serve as a reference for all future snapshots we are going to make. I am using a virtual machine with a fresh installation of Fedora 15, which is stored on an external USB drive in /usbdisk/Fedora15. Let us first copy the contents of this directory to our working copy /vm/work/Fedora, then tell svn to schedule it for addition to the repository:

$ cp -r /usbdisk/Fedora15/* /vm/work/Fedora
$ cd /vm/work/Fedora
$ svn add *
A  (bin)  Fedora.nvram
A  (bin)  Fedora-s001.vmdk
A  (bin)  Fedora-s002.vmdk
A  (bin)  Fedora-s003.vmdk
A  (bin)  Fedora-s004.vmdk
A  (bin)  Fedora-s005.vmdk
A  (bin)  Fedora-s006.vmdk
A  (bin)  Fedora-s007.vmdk
A         Fedora.vmdk
A         Fedora.vmsd
A         Fedora.vmx
A         Fedora.vmxf
$ █

Now everything is ready, and we can fire svn commit to store the initial snapshot of our Fedora virtual machine to the repository (please note that this takes some time, which is a nice opportunity to grab a cup of coffee or tee):

$ svn commit -m 'Fedora initial state'
Adding  (bin)  Fedora-s001.vmdk
Adding  (bin)  Fedora-s002.vmdk
Adding  (bin)  Fedora-s003.vmdk
Adding  (bin)  Fedora-s004.vmdk
Adding  (bin)  Fedora-s005.vmdk
Adding  (bin)  Fedora-s006.vmdk
Adding  (bin)  Fedora-s007.vmdk
Adding  (bin)  Fedora.nvram
Adding         Fedora.vmdk
Adding         Fedora.vmsd
Adding         Fedora.vmx
Adding         Fedora.vmxf
Transmitting file data ............ this takes some time
Committed revision 1.
$ █

Disk space calculation

Virtual machine snapshots are expensive in terms of disk space they occupy, and we should keep this in mind all the time. Checking disk space after each snapshot (i.e. commit) is a good way to acquire some sort of a feeling for this. It is also useful to compare the space occupied by the “raw” virtual machine inside the working copy to the space occupied by a snapshot in the repository:

$ du -sk /vm/repo/Fedora
736200  /vm/repo/Fedora
$ du -sk --exclude='.svn' /vm/work/Fedora
2240648 /vm/work/Fedora
$ █

The size of the repository is around 720MB, which is one third of the total size of the working copy. It is great to know that svn saves quite a bit of disk space by compressing binary files it stores to the repository.

Notice that we excluded the .svn directory from the calculation of the working copy disk usage. This is because the contents of .svn aren't really needed during normal operation of our virtual machine and don't have to be there all the time. The .svn directory is only required by the svn command for making snapshots (i.e. commits), and for that purpose we can always rebuild it from the repository with svn checkout.

Snapshot 2 – After installing Inkscape

To see how svn snapshots work, let us make some changes to our virtual machine and then take another snapshot. We boot Fedora 15 inside VMware Player and once it is up and running, we install Inkscape from the web, then shut Fedora down.

Back on our host Linux system, we check to see what has changed. The first thing to verify is the new size of the working copy:

$ du -sk --exclude='.svn' /vm/work/Fedora
2506568 /vm/work/Fedora
$ █

We can see that the size of our virtual machine has grown from 2188MB to 2448MB, which corresponds to an increase by 260MB. Running svn status reveals that six files have been modified:

$ svn status
M       Fedora.vmdk
M       Fedora-s001.vmdk
M       Fedora.nvram
M       Fedora-s002.vmdk
M       Fedora-s003.vmdk
M       Fedora.vmx
$ █

Again, we take a snapshot by committing the changes with svn:

$ svn commit -m 'Fedora after installing Inkscape'
Sending        Fedora-s001.vmdk
Sending        Fedora-s002.vmdk
Sending        Fedora-s003.vmdk
Sending        Fedora.nvram
Sending        Fedora.vmdk
Sending        Fedora.vmx
Transmitting file data ...... coffee again?
Committed revision 2.
$ █

At this point it is interesting to check how much space the new snapshot has occupied within the repository:

$ du -sk /vm/repo/Fedora
859316  /vm/repo/Fedora
$ █

As you can see, the snapshot uses an additional 120MB of space in the repository, which is less than 50% of the additional size occupied by the virtual machine itself.

Snapshot of a suspended VM

One particularly useful feature of commercial VMware products, is taking “online” snapshots while the virtual machine is running. Unfortunately, we cannot do this safely with svn, so the only thing which remains is to first suspend the virtual machine, then take the snapshot. The process is exactly the same as with a powered-off virtual machine.

To demonstrate how this works, I launched VMware Player, booted into Fedora again and then ran Inkscape. In Inkscape, I drew a couple of simple shapes and then ran a simple calculator. At this point, while both applications were running, I instructed VMware Player to suspend our virtual machine. Once the machine has been completely suspended, we are ready to proceed with a new snapshot:

$ svn status
?       Fedora.vmem
?       Fedora.vmss
M       Fedora.vmdk
M       Fedora-s001.vmdk
M       Fedora.nvram
M       Fedora-s002.vmdk
M       Fedora-s003.vmdk
M       Fedora.vmx
$ █

As indicated by svn status, there are two new files named Fedora.vmem and Fedora.vmss. According to the official documentation Fedora.vmem is the virtual machine's paging file and Fedora.vmss stores the state of a suspended virtual machine. Having this in mind, it is no wonder that the overall size occupied by our virtual machine has grown significantly:

$ du -sk --exclude='.svn' /vm/work/Fedora
3265340 /vm/work/Fedora
$ █

If you compare this to the size of a powered-off virtual machine, you will notice that suspending a running virtual machine with Inkscape and a calculator has costed us some 740MB of disk space. To proceed with the new snapshot, we first have to add the two new files to version control, then we can commit the changes:

$ svn add Fedora.vmem Fedora.vmss
A  (bin)  Fedora.vmem
A  (bin)  Fedora.vmss
$ svn commit -m 'Fedora suspended with Inkscape and calculator'
Sending        Fedora-s001.vmdk
Sending        Fedora-s002.vmdk
Sending        Fedora-s003.vmdk
Sending        Fedora.nvram
Sending        Fedora.vmdk
Adding  (bin)  Fedora.vmem
Adding  (bin)  Fedora.vmss
Sending        Fedora.vmx
Transmitting file data ........ even more coffee ...
Committed revision 3.
$ █

The new size of our repository is:

$ du -sk /vm/repo/Fedora
1111292 /vm/repo/Fedora
$ █

This time the snapshot has occupied an additional 245MB of disk space.

Going back in time – Reverting to a snapshot

Now that we have multiple snapshots of our Fedora virtual machine sitting in the repository, reverting to any particular of them is trivial. It is usual to first execute svn log in order to obtain a list of all snapshots:

$ svn log
------------------------------------------------------------------
r3 | kenan | 2011-10-11 14:27:28 +0200 (Tue, 11 Oct 2011) | 1 line

Fedora suspended with Inkscape and calculator
------------------------------------------------------------------
r2 | kenan | 2011-10-11 14:06:00 +0200 (Tue, 11 Oct 2011) | 1 line

Fedora after installing Inkscape
------------------------------------------------------------------
r1 | kenan | 2011-10-11 12:05:16 +0200 (Tue, 11 Oct 2011) | 1 line

Fedora initial state
------------------------------------------------------------------
$ █

Commit messages are a great help in identifying the snapshot we want to revert to. Once we have found our snapshot, running svn update restores it into the working copy:

$ svn update -r2
D    Fedora.vmem
D    Fedora.vmss
U    Fedora.vmdk
U    Fedora-s001.vmdk
U    Fedora-s002.vmdk
U    Fedora.nvram
U    Fedora-s003.vmdk
U    Fedora.vmx
Updated to revision 2.
$ █

The virtual machine in our working copy has now been reverted to the snapshot #2 (i.e. Fedora after installing Inkscape).

Where to go from here

This article introduced just the basics of using source code management systems for making virtual machine snapshots. The rest pretty much depends on your creativity, imagination and knowledge. Here are some things you may want to try:

• • •