How to Safely Expand Your VM Disk for LVM-Based Ubuntu Servers

KUMAR BISHOJITKUMAR BISHOJIT
6 min read

If you've ever upgraded your virtual server’s disk size from your hosting control panel (like SolusVM, VMware, Proxmox, etc.), you might have noticed that your Linux system doesn’t automatically see the new space. This is especially true if you’re using LVM (Logical Volume Manager): the extra space is available on the virtual disk, but the OS and filesystem can’t use it until you take some extra steps.

This blog walks you through using a safe, interactive Bash script (auto_disk_resize_fixed.sh) that automates these steps for Ubuntu/Debian systems. You’ll learn how it works, how to run it, and what’s happening behind the scenes.


Why Isn't the New Space Available Right Away?

When you expand the disk in your VPS control panel, the underlying virtual disk grows instantly. However:

  • Your existing partition (e.g., /dev/sda3) doesn’t automatically expand to fill the new space.

  • LVM’s physical volume (PV), volume group (VG), and logical volume (LV) are all still the same size as before.

  • Your filesystem (ext4, xfs, etc.) can only use the space allocated to the LV.

Result: Even though your disk is bigger, df -h still shows the old size for your root filesystem.


What Does the Script Do?

The script auto_disk_resize_fixed.sh guides you through the safest way to expand your root partition and filesystem:

  1. Detects your LVM setup, disk devices, partition numbers, and logical volumes.

  2. Prompts you for confirmation before making any changes.

  3. Grows the partition using growpart to fill the new disk.

  4. Resizes the LVM PV so LVM can use the new space.

  5. Extends the LV (root filesystem) to use all available space.

  6. Expands the filesystem (ext4 or xfs) to match the new LV size.

  7. Shows you the results with a final df -h.


Step-by-Step: How to Use the Script

1. Prepare the Script

Copy the following script and save it as auto_disk_resize_fixed.sh:

#!/bin/bash
set -euo pipefail

# ==============================================================================
# SAFE AUTO DISK RESIZE SCRIPT (FIXED)
# This script safely expands an LVM root filesystem after resizing a VM disk.
# - Automatically detects the correct disk, partition, and LVM layout.
# - Uses growpart, pvresize, lvextend, and resize2fs/xfs_growfs as appropriate.
# - Prompts user for confirmation before making changes.
# - Intended for Ubuntu/Debian systems using LVM.
# ==============================================================================

echo "==== SAFE AUTO DISK RESIZE SCRIPT (FIXED) ===="

# Step 1: Show current block devices so the user can visually confirm layout
echo "[1] Block devices:"
lsblk
echo

# Step 2: Detect the LVM physical volume (PV) partition (e.g., /dev/sda3)
# This is the partition we want to resize to fill the new disk size
PV_PATH=$(pvs --noheadings -o pv_name | awk '{print $1}' | head -1)
if [[ -z "$PV_PATH" ]]; then
  echo "ERROR: Could not detect LVM physical volume. Exiting."
  exit 1
fi

# Step 3: Detect the underlying disk device (e.g., /dev/sda) for the PV
DISK_DEV=$(lsblk -no PKNAME "$PV_PATH" | head -1)
if [[ -z "$DISK_DEV" ]]; then
  echo "ERROR: Could not detect underlying disk for $PV_PATH. Exiting."
  exit 1
fi
DISK="/dev/$DISK_DEV"

# Step 4: Extract the partition number (e.g., 3 for /dev/sda3)
PART_NUM=$(echo "$PV_PATH" | grep -o '[0-9]*$')
if [[ -z "$PART_NUM" ]]; then
  echo "ERROR: Could not determine partition number from $PV_PATH. Exiting."
  exit 1
fi

# Show current partition table for the detected disk
echo "[2] Partition table for $DISK:"
sudo fdisk -l "$DISK"
echo

echo "Detected:"
echo "  LVM PV      : $PV_PATH"
echo "  Disk device : $DISK"
echo "  Part number : $PART_NUM"
echo

