Running Hyper-V virtual machine images off SD card

Overview

I have a Thinkpad carbon X1, and even as a sub 1.2kg ultrabook its surprisingly powerful with 16GB of memory and both VT-d and VT-x support.

The only downside is it shipped with a small SSD.

One option is to swap the SSD, however I already have a 400GB SD card installed which has fast read but slow write speeds.

This led me to investigate if you can run a VM off a SD card.

It turns out you can if you go through a few hoops. The general idea is to create an image on the SD card, but then run a snapshot on the SSD. That way most reads will come of the SD card, but writes will go on the SSD. Every so often you then need to push the changes from the snapshot onto the SD card or else the SSD will fill to capacity.

I set this up and it worked pretty well, but with 2 ongoing pain points:

  • Hyper-V has/had some bugs with snapshot locations.
  • Manually flushing the snapshot becomes tedious.

The first issue was the snapshot feature - even if i specified a separate location for the snapshot, it always seemed to go into the same location as the HD image. my workorund was to create a link from a SSD location to the SD card image. This works well, execept that Hyper-V will change to the destination location whenever you create a snapshot - this means if you delete and recreate a snapshot it will go onto the SD card not the SSD.

My solution was to make a script to take care of it, at a high level it does the following:

  • Shutdown the VM
  • Flush SSD snapshot contents onto the SD card image
  • Fix the HD image path to point to the SSD symlink, not the physical SD card location
  • Re-create the snapshot

This is done with the script below. Note that you need to pass in the vm name and the SSD image link location as arguments.

I call this from a batch file for each VM and run it overnight every few weeks, so far it has worked flawlessly.

Networking however is not flawless in Hyper-V - every few weeks the virtual network bridge decides to switch to NAT mode until you reboot. I suspect this is something to do with suspend/resume.

powershell