Linux Disk Resize Tool: Automated LVM Home Partition Resize and Root Expansion

Published: 2026-06-04

Managing disk space on Linux servers is a common problem.

After a Linux system has been running for a long time, many users eventually encounter situations like:

  • The `/home` partition has too much unused space.
  • The `/` root partition is running out of space.
  • Installing packages or updating the system fails because the root filesystem is full.
  • Manual LVM resizing operations are complicated and risky.

Many enterprise Linux distributions use LVM by default, including:

  • AlmaLinux
  • Fedora
  • Red Hat Enterprise Linux
  • Rocky Linux
  • CentOS Stream

Usually the default configuration contains:

  • LVM Logical Volumes
  • XFS filesystem

Manually resizing partitions requires multiple dangerous steps:

lvremove

lvextend

lvcreate

mkfs.xfs

mount

tar restore

A mistake in any step may cause:

  • Data loss
  • System boot failure
  • Incorrect filesystem configuration

To simplify this process, I created this Linux Disk Resize Tool.

It automatically handles:

  • LVM detection
  • `/home` backup
  • Root volume expansion
  • New `/home` recreation
  • Data restoration
  • Permission recovery
  • Safety verification

The goal is to make Linux disk management easier and safer.

Features

Automatic LVM Detection

The script automatically detects:

Volume Group name

/home Logical Volume

/root Logical Volume

No need to manually modify device paths.

This reduces human errors during disk operations.

Automatic /home Backup

Before modifying the disk structure, the script creates a complete backup:

/opt/home.tar.gz

The backup contains:

  • User files
  • Development environments
  • Configuration files
  • Desktop settings
  • Personal data

The command used internally:

tar -zcvf /opt/home.tar.gz -C /home .

If anything goes wrong, the original data can be restored.

Automatic Root Filesystem Expansion

After removing the old `/home` logical volume, the released space is automatically added to:

/

The script performs:

lvextend -l +100%FREE

xfs_growfs /

No manual calculation of:

  • Physical extents
  • Logical volume size
  • Filesystem expansion

is required.

Automatic Permission Restoration

After restoring files, ownership is automatically repaired:

chown -R username:username /home/username

This prevents problems such as:

  • Permission denied errors
  • Incorrect ownership
  • Broken user environments

Important Safety Checks

This tool directly modifies disk structures.

Before running it, please verify the following requirements.

1. Verify Backup Space

The first step creates:

/opt/home.tar.gz

Therefore `/opt` must have enough free space.

Check:

df -h /opt

The available space should be larger than the current `/home` usage.

Otherwise the backup process may fail because of insufficient storage.

2. Run as Root User

This script requires full root privileges.

Recommended:

su -

cd /root

./disk_resize.sh 100

Do not run:

sudo ./disk_resize.sh 100

The script performs operations such as:

umount /home

lvremove

lvcreate

which require direct root access.

3. Verify Filesystem Type

Current version supports:

LVM + XFS filesystem

Check:

df -T /home

Confirm:

Type = xfs

Because the script uses:

mkfs.xfs

xfs_growfs

Ext4 systems require different filesystem commands.

Usage

Create the script:

cat << 'EOF' > /root/disk_resize.sh

#!/bin/bash

# Complete script content

EOF

chmod +x /root/disk_resize.sh

Run:

/root/disk_resize.sh 100

Parameter:

100
means the new /home size will become 100GB.

The remaining disk space will automatically be allocated to:

/

Script Workflow

The complete workflow:

1. Check system environment
↓
2. Detect LVM configuration
↓
3. Backup /home data
↓
4. Unmount /home
↓
5. Remove old /home volume
↓
6. Extend root volume
↓
7. Create new /home volume
↓
8. Format XFS filesystem
↓
9. Restore user data
↓
10. Restore permissions
↓
11. Complete

Complete Script

The following script contains:

  • Environment validation
  • LVM automatic detection
  • Disk safety checks
  • Backup mechanism
  • Error handling
  • Rollback protection
  • Data restoration
  • Permission recovery

cat << 'EOF' > /root/disk_resize.sh
#!/bin/bash

# Ensure the script triggers the error trap immediately on failure to prevent partial crashes
trap 'on_error' ERR

