Growing a Linux VM disk can usually be done online, including the root filesystem. First identify what sits between the virtual disk and the mount point: a plain partition, or LVM with ext4 or XFS on top.
The original version of this post was the short growpart + resize2fs recipe. That works for ext4 on a partition. A recent AlmaLinux 10 VM needed a few more steps.
1. Identify the filesystem and storage layout first
Run these inside the VM. The examples use /; replace it with the mount point you want to grow.
findmnt -no SOURCE,FSTYPE,TARGET /
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
df -hT /
ext4 and XFS are filesystems. LVM is a volume manager. You can have either filesystem on an LVM logical volume. A /dev/mapper/... path alone does not prove LVM; check the device tree and LVM reports.
If you see LVM2_member or devices with type lvm, also run:
pvs -o pv_name,vg_name,pv_size,pv_free
vgs -o vg_name,vg_size,vg_free
lvs -o lv_path,lv_size,segtype,devices
Record the actual disk, partition number, PV, LV path and mount point. Names such as /dev/sda3 and /dev/almalinux_ngm/root below are examples, not defaults to assume.
| Detected layout | Growth order |
|---|---|
| Partition → ext4 | growpart → resize2fs |
| Partition → XFS | growpart → xfs_growfs |
| Partition → LVM → ext4 | growpart → pvresize → lvextend → resize2fs |
| Partition → LVM → XFS | growpart → pvresize → lvextend → xfs_growfs |
Only grow the layers that still need space. If the partition already fills the disk, skip growpart. If the VG already has enough free extents, you can start at lvextend.
This guide covers expansion of plain partitions and ordinary linear LVM volumes. LUKS, software RAID, thin pools and other storage stacks need additional steps specific to their layout. Do not use these recipes for shrinking.
2. Make sure the guest sees the larger disk
Have a current recoverable backup before changing storage. Increase the correct virtual disk in your hypervisor, then check its size inside the guest:
lsblk -o NAME,SIZE,TYPE
fdisk -l /dev/sda
If a SCSI disk named sda still shows its old capacity, and its rescan file exists, run as root:
echo 1 > /sys/class/block/sda/device/rescan
lsblk -o NAME,SIZE,TYPE
This sysfs path is not universal: virtio-blk and NVMe devices may need a different, driver-specific rescan. Do not continue until the guest reports the expected disk capacity. If an online update is unavailable, a planned reboot may be necessary.
All modifying commands below assume a root shell. Install any missing tools for your distribution:
AlmaLinux / Rocky Linux / RHEL:
dnf install cloud-utils-growpart e2fsprogs xfsprogs lvm2 parted
Debian / Ubuntu:
apt update
apt install cloud-guest-utils e2fsprogs xfsprogs lvm2 parted
3. Grow the partition, if needed
Inspect the free space after the target partition. For partition 3 on /dev/sda:
parted /dev/sda unit s print free
growpart -N /dev/sda 3
-N previews the change. Review the disk and partition number, then apply it if growth is available:
growpart /dev/sda 3
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
growpart extends a partition into adjacent free space; it does not move a following partition. It also does not resize LVM or the filesystem. Confirm that the kernel now reports the enlarged partition before continuing. If the partition table changed but the kernel could not update the in-use device, resolve that first; a reboot may be needed.
The disk and partition number are separate arguments: growpart /dev/vda 3 targets /dev/vda3; growpart /dev/nvme0n1 3 targets /dev/nvme0n1p3.
If the filesystem or LVM PV lives directly on a whole disk with no partition table, there is no partition to grow. Use the actual filesystem device or PV in the next steps.
4A. Plain partition + ext4
For an ext4 filesystem directly on /dev/sda1, the original recipe still applies once the larger disk is visible and adjacent free space is available:
growpart /dev/sda 1
resize2fs /dev/sda1
df -hT /
Run each step separately and inspect its result. If the partition was already enlarged, skip the first command. resize2fs takes the filesystem’s block device and can grow a mounted ext4 filesystem when online resizing is supported.
4B. Plain partition + XFS
For XFS directly on /dev/sda1, mounted at /:
growpart /dev/sda 1
xfs_growfs -d /
df -hT /
Again, skip growpart if the partition already has the required size. xfs_growfs grows the mounted XFS filesystem; use its mount point, such as / or /data. resize2fs is not the tool for XFS.
4C. LVM + ext4
Assume the identified PV is /dev/sda3, the partition has already been enlarged where necessary, and lvs shows the target LV as /dev/vg0/root.
First let LVM recognize the PV’s available capacity, then inspect free space:
pvresize /dev/sda3
pvs
vgs
pvresize can resize a PV with active logical volumes. It does not enlarge the LV itself.
Choose how much space to allocate. The example below gives the target LV all currently free extents in its VG, including any space that was free before the disk expansion:
lvextend -l +100%FREE /dev/vg0/root
If you want to reserve space for other LVs or snapshots, use a bounded increase instead, for example lvextend -L +20G /dev/vg0/root, provided at least 20 GiB is available. Choose one allocation command, not both. See lvextend.
After the LV has grown, expand ext4 on that LV:
resize2fs /dev/vg0/root
df -hT /
The filesystem is on the LV, so the resize target is /dev/vg0/root, not the underlying LVM2_member partition.
4D. LVM + XFS: the AlmaLinux 10 example
In the recent session, the actual layout was:
| Layer | Observed state |
|---|---|
| Virtual disk | /dev/sda: 64 GiB |
| LVM partition | /dev/sda3: about 63 GiB, already filling the usable disk space |
| Volume group | almalinux_ngm |
| Root logical volume | /dev/mapper/almalinux_ngm-root: 27.79 GiB before extension |
| Filesystem | XFS mounted at / |
growpart /dev/sda 3 returned NOCHANGE because the partition already filled the available space. Running xfs_growfs / at that point could not make the root filesystem larger: its LV was still only 27.79 GiB.
The required sequence was:
pvresize /dev/sda3
vgs
lvextend -l +100%FREE /dev/mapper/almalinux_ngm-root
xfs_growfs /
df -hT /
Use +100%FREE only if allocating all remaining VG space to root is intentional. The session confirmed that lvextend increased the LV from 27.79 GiB to 59.79 GiB. The next step was to run xfs_growfs / again, then verify the filesystem capacity with df.
The actual VG name mattered too: /dev/mapper/almalinux-root failed because this VM’s VG was named almalinux_ngm. Copy the path reported by your own system.
Common errors and what to check
growpart: NOCHANGE
Check the disk capacity and adjacent free space. The partition may already fill the disk, the guest may still see the old disk size, or another partition may block growth. A very small increase can also fall below growpart’s minimum-change threshold. For LVM, inspect pvs, vgs and lvs: unused capacity may already be available at another layer.
resize2fs: bad magic number / no valid superblock / device busy
Recheck findmnt and lsblk before assuming corruption. You may be targeting XFS, an LVM PV, a boot partition, or the whole partitioned disk instead of the filesystem device. These messages alone do not establish the cause. Adding -f does not make resize2fs understand a different filesystem.
xfs_growfs runs, but df shows no extra space
Check the size of the device actually backing that mount point. With LVM, growing the disk or PV is not enough; extend the correct LV first. Then grow XFS and verify again.
Volume group not found
Use lvs -o lv_path,lv_size,devices to get the real LV path. Distribution names and hostnames in online examples are not guaranteed to match your installation.
The rule: identify the stack, make space available from the outside in, and verify the filesystem at the end. Online growth is often straightforward once every layer is accounted for.