Linux Disk Resize Tool

Published: 2026-06-04
Google AdSense 广告位 (待申请通过后开启)

The following command-line tool automatically creates partitions, is compatible with all Linux distributions, automatically recognizes the system name, and is simple, convenient, and practical.

Note that you must log in as the root user to perform this operation. Regular users must force log out before executing the command.

1. Check if /opt has enough space for the backup? Potential risk: The script's first step will completely package /home into /opt/home.tar.gz. If your /opt directory is actually under the root directory /, and the root directory is almost full, the tar backup will be interrupted due to insufficient disk space. Security recommendation: Before running, execute df -h /opt to ensure that the available space in /opt is greater than the total used space in /home.

2. The user logging in remotely via SSH must not be a user under /home! Potential risk: If you are currently logged in as a regular user (e.g., admin, whose home directory is /home/admin), and then switch to root using su -, when executing the second step fuser -km /home, the system will instantly disconnect your SSH connection, causing the script to terminate directly in the background. Since the old volume has been deleted and the new volume has not been created, the system will crash. Security recommendation: You must modify the SSH configuration to allow the root user to log in remotely, or run the script in the background in a tmux/screen virtual terminal.

3. Potential Risks in File System Type Confirmation: The script hardcodes `mkfs.xfs` and `xfs_growfs`. If your system was installed using the Ext4 file system (common in Debian/Ubuntu, and some older versions of CentOS), executing these commands will result in an error and crash, triggering a rollback. Security Recommendation: Before running the script, be sure to execute `df -T /home` to confirm that the `Type` column displays `xfs`.

Simply enter the numerical size of your home space.


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

`disk_resize.sh 100`

100 sets the home directory space size in GB, which cannot exceed 3/2 of the hard drive size. The remaining space is automatically allocated to the `/` root directory. Very convenient.

To ensure absolute security:

# 1. Create a 20GB secure snapshot (named root_backup) for the current root directory.

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

# 2. Create a 20GB secure snapshot (named home_backup) for the current home directory.

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

Snapshot creation takes only 1 second. If the script encounters an error, power outage, or the system freezes and becomes inaccessible:

You only need to type the following command as root:

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

The system will instantly rewind time, perfectly restoring all data, partitions, and environment to the state just before you executed the script. No system reinstallation is required! If the script executes successfully and you're sure there are no problems: type the command `lvremove /dev/mapper/almalinux-*_backup` to delete the snapshot; it won't take up any extra space.

Explore More

Technology Guides →

Building a Linux Command Search Tool with Java Swing

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

Linux 分区命令实战:fdisk、parted、lsblk 使用教程

How To Install Linux

Southeast Asia Insights →