I want turn a physical machine running MS Windows 7 into a VirtualBox virtual machine. This is easy, I have done this before, but this time I needed the virtual size/capacity of the disk to be a fixed and smaller size.
It needs to be fixed because I will install PGP disk encryption on it for compliance reasons. This will expand a dynamic disk to it maximum size.
Aside from this special case there are other reasons for wanting disks to be smaller and fixed. Is my experience. If you run for example a Jenkins build server on a dynamically expanding disk you could see the disk expanding quickly to its maximum size while in the guest OS disk space usage is stable and there is lots of free space.
Using Disk2vhd I have created a vhdx file. This file I converted to vdi format.
vboxmanage clonehd --format VDI MSWIN7.VHDX MSWIN7.vdi
Purportedly with vdi you could decrease virtual size/capacity with commands similar to
vboxmanage modifyhd MSWIN7.vdi --resize 160000
I found that this doesn't work. Even if you try variants you will consistently get error messages like:
Progress state: VBOX_E_NOT_SUPPORTED VBoxManage: error: Resize hard disk operation for this format is not implemented yet!
Below is the disk layout of my vdi disk. I added this to a Ubuntu VM to look at it using Gparted and CloneZilla. Capacity is around 300GB. Unallocated 145GB. Used is around 153GB.
I want to shrink capacity to around 160GB. This should be enough to fit /dev/sdb1
and /dev/sdb2
.
BTW, I tried CloneZilla but it also does not seem to like to shrink the capacity to a smaller disk. I tried various settings in CloneZilla but no success.
How can I decrease virtual size/capacity?
Deallocate space at the end of disk in guest OS, where space >= size(source-disk) - size(new-disk). Typically by shrinking last partition.
Turn off virtual machine.
Create new Virtual Box disk with desired size.
Move content from old disk to inside new disk:
Turn on virtual machine.
You may have to resize partition in guest OS to fill the rest of the disk depending of the space deallocated on step 1.
In the end I managed to solve this puzzle in a unexpected easy way using the preinstalled command line utility
dd
see Disk Cloning. As shown below I now have my 160GB drive in my guest OS stored in a 160GB fixed VirtualBox vdi file.I solved it using following steps:
MSWIN7.vdi
with MS Windows 7 to a Ubuntu VM as a second disk./dev/sda1
with the running Ubuntu VM,/dev/sdb2
with the sourceMSWIN7.vdi
and/dev/sdc1
with the new vdi./dev/sdc
. CloneZilla did this for me. It did not copy data but it did create the partitioning I wanted. Of course you can do this manually.sdb
tosdc
withdd
command similar tosudo dd if=/dev/sdb of=/dev/sdc
. The command ends with a no space left error message, that is expected. This I ignored because this is just unallocated space that it failed to copy.I think it is possible to run the command for each partition. Maybe it is better and will not show an error message.
sudo dd if=/dev/sdb1 of=/dev/sdc1
andsudo dd if=/dev/sdb2 of=/dev/sdc2
.In my case I had a windows VM with 50GB vdi to shrink to 20GB.
I have tried Andre Figueiredo solution but I had a problem with the cloned
vdi
.When I apply Andre Figueiredo solution and attach the shrinked
vdi
to the VM, while booting, Virtualbox stops with I/O error.Perhaps this is related to my
btrfs
filesystem (I heardbtrfs
causes problems with Vritualboxvdi
).My solution:
I tried a different solution in order to shrink the VM disk (
vdi
), named OVdi, (OVdi has disk size of 50GB, single ntfs partition with 40GB free space).Let's follow these steps (this is my case, you can adapt/invent different vdi names):
stop the VM (poweroff)
create a new disk (
vdi
) with name DVdi of desired size (20GB my case..)attach DVdi to the VM
boot VM and install the utility EaseUS Backup Free
Execute EasyUS and use the EasyUS Clone function (it clones OVdi MBR, and the ntfs partition of OVdi by shrinking to new disk DVdi)
Poweroff the VM
Detach OVdi from VM
Check if DVdi is the first boot device for the VM
reboot the VM
Have fun
Don't forget to delete the OVdi volume.
Following these steps I successfully reduced the VM disk size from 50GB to 20GB
I believe this solution is extremely dangerous! It relies upon all the files being in the first 153 GB of the original 300 GB partition. The dd command does not copy files. It simply copies ALL blocks in sequence. Thus, if you were unfortunate enough to have important files AFTER the 160 GB cutoff, dd will not know to copy them.
The typical solution I have seen in many, many posts is to power up the Windows VM and use some combination of defrag tools and administrative tools to consolidate all files to the front of the disk - the difficulty is that many defrag tools do not move unmovable Windows system files (I had to turn off System Recovery to delete a 7 GB unmovable chunk of disk), which are somewhere in the middle of the space you are trying to consolidate.
Once you have consolidated files to front of disk (MyDefrag is a freeware tool that provides a display of where on disk your files are), you must reduce the size of your Windows partition. I used the diskpart tool with the shrink option.
At this point, you can use dd to copy the now smaller partition to a new vdi.
I have also used vboxmanage modifymedium win10.vdi --compact, on my Linux host, but I first had to run sdelete.exe within the Windows system to zero out all the unused space first (sdelete -z c:). Using vboxmanage to compact the existing vdi file allows you to do everything in-place (but always have a backup).
As others have mentioned, Andre Figueiredo's answer is luck based as there is no guarantee that the "first X gb" of space is your space, unless you defrag, in which case it's still risky.
Paul Hursky's answer is much safer. I will list some extra steps I did (note this is for Windows, mine was XP but it should also work for others) :
1) Get the free edition of "MiniTool Partition Wizard Free 12" in this link
2) Install it inside guest OS and resize your drive, leave some breathing room just to be safe (don't pull it all the way back ..). Since you are most likely resizing the current OS's hard drive, it will give you an option to restart and perform the action, do this.
3) Now using the same MiniTool Partition program, select your now unallocated space (under
*:
) -> Right Click -> Wipe Partition -> Fill Sectors with Zero (Quick).4) Now safely shutdown guest OS. Go to the VirtualBox folder where VBoxManage.exe exists, open cmd in this path and run this:
5) And now it should all magically work. When you next open the guest OS, it will run check disk, LET IT RUN, it finds "orphan files" which looked like system files.
I did the same as @goamn except I used the free version of NIUBI partition editor inside of my windows VM, which allowed me to shrink the C drive partition and then move the free space to the end. After that, you can right click on the empty partition and have 0's written over it. Once that's complete, run the compaction command and you're good to go.