Safety and reliability: timestamped snapshot names, safer LUKS open via stdin, read-only filesystem-aware mounts, VG free-space preflight in GUI; CLI strict mode and file-level snapshot sizing; README updates
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
# 2. LV → Raw: Create fresh backup on raw device
|
||||
# 3. VG → Raw: Clone entire volume group to raw device
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
@@ -170,7 +171,7 @@ case "$MODE" in
|
||||
# Extract VG and LV names
|
||||
VG_NAME=$(lvs --noheadings -o vg_name "$SOURCE" | tr -d ' ')
|
||||
LV_NAME=$(lvs --noheadings -o lv_name "$SOURCE" | tr -d ' ')
|
||||
SNAPSHOT_NAME="${LV_NAME}_backup_snap"
|
||||
SNAPSHOT_NAME="${LV_NAME}_backup_snap_$(date +%s)"
|
||||
SNAPSHOT_PATH="/dev/$VG_NAME/$SNAPSHOT_NAME"
|
||||
|
||||
info "This will update the existing backup LV"
|
||||
@@ -216,7 +217,7 @@ case "$MODE" in
|
||||
# Extract VG and LV names
|
||||
VG_NAME=$(lvs --noheadings -o vg_name "$SOURCE" | tr -d ' ')
|
||||
LV_NAME=$(lvs --noheadings -o lv_name "$SOURCE" | tr -d ' ')
|
||||
SNAPSHOT_NAME="${LV_NAME}_backup_snap"
|
||||
SNAPSHOT_NAME="${LV_NAME}_backup_snap_$(date +%s)"
|
||||
SNAPSHOT_PATH="/dev/$VG_NAME/$SNAPSHOT_NAME"
|
||||
|
||||
info "This will create a fresh backup on raw device"
|
||||
@@ -303,7 +304,7 @@ case "$MODE" in
|
||||
# Extract VG and LV names
|
||||
VG_NAME=$(lvs --noheadings -o vg_name "$SOURCE" | tr -d ' ')
|
||||
LV_NAME=$(lvs --noheadings -o lv_name "$SOURCE" | tr -d ' ')
|
||||
SNAPSHOT_NAME="${LV_NAME}_borg_snap"
|
||||
SNAPSHOT_NAME="${LV_NAME}_borg_snap_$(date +%s)"
|
||||
SNAPSHOT_PATH="/dev/$VG_NAME/$SNAPSHOT_NAME"
|
||||
|
||||
# Get LV size to determine appropriate snapshot size
|
||||
@@ -425,7 +426,7 @@ case "$MODE" in
|
||||
|
||||
# Process each LV one by one to avoid space issues
|
||||
for LV_NAME in $LV_LIST; do
|
||||
SNAPSHOT_NAME="${LV_NAME}_borg_snap"
|
||||
SNAPSHOT_NAME="${LV_NAME}_borg_snap_$(date +%s)"
|
||||
SNAPSHOT_PATH="/dev/$SOURCE/$SNAPSHOT_NAME"
|
||||
LV_PATH="/dev/$SOURCE/$LV_NAME"
|
||||
|
||||
@@ -487,27 +488,21 @@ case "$MODE" in
|
||||
# Extract VG and LV names
|
||||
VG_NAME=$(lvs --noheadings -o vg_name "$SOURCE" | tr -d ' ')
|
||||
LV_NAME=$(lvs --noheadings -o lv_name "$SOURCE" | tr -d ' ')
|
||||
SNAPSHOT_NAME="${LV_NAME}_files_snap"
|
||||
SNAPSHOT_NAME="${LV_NAME}_files_snap_$(date +%s)"
|
||||
SNAPSHOT_PATH="/dev/$VG_NAME/$SNAPSHOT_NAME"
|
||||
|
||||
# Get LV size to determine appropriate snapshot size
|
||||
# Get LV size to determine appropriate snapshot size (file-level needs much smaller)
|
||||
LV_SIZE_BYTES=$(lvs --noheadings -o lv_size --units b "$SOURCE" | tr -d ' ' | sed 's/B$//')
|
||||
# Use different percentages based on options
|
||||
if [ "$GENEROUS_SNAPSHOTS" = true ]; then
|
||||
SNAPSHOT_SIZE_BYTES=$((LV_SIZE_BYTES / 4)) # 25%
|
||||
MIN_SIZE=$((2 * 1024 * 1024 * 1024)) # 2GB minimum
|
||||
# File-level generous: 5% with 1G min, 20G max
|
||||
SNAPSHOT_SIZE_BYTES=$((LV_SIZE_BYTES * 5 / 100))
|
||||
[ $SNAPSHOT_SIZE_BYTES -lt $((1 * 1024 * 1024 * 1024)) ] && SNAPSHOT_SIZE_BYTES=$((1 * 1024 * 1024 * 1024))
|
||||
[ $SNAPSHOT_SIZE_BYTES -gt $((20 * 1024 * 1024 * 1024)) ] && SNAPSHOT_SIZE_BYTES=$((20 * 1024 * 1024 * 1024))
|
||||
else
|
||||
# Auto mode: 10% normally, 15% for large LVs
|
||||
if [ $LV_SIZE_BYTES -gt $((50 * 1024 * 1024 * 1024)) ]; then
|
||||
SNAPSHOT_SIZE_BYTES=$((LV_SIZE_BYTES * 15 / 100)) # 15% for >50GB
|
||||
else
|
||||
SNAPSHOT_SIZE_BYTES=$((LV_SIZE_BYTES / 10)) # 10% normally
|
||||
fi
|
||||
MIN_SIZE=$((1024 * 1024 * 1024)) # 1GB minimum
|
||||
fi
|
||||
|
||||
if [ $SNAPSHOT_SIZE_BYTES -lt $MIN_SIZE ]; then
|
||||
SNAPSHOT_SIZE_BYTES=$MIN_SIZE
|
||||
# Auto: 3% with 1G min, 15G max
|
||||
SNAPSHOT_SIZE_BYTES=$((LV_SIZE_BYTES * 3 / 100))
|
||||
[ $SNAPSHOT_SIZE_BYTES -lt $((1 * 1024 * 1024 * 1024)) ] && SNAPSHOT_SIZE_BYTES=$((1 * 1024 * 1024 * 1024))
|
||||
[ $SNAPSHOT_SIZE_BYTES -gt $((15 * 1024 * 1024 * 1024)) ] && SNAPSHOT_SIZE_BYTES=$((15 * 1024 * 1024 * 1024))
|
||||
fi
|
||||
SNAPSHOT_SIZE_GB=$((SNAPSHOT_SIZE_BYTES / 1073741824))
|
||||
SNAPSHOT_SIZE="${SNAPSHOT_SIZE_GB}G"
|
||||
@@ -549,9 +544,17 @@ case "$MODE" in
|
||||
# Create temporary mount point
|
||||
TEMP_MOUNT=$(mktemp -d -t borg_files_backup_XXXXXX)
|
||||
|
||||
# Mount snapshot
|
||||
log "Mounting snapshot to $TEMP_MOUNT"
|
||||
mount "$SNAPSHOT_PATH" "$TEMP_MOUNT" || error "Failed to mount snapshot"
|
||||
# Mount snapshot read-only with safe FS options
|
||||
FS_TYPE=$(blkid -o value -s TYPE "$SNAPSHOT_PATH" 2>/dev/null || echo "")
|
||||
if [ "$FS_TYPE" = "ext4" ] || [ "$FS_TYPE" = "ext3" ]; then
|
||||
MNT_OPTS="ro,noload"
|
||||
elif [ "$FS_TYPE" = "xfs" ]; then
|
||||
MNT_OPTS="ro,norecovery"
|
||||
else
|
||||
MNT_OPTS="ro"
|
||||
fi
|
||||
log "Mounting snapshot to $TEMP_MOUNT (opts: $MNT_OPTS)"
|
||||
mount -o "$MNT_OPTS" "$SNAPSHOT_PATH" "$TEMP_MOUNT" || error "Failed to mount snapshot"
|
||||
|
||||
# Create Borg archive
|
||||
ARCHIVE_NAME="files_${LV_NAME}_$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
Reference in New Issue
Block a user