Last year I decided to build a new development server running a number of Virtual Machines. After spending two days hitting myself over the head with OpenSuse + Xen and coming away bloodied and bruised, I decided to give Ubuntu + KVM a go. So far I have been very impressed, everything worked as advertised and I was able to get up and running in no time at all, I think I am an Ubuntu convert…

I originally created my VM with 20GB of disk space under the false impression that my image file would grow automatically as more space was required. After using the VM for sometime I realised that 20GB was not going to be enough and that I was going to need more space. The question was how do I increase the size without having to create the VM from scratch, not a task I relished as I’d spent many hours using the VM and had installed a lot of software and really did not want to repeat the process.

I used Google to search for how I could achieve this thinking that a lot of people would strike this problem and that a solution would be but a few clicks away…wrong! After a lot of searching I found a few articles on how this could be achieved, a lot of them where complicated including having to hack the MBR. After making a backup of my image file, I tried a couple of solutions but they ended up damaging my image file to the point where I could no longer boot the VM.

It’s at this point I started to sweat, I had spent hours installing and setting up software within my VM, I really did not want to have to do it all over again! After a lot of experimentation I found something that works reliably for me, I’m sure there are better ways of doing this (is’nt there always!) but this works for me every time.

DISCLAIMER: Take care in what you do, make sure you have a reliable backup of the VM image before you start. You do this at your own risk, I accept no responsibility if it all goes wrong.

So let’s dive in…

Step 1: Stop the VM

Step 2: Change to the directory where your VM image files are stored, mine is in /kvm/ubuntu-dev/

cd /kvm/ubuntu-dev

Here is what my 20GB file looks like.

Step 3: Backup the image file, my image file is called ubuntu-dev.img. I created a sub-directory called bak where I store my image backup file

sudo cp ubuntu-dev.img bak/ubuntu-dev.img.bak

Step 4: Create a blank qemu file, this is the file we will be adding to our VM image. Create it with a size equal to the amount of extra disk space you want added to your VM. In my case I want to add an additional 30GB of space.

sudo qemu-img create -f raw addon.raw 30G

This is what the addon file looks like on my system after it is created.

Step 5: Rename the original image file to .save as is shown in the image above. We never actually modify the original image file so we end up with two backup files, the .save as well as the backup file we created in Step 3, just in case something goes wrong. When you are sure everything has worked you can always delete these files.

Step 6: We are now ready to combine the image file with the new blank qemu file we created earlier. You need to be logged in as the super user to perform this step.

su

cat ubuntu-dev.img.save addon.raw >> ubuntu-dev.img

Step 7: Once this completes you can check the new file size, my new file size is now 50GB which is my original 20GB + 30GB of extra space.

Step 8: We have successfully increased the size of our image file by 30GB to 50GB, now we need to fix our partitions. To do this you need to downloaded GParted and create a live CD. Once you have created the CD and loaded into your machine run the following command to start GParted using the new image file.

sudo qemu -hda ubuntu-dev.img -cdrom /dev/cdrom -boot d

The following window should be displayed.

Select the "GParted Live (Default settings)" option or the one appropriate for you. You will then be prompted with a number of setup options, I normally accept the defaults. Once GParted has been loaded you should see your current VM image partitions, here is mine:

The first thing we need to do is delete the swap partition so that the primary ext3 partition is next to the new unallocated space we added, this will allow us to expand the primary partition. Note that the correct device is selected in the top right hand corner, it shows our newly expanded 50GB device.

So select the swap partition and select "Delete", the command will be added to the pending operations list shown in the bottom panel. We can undo all operations until we select "Apply".

Now we can resize the primary partition, select primary partition and select "Rezise/Move" and resize the partition as required. I’m reserving 2GB for the swap partition and allocate the rest to the primary partition.

The last step is to create a new swap partition.

We have now completed all the steps required to re-partition our image. We deleted the old swap partition, resized the primary partition and created a new swap partition. All these steps are listed as pending actions, we can still undo anything at this stage but I’m happy with what I’ve done and select "Apply" to get GParted to make the changes.

GParted will then start making the changes.

Once completed we can see our new partitions, the primary partition is now 48GB in size and we have a 2GB swap partition.

Step 9: Exit GParted and restart your system, my VM automatically starts when the server is restarted. Login to the VM (hopefully everything starts ok). We need to activate the swap file in the new swap partition we created, so once you have logged in start GParted, your new partitions should be displayed.

To activate the swap file, select the swap partition and press the right mouse button. The following popup menu should be displayed, select the "Swapon" option to turn the swap file on.

