Tweaked some settings in zfs-replicate.
authorAlan J. Pippin <ajp@pippins.net>
Fri, 29 Jan 2010 04:43:28 +0000 (21:43 -0700)
committerAlan J. Pippin <ajp@pippins.net>
Fri, 29 Jan 2010 04:43:28 +0000 (21:43 -0700)
Added BRAND NEW restore scripts to aid in restoring filesystems from backup pool to a destination pool.

zfs-replicate
zfs-restore [new file with mode: 0755]
zfs-restore-all [new file with mode: 0755]

index 347bcbe4ad4223872e5450d0b509ebb6d0d88b5c..8b53d1fb0d4e7a53f4475778cb21c02fc4047251 100755 (executable)
@@ -1,4 +1,4 @@
-#/bin/bash
+#!/bin/bash
 
 # Author: Carl Baldwin & Alan Pippin
 # Description: This script replicates a remote zfs filesystem to a local zfs pool.
@@ -92,7 +92,7 @@ set -x
 # Create the remote lockdir before continuing with the replicate
 # Spinlock on creating the lock
 maxsleeptime=60
-maxattempts=100
+maxattempts=500
 attempts=0
 while true; do
   ssh $remote mkdir "$lockdir" >/dev/null 2>&1
diff --git a/zfs-restore b/zfs-restore
new file mode 100755 (executable)
index 0000000..ec647b7
--- /dev/null
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+# Author: Alan Pippin
+# Description: This script "restores" or sends a local filesystem to a remote zfs pool.
+# Usage: zfs-restore <src pool> <src filesystem> <dst pool> <dst filesystem> <dst hostname>
+
+# source our configuration
+config="${0%/*}/zfs-scripts.conf"
+[ -e "${config}.dist" ] && . ${config}.dist
+[ -e "${config}" ] && . ${config}
+
+# command line arg parsing
+src_pool=$1
+src_fs=$2
+dst_pool=$3
+dst_fs=$4
+dst_hostname=$5
+
+if [[ -z "$SCRIPT_UNDER_TEST" ]]; then
+    exec >> $logdir/zfs-replicate.log 2>&1
+fi
+
+fatal_and_exit() {
+  echo -e 2>&1 "$1"
+  exit 1
+}
+trap fatal_and_exit INT
+
+# Make sure we have valid arguments
+if [[ -z "$src_pool" ]] || [[ -z "$src_fs" ]] || [[ -z "$dst_pool" ]] || [[ -z "$dst_fs" ]] || [[ -z "$dst_hostname" ]]; then
+  fatal_and_exit "Usage: $0 <src pool> <src filesystem> <dst pool> <dst filesystem> <dst hostname>"
+fi
+
+date=`date`
+echo "$date ZFS restore started: $src_pool/$src_fs -> $dst_hostname:$dst_pool/$dst_fs"
+
+# Make sure the src pool and src filesystem exist, or print some errors
+zpool list -H "$src_pool" >/dev/null 2>&1
+if [ $? != 0 ]; then
+  fatal_and_exit "-E- The src pool, '$src_pool' doesn't seem to exist."
+fi
+zfs list "$src_pool/$src_fs" >/dev/null 2>&1
+if [ $? != 0 ]; then
+  fatal_and_exit "-E- The src filesystem for the src pool, '$src_pool/$src_fs' doesn't seem to exist."
+fi
+
+# Obtain the zpool guid for the src pool
+src_pool_guid=`zpool get guid $src_pool 2>&1 | grep $src_pool | awk '{ print $3 }'`
+zpool get guid $src_pool > /dev/null 2>&1
+if [ $? != 0 ]; then
+  fatal_and_exit "-E- Unable to extract the guid for the src pool: $src_pool" $mailto
+fi
+
+# Setup our backup marker names
+last_backup_marker=${src_fs}@previous-backup-${src_pool_guid}
+
+# Check to make sure the src fs exists
+$zfs list -t snapshot "$src_pool/$last_backup_marker" > /dev/null 2>&1
+if [ $? != 0 ]; then
+  fatal_and_exit "-E- The src snapshot '$src_pool/$last_backup_marker' does not exist. Unable to continue."
+fi
+
+# Check to make sure the dst pool exists
+ssh $dst_hostname "$zfs list ${dst_pool}" > /dev/null 2>&1
+if [ $? != 0 ]; then
+  fatal_and_exit "-E- The destination pool '$dst_pool' does not exist. Create the pool '$dst_pool' and try again."
+fi
+
+# Check to make sure the dst filesystem does not exist
+ssh $dst_hostname "$zfs list ${dst_pool}/${dst_fs}" > /dev/null 2>&1
+if [ $? == 0 ]; then
+  fatal_and_exit "-E- The destination pool/filesystem '$dst_pool/$dst_fs' already exists. Destroy the filesystem '$dst_fs' and try again."
+fi 
+
+# Now send the src filesystem
+if [[ -n "$SCRIPT_UNDER_TEST" ]]; then
+  echo "$zfs send -R $src_pool/$last_backup_marker | ssh $dst_hostname $zfs recv -dv $dst_pool"
+else 
+  $zfs send -R "$src_pool/$last_backup_marker" | ssh $dst_hostname "$zfs recv -dv $dst_pool"
+fi
+
+# Now rename the dst filesystem (move it into place)
+if [[ -n "$SCRIPT_UNDER_TEST" ]]; then
+  echo "$dst_hostname $zfs rename $dst_pool/$src_fs $dst_pool/$dst_fs"
+else
+  ssh $dst_hostname "$zfs rename $dst_pool/$src_fs $dst_pool/$dst_fs"
+fi
+
+# All done!
+date=`date`
+echo "$date ZFS restore completed: $src_pool/$src_fs -> $dst_hostname:$dst_pool/$dst_fs"
+
diff --git a/zfs-restore-all b/zfs-restore-all
new file mode 100755 (executable)
index 0000000..76c7bf8
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# Author: Alan J. Pippin
+# Description: This script calls zfs-restore for each filesystem needing
+#              to be restored (that was formerly replicated here) to another ZFS pool.
+
+# source our configuration 
+config="${0%/*}/zfs-scripts.conf"
+[ -e "${config}.dist" ] && . ${config}.dist
+[ -e "${config}" ] && . ${config}
+
+# Setup some default values
+logfile="$logdir/zfs-replicate-all.log"
+
+# Setup our output
+if [[ -z "$SCRIPT_UNDER_TEST" ]]; then
+    exec >> $logfile 2>&1
+fi
+
+cleanup_and_exit() {
+  exit 1
+}
+trap cleanup_and_exit INT
+
+
+# See if the user has a specific pool to restore in mind
+restore_pool=$1
+
+# Restore every ZFS filesystem we were told to replicate 
+echo `date` ZFS restore started
+
+# For each filesystem we are supposed to restore, do it
+for filesystem in $filesystems_to_replicate; do
+  dst_pool=${filesystem%%/*}
+  dst_fs=${filesystem#*/}
+  # Check to make sure the dst filesystem does not exist
+  ssh $remote "$zfs list ${dst_pool}/${dst_fs}" > /dev/null 2>&1
+  if [ $? != 0 ]; then
+    echo "$filesystem" | grep -q "$restore_pool" 
+    if [ $? == 0 ]; then
+      # This filesystem matches our restore pool pattern 
+      echo `date` Restoring $filesystem to $remote
+      zfs-restore $local_pool $filesystem $dst_pool $dst_fs $remote
+    fi
+  else
+    echo "-I- Filesystem already exists on destination. Skipping: $filesystem"
+  fi 
+done
+
+# All done
+echo `date` ZFS restore complete
+