# Step 5: Prompt user to confirm values before making any changes
read -rp "Are these values correct and do you want to proceed with resizing? (yes/no): " confirm
if [[ "$confirm" != "yes" ]]; then
  echo "Aborting for safety."
  exit 1
fi

# Step 6: Install growpart if not already available
echo "[3] Installing growpart if needed..."
if ! command -v growpart &>/dev/null; then
  sudo apt-get update
  sudo apt-get install -y cloud-guest-utils
fi

# Step 7: Grow the LVM partition to occupy the new disk space
echo "[4] Growing partition $PART_NUM on $DISK using growpart..."
sudo growpart "$DISK" "$PART_NUM"

# Step 8: Resize the LVM physical volume to utilize the expanded partition
echo "[5] Resizing LVM physical volume $PV_PATH..."
sudo pvresize "$PV_PATH"

# Step 9: Find the logical volume (LV) path for the root filesystem (e.g., /dev/ubuntu-vg/ubuntu-lv)
ROOT_LV_PATH=$(findmnt -n -o SOURCE /)
VG=$(lvs --noheadings -o vg_name "$ROOT_LV_PATH" | awk '{print $1}' | head -1)
LV=$(lvs --noheadings -o lv_name "$ROOT_LV_PATH" | awk '{print $1}' | head -1)
LV_PATH="/dev/$VG/$LV"

echo
echo "Root LV Path  : $LV_PATH"
read -rp "Ready to extend LV ($LV_PATH) and resize filesystem. Proceed? (yes/no): " confirm2
if [[ "$confirm2" != "yes" ]]; then
  echo "Aborting for safety."
  exit 1
fi

# Step 10: Extend the logical volume to use all newly available space
echo "[6] Extending logical volume to use all free space..."
sudo lvextend -l +100%FREE "$LV_PATH"

# Step 11: Resize the filesystem on the logical volume to match the new size
echo "[7] Resizing filesystem..."
FS_TYPE=$(df -T / | tail -1 | awk '{print $2}')
if [[ "$FS_TYPE" == "xfs" ]]; then
  sudo xfs_growfs /
else
  sudo resize2fs "$LV_PATH"
fi

# Step 12: Show the new disk usage to confirm success
echo
echo "[8] Disk usage after resize:"
df -h

echo "==== Done. Your disk should now show the full size. ===="

2. Make the Script Executable

chmod +x auto_disk_resize_fixed.sh

3. Run the Script as Root

sudo ./auto_disk_resize_fixed.sh

4. Follow the Prompts

  • The script will show you the detected disk, LVM, and partition details.

  • Carefully review these before answering "yes" to proceed.

  • The script will pause before each major change for your confirmation.


What’s Happening Behind the Scenes?

  • growpart expands the partition table entry for your LVM partition to fill the whole virtual disk.

  • pvresize tells LVM that new space is available in the physical volume.

  • lvextend grows the logical volume (LV) so your root filesystem can use the new space.

  • resize2fs or xfs_growfs grows the filesystem itself to match the new LV size.


Safety Tips

  • Always backup any critical data before resizing disks or filesystems.

  • This script is interactive. If anything looks wrong in the detected devices, abort and double-check your server’s layout!

  • Only run this if your root filesystem is on LVM (most Ubuntu "Guided - use entire disk and set up LVM" installs use this layout).


Troubleshooting

  • If the script aborts with an error, check that your system uses LVM and that you’ve actually expanded the disk in your VPS control panel.

  • If your system uses standard partitions (not LVM), this script will not work for you.

  • If you see any error, copy the error message and seek advice before retrying.


Conclusion

Expanding a disk on a virtual server isn’t finished after you click “resize” in your cloud control panel. Use this script to safely automate the process for LVM-based Ubuntu systems, with full visibility and control at each step.

Have questions or feedback? Leave a comment below!

0
Subscribe to my newsletter

Read articles from KUMAR BISHOJIT directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

KUMAR BISHOJIT
KUMAR BISHOJIT