Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #
- # Author: Ryan Kernan
- # Date: September 23, 2011
- # Version: 1.1
- # Credits: Mike La Spina for the original concept and script http://blog.laspina.ca/
- #
- # Mike La Spina - 1.1 added vars to support full paths on remote ssh executions
- # Mike La Spina - 1.2 added var symbol to last_snap_shost input parse.
- #
- # Function: Provides snapshot and send process which replicates ZFS file systems from a source to target server.
- # Maintains a runing snapshot archive for X days (X being the value of keep_snaps).
- #
- # The input format should conform to the following:
- # source zfspath, source host, dest host
- #
- # eg.
- #
- # pool/zfsstore,host1,host2
- #
- # Input parms:1
- # rep_list - a file name var of which the file contains a list of comma delimed zfs paths, source and target host names.
- # keep_snaps - Number of days to keep snaps for.
- # snap_list - temp file to list current snapshots.
- #
- #
- #
- ZFS=/sbin/zfs
- DATE=/bin/date
- SSH=/usr/bin/ssh
- PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin
- rep_list=$1
- keep_snaps=7
- snap_list=snaplist.lst
- if [ -e /tmp/zfs-rep.lock ];
- then
- exit
- else
- touch /tmp/zfs-rep.lock
- fi
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function parse the comma delimited input file and assign the field to the respective
- # variables for file system, pool and host names.
- #
- # Global output parms
- # zfspool
- # zfspath
- # shost
- # dhost
- parse_rep_list() {
- rep_list_line=$1
- zfspool="$(echo $rep_list_line | cut -d/ -f1)"
- zfspath="$(echo $rep_list_line | cut -d, -f1)"
- shost="$(echo $rep_list_line | cut -d, -f2)"
- dhost="$(echo $rep_list_line | cut -d, -f3)"
- }
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function issue zfs list commands and assign the variables the last snapshot names for
- # both the source and destination hosts.
- #
- # Global input parms
- # zfspath
- # shost
- # dhost
- check_last_snap() {
- last_snap_dhost=""
- last_snap_shost=""
- last_snap_shost=$( $ZFS list -o name -t snapshot | grep $zfspath | tail -1 )
- last_snap_dhost=$( $SSH -n $dhost $ZFS list -H -o name -r -t snapshot | grep $zfspath | tail -1 )
- true
- }
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function check if the destination $ZFS path exists and assign the result to the
- # variable dhost_fs_name.
- #
- # Global input parms
- # $zfspath
- # dhost
- dhost_fs_exists() {
- dhost_fs_name=""
- dhost_fs_name=$($SSH -n $dhost $ZFS list -o name -H $zfspath | tail -1)
- if [ "$dhost_fs_name" = "" ]
- then
- echo $($DATE) "->" $zfspath file system does not exist on target host $dhost. >> replicate.log
- fi
- }
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function create a zfs path on the destination to allow the receive command
- # funtionallity then issue zfs snap and send to transfer the zfs object to the
- # destination host
- #
- # Global input parms
- # zfspath
- # dhost
- dhost_create_fs() {
- $SSH -n $dhost $ZFS create -p $zfspath
- $SSH -n $dhost $ZFS set mountpoint=none $zfspath
- last_snap_shost=$( $ZFS list -o name -t snapshot -H | grep "$zfspath\@" | tail -1 )
- echo $($DATE) "->" $last_snap_shost Initial replication start. >> replicate.log
- $ZFS send -v -R $last_snap_shost | $SSH $dhost $ZFS recv -v -F -d $zfspool
- echo $($DATE) "->" $last_snap_shost Initial replication end. >> replicate.log
- }
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function Issue a snapshot for the source zfs path
- #
- # Global input parms
- # zfspath
- create_fs_snap() {
- snap_date="$($DATE +%m-%d-%y-%H:%M)"
- echo $($DATE) "->" $zfspath@$snap_date Snapshot creation start. >> replicate.log
- $ZFS snapshot $zfspath@$snap_date
- echo $($DATE) "->" $zfspath@$snap_date Snapshot creation end. >> replicate.log
- }
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function create a zfs send/recv command set based on a the zfs path source
- # and target hosts for an established replication state. (aka incremental replication)
- #
- # Global input parms
- # zfspath
- # dhost
- incr_repl_fs() {
- echo $($DATE) "->" $last_snap_dhost $last_snap_shost Incremental send start. >> replicate.log
- $ZFS send -I $last_snap_dhost $last_snap_shost | $SSH $dhost $ZFS recv -d -F $zfspool >> replicate.log
- echo $($DATE) "->" $last_snap_dhost $last_snap_shost Incremental send end. >> replicate.log
- }
- #######################################################################################
- ####################################Function###########################################
- #######################################################################################
- #
- # Function to clean up snapshots that are older than X days old X being the
- # value set by "keep_snaps" on both the source and destination hosts.
- clean_snaps() {
- PreviousSnapDate=""
- PreviousSnap=""
- CurrentYear="$( $DATE +%y )"
- CurrentMonth="$( $DATE +%m )"
- CurrentDay="$( $DATE +%d )"
- if [ "$zfspath" != "" ]
- then
- $ZFS list -o name -t snapshot | grep $zfspath\@ > $snap_list
- while read snaps
- do
- SnapDate=`echo $snaps | cut -d @ -f 2`
- SnapDay="$(echo $SnapDate | cut -d- -f2)"
- SnapMonth="$(echo $SnapDate | cut -d- -f1)"
- SnapYear="$(echo $SnapDate | cut -d- -f3)"
- SnapDate="$SnapMonth-$SnapDay-$SnapYear"
- if [ "$($DATE -v-${keep_snaps}d +%m-%d-%y)" = "$SnapDate" ]
- then
- echo "Destroying $SnapDate snapshot $snaps on $shost" >> replicate.log
- $ZFS destroy $snaps
- echo "Destroying $SnapDate snapshot $snaps on $dhost" >> replicate.log
- $SSH -n $dhost $ZFS destroy $snaps
- fi
- done < $snap_list
- rm $snap_list
- fi
- }
- #######################################################################################
- #####################################Main Entery#######################################
- #######################################################################################
- #
- #
- # Init Global Parms
- zfspath=""
- shost=""
- dhost=""
- # Create the snapshots all at the same time
- while read line
- do
- parse_rep_list $line
- if [ "$zfspath" != "" ]
- then
- create_fs_snap >> replicate.log # Create a new snapshot of the path spec.
- fi
- done < $rep_list
- # Send the snapshots to the remote and create the fs if required
- while read line
- do
- parse_rep_list $line
- if [ "$zfspath" != "" ]
- then
- dhost_fs_exists # Test for the existence of our listed
- # zfs file system path on the target host.
- if [ "$dhost_fs_name" ]
- then
- check_last_snap >> replicate.log # Get the start and stop snaps.
- incr_repl_fs >> replicate.log # Initiate a dif replication.
- clean_snaps # Clean up any snapshots that are X days old.
- else
- dhost_create_fs >> replicate.log # Create a first time replication.
- fi
- fi
- done < $rep_list
- rm /tmp/zfs-rep.lock
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement