How do you increase a KVM guest's disk space?

Solution 1:

  1. stop the VM
  2. run qemu-img resize vmdisk.img +10G to increase image size by 10Gb
  3. start the VM, resize the partitions and LVM structure within it normally

Solution 2:

Online Method (using qemu, libvirt, and virtio-block)

For better or worse, the commands below will run even if the target virtual disk is mounted. This can be useful in environments where the disk cannot be unmounted (such as a root partition), the VM must stay on, and the system owner is willing to assume the risk of data corruption. To remove that risk, you would need to log into the VM and unmount the target disk first, something that isn't always possible.

Perform the following from the KVM hypervisor.

  1. Increase the size of the disk image file itself (specify the amount to increase):

    qemu-img resize <my_vm>.img +10G
    
  2. Get the name of the virtio device, via the libvirt shell (drive-virtio-disk0 in this example):

    virsh qemu-monitor-command <my_vm> info block --hmp
      drive-virtio-disk0: removable=0 io-status=ok file=/var/lib/libvirt/images/<my_vm>.img ro=0 drv=raw encrypted=0
      drive-ide0-1-0: removable=1 locked=0 tray-open=0 io-status=ok [not inserted]
    
  3. Signal the virtio driver to detect the new size (specify the total new capacity):

    virsh qemu-monitor-command <my_vm> block_resize drive-virtio-disk0 20G --hmp
    

Then log into the VM. Running dmesg should report that the virtio disk detected a capacity change. At this point, go ahead and resize your partitions and LVM structure as needed.


Solution 3:

These serverfault questions are similar but more specific, KVM online disk resize? & Centos Xen resizing DomU partition and volume group. The 1st asks the question of how to increase a KVM guest while it's online, while the 2nd is XEN specific using LVM. I'm asking how to accomplish this while the KVM is offline.

NOTE: This link was useful for METHOD #1, and shows how to accomplish increasing a KVM's disk space (ext3 based), HOWTO: Resize a KVM Virtual Machine Image.

One thing to be aware of with KVM guests is that the partitions they're using inside can effect which method you can use to increase their disk space.

METHOD #1: Partitions are ext2/ext3/ext4 based

The nuts of this method are as follows:

# 1. stop the VM
# 2. move the current image
mv mykvm.img mykvm.img.bak

# 3. create a new image
qemu-img create -f raw addon.raw 30G

# 4. concatenate the 2 images
cat mykvm.img.bak addon.raw >> mykvm.img

Now with the larger mykvm.img file in hand, boot gparted and extend the existing partition into the newly added disk space. This last step basically extends the OS partition so that it can make use of the extra space.

METHOD #2: Partitions are LVM based

Here are the steps that I roughly followed to resize a KVM guest that used LVM internally.

  1. Shutdown the VM
  2. add more space to the guest's "image file" (something like: cat old.img 10G_addon.raw >> new.img
  3. start the VM (using the newly created new.img)
  4. run fdisk inside VM and delete & re-create LVM partition

    % fdisk /dev/vda
    ...
    Device Boot      Start         End      Blocks   Id  System
    /dev/vda1   *           1          13      104391   83  Linux
    /dev/vda2              14        3263    26105625   8e  Linux LVM
    
    Command (m for help): d
    Partition number (1-4): 2
    
    Command (m for help): p
    
    Disk /dev/vda: 48.3 GB, 48318382080 bytes
    255 heads, 63 sectors/track, 5874 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
    Device Boot      Start         End      Blocks   Id  System
    /dev/vda1   *           1          13      104391   83  Linux
    
    Command (m for help): n 
    Command action
      e   extended
      p   primary partition (1-4)
    p
    Partition number (1-4): 2
    First cylinder (14-5874, default 14): 14
    Last cylinder or +size or +sizeM or +sizeK (14-5874, default 5874): 
    Using default value 5874
    
    Command (m for help): p
    
    Disk /dev/vda: 48.3 GB, 48318382080 bytes
    255 heads, 63 sectors/track, 5874 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
    Device Boot      Start         End      Blocks   Id  System
    /dev/vda1   *           1          13      104391   83  Linux
    /dev/vda2              14        5874    47078482+  83  Linux
    
    Command (m for help): t
    Partition number (1-4): 2
    Hex code (type L to list codes): 8e
    Changed system type of partition 2 to 8e (Linux LVM)
    
    Command (m for help): p
    
    Disk /dev/vda: 48.3 GB, 48318382080 bytes
    255 heads, 63 sectors/track, 5874 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    
    Device Boot      Start         End      Blocks   Id  System
    /dev/vda1   *           1          13      104391   83  Linux
    /dev/vda2              14        5874    47078482+  8e  Linux LVM
    
    Command (m for help): w
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table.
    
    WARNING: Re-reading the partition table failed with error 16: Device or 
    resource busy.
    The kernel still uses the old table.
    The new table will be used at the next reboot.
    Syncing disks.
    %
    
  5. Reboot the VM

  6. Resize the LVM physical volume

    % pvdisplay 
      --- Physical volume ---
      PV Name               /dev/vda2
      VG Name               VolGroup00
      PV Size               24.90 GB / not usable 21.59 MB
      Allocatable           yes (but full)
      PE Size (KByte)       32768
      Total PE              796
      Free PE               0
      ...
    
    % pvresize /dev/vda2
    
    % pvdisplay
      --- Physical volume ---
      PV Name               /dev/vda2
      VG Name               VolGroup00
      PV Size               44.90 GB / not usable 22.89 MB
      Allocatable           yes 
      PE Size (KByte)       32768
      Total PE              1436
      Free PE               640
      ...
    
  7. Resize the LVM Logical Volume

      % lvresize /dev/VolGroup00/LogVol00 -l +640
      Extending logical volume LogVol00 to 43.88 GB
      Logical volume LogVol00 successfully resized
    
  8. Grow the File system

      % resize2fs /dev/VolGroup00/LogVol00 
      resize2fs 1.39 (29-May-2006)
      Filesystem at /dev/VolGroup00/LogVol00 is mounted on /; on-line resizing required
      Performing an on-line resize of /dev/VolGroup00/LogVol00 to 11501568 (4k) blocks.
      The filesystem on /dev/VolGroup00/LogVol00 is now 11501568 blocks long.
    

