LinuxLXXVI · Virtualisation and LinuxGuest operations
Growing a guest online - disk, filesystem, memory and CPU
What you'll learn
- Make a guest see a virtual disk that has been enlarged on the hypervisor
- Execute the full grow chain from device to filesystem, and identify where it stops
- Bring hot-added memory and CPUs into service, and explain when they will not be used
- State what cannot be done online, and why shrinking is a different operation entirely
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11
Growing a VM is presented as a hypervisor operation: change a number in the VM configuration and the guest is bigger. The hypervisor half is genuinely that easy. The guest half is a chain of four or five separate steps, each of which reports success independently, and the reason resize tickets get reopened is that the chain stops partway and nothing says so.
The principle behind all of it: the hypervisor changes the virtual hardware, and the guest keeps using the numbers it already has until something makes it look again.
Disk: the chain, end to end
- Enlarge the virtual disk on the hypervisor.
- Make the guest kernel see the new device size.
- Grow the partition, and make the kernel re-read the partition table.
- Grow the LVM physical volume and logical volume, if LVM is in use.
- Grow the filesystem.
Step 1 is where the change is made and steps 2 to 5 are where it is delivered. Each has its own failure.
Step 2: rescan the device
Whether you need to do anything depends on the bus:
# What am I working with?
lsblk -o NAME,TYPE,TRAN,SIZE,MOUNTPOINTS
# SCSI, SAS, and virtio-scsi: ask the device to rescan
echo 1 | sudo tee /sys/block/sda/device/rescan
# Confirm the kernel now agrees with the hypervisor
lsblk -o NAME,SIZE /dev/sda
A virtio-blk device (/dev/vdX) signals its own size
change through a configuration-change interrupt, so the
kernel usually picks it up with no action. A SCSI device -
which includes virtio-scsi, VMware paravirtual SCSI, and
anything emulated - does not, and needs the rescan write
above.
If lsblk still shows the old size, nothing later in the
chain can work, and the error you get from growpart will
be about there being no free space rather than about the
rescan.
Step 3: grow the partition
sudo growpart --dry-run /dev/sda 2
sudo growpart /dev/sda 2
sudo partx -u /dev/sda
lsblk -o NAME,SIZE /dev/sda
Note the space: growpart /dev/sda 2, disk and partition
number as separate arguments. --dry-run reports what it
would do without doing it, and it is worth running first
because a partition number typo is how you resize the wrong
partition.
growpart attempts the kernel partition-table update itself
via partx --update, and partx -u afterwards is a cheap
confirmation. Older advice says partprobe; on a disk with a
mounted partition partprobe can return EBUSY while
partx -u succeeds, so prefer partx.
Steps 4 and 5: LVM and the filesystem
# LVM: grow the PV to fill the enlarged partition, then the LV
sudo pvresize /dev/sda2
sudo vgs; sudo pvs
sudo lvextend -r -l +100%FREE /dev/mapper/vg0-root
# No LVM: grow the filesystem directly
sudo resize2fs /dev/sda2 # ext4, online grow supported
sudo xfs_growfs / # XFS takes the MOUNT POINT, not the device
Three details that account for most of the confusion here:
lvextend -r(--resizefs) grows the filesystem in the same command. Without-r, the LV is bigger anddfis unchanged, which is the single most common “the resize did not work” report.xfs_growfstakes a mount point. Passing it a device path fails with an error that reads like the device is wrong.resize2fstakes a device. They are opposites and it catches everyone once.- Both grow online, on a mounted filesystem, including the root filesystem. That is normal and supported.
Memory hotplug
Two different mechanisms are often confused:
Ballooning changes how much of the guest’s already configured memory it may use. Covered in the overview lesson; the total never exceeds what the VM was given.
Hotplug adds new memory blocks to the guest, up to the
maximum memory the VM was configured to allow. The blocks
arrive as entries under /sys/devices/system/memory/, and
whether they are usable depends on one file:
$ lsmem --summary; cat /sys/devices/system/memory/auto_online_blocksMemory block size: 128M
Total online memory: 48G
Total offline memory: 0B
onlineIllustrative output
If auto_online_blocks reads offline, hot-added blocks
appear in lsmem as offline and contribute nothing. free
and /proc/meminfo do not count them, and the guest keeps
running under memory pressure with the memory sitting there
unused - a resize that appears to have been applied on the
hypervisor and had no effect at all.
lsmem # STATE column: online or offline
sudo chmem -e 4G # bring 4G of offline memory online
lsmem --summary
The durable fix is the kernel parameter
memhp_default_state=online on the kernel command line, or
the distribution’s udev rule that onlines new blocks. Set it
in the image rather than fixing it per host.
Removal is not symmetrical
Memory can only be taken away if the blocks are movable and
nothing unmovable is allocated in them. lsmem shows this
in its REMOVABLE column, and the honest summary is that
growing a guest is routine and shrinking it is unreliable
and should be planned as a reboot.
CPU hotplug
lscpu -e # per-CPU list, with an ONLINE column
sudo chcpu -e 8-11 # bring vCPUs 8 to 11 online
sudo chcpu -d 11 # take vCPU 11 offline
Newly added vCPUs may come up offline depending on the
distribution’s udev rules, which is what chcpu -e is for.
chcpu -r triggers a rescan for newly added CPUs where the
platform needs it. CPU 0 generally cannot be offlined -
there is no online file for it on most builds, which is
why chcpu -d 0 fails in a way that looks like a permission
problem.
What you cannot do online
Validation after any resize
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS
df -h; df -i
sudo pvs; sudo vgs; sudo lvs
lsmem --summary
lscpu -e | tail -5
findmnt --verify
findmnt --verify checks /etc/fstab against reality, which
catches the other way a resize goes wrong: a device path that
changed during the work and an fstab entry that still names
the old one, discovered at the next reboot rather than now.
Knowledge check
Knowledge check · 4 questions
Q1. A virtual disk was enlarged on the hypervisor, but `lsblk` in the guest still shows the old size. The disk is a virtio-scsi device. What is missing?
Q2. Growing an ext4 or XFS root filesystem requires unmounting it, so it needs a maintenance window.
Q3. Which of these commonly cause a resize where every command reported success and `df` did not change? Select all that apply.
Q4. Four vCPUs were hot-added and brought online with chcpu -e. nproc reports the new count and application throughput is unchanged. Why?
Passing score: 75%. Answers are checked in this browser.