Files
backup_to_external_m.2/lvm_block_backup.sh
root 56c07dbe49 Complete rewrite: Single working LVM block-level backup script
- Removed 40+ broken/messy scripts, moved to old_scripts/
- Created lvm_block_backup.sh - proper block-level LVM snapshot backup
- Uses dd for block-level cloning instead of file-level rsync
- Successfully tested: 462GB backup in 33 minutes
- Creates exact, bootable clone of internal drive to external drive
- Proper LVM snapshot management with cleanup
- Clear documentation in README_BACKUP.md
- Clean, minimal solution that actually works
2025-09-30 17:35:22 +02:00

193 lines
5.5 KiB
Bash
Executable File

#!/bin/bash
# LVM Block-Level Backup Script
# Creates consistent snapshots and clones entire volumes block-for-block
# This is the ONLY backup script you need!
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Configuration
SOURCE_VG="internal-vg"
TARGET_VG="migration-vg"
SNAPSHOT_SIZE="2G"
LOG_FILE="/var/log/lvm-block-backup.log"
log() {
local message="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
echo -e "${BLUE}$message${NC}"
echo "$message" >> "$LOG_FILE"
}
error() {
local message="[ERROR] $1"
echo -e "${RED}$message${NC}" >&2
echo "$message" >> "$LOG_FILE"
exit 1
}
success() {
local message="[SUCCESS] $1"
echo -e "${GREEN}$message${NC}"
echo "$message" >> "$LOG_FILE"
}
warning() {
local message="[WARNING] $1"
echo -e "${YELLOW}$message${NC}"
echo "$message" >> "$LOG_FILE"
}
check_requirements() {
log "Checking system requirements..."
# Check if running as root
if [ "$EUID" -ne 0 ]; then
error "This script must be run as root. Use: sudo $0"
fi
# Check if source VG exists
if ! vgs "$SOURCE_VG" >/dev/null 2>&1; then
error "Source volume group '$SOURCE_VG' not found"
fi
# Check if target VG exists
if ! vgs "$TARGET_VG" >/dev/null 2>&1; then
error "Target volume group '$TARGET_VG' not found"
fi
# Check if volumes exist
local volumes=("root" "home" "boot")
for vol in "${volumes[@]}"; do
if ! lvs "$SOURCE_VG/$vol" >/dev/null 2>&1; then
error "Source logical volume '$SOURCE_VG/$vol' not found"
fi
if ! lvs "$TARGET_VG/$vol" >/dev/null 2>&1; then
error "Target logical volume '$TARGET_VG/$vol' not found"
fi
done
# Check available space for snapshots
local vg_free=$(vgs --noheadings -o vg_free --units g "$SOURCE_VG" | tr -d ' G')
local vg_free_int=${vg_free%.*}
if [ "$vg_free_int" -lt 6 ]; then
error "Insufficient free space for snapshots. Need at least 6GB, have ${vg_free}GB"
fi
success "System requirements check passed"
}
cleanup_snapshots() {
log "Cleaning up any existing snapshots..."
lvremove -f "$SOURCE_VG/root-backup-snap" 2>/dev/null || true
lvremove -f "$SOURCE_VG/home-backup-snap" 2>/dev/null || true
lvremove -f "$SOURCE_VG/boot-backup-snap" 2>/dev/null || true
}
create_snapshots() {
log "Creating LVM snapshots for consistent backup..."
cleanup_snapshots
# Create snapshots
lvcreate -L "$SNAPSHOT_SIZE" -s -n root-backup-snap "$SOURCE_VG/root" || error "Failed to create root snapshot"
lvcreate -L "$SNAPSHOT_SIZE" -s -n home-backup-snap "$SOURCE_VG/home" || error "Failed to create home snapshot"
lvcreate -L 1G -s -n boot-backup-snap "$SOURCE_VG/boot" || error "Failed to create boot snapshot"
success "Snapshots created successfully"
}
clone_volumes() {
log "Starting block-level volume cloning..."
# Unmount target volumes if mounted
umount "/dev/$TARGET_VG/home" 2>/dev/null || true
umount "/dev/$TARGET_VG/root" 2>/dev/null || true
umount "/dev/$TARGET_VG/boot" 2>/dev/null || true
# Clone root volume
log "Cloning root volume (this may take a while)..."
dd if="/dev/$SOURCE_VG/root-backup-snap" of="/dev/$TARGET_VG/root" bs=64M status=progress || error "Failed to clone root volume"
success "Root volume cloned"
# Clone home volume
log "Cloning home volume (this will take the longest)..."
dd if="/dev/$SOURCE_VG/home-backup-snap" of="/dev/$TARGET_VG/home" bs=64M status=progress || error "Failed to clone home volume"
success "Home volume cloned"
# Clone boot volume
log "Cloning boot volume..."
dd if="/dev/$SOURCE_VG/boot-backup-snap" of="/dev/$TARGET_VG/boot" bs=64M status=progress || error "Failed to clone boot volume"
success "Boot volume cloned"
}
verify_backup() {
log "Verifying backup integrity..."
# Check filesystem integrity
fsck -n "/dev/$TARGET_VG/root" || warning "Root filesystem check showed issues"
fsck -n "/dev/$TARGET_VG/boot" || warning "Boot filesystem check showed issues"
# Note: Can't check encrypted home volume without decryption
success "Backup verification completed"
}
show_backup_info() {
log "Creating backup information..."
cat << EOF
=====================================
LVM Block-Level Backup Complete
=====================================
Date: $(date)
Source: $SOURCE_VG
Target: $TARGET_VG
Volume Information:
$(lvs $SOURCE_VG $TARGET_VG)
The external drive now contains an exact block-level copy of your internal drive.
You can boot from the external drive by selecting it in your BIOS/UEFI boot menu.
To mount the backup volumes:
sudo mount /dev/$TARGET_VG/root /mnt/backup-root
sudo mount /dev/$TARGET_VG/boot /mnt/backup-boot
# Home volume needs LUKS decryption first
EOF
}
main() {
echo -e "${GREEN}=== LVM Block-Level Backup Tool ===${NC}"
echo "This will create an exact copy of your internal LVM volumes to the external drive."
echo
read -p "Are you sure you want to proceed? This will OVERWRITE data on $TARGET_VG! [y/N]: " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Backup cancelled."
exit 0
fi
check_requirements
create_snapshots
clone_volumes
cleanup_snapshots
verify_backup
show_backup_info
success "Backup completed successfully!"
}
# Trap to cleanup on exit
trap cleanup_snapshots EXIT
main "$@"