4 # Description: This script "restores" or sends a local filesystem to a remote zfs pool.
5 # Usage: zfs-restore <src pool> <src filesystem> <dst pool> <dst filesystem> <dst hostname>
7 # source our configuration
8 config="${0%/*}/zfs-scripts.conf"
9 [ -e "${config}.dist" ] && . ${config}.dist
10 [ -e "${config}" ] && . ${config}
12 # command line arg parsing
19 # return non-zero exit code if any command in the pipe fails
22 if [[ -z "$SCRIPT_UNDER_TEST" ]]; then
23 exec >> $logdir/zfs-restore.log 2>&1
30 trap fatal_and_exit INT
32 # Make sure we have valid arguments
33 if [[ -z "$src_pool" ]] || [[ -z "$src_fs" ]] || [[ -z "$dst_pool" ]] || [[ -z "$dst_fs" ]] || [[ -z "$dst_hostname" ]]; then
34 fatal_and_exit "Usage: $0 <src pool> <src filesystem> <dst pool> <dst filesystem> <dst hostname>"
38 echo "$date ZFS restore started: $src_pool/$src_fs -> $dst_hostname:$dst_pool/$dst_fs"
41 if [[ $dst_hostname = "localhost" ]]; then
46 # Make sure the src pool and src filesystem exist, or print some errors
47 zpool list -H "$src_pool" >/dev/null 2>&1
49 fatal_and_exit "-E- The src pool, '$src_pool' doesn't seem to exist."
51 zfs list "$src_pool/$src_fs" >/dev/null 2>&1
53 fatal_and_exit "-E- The src filesystem for the src pool, '$src_pool/$src_fs' doesn't seem to exist."
56 # Obtain the zpool guid for the src pool
57 src_pool_guid=`zpool get guid $src_pool 2>&1 | grep $src_pool | awk '{ print $3 }'`
58 zpool get guid $src_pool > /dev/null 2>&1
60 fatal_and_exit "-E- Unable to extract the guid for the src pool on $hostname: $src_pool" $mailto
63 # Setup our backup marker names
64 last_backup_marker=${src_fs}@previous-backup-${src_pool_guid}
66 # Check to make sure the src fs exists
67 $zfs list -t snapshot "$src_pool/$last_backup_marker" > /dev/null 2>&1
69 fatal_and_exit "-E- The src snapshot '$src_pool/$last_backup_marker' does not exist. Unable to continue."
72 # Check to make sure the dst pool exists
73 $ssh $dst_hostname $zfs list ${dst_pool} > /dev/null 2>&1
75 fatal_and_exit "-E- The destination pool '$dst_pool' does not exist. Create the pool '$dst_pool' and try again."
78 # Check to make sure the dst filesystem does not exist
79 $ssh $dst_hostname $zfs list ${dst_pool}/${dst_fs} > /dev/null 2>&1
81 fatal_and_exit "-E- The destination pool/filesystem '$dst_pool/$dst_fs' already exists. Destroy the filesystem '$dst_fs' and try again."
84 # Now send the src filesystem
85 if [[ -n "$SCRIPT_UNDER_TEST" ]]; then
86 echo "$zfs send -Rc $src_pool/$last_backup_marker | $ssh $dst_hostname $zfs recv -dv $dst_pool"
88 if [[ $throttle_enable == 1 && -e $throttle ]]; then
89 $zfs send -Rc "$src_pool/$last_backup_marker" | $throttle $throttle_opt | $ssh $dst_hostname $zfs recv -dv $dst_pool
91 $zfs send -Rc "$src_pool/$last_backup_marker" | $ssh $dst_hostname $zfs recv -dv $dst_pool
95 # Now rename the dst filesystem (move it into place)
96 if [[ -n "$SCRIPT_UNDER_TEST" ]]; then
97 echo "$ssh $dst_hostname $zfs rename $dst_pool/$src_fs $dst_pool/$dst_fs"
99 $ssh $dst_hostname $zfs rename $dst_pool/$src_fs $dst_pool/$dst_fs
104 echo "$date ZFS restore completed: $src_pool/$src_fs -> $dst_hostname:$dst_pool/$dst_fs"