Let's say I have linux-vm-image.raw
with size of 10GB. Inside there is one primary ("classical" MS-DOS-like partition table used, not GPT) etx4
partition (no LVM used), extending to the entire volume. And real data allocated on that partition is, for example, 3GB.
This image is prepared to use for some virtualization environment (kvm+OpenStack in my case), and any VM created from this image would resize itself to target virtual disk size, depending on user's choice. So there are no reasons to keep any free diskspace inside of that disk image.
How could I shrink size of this raw disk image to minimal (from 10GB to ~3GB)?
There are some instructions for qcow2
disk images, but I have to use raw
images only - not qcow
, not OVF
and not others.
My guess is somethink like
- mount this image somewhere as a block device
- do some maintenance to have all files inside of ext4 partition moved to "beginning" of it, another words - do a freespace defragmentation
- unmount image
- minify size of filesystem into image (to match the size of data inside of it)
- minify size of image (to match the size of filesystem inside of it)
- update partition table into image to match new partition size
But don't I try to invent a bicycle? Is there some one-line command or special software to do what I want?
Raw images are not really resize-friendly. You can however try
zerofree
on (unmounted) filesystem and then compress the resulting image file.Also, check if your target environment supports OVF container format, which allows for compressed disk images. (zerofree still applies).
You're on the right track. If you can mount it as a block device (loop mount), you can probably get gparted to work on it.
gparted will do the bulk of what you want:
1. move FS data to the front of its partition (shrink FS)
2. shrink the partition and adjust the partition table
3. it may even be able to give you the remaining "disk" size when you have it print the updated partition table (e.g. last sector of last partition, etc.).
That's the hard part. After that, unmount it. You may have to calculate the exact size things of your "disk" by hand, but after that, a simple truncate on the file should do it.
UPDATE: If your partition table is MBR type, you're fine. With GPT, it has a mirror copy at the end of the disk. So, be careful with that as gparted may not be smart enough for that (unless you can give it the raw image directly). If you have trouble, consider gdisk as a step after the truncate. Truncate with a few extra blocks and get gdisk/equiv to rebuild the mirror copy (probably will need to loop mount a second time).