virtualbox

Shrink a vmdk Virtualbox disk image


VirtualBox is able to compact (reduce the size) of .vdi images but it is not possible with .vmdk disk images. But we can compact .vmdk files if we:

  1. detach
  2. convert to .vdi
  3. compact
  4. convert back to .vmdk
  5. attach again to the original vitual machine

So I tried to shrink my VirtualBox image with this script:

#/bin/bash

VM_PATH=~/VirtualBox\ VMs
cd "$VM_PATH"
VM="$(ls ffnord-example_gc-gw0_* -d -1|head -n 1)"
cd "$VM"
VM_VDMK_NAME="$(ls *.vmdk -1|head -n 1)"
VM_NAME="$VM_PATH/$VM/$VM_VDMK_NAME"

echo reducing size of "$VM_NAME"
ls -lah "$VM_NAME"
set -x
vboxmanage showvminfo "${VM}"
vboxmanage storageattach "${VM}" --storagectl SATA --port 0 --device 0 --type hdd --medium none
vboxmanage clonehd --format vdi "${VM_NAME}" /tmp/VM-disk.vdi
vboxmanage closemedium disk "${VM_NAME}" --delete
vboxmanage modifyhd /tmp/VM-disk.vdi --compact
vboxmanage clonehd --format vmdk /tmp/VM-disk.vdi "${VM_NAME}"
vboxmanage closemedium disk /tmp/VM-disk.vdi --delete
vboxmanage storageattach "${VM}" --storagectl SATA --port 0 --device 0 --type hdd --medium 4/VMs/VM-disk1.vmdk

I adapted this script from crysol but it seems this is not working on Ubuntu? The first vboxmanage storageattach starts with an error right away:

VBoxManage: error: Could not find a controller named 'SATA'

If I try "SATA Controller" instead:

vboxmanage storageattach "${VM}" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium none

I get this error:

VBoxManage: error: No storage device attached to device slot 0 on port 0 of controller 'SATA Controller'
VBoxManage: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component SessionMachine, interface IMachine, callee nsISupports
VBoxManage: error: Context: "DetachDevice(Bstr(pszCtl).raw(), port, device)" at line 381 of file VBoxManageStorageController.cpp

If I comment out those vboxmanage storageattach lines, the script works fine, but the resulting VM is the same size as before and it doesn't boot anymore.

This is the output of vboxmanage showvminfo "${VM}"


Solution

  • I found a solution:

    First inside the VM fill all free space with zeros:

    cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill
    

    In your Host, install vmware-vdiskmanager from the VMware Knowledge Base:

    cd /tmp/
    wget http://kb.vmware.com/selfservice/viewAttachment.do?attachID=1023856-vdiskmanager-linux.7.0.1.zip&documentID=1023856
    unp 1023856-vdiskmanager-linux-7.0.1.zip
    mv 1023856-vmware-vdiskmanager-linux.7.0.1 /usr/bin/vmware-vdiskmanager
    chmod +x /usr/bin/vmware-vdiskmanager
    

    Take care, that you have enough free disk-space before you start, you need the MV grows to double size during the process.

    Then compress it with:

    /usr/bin/vmware-vdiskmanager -k ~/VirtualBox\ VMs/<virtual disk.vmdk>
    

    Source