When working with a virtualised server I came across an issue. The virtual server kept going into a suspended state.
I noticed that the 2 virtual disks for the VM had managed to outsize the total available physical disk space on the host server. This was causing the server to be automatically suspended due to a lack of space on the host. This had been caused by a miscalculation in the maximum size of the dynamically expanding VHD’s.
When each VHD for the server was setup, it was given a maximum disk size it could expand to. However, the second VHD which holds all the data had been expanded since its original creation causing the total size of both VHD’s to be more than the total available physical disk space on the host server.
As these disks were dynamically expanding this didn’t become an issue until the VHD’s started to fill to capacity and expand to their maximum size. As there wasn’t enough physical disk space when they started to reach maximum capacity the virtual server was suspended.
The first thought is to try and reduce the amount of data on the virtual drives to try and free up some physical space. But when the VM is suspended because of a lack of disk space this can be tricky and doesn’t always solve the issue, at least not in the long term.
You can also try compacting the VHD’s which can be very effective as it removes any blank, unused space that the VHD is still holding. The problem is, where the VHD is at or approaching its maximum size there may not be a lot of blank space to free up. It also means that when you boot the virtual machine up again it could just swallow that freed space right back up! The end result is that we want to stop this happening again and somehow shrink the maximum VHD size. As you can’t shrink a dynamically expanding VHD (at least not easily and certainly not in Hyper-V Server 2008) you need a work around.
The easiest work around this is to shrink the disk volume in the VM itself so that it can no longer reach its maximum disk size.
The first step was to shut the server down and move the virtual hard disks to a drive with enough space to hold their combined maximum disk sizes. This is ideally an internal drive but if like me you didn’t have that option use an external drive. A USB 3.0 drive connected to a USB 3.0 port would be best due to a much faster transfer rate but unfortunately I only had USB 2.0 ports to work with!
(As always make sure you take some kind of backup of your VHD’s!)
Next copy the VHD’s to the chosen drive and then point the virtual machine at the new location (Depending on the size of the VHD’s and the transfer rate this can take a long time). This is done by selecting the VM in Hyper-V Manger and then clicking ‘Settings. . .‘ down the right hand side:
Next select the ‘Hard Drive‘ in the list on the left hand side and then click ‘Browse. . .‘:
You will then be able to navigate to the new VHD location and select it. Repeat this process for any VHD’s you have moved for this virtual machine.
Once this is done boot the virtual machine and wait for it to finish starting up. If like me, you had to use USB 2.0’s you will find that the machine is very slow due to the poor transfer speeds. Hence why an internal drive would be a lot better for this!
Next in the VM itself run a disk defragmentation to move data and clear up some free space. Once this has finished we need to download a little application called ‘sdelete.exe’, which can be found here.
This application is run from command line inside the VM itself and writes 0’s over any free space in the VHD. This will effectively make sure that any free space in the VHD is actually free and not still containing any old fragments of data that might stop the next steps from being effective.
Download the application and copy it into the VM. Navigate to it in command prompt opened as administrator:
The syntax for ‘sdelete.exe’ is as follows:
sdelete.exe -Z E:
‘E:’ is the drive you would like sdelete.exe to process.
Do this for any drives you wish to shrink.
Once this process has finished we next need to load up Disk Management. In here we are going to shrink any VHD’s who’s maximum size is too large.
Choose the disk you would like to shrink, right click and select ‘Shrink Volume’. Once the system finishes calculating how much you can shrink it by you will be displayed with a box like this:
Next work out how much you would like to shrink it by. I needed to save 15GB when I first did this as the total maximum size of both VHD’s was about 10GB more than the physical disk space I had available. (-10GB so that it would fit back on the physical disk and -5GB for a safety buffer = -15GB)
I entered this in MB’s and clicked shrink. Once this has finished you will see that in ‘Disk Management’ next to the disk you just shrunk, you will now have a chunk of unallocated disk space.
Now we have done all that we can shut the VM down and look at compacting any disks that we have just shrunk. First we need to open Hyper-V Manger and on the right hand side click ‘Edit Disk. . .‘:
Click ‘Next‘:
Next click ‘Browse. . .‘:
Navigate to the VHD you want to compact, highlight it and click open. Then click ‘Next‘:
Select ‘Compact‘ from the 3 options and click ‘Next‘:
On the summary page click ‘Next‘:
Now wait for the process to finish:
Once this has completed you should notice that the size of your VHD has shrunk a good amount. Repeat this process for any other VHD’s you need to compact.
Previously if we compacted the VHD’s they either expanded again when we booted them up due to the VHD’s being full with data or they didn’t shrink as much as we needed. This was because file fragments were still located in what is seen as free space. This stops the compacting process from fully reducing the size of the VHD as it would avoid freeing up these areas. This is the reason for ‘sdelete.exe’, it effectively flattens the free space so that it contains no data. Along with this and having shrunk the volume size in the VM itself the VHD can no longer expand to its maximum size.
As we are now happy with our new VHD drives we can look at moving the VHD’s back over to their original store.
First we need to delete the old VHD’s in the original location and then copy the new VHD’s back over. Once this is done change the settings for the virtual machine in Hyper-V Manager to point to the new location. (The same process we did at the beginning)
And that’s it! You can now boot the VM as normal without the risk of it expanding larger than the physical disk space available.