[Continuing a discussion from IRC so we have a permanent record]
We want to shrink a disk image using virt-resize. Shrinking is harder
and not really documented. It requires some manual calculations too.
Here is the original:
$ virt-df -a 209e6911-fe48-4321-900f-928b3400df88
Filesystem 1K-blocks Used Available Use%
209e6911-fe48-4321-900f-928b3400df88:/dev/sda1
51564664 8000404 40943880 16%
$ virt-filesystems -a 209e6911-fe48-4321-900f-928b3400df88 --all --long
Name Type VFS Label MBR Size Parent
/dev/sda1 filesystem ext4 cloudimg-rootfs - 53678177280 -
/dev/sda1 partition - - 83 53678177280 /dev/sda
/dev/sda device - - - 53687091200
The first question was: Why doesn't the filesystem Size in
virt-filesystems match the 1K-blocks field in virt-df? That's because
the 1K-blocks field in virt-df doesn't include filesystem metadata
overhead (more accurately: it depends on the filesystem and different
fses will report slightly different things for this field). The
virt-filesystems Size field is reporting the entire, true size of the
partition.
My observations are: (1) There's plenty of scope for shrinking. Note
that Use% is just 16%. (2) There's only one filesystem, no swap or
boot partitions, and that makes the calculations easy.
To shrink down to, say, 1/2 of the original size, total device size of
53687091200 / 2 == 26843545600 bytes (25 GB).
As there is always some filesystem overhead, you'll need to shrink the
filesystem by a bit more than 1/2. I would shrink it down to 20 GB
(which is still well over 16% of the original).
Start the guest up in virt-rescue:
virt-rescue -a 209e6911-fe48-4321-900f-928b3400df88
[... boot messages ...]
<rescue> resize2fs /dev/sda1 20G
<rescue> sync
<rescue> exit
Now after that, it should be possible to run virt-resize:
rm -f output.img
truncate -s 25G output.img
virt-resize 209e6911-fe48-4321-900f-928b3400df88 output.img \
--shrink /dev/sda1
Note (1) The shrink path of virt-resize isn't well tested at all, so
you might hit bugs. If you do, run it again with --debug and file a
bugzilla.
Now (you can check with virt-filesystems) you should have 'output.img'
which has one partition that is just under 25GB, but contains a 20GB
filesystem. You can now *expand* the filesystem on /dev/sda1 to
occupy the full space:
virt-rescue -a output.img
<rescue> resize2fs /dev/sda1
<rescue> sync
<rescue> exit
Note (2) The virt-rescue steps could also be done using guestfish (or
the API) which is especially useful if you wish to automate any of this.
Note (3) There's an entirely different way to think about this, which
is also much easier. Make the file sparse (or use qcow2 or LVM thinp),
using virt-sparsify. It'll save MORE disk space ...
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top