Conclusion

That’s it we have successfully added and extra 30GB of space to our VM image file. Once you are happy that everything is working you can remove your backup files. I normally keep mine for a little while until I’m 100% sure everything is working as it should.

19 Responses to “HOWTO: Resize a KVM Virtual Machine Image”

Thanks much, your tutorial was very helpful and it worked fine. One problem though: in Ubuntu 8.10, swap is listed by UUID in /etc/fstab, and the newly-created swap partition of course got a new UUID so would not automatically turn on. In this case, you just have to change the UUID in /etc/fstab to match the new partition. To determine the new UUID:

Excellent article, I am new to Ubuntu. I would like to ask a question to see whether your article solves my problem.

I have Ubuntu 9.04 installed on my machine. I have created a virual machine with 40GB, I have installed Windows server 2008, SQL Server 2008 and other things and now I only have 6GB left and would like to add more space. What I did was to go to the details of my image (VM) and added storage of 10GB, and then started my VM and logged on and I cannot see the extra allocated space. However when I go to disk management I see the extra 10GB as unallocated.

I appreciate the blog post. I’m trying to resize an image on a remote server. Do you have some suggestions on how to use gparted on the VM I amd resizing? I have full admin access to the machine, but no physical access.

Yes you can store the iso for gparted on the local disk of your esx server and choose to boot from the iso instead of a real or virtual CD drive. If your OS boots too quickly or wont boot to the ISO, there is a setting in the VM settings that forces the VM to boot into BIOS where you can change the boot order so that CD comes up first before the VM hard drives. After that the process is exactly the same as has been mentioned here.

Another option is to use EASEUS Partition Master free version. Boot up on the larger sized image, install EPM and then use it to expand the original partition to the full size. At least this worked on Ubuntu 10.10 with a Win XP Pro VM.

great article. To save time you don’t need to use GParted. When you have your new image at step 7 do this
(i) losetup -f (we will assume it returns /dev/loop0)
(ii) losetup -f /dev/loop0 ./ubuntu-dev.img
(iii) fdisk /dev/loop0,
then use fdisk to delete and re-create your partitions, take care to ensure the partition numbers are the same and that the boot partition starts on the same block number, also remember to mark your swap partition as swap (type 82) and make the boot partition bootable.
(iv) kpartx -av /dev/loop0
(v) e2fsck -f /dev/mapper/loop0p1 (assuming this is the partition we are extending)
(vi) resize2fs /dev/mapper/loop0p1 (assuming this is the partition we are extending)
(viii) mkswap /dev/mapper/loop0p2 (assuming you moved the swap partition which you probably did to make space)
(ix) mount /dev/mapper/loop0p1 /mnt (to check that everything is okay before booting)
(x) umount /mnt
(xi) kpartx -dv /dev/loop0
(xii) losetup -d /dev/loop0
(xiii) boot up and correct the UUIDs or just remove them and reference the swap and other partition(s) directly. I just removed the UUID markers assuming that since the disk is already virtualised through KVM then I would use this type of technique to keep the partition names consistent.

Response #8 is the winner. Ironically, I think the article needed to happen in order to find out that there is a simple qemu-img resize myimage.img +8GB that does all this in a split second. I tried it and it worked perfectly.

I tested it on Windows 7 image, and it works great, after step 8 don’t take care the swap there is no swap on windows systems, launch the system and go to the manage disk via right click on desktop you find a second partition do an extend of the primary partition. it work’s for me very well.
NB: excuse my poor english and hope it helps.

Does not work. Could you shine a little light on this please? Using Gparted 0.12.0-5 and CentOS 6.1 with kernel 2.6.32-220.7.1.el6.centos.plus.x86_64 SMP. I don’t get any meaningful errors. It just returns me to the prompt. I tried changing “qemu” to “qemu-img” and that didn’t change anything. Thanks.

I found another way to disk in KVM.
I have done in Fedora 17 which is Host and added the disk to Debian 6 vm (Guest)
Make sure the GUEST VM is not running.
# cd /etc/libvirt/qemu
Here you will find the xml of the Guest o/s.
Create the image anywhere in the Host system now.
# qemu-img create -f raw /opt/debian-add.img 10G (Creating the image in /opt )
Then type
# virsh edit Debian6
The name of the guest that I had given when I installed the guest for the first time was Debian6.

ADD THE BELOW LINES

Then save the file. It work like vi editor.

# virsh create /etc/libvirt/qemu/Debian6.xml
The GUEST O/S will start with this command.
Then you can go to libvirt-manager and open the Guest o/s.