on_error() {
    echo -e "\nāŒ WARNING: Exception triggered during script execution! Initiating rollback mechanism..."
    # If the home volume is missing, try to restore the original state
    if ! lvs | grep -q "home"; then
        echo "Attempting to recreate default home volume to safeguard the boot system..."
        lvcreate -L ${CURRENT_HOME_SIZE_G}G -n home $VG_NAME || true
        mkfs.xfs -f /dev/mapper/${VG_NAME}-home || true
        mount /dev/mapper/${VG_NAME}-home || true
    fi
    echo "āš ļø Emergency rollback complete. System cleared from deadlock risk. Please check errors above, DO NOT reboot!"
    exit 1
}

# ==================== [Strict Numeric Parameter Validation] ====================
if [ -z "$1" ]; then
    echo "āŒ ERROR: Missing target size parameter!"
    echo "šŸ’” Usage: $0 [integer_only]"
    echo "   Example: $0 97"
    exit 1
fi

INPUT_SIZE="$1"

if [[ ! "$INPUT_SIZE" =~ ^[0-9]+$ ]]; then
    echo "āŒ FORBIDDEN: For production safety, unit suffixes (such as G, GB, M, K) are strictly prohibited!"
    echo "šŸ’” Correct approach: Enter numbers only. For 97GB, type: $0 97"
    exit 1
fi

NUMERIC_SIZE=$INPUT_SIZE
TARGET_SIZE="${NUMERIC_SIZE}G"

if [ "$NUMERIC_SIZE" -le 5 ]; then
    echo "āŒ SAFETY BLOCK: The new size for /home must be [greater than 5GB]!"
    exit 1
fi

echo "=== [Verification] Comprehensive environment, disk boundaries, and inode risks check ==="

if [ "$EUID" -ne 0 ]; then
    echo "āŒ ERROR: Do not use sudo or a standard user to run this script! Please log in directly as root."
    exit 1
fi

if pwd | grep -q "^/home"; then
    echo "āŒ ERROR: Your current working directory is inside /home! Please switch out by running 'cd /root'."
    exit 1
fi

