VMware Workstation: how to reduce .vmdk maximum size
Solution 1:
The usual procedure for reducing the size of a .vmdk disk is to:
Defragment the disk via the guest, choosing a defragmentation mode that consolidates empty space at the end of the disk. For a Windows guest, you should empty the Recycle Bin and turn off hibernation and paging, returning them after the defragmentation is done.
Zero all unused space on the disk.
For Windows use sdelete :sdelete -c
.
For Linux :dd if=/dev/zero of=/mytempfile && rm -f /mytempfile
.Shrink the disk (which may take quite a long time to complete).
VMware Workstation : Menu VM / Manage / Clean up disks.
Or use :vmware-vdiskmanager.exe -k [VMDK PATH]
.
for ESX :vmkfstools --punchzero [VMDK PATH]
.
Converting the disk from growable to preallocated could stop its growing.
This can be done using vmware-vdiskmanager with the -t
parameter whose values are:
0 : single growable virtual disk
1 : growable virtual disk split in 2Gb files
2 : single preallocated virtual disk
3 : preallocated virtual disk split in 2Gb files
The following command will convert the .vmdk from growable to preallocated :
vmware-vdiskmanager -r current_disk_name.vmdk -t 3 new_disk_name.vmdk
If you wish to change the size of the disk, this should be done while the disk is still in growable format (examples here).
For more information see the Virtual Disk Manager User’s Guide.
Solution 2:
The file is currently 20GB, but it is growing everyday, even though I'm not storing anything new in the guest file system.
Because the OS and its application programs temporarily use lots of disk space for temporary files, page files, hibernate file and config files. Once they get deleted depending on the policy of the OS new sectors on disk are used at the next time. The VM allocate storage for the virtual disk from real disk whenever a new sector is used in the virtual disk. As the sector on virtual disk are always not reused by guest OS the VM thinks its a disk usage and give space from real disk and this will lead to growing virtual disk image.
Your question title is less likely to be solved as using such a tool without inspection of image may lead to total disaster. But you can prevent growing of the image beyond 30GB. There are many way to achieve the goal.
A. Use only 30GB partitioned and leave remaining as free space. If you already partitioned more space then you need to shrink/delete it, the create a new partition then dump it with zeros and punch it as described by @harrymc . As the space in unpartitioned area is never used virtual disk will never grow beyond 30GB.
B. Create a snapshot and restore to it after usage. After creating snapshot VM store data into a new image file. If you restore to it, without saving or making new snapshots, all changed data is deleted and thus space is freed.
C. Create a new virtual disk of maximum 30GB, add it as a new disk into your current virtual machine, move all data to the new virtual disk using a backup tool. You may use a live Linux for the cloning.
Recommended option is A
Solution 3:
The answer of @harrym is pretty good, but it actually does not answer the question. The OP wants to reduce the maximum size. The problem is the hypervisor does not know how much of the presented size (aka maximum size) is indeed used by the OS. The compaction (vmware-vdiskmakager -k) applies to a growable vmdk. It does nothing on preallocated one's.
So the steps to shrink the disk are:
- Resize the partition on disk via the OS, or via a suitable live CD
- Resize the vmdk device, carefully choosing the boundary not to cut any usable partition space. You can always leave some more space in the imnage than it is actually needed.
The first step involves a procedure from within the VM and varies with guest OS. The second step could be supported by the vmware commands but I haven't found a profound way of doing so. Thus the hacky approach.
Here is a non so quick (due to large data moving involved) and dirty solution that did the trick. We will need to have available space equal to the maximum device size.
WARNING: Remember to backup important data before any operation !!
-
Find a way to resize the guest partition and leave unallocated space at the end of the device. Two examples:
From the guest OS: windows 7
- You can use the online resizing capability. It's a good idea to first defragment the disk from within the quest OS.
- Run diskmgmt.msc, select the partition(volume) on the disk you want to resize, right click->Shrink volume. In the dialog that appears reduce the size as per your requirements. Note that since the partition is in use (if it is the system disk, or heavily fragmented) you might not be able to recover most of your free space. Provision to leave extra free space.
- Now we want to know the partitions ending disk sector (or byte). Assuming this is the only partition on the device, we take the size of the volume as displayed on my computer->select disk->right click->properties->Capacity: Note the number in bytes. (e.g. in my example 107371032576 for 99,9GB). Add some hundred megs for safety (+204800) (e.g. 107371237376). To be sure that we do not need to add anything missing, we can use the diskpart cmd line utility to find the partition's offset from the start of the device. run diskpart then: list disk, select disk id, list part, select part id, detail. Example:
DISKPART> detail part
Partition 1
Offset in Bytes: 1048576
Make sure you add at least this number to the disk size. Now we need convert the bytes to sectors dividing by 512 and rounding upwards (ceiling). E.g. 209709448. Note this number for step 3.
Via a live cd: SystemResqueCD
- Alternatively you can use an resque cd, (SystemResqueCD is my proposal), download bootable ISO, mount it as a virtual cd rom device on you VM, boot from CD (by pressing Esc key on the VMWare boot screen, you might need to try some times as it appears very shortly). When reaching command prompt type: startx, this will hopefully bring you to graphical interface.
- Once on the systemresque's desktop, start gparted (e.g. from a terminal). Find the partition to be resized (this must be cleanly unmounted, if in doubt do a scandisk from the guest operating system). Do the resize, carefully planning your space needs.
- Again we need to find the ending offset in sectors (or bytes) of the partition. Open terminal and write parted [device], then unit s, print. E.g.
Number Start End Size Type File system Flags
1 2048s 113455103s 113453056s primary ntfs boot
Note the ending sector and add 1. E.g. 113455104. Note this number for step 3.
-
As the hack works on single file preallocated (type 2) vmdks (haven't tried on multiple file types) we first convert the growable to preallocated. We will temporarily need a partition with physical space as the maximum size of the device. (e.g. 150GB).
vmware-vdiskmanager.exe -r sourcevmdk -t 2 destvmdk
-
Now the tricky part, for the preallocated disk there should be 2 vmdks
disk.vmdk disk-flat.vmdk
the former being only KB long, and the latter holding the data extends. Open the first (disk.vmdk) while VMWare workstation is off, whith a text editor (Notepad++ being my suggestion). Find the line
RW 113455104 FLAT "Windows 7_x64-fl-flat.vmdk" 0
Yes you get the point, the second field is the number of sectors allocated for the device. As a validation multiply by 512 and find the size in bytes, then divide by 1073741824(1024**3) to find size in GB. This should be the previous device's size.
Now replace that number with the noted number from step one and save the file. WARNING: A mistake here and you could end up trimming actual data used on the filesystem. (But we resized the fs on the beginning of the device and made correct and safe calculations right? )
-
Until now no data have been touched yet. Do this final step to actually trim the extends. We will use the rename functionality of vmware-vdiskmanager to recreate the vmdk with it's size now trimmed.
vmware-vdiskmanager.exe -n destvmdk sourcevmdk
Solution 4:
Why not simply set the size of the disk involved to 30GB from 150GB.
You'll have to set the sum of all partitions to be less than 30GB. You'll have to shrink the sizes of the partitions down as you go. There is a LOT of documentation on this site on how to shrink partitions down so I will not repeat this here AGAIN.
Why did you create a 150GB (thin partition) if you did not have the space to support it at maximum size? Seems like this is just asking for trouble.
Solution 5:
There is a roundabout way of using VMWare Converter to create a new VM and smaller VMDK size, then convert the original VMDK to the newly created, smaller VMDK.
Detailed steps here.
Note that any changes to the VMDK size will also need a corresponding update to the partition table.