Btrfs to Ext4 Migration Automation Helper Script
# ==============================================================================
# Btrfs to Ext4 Migration Automation Helper Script
# ==============================================================================
# This script guides and automates the migration of a filesystem from Btrfs to Ext4.
# Because in-place conversion is not possible, this script automates the:
# 1. Backup phase (via rsync with preservation of all attributes)
# 2. Unmounting and formatting of the target partition to Ext4
# 3. Acquisition of the new UUID and generation of the /etc/fstab entry
# 4. Verification and mounting test of the new configuration
# 5. Restore phase (via rsync)
# WARNING: Formatting is destructive. Ensure your backups are complete and verified.
# ==============================================================================
set -euo pipefail
# ANSI color codes for readability
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log_info() {
echo -e "
}
log_success() {
echo -e "
}
log_warn() {
echo -e "
}
log_error() {
echo -e "
}
# ------------------------------------------------------------------------------
# 1. Root Check
# ------------------------------------------------------------------------------
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run with root privileges (sudo)."
exit 1
fi
# ------------------------------------------------------------------------------
# 2. Interactive Input Gather & Validation
# ------------------------------------------------------------------------------
echo -e "
echo "This helper will guide you through backing up, formatting, and restoring your data."
echo ""
# Get Source Mount
read -rp "Enter the current Btrfs mount path (e.g., /mnt/btrfs-source): " SOURCE_MOUNT
if [! -d "$SOURCE_MOUNT" ]; then
log_error "Source directory '$SOURCE_MOUNT' does not exist."
exit 1
fi
# Ensure trailing slash for rsync
RSYNC_SOURCE="${SOURCE_MOUNT%/}/"
# Get Backup Destination
read -rp "Enter the backup destination directory (e.g., /mnt/backup-destination): " BACKUP_DEST
if [! -d "$BACKUP_DEST" ]; then
log_warn "Backup directory '$BACKUP_DEST' does not exist. Attempting to create it..."
mkdir -p "$BACKUP_DEST"
fi
RSYNC_BACKUP="${BACKUP_DEST%/}/"
# Get Partition Block Device
read -rp "Enter the partition block device to be formatted (e.g., /dev/sdXN): " BLOCK_DEVICE
if [! -b "$BLOCK_DEVICE" ]; then
log_error "Block device '$BLOCK_DEVICE' does not exist or is not a block device."
exit 1
fi
# Confirm device details to prevent disastrous formatting of wrong drive
echo -e "\n
lsblk "$BLOCK_DEVICE" || true
echo ""
read -rp "Are you absolutely sure '$BLOCK_DEVICE' is the correct partition to format? (type 'YES' to confirm): " CONFIRM_DEVICE
if [ "$CONFIRM_DEVICE"!= "YES" ]; then
log_error "Migration aborted by user."
exit 1
fi
# ------------------------------------------------------------------------------
# 3. Step 1: Backup Phase
# ------------------------------------------------------------------------------
echo -e "\n
log_info "Running rsync to back up $RSYNC_SOURCE to $RSYNC_BACKUP"
log_info "Preserving ownership (numeric IDs), hard links, ACLs, and extended attributes..."
# Execute rsync with recommended flags
rsync -aHAXv --numeric-ids --progress "
log_success "Backup completed successfully."
# ------------------------------------------------------------------------------
# 4. Step 2: Unmount & Format
# ------------------------------------------------------------------------------
echo -e "\n
log_info "Unmounting '$BLOCK_DEVICE'..."
if mountpoint -q "
umount "
log_success "Successfully unmounted '$BLOCK_DEVICE'."
else
log_info "'$BLOCK_DEVICE' is already unmounted."
fi
log_warn "formatting '$BLOCK_DEVICE' to Ext4 in 5 seconds. Press Ctrl+C to abort now!"
sleep 5
log_info "Formatting '$BLOCK_DEVICE' with mkfs.ext4..."
mkfs.ext4 "$BLOCK_DEVICE"
log_success "Partition formatted to Ext4 successfully."
# ------------------------------------------------------------------------------
# 5. Step 3: Get New UUID & Guide fstab Updates
# ------------------------------------------------------------------------------
echo -e "\n
NEW_UUID=
log_info "New partition UUID: $NEW_UUID"
FSTAB_LINE="UUID=$NEW_UUID $SOURCE_MOUNT ext4 defaults,noatime,x-systemd.mount-timeout=10s 0 2"
echo -e "\n
echo -e "Replace the old Btrfs entry for '$SOURCE_MOUNT' with the following line:\n"
echo -e "
echo "Options used:"
echo " - defaults: Standard mounting options."
echo " - noatime: Disables writing access times to increase speed and decrease disk wear."
echo " - x-systemd.mount-timeout=10s: Safe systemd timeout to avoid boot hang in case of failure."
echo " - 0: Disables dump backup."
echo " - 2: Performs fsck check on boot after root."
echo ""
read -rp "Press [Enter] after you have updated and saved /etc/fstab (you can do this in another terminal tab)." DUMMY
# ------------------------------------------------------------------------------
# 6. Step 4: Verification and Mount Test
# ------------------------------------------------------------------------------
echo -e "\n
log_info "Checking /etc/fstab structure using findmnt..."
if! findmnt --verify; then
log_error "/etc/fstab verification failed! Please fix your fstab before continuing."
exit 1
fi
log_success "fstab syntax and structure verified successfully."
log_info "Testing mount of configured paths..."
# Unmount if target path is active to ensure we test mount-a cleanly
if mountpoint -q "$SOURCE_MOUNT"; then
umount "$SOURCE_MOUNT"
fi
log_info "Running 'mount -a -v' to test the new configuration..."
mount -a -v
# Verify active mount point
if findmnt "$SOURCE_MOUNT" > /dev/null; then
log_success "The partition successfully mounted to '$SOURCE_MOUNT' using the new /etc/fstab configuration."
df -h "$SOURCE_MOUNT"
else
log_error "Failed to mount the partition to '$SOURCE_MOUNT'. Please check fstab."
exit 1
fi
# ------------------------------------------------------------------------------
# 7. Step 5: Restore Phase
# ------------------------------------------------------------------------------
echo -e "\n
log_info "Restoring files from backup location (
rsync -aHAXv --numeric-ids --progress "
log_success "Data restore complete!"
echo -e "\n
echo -e " Migration of '$BLOCK_DEVICE' from Btrfs to Ext4 is fully complete!"
echo -e " Your partition is mounted at '$SOURCE_MOUNT' and your files are restored."
echo -e "======================================================================${NC}"
Gemini
Data Loss Hazard
This script formats a storage drive (mkfs.ext4). If you enter the wrong block device name during the interactive prompts, you will permanently erase data. Ensure you have an external backup before proceeding.
To run this script on a Linux system, save the code to a file, make it executable, and run it with sudo privileges.
1
Save the script to a file
Terminal command
Open a terminal and save the content into a script file named btrfs_to_ext4.sh using your preferred text editor (e.g., nano):
nano btrfs_to_ext4.sh
Paste the script into the file, save, and exit (Ctrl+O, Enter, then Ctrl+X in nano).
2
Make the script executable
Permissions setup
Grant execution permissions to the script file:
chmod +x btrfs_to_ext4.sh
3
Identify your paths and drives
Prerequisite data collection
Before executing, run lsblk and df -h in your terminal to note down:
- Current Btrfs mount path (e.g.,
/mnt/btrfs-source) - Backup destination path (must be on a different drive/partition with enough free space to hold all your data)
- Target partition block device (e.g.,
/dev/sdb1)
4
Execute the script with root privileges
Requires sudo
Run the script using sudo:
sudo ./btrfs_to_ext4.sh
5
Follow the interactive prompts
During execution
The script will prompt you for inputs sequentially:
- Enter the current mount path.
- Enter the backup location path.
- Enter the block device (e.g.,
/dev/sdXN). - Type
YESin all caps to confirm formatting. - When prompted in Step 3, open a separate terminal window to update
/etc/fstabwith the generated line before pressing[Enter]to finish.
You
Can you guide me step-by-step on how to edit /etc/fstab safely?
Gemini
Editing /etc/fstab requires root privileges. Because syntax errors or incorrect UUIDs can prevent your Linux system from booting, always create a backup copy before making changes and verify your changes before rebooting.
System Boot Hazard
An invalid line in /etc/fstab can cause systemd to fail to mount root or local drives during startup, dropping you into an emergency recovery shell. Always run verification commands before rebooting.
1
Create a backup of /etc/fstab
Safety prerequisite
Open your terminal and copy the current working configuration file to a safe backup location:
sudo cp /etc/fstab /etc/fstab.bak
2
Open the file in a text editor
Terminal command
Use a simple text editor like nano with root privileges:
sudo nano /etc/fstab
3
Navigate using your keyboard's arrow keys.
- To replace an existing line: Locate the old Btrfs entry for your mount point, use
Ctrl+Kto delete the line, and type (or paste) your new Ext4 entry. - To add a new line: Scroll to the bottom of the file and add your line on a new row.
Ensure fields are separated by single spaces or tabs: UUID=<your-uuid> <mount-point> ext4 defaults,noatime,x-systemd.mount-timeout=10s 0 2
4
Save and exit nano
Nano shortcuts
- Press
Ctrl + Oand pressEnterto write the file. - Press
Ctrl + Xto exit the editor.
5
Verify the configuration
Critical step before rebooting
Verify the file syntax and test mounting without rebooting:
sudo findmnt --verify
If findmnt returns errors, re-open /etc/fstab and fix the syntax immediately. If it passes, test mounting all filesystems defined in fstab:
sudo mount -a -v
If mount -a completes without throwing errors, your /etc/fstab configuration is safe and working.
What to do if something goes wrong
If findmnt fails or mount -a throws an error, you can immediately restore your working backup with:
sudo cp /etc/fstab.bak /etc/fstab
Where would you like to go next?