github email
Resizing the disk of a Vagrant guest
May 17, 2017
3 minutes read

Some people occasionally ask in #centos how to resize the disk of a virtual machine. Most Linux distributions use LVM by default, which simplifies things considerably:

  1. Resize the disk image using the native tools provided by your virtualization software;
  2. Add a new partion inside the guest and use it for a new LVM physical volume;
  3. Extend the existing volume group to include the new physical volume;
  4. Extend the logical volume whose size you’d like to increase and resize its filesystem accordingly.

As an example, we’ll resize the disk of a Vagrant guest using centos/7, the official CentOS Linux 7 image for Vagrant.

Resizing the disk image

Vagrant boxes use disk image in VMware’s VMDK format (simply because they are cloned from an exported OVA file). VMware’s vdiskmanager tool can resize such images directly, but VirtualBox and QEMU don’t support resizing VMDKs natively, so we have to convert the disk image to another format, and then convert it back after resizing. Of course, the guest needs to be powered off before resizing its disk image.

VirtualBox can only resize disk images in its native VDI format:

VBoxManage clonemedium disk centos-7-1-1.x86_64.vmdk centos-7-1-1.x86_64.vdi --format vdi
VBoxManage modifymedium disk centos-7-1-1.x86_64.vdi --resize 65536
VBoxManage clonemedium disk centos-7-1-1.x86_64.vdi centos-7-1-1.x86_64.vmdk --existing

With QEMU, we have to convert the image to the “raw” file format, increase its size with dd and then convert it back to the VMDK format:

qemu-img convert -O raw centos-7-1-1.x86_64.vmdk tmp.raw
dd if=tmp.raw of=centos-7-1-1.x86_64.raw bs=1M seek=65536 oflag=append
qemu-img convert -O vmdk centos-7-1-1.x86_64.raw centos-7-1-1.x86_64.vmdk

Resizing the guest filesystem

The new disk size is seen correctly by the guest, after booting it again:

$ sudo parted /dev/sda
GNU Parted 3.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system  Flags
        32.3kB  1049kB  1016kB           Free Space
 1      1049kB  2097kB  1049kB  primary
 2      2097kB  1076MB  1074MB  primary  xfs          boot
 3      1076MB  42.9GB  41.9GB  primary               lvm
        42.9GB  68.7GB  25.8GB           Free Space

We can now create a new primary partition covering the free space and mark it for use with LVM:

(parted) mkpart primary 42.9G 100%
(parted) set 4 lvm on
(parted) quit
Information: You may need to update /etc/fstab.

No changes to /etc/fstab are necessary in our case (the new partition will only be used by LVM inside the logical volume for root, it will never be mounted directly).

We can now create a new LVM physical volume in the partition we just created and extend the existing volume group:

$ sudo pvcreate /dev/sda4
  Physical volume "/dev/sda4" successfully created.

$ sudo pvs
  PV         VG         Fmt  Attr PSize  PFree
  /dev/sda3  VolGroup00 lvm2 a--  38.97g     0
  /dev/sda4             lvm2 ---  24.00g 24.00g

$ sudo vgextend VolGroup00 /dev/sda4
  Volume group "VolGroup00" successfully extended

The last step is to resize the LVM logical volume for root and the filesystem it hosts:

$ sudo lvextend /dev/mapper/VolGroup00-LogVol00 -rl +100%FREE
  Size of logical volume VolGroup00/LogVol00 changed from 37.47 GiB (1199 extents) to 61.44 GiB (1966 extents).
  Logical volume VolGroup00/LogVol00 successfully resized.
meta-data=/dev/mapper/VolGroup00-LogVol00 isize=512    agcount=4, agsize=2455552 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=9822208, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=4796, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 9822208 to 16105472

Back to posts