Pither.com / Simon
Development, systems administration, parenting and business

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

With 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 seek=20G.

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.

Comments

On Aug. 18, 2010, 3:23 a.m. Cloud said...

Awesome post, thanks so much for putting it so clearly!!

I'm getting hung up on the e2fsk/resize2fs step though, "bad magic number in superblock" against /dev/VolGroup01/LogVol01 (which I guess makes sense since it's not the first partition).

Ideas?

On May 13, 2011, 10:09 a.m. Miba said...

Wonderful tutorial, but I was (like Cloud) stuck on the same step!!! e2fsck failed to run... After hours of searching I finally found the problem and solution...

Just BEFORE you type "e2fsck...", you just type in the command "$ vgchange -a y" and THEN you do the e2fsck step :D

I noticed that when you do "$ lvdisplay" the "LV status" of the logical volumes of your virtual machines are set to "not available" and so the "$ vgchange -a y" command sets them to "available"... Which allows you to do the e2fsck command...

I hope this will help some other people out...

Cheers

Add a comment