VG_NAME=$(lvs --noheadings -o vg_name /dev/mapper/*-home | head -n1 | tr -d ' ')
if [ -z "$VG_NAME" ]; then
    echo "āŒ ERROR: Failed to automatically detect the Volume Group (VG) name!"
    exit 1
fi
export VG_NAME
HOME_LV_PATH="/dev/mapper/${VG_NAME}-home"
ROOT_LV_PATH="/dev/mapper/${VG_NAME}-root"

VG_TOTAL_SIZE_G=$(vgs --noheadings -o vg_size --units g $VG_NAME | head -n1 | grep -o -E '[0-9]+' | head -n1)
MAX_ALLOWED_SIZE=$(( (VG_TOTAL_SIZE_G * 2) / 3 ))

if [ "$NUMERIC_SIZE" -ge "$MAX_ALLOWED_SIZE" ]; then
    echo "āŒ LIMIT EXCEEDED: The requested ${NUMERIC_SIZE}GB reaches or exceeds the maximum safety cap of ${MAX_ALLOWED_SIZE}GB (2/3 of total space)!"
    exit 1
fi

CURRENT_HOME_SIZE_G=$(df -G /home | awk 'NR==2 {print $2}' | grep -o -E '[0-9]+' || df -h /home | awk 'NR==2 {print $2}' | grep -o -E '[0-9]+' | head -n1)
export CURRENT_HOME_SIZE_G
if [ -n "$CURRENT_HOME_SIZE_G" ]; then
    if [ "$NUMERIC_SIZE" -ge "$CURRENT_HOME_SIZE_G" ]; then
        echo "āŒ SAFETY CIRCUIT: The new size must be [smaller] than the current total size (${CURRENT_HOME_SIZE_G}GB)!"
        exit 1
    fi
fi

USED_HOME_SIZE_G=$(df -G /home | awk 'NR==2 {print $3}' || df -h /home | awk 'NR==2 {print $3}' | grep -o -E '[0-9]+' | head -n1)
if [ -n "$USED_HOME_SIZE_G" ]; then
    if [ "$NUMERIC_SIZE" -le "$USED_HOME_SIZE_G" ]; then
        echo "āŒ SAFETY BLOCK: The input value must be [greater] than the currently used space: ${USED_HOME_SIZE_G}GB!"
        exit 1
    fi
fi

CURRENT_INODES_USED=$(df -i /home | awk 'NR==2 {print $3}')
ESTIMATED_NEW_INODES=$(( NUMERIC_SIZE * 200000 ))
if [ "$CURRENT_INODES_USED" -gt "$ESTIMATED_NEW_INODES" ]; then
    echo "āŒ INODE EXHAUSTION WARNING: Too many small files detected. Insufficient space will trigger an inode crash!"
    exit 1
fi

USER_NAME=$(ls /home/ | head -n1 | tr -d ' ')
if [ "$USER_NAME" = "lost+found" ] || [ -z "$USER_NAME" ]; then USER_NAME=""; fi

echo "=== [1/5] Starting system data backup ==="
df -hT
tar -zcvf /opt/home.tar.gz -C /home .
echo "āœ… Data successfully backed up to /opt/home.tar.gz"

echo "--------------------------------------------------------"
echo "āš ļø  āš ļø  āš ļø  [CRITICAL WARNING: PROCEEDING TO PHYSICAL DISK ALTERATION] āš ļø  āš ļø  āš ļø"
echo "   All environment metrics passed verification. Backup completed."
echo "   Press [Enter] to execute disk resizing. If you are unsure, press [Ctrl + C] to exit safely!"
echo "--------------------------------------------------------"
read -r -p "Confirm and proceed? [Enter]"

echo "=== [2/5] Force unmounting volume ==="
fuser -km /home || true
umount /home

echo "=== [3/5] Removing old volume and fully extending root directory ==="
lvremove -f $HOME_LV_PATH
lvextend -l +100%FREE $ROOT_LV_PATH
xfs_growfs /

echo "=== [4/5] Recreating custom-sized [ ${TARGET_SIZE} ] home volume ==="
lvcreate -L $TARGET_SIZE -n home $VG_NAME
mkfs.xfs -f $HOME_LV_PATH
mount $HOME_LV_PATH

echo "=== [5/5] Restoring user data and permissions ==="
tar -zxvf /opt/home.tar.gz -C /home/
if [ -n "$USER_NAME" ]; then chown -R ${USER_NAME}:${USER_NAME} /home/${USER_NAME}/; fi

# Clear error trap context upon successful execution
trap - ERR

echo "=== šŸŽ‰ Congratulations, all automated actions completed successfully! System is secure! ==="
df -h
EOF

chmod +x /root/disk_resize.sh

Example

Resize `/home` to 100GB:

/root/disk_resize.sh 100

The script will:

  • Backup existing `/home`
  • Release old `/home` space
  • Expand `/`
  • Create a new `/home`
  • Restore all files

Additional Protection: LVM Snapshot Backup

For important production systems, creating an LVM snapshot before modification is strongly recommended.

Create a root filesystem snapshot:

lvcreate \
-L 20G \
-s \
-n root_backup \
/dev/mapper/almalinux-root

Create a home snapshot:

lvcreate \
-L 20G \
-s \
-n home_backup \
/dev/mapper/almalinux-home

Snapshot creation usually completes within seconds.

The advantage:

  • No reinstall required
  • No configuration loss
  • Fast rollback
  • Keeps original filesystem state

Rollback

If the system becomes unusable because of:

  • Power failure
  • Unexpected script interruption
  • Filesystem problem
  • Configuration error

Restore the previous state:

lvconvert --merge \
/dev/mapper/almalinux-root_backup

After reboot, the system returns to the snapshot state.

Remove Snapshot After Verification

If everything works correctly:

lvremove \
/dev/mapper/almalinux-*_backup

This removes the snapshot and returns the system to normal operation.

Real Usage Scenario

This tool is especially useful for:

  • Linux workstation migration
  • Developer machines
  • Virtual machines
  • Cloud servers
  • Lab environments
  • Enterprise Linux testing

For example:

A developer installs AlmaLinux with:

/
/home

After several months:

/home  → 200GB used space available

/      → almost full

Instead of reinstalling the system, this tool can rebalance the storage layout automatically.

Conclusion

Linux LVM provides extremely flexible storage management, but manual operations are still complicated and error-prone.

This tool simplifies the entire process:

  • Automatic detection
  • Automatic backup
  • Automatic resize
  • Automatic recovery
  • Minimal manual operation

For Linux administrators and developers, a reliable disk management script can save hours of maintenance work.

Always remember:

Before changing disk structures:
Backup first.
Verify twice.
Execute once.

Explore More

Technology Guides →

› Linux LVM Partition Management: Safely Resize `/home` and Extend Root Filesystem on AlmaLinux and RHEL

› Building a Linux Command Search Tool with Java Swing

› Firefox vs Chrome on Linux: Why Firefox Remains the Default Choice

› How to Stream Linux Command Output to a Swing JTextArea with ANSI Colors

Southeast Asia Insights →