Resize ext3 in LVM in partition in (KVM/QEMU) virtual image file
I started out with a virtual machine image that was 10GB in size. Within this are two partitions - the first a few hundred MB for /boot and the rest is a LVM partition. The LVM then contains swap, root and /home. In this particular case I needed to make /home bigger, I actually needed an extra couple of GB but thought I may as well add 10GB for good measure. This post is just a record of the process/commands I used to do this, along with a few notes.
For this to work, you have to be working with a RAW format image file. For me, this is what I started with, but if you need to convert to RAW, this is how:
$ qemu-img convert -O raw old_image.qcow new_image.raw
If you haven't just converted your image file and hence don't have a spare copy as the original, I suggest you make a backup of your image before you continue!
$ cp old_image.raw new_image.raw
First off, you need to extend the image file itself, hopefully you're on a system that allows sparse files, so this wont actually take any extra space:
$ dd if=/dev/zero of=new_image.raw seek=20G obs=1 count=0
obs=1 you can set the
seek= to be your target image size. I started with 10GB and wanted to add another 10, so I've set
Next is extending the partition that contains LVM. In theory you can use fdisk directly on image files, but in this case it didn't work for me, so an easy solution was to attach the image to a loopback device:
$ sudo losetup /dev/loop0 new_image.raw
Next up is fdisk:
$ sudo fdisk /dev/loop0
Here you want to delete the existing partition and re-create a larger one in it's place. It's important that the new partition starts in exactly the same place as the old one. For me, this was nice and easy - just delete the second partition and create a new one using the defaults, then save and quit. My commands were (I included a couple of "p"s to verify where I started and finished):
p d 2 n p 2 <enter to accept default> <enter to accept default> p w
We're done with fdisk, so now the loopback device can be cleared:
$ sudo losetup -d /dev/loop0
Now you want access to the partitions within the image file, so that you can get at LVM to resize it:
$ sudo kpartx -av new_image.raw
This should show each of the partitions within the image and which loopback device they've been mapped to. For me, the interesting one was the second partition which got assigned to /dev/mapper/loop0p2.
There are a couple of bits that need resizing in LVM, the first is the physical volume. The default action of pvresize is to resize to consume all available space, so all that's needed is:
$ sudo pvresize /dev/mapper/loop0p2
To resize the logical volume I looked up the number of extents that were now free and used this number in my lvresize command (the number after -l). If you don't already know the name/device of your LV, you'll also want to run lvdisplay to find it.
$ sudo vgdisplay $ sudo lvresize -l +2559 /dev/virt-machine/home /dev/mapper/loop0p2
Nearly there now. The image file, partition and LVM are done. Just the actual file system left. For me this was ext3, so pretty simple to extent to the full LV, just need to fsck and resize:
$ sudo e2fsck -f /dev/virt-machine/home $ sudo resize2fs /dev/virt-machine/home
That's it! Everything should be resized. The only thing left is to tidy up and get rid of the loopbacks you created early. First you have to deactivate the LVM volume group, then you can remove the loopback devices:
$ sudo vgchange -a n virt-machine $ sudo kpartx -d new_image.raw
Now fire up the virtual and enjoy the extra space.