End-to-End Guide to Expanding Linux Volumes and Mount Points

Overview

If your Azure Portal shows a larger disk size (e.g., 128GB) but Linux reports smaller sizes in df -h or lsblk, the issue is almost always one of these:

  • The disk is resized in Azure, but the Linux partition (and/or LVM Physical Volume) was never expanded.
  • A new disk is attached, but it’s not partitioned, formatted, mounted, or added into LVM yet.
  • df -h only shows mounted filesystems, not raw disks—so unmounted disks won’t appear there.

This guide covers:

  1. How to confirm what’s happening, and
  2. How to place /opt on a separate 128GB LVM disk (clean isolation, easy growth, easy recovery).

Symptoms You’ll See

  • Azure shows 128GB disks, but Linux shows:
    • OS LVM only using ~60GB
    • Another disk showing smaller (e.g., 16GB)
    • A 128GB disk appears in lsblk, but not in df -h

Example:

  • lsblk shows sdc 128G (no mount)
  • df -h does not show it (because it’s not mounted or not formatted yet)

Why df -h Doesn’t Show Your Disk

df -h reports filesystems that are mounted (like /, /opt, /home).
It does not list:

  • unpartitioned disks,
  • disks without filesystems,
  • LVM physical volumes (PV) unless they’re part of a mounted filesystem.

Use this instead to see disks:

lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT

Safety First (Recommended)

Before making storage changes:

  • Take an Azure Disk Snapshot (OS disk + any attached data disks)
  • Confirm the maintenance window (changes may require stopping services that use /opt)

Target Design (Best Practice)

✅ Keep OS system VG unchanged
✅ Put /opt on a dedicated VG using the new disk /dev/sdc (128GB)

Final view will look like:

sdc              disk 128G LVM2_member
└─optvg-optlv    lvm  128G xfs /opt

Note: if /opt is in a separate VG, it will not be named rootvg-optlv because rootvg- indicates the VG name. For a separate VG, you’ll see optvg-optlv.


Step-by-Step: Move /opt to Separate 128GB LVM Disk (/dev/sdc)

1) Confirm current /opt and new disk

df -Th /opt
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT
wipefs -n /dev/sdc

2) Unmount /opt (no running process should be using it)

Check usage:

fuser -vm /opt

Unmount:

sudo umount /opt

If it still refuses (rare, but safe when no processes are using it):

sudo umount -l /opt

3) Create LVM PV on the whole disk (so sdc shows LVM2_member)

sudo wipefs -a /dev/sdc
sudo pvcreate /dev/sdc

4) Create a dedicated VG for /opt

sudo vgcreate optvg /dev/sdc

5) Create a 128GB LV and format XFS

sudo lvcreate -n optlv -l 100%FREE optvg
sudo mkfs.xfs -f /dev/optvg/optlv

6) Mount old /opt temporarily and mount the new /opt

sudo mkdir -p /opt_old
sudo mount /dev/rootvg/optlv /opt_old

sudo mount /dev/optvg/optlv /opt

7) Copy data across (safe migration)

sudo rsync -aHAXx --numeric-ids /opt_old/ /opt/
sudo restorecon -RFv /opt

8) Make it persistent via /etc/fstab using UUID

sudo blkid /dev/optvg/optlv
sudo cp /etc/fstab /etc/fstab.bak
sudo vi /etc/fstab

Add:

UUID=<NEW_UUID>  /opt  xfs  defaults,nofail  0  0

Test:

sudo umount /opt
sudo mount -a
df -Th /opt

9) Verify final layout

lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT
lvs -o lv_name,vg_name,lv_size,devices

Troubleshooting Tips

“mv: cannot move /opt … resource busy”

That happens when /opt is mounted and/or actively used. The right fix is:

  • stop services using /opt (if any)
  • unmount /opt
  • remount as per above

df -h still doesn’t show sdc

That’s expected until:

  • filesystem exists, AND
  • it’s mounted (e.g., /opt)