Resize a Centos 7 Virtual Machine in KVM/QEMU
Being relatively new to the RHEL/Centos world, it’s safe to say I’m learning a lot as I go. While Linux is mostly, well, Linux between distributions, each one has its own particular nuances.
One of these nuances bit me last weekend on a new Centos 7 VM. I was spinning up a borg-backup server to back up my roughly 50GB Nextcloud instance, so I provisioned a 160GB qcow2 image to give it adequate wiggle room. After logging in for the first time post-install, I was dismayed to see only 100GB available for backup. It turns out that Centos 7 default paritioning included separate
/home partitions, and allocated a whole 50GB for root. What good is 50GB going to do me when all I’m instaling is borg?
One additional differentiator of RHEL/Centos from Ubuntu is the use of XFS as the default filesystem. XFS is a solid, feature-packed filesystem, but one thing it can’t do is shrink. This ruled out shrinking
/ and expanding
/home, so I decided to eat my mistake and just expand the whole VM. Below is the process for future reference.
Extend the QCOW2 Image
Shut down your VM
$ sudo poweroff
SSH into your host machine and run the
qemu-img tool on your VM guest image. I added an additional 100GB in the example below.
$ sudo qemu-img resize /path/to/image.qcow2 +100G Image resized.
Extend the Partition
Since resizing root LVM paritions can be difficult from a running system, we’re going to boot into a live environment for the remaining steps. You can use any Linux live environment for this, but I’ll be using GParted to keep things simple.
Open up virt-manager and load the GParted ISO into the VM’s optical drive, then click Apply.
Select Boot Options and enable the optical drive before moving it to first in the boot order, then click Apply.
Start your VM and follow the prompts to boot into the GParted live environment. You should notice the extra space you added as “unallocated”.
Select the LVM parition and click on Resize/Move.
Drag the slider to fill in the remaining space and click Resize.
Extend the Logical Volume
Close/minimize GParted and open the Terminal in the live environment.
We have to help the live environment disover the logical volumes. You’ll be able to use
sudo without a password in all the following commands.
$ sudo pvscan PV /dev/vda2 VG centos lvm2 [<259.00 GiB / 100.00 GiB free] Total: 1 [<259.00 GiB] / in use: 1 [<259.00 GiB] / in no VG: 0 [0 ]
$ sudo vgscan Reading volume groups from cache. Found volume group "centos" using metadata type lvm2
$ sudo vgdisplay --- Volume group --- VG Name centos System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 5 VG Access read/write VG Status resizable MAX LV 0 Cur LV 3 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size <259.00 GiB PE Size 4.00 MiB Total PE 66303 Alloc PE / Size 40702 / 158.99 GiB Free PE / Size 25601 / 100.00 GiB VG UUID r8vEjh-ZHBf-WWfi-lBSb-xfSd-HiTy-02TPMe
You can see from the above information that our Volume Group is resizable and has 100GB available for expansion. Take note of the number after “Free PE / Size”.
Let’s confirm our available volumes.
$ sudo lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert home centos -wi-a----- 106.99g root centos -wi-a----- 50.00g swap centos -wi-a----- 2.00g
Now we’ll use the
lvextend tool tool to expand our
/home volume. The number noted earlier from the
vgdisplay command will be used to signify the size increase.
$ sudo lvextend -l +25601 /dev/centos/home Size of logical volume centos/home changed from 106.99 GiB (27390 extents) to <207.00 GiB (52991 extents). Logical volume centos/home successfully resized.
Expand the Filesystem
Since Centos 7 defaults to XFS, we’ll use the
xfs_growfs tool. This requires the filesystem to be mounted first, so lets create a mount point and mount it there.
$ sudo mkdir /mnt/home
$ sudo mount /dev/centos/home /mnt/home
xfs_growfs to expand the filesystem into the available volume space.
$ sudo xfs_growfs /mnt/home meta-data=/dev/mapper/centos-home isize=512 agcount=4, agsize=7011840 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0 spinodes=0 rmapbt=0 = reflink=0 data = bsize=4096 blocks=28047360, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal bsize=4096 blocks=13695, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 data blocks changed from 28047360 to 54262784
Confirm the new volume size.
$ df -h Filesystem Size Used Avail Use% Mounted on udev 489M 0 489M 0% /dev /dev/sr0 309M 309M 0 100% /run/live/medium /dev/loop0 269M 269M 0 100% /run/live/rootfs/filesystem.squashfs /dev/mapper/centos-home 207G 44G 164G 21% /mnt/home
You can see that your
/home volume is now ‘207GB’ total in size.
Power off your VM and be sure to remove the optical drive from the boot list in
virt-manager before booting into your Centos 7 install.
That’s it! Please let me know via email or comment if you have a more efficient way to accomplish this. Going forward, the best thing to do is to set the desired paritioning at install time.
Thanks for reading and happy hacking!
Leave a comment