#!/bin/bash # Simple LVM Backup Script # Does exactly what it says: snapshot -> copy -> cleanup # NO complex logic, just the essentials set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' usage() { echo "Usage: $0 SOURCE_LV TARGET_DEVICE" echo "" echo "Example: $0 /dev/internal-vg/root /dev/sdb" echo "" echo "This will:" echo "1. Create a snapshot of SOURCE_LV" echo "2. Copy it block-for-block to TARGET_DEVICE" echo "3. Clean up the snapshot" echo "" echo "WARNING: TARGET_DEVICE will be completely overwritten!" exit 1 } log() { echo -e "${GREEN}[$(date '+%H:%M:%S')] $1${NC}" } error() { echo -e "${RED}[ERROR] $1${NC}" >&2 cleanup_and_exit 1 } warn() { echo -e "${YELLOW}[WARNING] $1${NC}" } cleanup_and_exit() { local exit_code=${1:-0} if [ -n "$SNAPSHOT_PATH" ] && lvs "$SNAPSHOT_PATH" >/dev/null 2>&1; then warn "Cleaning up snapshot: $SNAPSHOT_PATH" lvremove -f "$SNAPSHOT_PATH" || warn "Failed to remove snapshot" fi exit $exit_code } # Trap for cleanup trap 'cleanup_and_exit 130' INT TERM # Check arguments if [ $# -ne 2 ]; then usage fi SOURCE_LV="$1" TARGET_DEVICE="$2" # Check if running as root if [ "$EUID" -ne 0 ]; then error "This script must be run as root" fi # Basic validation if [ ! -e "$SOURCE_LV" ]; then error "Source LV does not exist: $SOURCE_LV" fi if [ ! -e "$TARGET_DEVICE" ]; then error "Target device does not exist: $TARGET_DEVICE" fi # Extract VG and LV names VG_NAME=$(lvs --noheadings -o vg_name "$SOURCE_LV" | tr -d ' ') LV_NAME=$(lvs --noheadings -o lv_name "$SOURCE_LV" | tr -d ' ') SNAPSHOT_NAME="${LV_NAME}_simple_backup" SNAPSHOT_PATH="/dev/$VG_NAME/$SNAPSHOT_NAME" log "Simple LVM Backup Starting" log "Source: $SOURCE_LV" log "Target: $TARGET_DEVICE" log "Snapshot will be: $SNAPSHOT_PATH" # Final confirmation echo "" echo -e "${YELLOW}WARNING: This will completely overwrite $TARGET_DEVICE${NC}" echo -e "${YELLOW}All data on $TARGET_DEVICE will be lost!${NC}" echo "" read -p "Are you sure you want to continue? (yes/no): " confirm if [ "$confirm" != "yes" ]; then echo "Backup cancelled." exit 0 fi echo "" log "Starting backup process..." # Step 1: Create snapshot log "Creating snapshot..." if ! lvcreate -L1G -s -n "$SNAPSHOT_NAME" "$SOURCE_LV"; then error "Failed to create snapshot" fi log "Snapshot created: $SNAPSHOT_PATH" # Step 2: Copy data log "Starting copy operation..." log "This may take a long time depending on the size of your data" # Use pv if available for progress, otherwise dd with progress if command -v pv >/dev/null 2>&1; then log "Using pv for progress monitoring" if ! pv "$SNAPSHOT_PATH" | dd of="$TARGET_DEVICE" bs=4M; then error "Copy operation failed" fi else log "Using dd (install 'pv' for progress monitoring)" if ! dd if="$SNAPSHOT_PATH" of="$TARGET_DEVICE" bs=4M status=progress; then error "Copy operation failed" fi fi log "Copy completed successfully" # Step 3: Clean up snapshot log "Removing snapshot..." if ! lvremove -f "$SNAPSHOT_PATH"; then warn "Failed to remove snapshot, but backup completed" warn "You may need to manually remove: $SNAPSHOT_PATH" else log "Snapshot cleaned up" fi log "Backup completed successfully!" log "Your data has been copied to: $TARGET_DEVICE" echo "" echo -e "${GREEN}SUCCESS: Backup completed!${NC}" echo "" echo "To verify the backup, you can:" echo "1. Mount $TARGET_DEVICE and check the files" echo "2. Boot from $TARGET_DEVICE if it's bootable" echo ""