Skip to content

Resizing and Cloud Disks

Growing a disk in a cloud console changes only the block device; the partition, the LVM physical volume and the filesystem above it each need their own step. The full sequence is a common operations ticket and a common interview task.

Track: Core · Interview weight: Med


Must-Know Facts

Fact Value Verify with
Layers to grow Disk → partition → PV (if LVM) → LV → filesystem lsblk
See the new disk size NVMe and Virtio: automatic; SCSI: echo 1 > /sys/class/block/sdX/device/rescan lsblk
Grow a partition growpart <disk> <number> (package cloud-utils-growpart on RHEL, cloud-guest-utils on Ubuntu) lsblk
Grow a PV pvresize <partition> pvs
Grow an LV and its filesystem lvextend -r -l +100%FREE <vg>/<lv> df -h
Grow a filesystem ext4: resize2fs <device>; XFS: xfs_growfs <mountpoint> df -h
Online Every step above works on mounted filesystems, including / findmnt /
Shrinking Cloud volumes cannot shrink; create a smaller volume and copy the data provider console
Boot-time growth cloud-init growpart and resize_rootfs grow the root partition and filesystem on first boot cloud-init status --long
Partition position Only the last partition, or one followed by free space, can grow in place sudo parted <disk> print free
MBR limit A partition on an MBR disk cannot use space beyond 2 TiB sudo fdisk -l
AWS aws ec2 modify-volume --size; repeated modifications of one volume are rate-limited aws ec2 describe-volumes-modifications

Growing a Partition and Its Filesystem

cloud1.img stands in for a 1 GiB cloud volume with one GPT partition holding XFS:

cd /var/tmp/disks
truncate -s 1G cloud1.img
sudo losetup -fP --show cloud1.img
sudo parted -s /dev/loop4 mklabel gpt mkpart data 1MiB 100%
sudo mkfs.xfs -q /dev/loop4p1
sudo mkdir -p /srv/cloud && sudo mount /dev/loop4p1 /srv/cloud
df -h /srv/cloud

Output:

/dev/loop4
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop4p1    958M   51M  908M   6% /srv/cloud

Enlarging the file plays the part of the console resize. A loop device needs losetup -c to notice, which matches the SCSI rescan on a physical or VMware disk:

truncate -s 3G cloud1.img
lsblk /dev/loop4
sudo losetup -c /dev/loop4
lsblk /dev/loop4

Output:

NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop4       7:4    0    1G  0 loop 
└─loop4p1 259:3    0 1022M  0 part /srv/cloud
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop4       7:4    0    3G  0 loop 
└─loop4p1 259:3    0 1022M  0 part /srv/cloud

Then the partition and the filesystem, each in its own step:

sudo growpart /dev/loop4 1
sudo growpart /dev/loop4 1; echo "rc=$?"
lsblk /dev/loop4
df -h /srv/cloud
sudo xfs_growfs /srv/cloud | tail -1
df -h /srv/cloud

Output:

CHANGED: partition=1 start=2048 old: size=2093056 end=2095103 new: size=6289375 end=6291422
NOCHANGE: partition 1 is size 6289375. it cannot be grown
rc=1
NAME      MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop4       7:4    0   3G  0 loop 
└─loop4p1 259:3    0   3G  0 part /srv/cloud
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop4p1    958M   51M  908M   6% /srv/cloud
data blocks changed from 261632 to 786171
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop4p1    3.0G   91M  2.9G   4% /srv/cloud

growpart takes the disk and the partition number as separate arguments, keeps the start sector and moves the end. The partition was 3 GiB while df still showed 958 MiB, until xfs_growfs grew the filesystem. On ext4, the last step is sudo resize2fs /dev/loop4p1.

growpart /dev/loop4p1 is wrong

Passing the partition as one argument prints the usage text and must supply partition-number (exit 2); the syntax is growpart /dev/nvme0n1 1 or growpart /dev/xvda 1. On NVMe the partition is nvme0n1p1, but growpart still takes nvme0n1 and 1.


Growing an LVM Root Layout

RHEL images put the root filesystem in LVM on the last partition. cloud2.img reproduces that with vgroot/root on loop5p1, created with parted, vgcreate, lvcreate -l 100%FREE and mkfs.ext4, and mounted at /srv/root:

truncate -s 2G cloud2.img
sudo losetup -c /dev/loop5
sudo growpart /dev/loop5 1
sudo pvs /dev/loop5p1
sudo pvresize /dev/loop5p1
sudo lvextend -r -l +100%FREE vgroot/root
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS /dev/loop5
df -h /srv/root

Output:

