#!/bin/bash
#
#  Author: Mike La Spina
#    Date: May 5, 2010
# Version: 0.4
#
# Function: Provides a daily snapshot and send process which replicates ZFS file systems from a source to target server.
#
# Rev 0.3 Date format changed to dd/mm/yy on the snapshot name  
# Input parms:1
#		 fs_list - a file name var of which the file contains a list of comma delimed zfs paths, source and target host names.
# Rev 0.4 Removed iscsi SMF service properties and scp backup  
#


	
fs_list=$1

###############################################################################
# Parse the comma delimited input file and assign the field to the respective variables

# Global output parms
# zfspath
# shost
# dhost
 
parse_fs_list() {

fs_list_line=$1
  zfspath="$(echo $fs_list_line | cut -d, -f1)"
  shost="$(echo $fs_list_line | cut -d, -f2)"
  dhost="$(echo $fs_list_line | cut -d, -f3)"

}

###############################################################################
# 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=$( pfexec zfs list -o name -t snapshot | grep $zfspath | tail -1 ) 
last_snap_dhost=$( ssh -n $dhost pfexec zfs list -H -o name -r -t snapshot | grep $zfspath | tail -1 )
true

}

###############################################################################
# Check for a destination zfs path 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 pfexec 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

}


###############################################################################
# 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 pfexec zfs create -p $zfspath 
ssh -n $dhost pfexec zfs set mountpoint=none $zfspath
last_snap_shost=$( pfexec zfs list -o name -t snapshot -H | grep $zfspath | tail -1 ) 
echo $(date) "->" $last_snap_shost Initial replication start. >> replicate.log
pfexec zfs send -v -R $last_snap_shost | ssh $dhost pfexec zfs recv -v -F -d sp2
echo $(date) "->" $last_snap_shost Initial replication end. >> replicate.log

}


###############################################################################
# Issue a snapshot for the source zfs path

# Global input parms
# zfspath

create_fs_snap() {

snap_date="$(date +%d-%m-%y-%H:%M)"
echo $(date) "->" $zfspath@$snap_date Snapshot creation start. >> replicate.log
pfexec zfs snapshot $zfspath@$snap_date 
echo $(date) "->" $zfspath@$snap_date Snapshot creation end. >> replicate.log

}

###############################################################################
# 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
pfexec zfs send -I $last_snap_dhost $last_snap_shost | ssh $dhost pfexec zfs recv -d rp1 >> replicate.log
echo $(date) "->" $last_snap_dhost $last_snap_shost Incremental send end. >> replicate.log

}


###############################################################################
###############################################################################
#############################Main Entry Point##################################

# Init Global Parms
zfspath="" 
shost="" 
dhost=""


# Create the snapshots all at the same time
while read line 
do

  parse_fs_list $line 

  if [ "$zfspath" != "" ]
  then
    	create_fs_snap >> replicate.log		#Create a new snapshot of the path spec
  fi

done < $fs_list



 
# Send the snapshots to the remote and create the fs if required 
while read line 
do

  parse_fs_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
    else
      	dhost_create_fs >> replicate.log		#Create a first time replication
    fi
    
  fi

done < $fs_list

exit 0
  
  



 
 
