How to Efficiently Clone a BTRFS Partition While Preserving Subvolumes and Snapshots


2 views


When dealing with BTRFS partitions containing subvolumes and snapshots, traditional block-level tools like dd become inefficient solutions. Here's why we need specialized approaches:

  • BTRFS uses copy-on-write (COW) mechanisms for snapshots
  • Subvolume relationships must be preserved
  • Metadata consistency is critical for restore operations

The most effective approach combines BTRFS-native commands with proper mounting techniques:

# First, create the target filesystem
sudo mkfs.btrfs /dev/sdX1

# Mount both source and target
sudo mkdir -p /mnt/{source,target}
sudo mount /dev/sdY1 /mnt/source
sudo mount /dev/sdX1 /mnt/target

# Send/receive the root subvolume
sudo btrfs subvolume snapshot -r /mnt/source /mnt/source/root_snap
sudo btrfs send /mnt/source/root_snap | sudo btrfs receive /mnt/target

# Repeat for other subvolumes
for subvol in home var; do
    sudo btrfs subvolume snapshot -r /mnt/source/$subvol /mnt/source/${subvol}_snap
    sudo btrfs send /mnt/source/${subvol}_snap | sudo btrfs receive /mnt/target
done

For regular backups, use the incremental send/receive feature:

# Initial full backup
sudo btrfs send /mnt/source/full_snap | sudo btrfs receive /mnt/target

# Later incremental backup
sudo btrfs send -p /mnt/source/full_snap /mnt/source/incr_snap | sudo btrfs receive /mnt/target

Consider these specialized utilities for more complex scenarios:

# Using btrbk for automated backups
btrbk -c btrbk.conf run

# Example btrbk.conf snippet:
snapshot_preserve_min   2d
snapshot_preserve      14d
target_preserve_min    7d
target_preserve       30d

Always validate your backups with these commands:

sudo btrfs scrub start /mnt/target
sudo btrfs fi show /mnt/target
sudo btrfs subvolume list /mnt/target

For large partitions, optimize with these parameters:

# Use compression during transfer
sudo btrfs send -c /mnt/source/snap | pv | sudo btrfs receive /mnt/target

# Parallel processing (requires recent kernels)
sudo btrfs send --compress zstd --max-errors 0 /mnt/source/snap | \
    sudo btrfs receive --max-errors 0 /mnt/target


When working with Btrfs partitions containing subvolumes and snapshots, traditional backup methods like dd or rsync often fall short. The challenge lies in preserving:

  • Copy-on-Write (COW) metadata
  • Subvolume relationships
  • Snapshot tree structures
  • Compression attributes

Btrfs provides several built-in tools specifically designed for this purpose:

# Create a read-only snapshot first (recommended)
sudo btrfs subvolume snapshot -r /mnt/btrfs_root /mnt/btrfs_root/backup_snapshot

# Send/receive between mounted Btrfs filesystems
sudo btrfs send /mnt/btrfs_root/backup_snapshot | sudo btrfs receive /mnt/backup_destination

For regular backups, use the incremental send/receive feature:

# Initial full backup
sudo btrfs send /mnt/btrfs_root/snapshot_v1 | sudo btrfs receive /mnt/backup

# Subsequent incremental backup
sudo btrfs send -p /mnt/btrfs_root/snapshot_v1 /mnt/btrfs_root/snapshot_v2 | sudo btrfs receive /mnt/backup

For complex setups with multiple subvolumes:

# Backup root subvolume with all child subvolumes
sudo btrfs subvolume snapshot -r / /mnt/snapshots/full_backup
sudo btrfs send /mnt/snapshots/full_backup | sudo btrfs receive /mnt/backup_drive

# Using compression during transfer (recommended)
sudo btrfs send /mnt/snapshots/full_backup | gzip | sudo btrfs receive /mnt/backup_drive

Here's a practical bash script for scheduled backups:

#!/bin/bash
SOURCE="/mnt/btrfs_root"
DEST="/mnt/backup_drive"
SNAPSHOT_NAME="backup_$(date +%Y%m%d_%H%M%S)"

# Create read-only snapshot
btrfs subvolume snapshot -r "${SOURCE}" "${SOURCE}/${SNAPSHOT_NAME}"

# Get last snapshot for incremental backup
LAST_SNAP=$(ls -1t "${SOURCE}" | grep -E '^backup_' | head -2 | tail -1)

if [ -z "${LAST_SNAP}" ]; then
    # Full backup
    btrfs send "${SOURCE}/${SNAPSHOT_NAME}" | btrfs receive "${DEST}"
else
    # Incremental backup
    btrfs send -p "${SOURCE}/${LAST_SNAP}" "${SOURCE}/${SNAPSHOT_NAME}" | btrfs receive "${DEST}"
fi

Always verify your backups:

# Compare source and backup checksums
sudo btrfs filesystem du -s /mnt/btrfs_root/backup_snapshot
sudo btrfs filesystem du -s /mnt/backup_drive/backup_snapshot

# Check filesystem integrity
sudo btrfs scrub start /mnt/backup_drive