CHANGED: partition=1 start=2048 old: size=2093056 end=2095103 new: size=4192223 end=4194270
  PV           VG     Fmt  Attr PSize  PFree
  /dev/loop5p1 vgroot lvm2 a--  <2.00g 1.00g
  Physical volume "/dev/loop5p1" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
  File system ext4 found on vgroot/root mounted at /srv/root.
  Size of logical volume vgroot/root changed from 1020.00 MiB (255 extents) to <2.00 GiB (511 extents).
  Extending file system ext4 to <2.00 GiB (2143289344 bytes) on vgroot/root...
resize2fs /dev/vgroot/root
resize2fs 1.47.1 (20-May-2024)
Filesystem at /dev/vgroot/root is mounted on /srv/root; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vgroot/root is now 523264 (4k) blocks long.

resize2fs done
  Extended file system ext4 on vgroot/root.
  Logical volume vgroot/root successfully resized.
NAME            SIZE TYPE MOUNTPOINTS
loop5             2G loop 
└─loop5p1         2G part 
  └─vgroot-root   2G lvm  /srv/root
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/vgroot-root  2.0G   24K  1.9G   1% /srv/root

pvresize records the new partition size in the PV metadata, and lvextend -r takes the free extents and resizes ext4 while it stays mounted. On a real RHEL instance the same commands read sudo growpart /dev/nvme0n1 3, sudo pvresize /dev/nvme0n1p3 and sudo lvextend -r -l +100%FREE rhel/root.

Snapshot the cloud volume before resizing

Growing is safe on current tools, but a snapshot in the provider console costs little and covers a mistyped device name.


When the Partition Cannot Grow

Situation Approach
Swap or another partition follows the one to grow Move or remove that partition, or add a new disk to the VG instead
Filesystem directly on the disk (no partition), as on these playgrounds Skip growpart; run resize2fs or xfs_growfs after the rescan
MBR disk growing past 2 TiB Convert to GPT with sgdisk -g (needs free space at the end for the backup table)
XFS must become smaller New smaller volume, copy with rsync -aHAX or xfsdump, switch mount points

Common Errors

NOCHANGE: partition 1 is size 6289375. it cannot be grown

Cause: there is no free space after the partition: the disk resize has not reached the kernel yet, or the partition was already grown.

Fix: check lsblk for the new disk size; rescan the device (echo 1 | sudo tee /sys/class/block/sdb/device/rescan) or wait for the provider's modification to finish.

sudo: growpart: command not found

Cause: the tool comes in a separate package.

Fix: sudo dnf install cloud-utils-growpart or sudo apt install cloud-guest-utils; sudo parted /dev/sdb resizepart 1 100% does the same job.


Interview Checkpoints

L1: An EBS volume was enlarged from 20 to 50 GiB, but df still shows 20 GiB. Why?

Say first: the volume grew, but the partition and filesystem on it keep their old size until they are grown too.

Proof: lsblk shows a 50 GiB disk with a 20 GiB partition; df -h shows the filesystem.

Follow-up: Which commands finish the job for XFS on a partition?

L1: Can a cloud volume be shrunk?

Say first: no; the data must be copied to a new, smaller volume.

Proof: the provider rejects a smaller size in modify-volume.

Follow-up: Which filesystem also rules out shrinking in place?

L2: Grow the root filesystem of an Ubuntu EC2 instance after enlarging its volume.

Say first: grow partition 1 of the NVMe disk, then the ext4 filesystem.

Proof: lsblk; sudo growpart /dev/nvme0n1 1; sudo resize2fs /dev/nvme0n1p1; df -h /.

Follow-up: Why can this run while / is mounted?

L2: Grow the LVM root filesystem of a RHEL VM after its disk was enlarged.

Say first: rescan if needed, grow the partition, resize the PV, then extend the LV with its filesystem.

Proof: sudo growpart /dev/sda 3; sudo pvresize /dev/sda3; sudo lvextend -r -l +100%FREE rhel/root.

Follow-up: What is the alternative when the partition is not the last one? (A new partition or disk added with vgextend.)

L2: A VMware disk was enlarged, but lsblk shows the old size.

Say first: SCSI disks need a rescan before the kernel sees the new capacity.

Proof: echo 1 | sudo tee /sys/class/block/sdb/device/rescan; lsblk /dev/sdb.

Follow-up: Which command does the same for a loop device? (losetup -c.)

L3: After growpart and xfs_growfs, df still shows the old size. What do you check?

Say first: whether each layer changed: disk, partition, PV and LV, and whether xfs_growfs ran against the right mount point.

Proof: lsblk; sudo pvs; sudo lvs; xfs_info <mountpoint>; for LVM, sudo lvextend -r was probably skipped.

Follow-up: Why does xfs_growfs take a mount point and resize2fs a device?


  • LVM: pvresize, lvextend and adding disks
  • Partitioning: partition layout and table types
  • Filesystems: which filesystems grow and shrink
  • Disk Usage: finding what filled the volume first

Captured on Rocky Linux 10.2 (iximiuz Labs microVM, kernel 6.1.167, cloud-utils-growpart, LVM 2.03.36), 2026-09.