The above is my example, but I followed the steps on this website


Solution 4:

Resize and Expand Internal Partitions in One Step

I had an Ubuntu host with a qcow2 guest file image and wanted to resize the disk and expand the appropriate partitions all in one step. It requires you to set up the libvirt guest filesystem utilities, but those are useful to have around anyway.

Inspiration from here: http://libguestfs.org/virt-resize.1.html

The key command here is: virt-resize

  • this is a libvirt utility
  • it can expand a guest disk AND expand the partitions inside in one step
  • it copies the disk, it doesn't expand it in-place
    • this is good because you have the untouched original as a backup

Preparation:

* Install libvirt file system utilities package 
    * sudo apt-get install libguestfs-tools

* Test to see if it works (it won't) -- you need to see "===== TEST FINISHED OK =====" at the bottom:
    * sudo libguestfs-test-tool

* If you don't see "===== TEST FINISHED OK =====" at the bottom then repair it:
    * sudo update-guestfs-appliance

* Run the test again and verify it works
    * sudo libguestfs-test-tool

Now do the following:

1) shutdown the guest:

2) Check out the current sizing and view the partition name you want to expand using libvirt utility:

sudo virt-filesystems --long --parts --blkdevs -h -a name-of-guest-disk-file

3) Create the new (40G) output disk:

qcow: sudo qemu-img create -f qcow2 -o preallocation=metadata outdisk 40G
img:  sudo truncate -s 40G outdisk

4) Copy the old to the new while expand the appropriate partition (assuming your disk partition from step 2 was /dev/sda1):

sudo virt-resize --expand /dev/sda1 indisk outdisk

5) Rename the indisk file as a backup, rename the outdisk as indisk (or modify the guest XML)

6) Reboot the guest and test the new disk file carefully before deleting the original file

7) Profit!


Solution 5:

It is possible to do online resize. libvirtd supports this natively:

Find the block device name. Should be something like "vda"

$ virsh domblklist <libvirtd_vm_name>

Resize the virtual device:

$ virsh blockresize --domain <libvirtd_vm_name> --path <block_device_name> --size <new_size>

Here is an example were I expand the vda disk from 50GB to 51GB for undercloud VM.

[root@localhost ~]# virsh domblklist undercloud
Target     Source
------------------------------------------------
vda        /home/images/undercloud.qcow2

Now take a look at the .qcow2 image file's details:

[root@localhost ~]# qemu-img info /home/images/undercloud.qcow2
image: /home/images/undercloud.qcow2
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 38G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

Now let's resize the vda block device:

[root@localhost ~]# virsh blockresize undercloud vda 51G
Block device 'vda' is resized

And confirm:

[root@localhost ~]# qemu-img info /home/images/undercloud.qcow2
image: /home/images/undercloud.qcow2
file format: qcow2
virtual size: 51G (54760833024 bytes)
disk size: 38G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
[root@localhost ~]#

Then you can use this script inside the VM to show the commands to resize the block devices and fs: https://github.com/mircea-vutcovici/scripts/blob/master/vol_resize.sh.