]> arthur.barton.de Git - backup-script.git/commitdiff
Add support for generations using btrfs snapshots
authorAlexander Barton <alex@barton.de>
Thu, 26 Sep 2013 16:33:22 +0000 (18:33 +0200)
committerAlexander Barton <alex@barton.de>
Thu, 26 Sep 2013 16:33:22 +0000 (18:33 +0200)
Actually this patch lacks the cleanup functionality, so you have to
delete old snapshots manually. But this will come in a separate patch!

bin/backup-script
bin/backup-status

index 89abead0610b6c11cfd63c5effe25cf1d7a649d0..f19992ef8eef656c57979586bda712bd44b29bdb 100755 (executable)
@@ -37,6 +37,7 @@ default_exclude_args_add=""
 default_compress=1
 default_ping=1
 default_local=0
+default_generations=0
 
 Usage() {
        echo "Usage: $NAME [<options>] [<system> [<system> [...]]]"
@@ -156,6 +157,7 @@ for f in $sys; do
        compress="$default_compress"
        ping="$default_ping"
        local="$default_local"
+       generations="$default_generations"
 
        # Read in system configuration file
        source "$f"
@@ -201,6 +203,64 @@ for f in $sys; do
                echo "OK, host \"$system\" seems to be alive."
        fi
 
+       if [ $generations -gt 0 ]; then
+               # Make sure no old backup is stored in system directory
+               if [ -e "$sys_target/.stamp" ]; then
+                       # There seems to be a genearation-less backup in the
+                       # target directory!
+                       echo "Target directory \"$sys_target\" seems to be unclean!? \"$system\" skipped!"
+                       echo; continue
+               fi
+
+               # Search directory of last generation, if any
+               last="`ls -1 "$sys_target" 2>/dev/null | sort -r | head -n1`"
+               if [ -n "$last" ]; then
+                       last="$sys_target/$last"
+                       if [ ! -d "$last" ]; then
+                               echo "Last snapshot \"$last\" seems not to be a directory!? \"$system\" skipped!"
+                               echo; continue
+                       fi
+               fi
+               sys_target="$sys_target/`date +%Y%m%d-%H%M%S`"
+
+               if [ -n "$last" -a ! -e "$last/.stamp" ]; then
+                       # Old backup directory without "stamp file", continue
+                       echo "Found incomplete snapshot in \"$last\", reusing and renaming it ..."
+                       mv "$last" "$sys_target" >/dev/null 2>&1
+                       if [ $? -ne 0 ]; then
+                               echo "Failed to rename last snapshot \"$last\" to \"$sys_target\"!? \"$system\" skipped!"
+                               echo; continue
+                       fi
+               elif [ -n "$last" ]; then
+                       # Old backup directory found, create new snapshot
+                       echo "Found last snapshot in \"$last\"."
+                       if [ "$DRYRUN" -eq 0 ]; then
+                               btrfs subvolume snapshot \
+                                 "$last" "$sys_target" >/dev/null 2>&1; r=$?
+                               if [ $r -ne 0 ]; then
+                                       echo "Can't create btrfs snapshot \"$sys_target\" of \"$last\", code $r!? \"$system\" skipped!"
+                                       echo; continue
+                               fi
+                               echo "Created new snapshot in \"$sys_target\"."
+                       else
+                               echo " *** Trial run, not creating new snapshot in \"$sys_target\"!"
+                       fi
+               else
+                       # No old backup found, create new subvolume
+                       if [ "$DRYRUN" -eq 0 ]; then
+                               btrfs subvolume create \
+                                 "$sys_target" >/dev/null 2>&1; r=$?
+                               if [ $r -ne 0 ]; then
+                                       echo "Can't create btrfs subvolume \"$sys_target\", code $r!? \"$system\" skipped!"
+                                       echo; continue
+                               fi
+                               echo "Created new subvolume in \"$sys_target\"."
+                       else
+                               echo " *** Trial run, not creating new subvolume \"$sys_target\"!"
+                       fi
+               fi
+       fi
+
        ssh_cmd="ssh"
        [ -n "$ssh_args_add" ] && ssh_cmd="$ssh_cmd $ssh_args_add"
 
index bbb6b056265baa6e2e68fc9005d69cee10915c4b..ea120d6e06c7a5f299baf09eeccb6d827b0c2fe9 100755 (executable)
@@ -17,9 +17,42 @@ QUICK=0
 export LC_ALL=C
 
 declare -i count=0
+declare -i snapshots=0
 
 # Default settings, can be overwritten in backup-script.conf:
 default_target=""
+default_generations=0
+
+Check_Size() {
+       # $1: directory
+       # $2: padding
+
+       if [ "$QUICK" = "0" ]; then
+               size=`du -sh "$1" | cut -f1`
+               echo "$2  - Size:" $size
+       fi
+}
+
+Check_Stamp() {
+       # $1: stamp file
+       # $2: padding
+
+       if [ -f "$1" ]; then
+               last=`stat "$1" | grep "^Modify: " \
+                 | cut -d':' -f2- | cut -d. -f1`
+               [ -n "$last" ] && echo "$2  - Date:" $last
+               unset code
+               source "$1"
+               case "$code" in
+                 0)    txt=", OK"; ;;
+                 24)   txt=", files changed during backup"; ;;
+                 *)    txt=""
+               esac
+               [ -n "$code" ] && echo "$2  - Result code: $code$txt"
+       else
+               echo "$2  - No timestamp recorded!? Backup aborted?"
+       fi
+}
 
 if [ "$1" == "-q" ]; then
        QUICK=1
@@ -60,6 +93,7 @@ for f in $sys; do
        # Set global defaults
        system="$fname"
        target="$default_target"
+       generations="$default_generations"
 
        # Read in system configuration file
        source "$f"
@@ -73,24 +107,23 @@ for f in $sys; do
        [ -d "$target" ] || continue
 
        # System name
-       [ "$system" = "$fname" ] && echo "$system" || echo "$system [$fname]"
+       [ "$system" = "$fname" ] && echo "$fname" || echo "$fname [$system]"
 
        # System target directory
        echo "- Target: $target"
-       if [ "$QUICK" = "0" ]; then
-               size=`du -sh "$target" | cut -f1`
-               echo "- Size:" $size
-       fi
 
-       # Timestamp and result code
-       if [ -f "$target/.stamp" ]; then
-               last=`stat "$target/.stamp" | grep "^Modify: " | cut -d':' -f2- | cut -d. -f1`
-               [ -n "$last" ] && echo "- Date:" $last
-               unset code
-               source "$target/.stamp"
-               [ -n "$code" ] && echo "- Result code:" $code
+       if [ $generations -gt 0 ]; then
+               for s in $target/[0-9]*-[0-9]*; do
+                       echo "  - Snapshot: $s"
+                       Check_Size "$s" "  "
+                       Check_Stamp "$s/.stamp" "  "
+                       snapshots=$snapshots+1
+               done
        else
-               echo "- No timestamp recorded!?"
+               # Timestamp and result code
+               Check_Size "$s"
+               Check_Stamp "$target/.stamp"
+               snapshots=$snapshots+1
        fi
 
        count=$count+1
@@ -101,6 +134,8 @@ if [ $count -lt 1 ]; then
        echo "No backups found!"
        exit 1
 fi
-echo "$count system backup(s) found."
+[ $count -eq 1 ] && sc="" || sc="s"
+[ $snapshots -eq 1 ] && ss="" || ss="s"
+echo "$count system backup$sc found, $snapshots snapshot$ss."
 
 # -eof-