Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- ##
- ## Initial and continous ZFS filesystems replication
- ##
- PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
- if [ ! `whoami` = "root" ]; then
- echo "You need to be root."
- exit
- fi
- l_old="@local_replicate.base"
- r_old="@remote_replicate.base"
- l_new="@local_replicate.delta"
- r_new="@remote_replicate.delta"
- log="/var/log/replicate.log"
- cmd=$(mktemp /tmp/replicate.job.XXXXXX)
- ERR=$(mktemp /tmp/replicate.err.XXXXXX)
- pid="/var/run/replicate.pid"
- path="/usr/local/etc/replicatejobs/"
- jobs=`find $path -type f ! -iname sample_* ! -iname noauto_* | sort -d`
- ##
- ## Mail settings
- ##
- subject="A replication error has occurred!"
- address="storageadm@slu.se"
- mail=$(mktemp /tmp/replicate.mail.XXXXXX)
- usage()
- {
- echo ""
- echo "Usage: `basename $0` [Options] [Flags] [Job]"
- echo ""
- echo "Options: -c|-h"
- echo "-c: Clean."
- echo " removes replicated filesystems and snapshot(s)."
- echo "-h: Usage."
- echo ""
- echo "Flags: auto"
- echo "auto: Clean auto."
- echo " removes all scheduled snapshot(s)."
- echo ""
- echo "Examples: `basename $0` | `basename $0` jobname"
- echo " `basename $0` -c | `basename $0` -c jobname | `basename $0` -c auto"
- echo ""
- }
- l_base()
- {
- ##
- ## Makes local baseline replication
- ##
- if zpool status `echo $lfs | cut -f1 -d /` | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on source pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif zpool status $lp | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on destination pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- if [ "$r" = "yes" ]
- then
- SNAPSHOT="zfs snapshot -r"
- SEND="zfs send -R"
- else
- SNAPSHOT="zfs snapshot"
- SEND="zfs send -p"
- fi
- tfs=$(echo $lfs | cut -f 2-512 -d / | sed "s/^/$lp\//")
- echo "echo \"\`date\`: Beginning local baseline replication sequence on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- # Take initial snapshot(s):
- echo "sudo ${SNAPSHOT} $lfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Initial snapshot(s) created\" >> $log" >> ${cmd}
- # Replicate data:
- echo "sudo ${SEND} $lfs$l_old 2>> ${ERR} | sudo zfs recv -du $lp 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Data replicated\" >> $log" >> ${cmd}
- # Delete unwanted, scheduled source snapshots from target:
- if [ "$r" = "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | egrep -v "$l_old|$l_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | egrep -v "$l_old|$l_new"); do
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted local target snapshot(s) destroyed" >> $log
- fi
- EOF
- else
- cat >> ${cmd} << EOF
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$l_old|$l_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$l_old|$l_new"); do
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted local target snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- echo "echo \"\`date\`: Local baseline replication sequence finished on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- echo "echo \"\" >> $log" >> ${cmd}
- echo "exit 0" >> ${cmd}
- echo "" >> ${cmd}
- }
- r_base()
- {
- ##
- ## Makes remote baseline replication
- ##
- SSH="ssh"
- if [ "${compress}" = "yes" ]; then
- SSH="ssh -C"
- fi
- if [ ! -z ${port} ]; then
- SSH="${SSH} -p ${port}"
- else
- SSH="${SSH} -p 22"
- fi
- if [ `ping -c 1 -W 1000 $rh | grep -oe "[0-9] packets received" | awk '{print $1}'` -eq "0" ]; then
- echo "`date`: Remote baseline replication sequence aborted on \"$lfs\"! No response from \"$rh\"." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif zpool status `echo $lfs | cut -f1 -d /` | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on source pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif su replicator -c "${SSH} $rh zpool status $rp | grep \"scan:\" | egrep -qo '(scrub in progress|resilver in progress)'"; then
- echo "`date`: A Scrub or Resilver is currently in progress on remote pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- if [ "$r" = "yes" ]
- then
- SNAPSHOT="zfs snapshot -r"
- SEND="zfs send -R"
- else
- SNAPSHOT="zfs snapshot"
- SEND="zfs send -p"
- fi
- tfs=$(echo $lfs | cut -f 2-512 -d / | sed "s/^/$rp\/$lh\//")
- echo "echo \"\`date\`: Beginning remote baseline replication sequence on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- # Take initial snapshot(s):
- echo "sudo ${SNAPSHOT} $lfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Initial snapshot(s) created\" >> $log" >> ${cmd}
- # Replicate data:
- echo "sudo ${SEND} $lfs$r_old 2>> ${ERR} | ${SSH} $rh sudo zfs recv -du $rp/$lh 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Data replicated\" >> $log" >> ${cmd}
- # Clean unwanted, scheduled source snapshots from target:
- if [ "$r" = "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | egrep -v "$r_old|$r_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | egrep -v "$r_old|$r_new"); do
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- ${SSH} $rh sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted remote target snapshot(s) destroyed" >> $log
- fi
- EOF
- else
- cat >> ${cmd} << EOF
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$r_old|$r_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$r_old|$r_new"); do
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- ${SSH} $rh sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted remote target snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- echo "echo \"\`date\`: Remote baseline replication sequence finished on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- echo "echo \"\" >> $log" >> ${cmd}
- echo "exit 0" >> ${cmd}
- echo "" >> ${cmd}
- }
- l_inc()
- {
- ##
- ## Makes local incremental replication
- ##
- if zpool status `echo $lfs | cut -f1 -d /` | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on source pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif zpool status $lp | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on destination pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- tfs=`echo $lfs | cut -f 2-512 -d / | sed "s/^/$lp\//"`
- echo "`date`: Beginning local incremental replication sequence on \"$lfs\"" >> $log
- # Take new source snapshot(s):
- if [ "$r" = "yes" ]; then
- SOURCEBASE=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.base)
- SOURCEDELTA=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.delta)
- DESTBASE=$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.base)
- DESTDELTA=$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.delta)
- SNAPSHOT="zfs snapshot -r"
- SEND="zfs send -R"
- DESTROY="zfs destroy -r"
- RENAME="zfs rename -r"
- else
- SOURCEBASE=$(zfs list -H -t snapshot -o name $lfs$r_old 2>/dev/null | awk 'END{print NR}')
- SOURCEDELTA=$(zfs list -H -t snapshot -o name $lfs$r_new 2>/dev/null | awk 'END{print NR}')
- DESTBASE=$(zfs list -H -t snapshot -o name $tfs$r_old 2>/dev/null | awk 'END{print NR}')
- DESTDELTA=$(zfs list -H -t snapshot -o name $tfs$r_new 2>/dev/null | awk 'END{print NR}')
- SNAPSHOT="zfs snapshot"
- SEND="zfs send -p"
- DESTROY="zfs destroy"
- RENAME="zfs rename"
- fi
- rebaseline()
- {
- echo "echo \"\`date\`: No appropriate correctional steps where found, have to rebaseline\" >> $log" >> ${cmd}
- if [ ${SOURCEBASE} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${SOURCEDELTA} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$l_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTBASE} -gt "0" ]; then
- echo "sudo ${DESTROY} $tfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTDELTA} -gt "0" ]; then
- echo "sudo ${DESTROY} $tfs$l_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ "$r" != "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$l_old|$l_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$l_old|$l_new"); do
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted local target snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- if [ $(zfs list -H -o name -r $tfs 2>/dev/null | awk 'END{print NR}') -gt "0" ]; then
- echo "sudo ${DESTROY} $tfs 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target filesystem destroyed\" >> $log" >> ${cmd}
- fi
- echo "sudo ${SNAPSHOT} $lfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Base snapshot(s) created\" >> $log" >> ${cmd}
- echo "sudo ${SEND} $lfs$l_old 2>> ${ERR} | sudo zfs recv -du $lp 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Data replicated\" >> $log" >> ${cmd}
- echo "echo \"\`date\`: Rebaseline complete\" >> $log" >> ${cmd}
- echo "sudo ${SNAPSHOT} $lfs$l_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Delta snapshot(s) created\" >> $log" >> ${cmd}
- }
- dryrun()
- {
- DRYRUNOUT=$(mktemp /tmp/replicate.dryrun.XXXXXX)
- if [ "$r" = "yes" ]
- then
- DODRYRUN=`zfs send -vRi $lfs$l_old $lfs$l_new 2> ${DRYRUNOUT} | zfs recv -vdn $lp 2>> ${DRYRUNOUT}`
- else
- DODRYRUN=`zfs send -vi $lfs$l_old $lfs$l_new 2> ${DRYRUNOUT} | zfs recv -vdn $lp 2>> ${DRYRUNOUT}`
- fi
- DRYRUNOK=`egrep '(could not send|cannot receive)' ${DRYRUNOUT} | wc -l | sed 's/^[ \t]*//'`
- rm ${DRYRUNOUT}; echo ${DRYRUNOK}
- }
- if [ ${SOURCEBASE} -gt "0" ]
- then
- if [ ${SOURCEDELTA} -gt "0" ]
- then
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${DESTDELTA} = ${DESTBASE} ]
- then
- echo "`date`: Probably interrupted while destroying target .base(s)" >> $log
- ${DESTROY} $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .base snapshot(s) destroyed" >> $log
- ${RENAME} $tfs$l_new $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${DESTROY} $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .base snapshot(s) destroyed" >> $log
- ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful" >> $log
- echo "`date`: Probably interrupted while destroying source .base(s)" >> $log
- ${DESTROY} $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .base snapshot(s) destroyed" >> $log
- ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- echo "`date`: Dry run successful" >> $log
- echo "`date`: Probably interrupted while transferring, resending" >> $log
- fi
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEDELTA} = ${DESTDELTA} ]
- then
- echo "`date`: Probably interrupted while renaming target .delta to .base" >> $log
- ${RENAME} $tfs$l_new $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${DESTROY} $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .base snapshot(s) destroyed" >> $log
- ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- rebaseline
- fi
- fi
- else
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- ${DESTROY} $tfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) found and destroyed" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- else
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEBASE} = ${DESTDELTA} ]
- then
- echo "`date`: No target .base found, but source .base matches target .delta. Renaming target .delta to .base" >> $log
- ${RENAME} $tfs$l_new $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- rebaseline
- fi
- fi
- fi
- else
- if [ ${SOURCEDELTA} -gt "0" ]
- then
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEDELTA} = ${DESTDELTA} ]
- then
- echo "`date`: Probably interrupted while destroying target .base(s)" >> $log
- ${DESTROY} $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .base snapshot(s) destroyed" >> $log
- ${RENAME} $tfs$l_new $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- if [ ${SOURCEDELTA} = ${DESTBASE} ]
- then
- echo "`date`: Probably interrupted while renaming source .delta to .base" >> $log
- ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEDELTA} = ${DESTDELTA} ]
- then
- echo "`date`: No source or target .base, but source and target .delta matches. Can try to rename them to .base and test a resend"
- ${RENAME} $tfs$l_new $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$l_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- rebaseline
- fi
- fi
- else
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- rebaseline
- else
- rebaseline
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- rebaseline
- else
- rebaseline
- fi
- fi
- fi
- fi
- # Replicate data:
- echo "sudo ${SEND} -i $lfs$l_old $lfs$l_new 2>> ${ERR} | sudo zfs recv -du $lp 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Data replicated\" >> $log" >> ${cmd}
- # Destroy target .base snapshot(s):
- if [ "$r" = "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.base)" -gt "0" ]; then
- sudo ${DESTROY} $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "\$(date): Target .base snapshot(s) destroyed" >> $log
- fi
- EOF
- else
- cat >> ${cmd} << EOF
- if [ "\$(zfs list -H -t snapshot -o name $tfs$l_old 2>/dev/null | awk 'END{print NR}')" -gt "0" ]; then
- sudo ${DESTROY} $tfs$l_old 2>> ${ERR}
- errorcheck
- echo "\$(date): Target .base snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- # Rename target .delta snapshot(s) .old:
- echo "sudo ${RENAME} $tfs$l_new $tfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target .delta snapshot(s) renamed .base\" >> $log" >> ${cmd}
- # Destroy source .base snapshot(s):
- echo "sudo ${DESTROY} $lfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Source .base snapshot(s) destroyed\" >> $log" >> ${cmd}
- # Rename source .delta snapshot(s) .base:
- echo "sudo ${RENAME} $lfs$l_new $lfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Source .delta snapshot(s) renamed .base\" >> $log" >> ${cmd}
- echo "echo \"\`date\`: Local incremental replication sequence finished on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- echo "echo \"\" >> $log" >> ${cmd}
- echo "exit 0" >> ${cmd}
- echo "" >> ${cmd}
- }
- r_inc()
- {
- ##
- ## Makes remote incremental replication
- ##
- SSH="ssh"
- if [ "${compress}" = "yes" ]; then
- SSH="ssh -C"
- fi
- if [ ! -z ${port} ]; then
- SSH="${SSH} -p ${port}"
- else
- SSH="${SSH} -p 22"
- fi
- if [ `ping -c 1 -W 1000 $rh | grep -oe "[0-9] packets received" | awk '{print $1}'` -eq "0" ]; then
- echo "`date`: Remote incremental replication sequence aborted on \"$lfs\"! No response from \"$rh\"." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- if zpool status `echo $lfs | cut -f1 -d /` | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on source pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif su replicator -c "${SSH} $rh zpool status $rp | grep \"scan:\" | egrep -qo '(scrub in progress|resilver in progress)'"; then
- echo "`date`: A Scrub or Resilver is currently in progress on remote pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- tfs=`echo $lfs | cut -f 2-512 -d / | sed "s/^/$rp\/$lh\//"`
- echo "`date`: Beginning remote incremental replication sequence on \"$lfs\"" >> $log
- # Take new source snapshot(s):
- REPID="`awk -F':' '{print $6}' /etc/passwd | grep replicator`/.ssh/id_rsa"
- if [ "$r" = "yes" ]; then
- SOURCEBASE=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.base)
- SOURCEDELTA=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.delta)
- DESTBASE=$(su replicator -c "${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.base")
- DESTDELTA=$(su replicator -c "${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.delta")
- SNAPSHOT="zfs snapshot -r"
- SEND="zfs send -R"
- DESTROY="zfs destroy -r"
- RENAME="zfs rename -r"
- else
- SOURCEBASE=$(zfs list -H -t snapshot -o name $lfs$r_old 2>/dev/null | awk 'END{print NR}')
- SOURCEDELTA=$(zfs list -H -t snapshot -o name $lfs$r_new 2>/dev/null | awk 'END{print NR}')
- DESTBASE=$(su replicator -c "${SSH} $rh zfs list -H -t snapshot -o name $tfs$r_old 2>/dev/null | awk 'END{print NR}'")
- DESTDELTA=$(su replicator -c "${SSH} $rh zfs list -H -t snapshot -o name $tfs$r_new 2>/dev/null | awk 'END{print NR}'")
- SNAPSHOT="zfs snapshot"
- SEND="zfs send -p"
- DESTROY="zfs destroy"
- RENAME="zfs rename"
- fi
- rebaseline()
- {
- echo "echo \"\`date\`: No appropriate correctional steps where found, have to rebaseline\" >> $log" >> ${cmd}
- if [ ${SOURCEBASE} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${SOURCEDELTA} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$r_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTBASE} -gt "0" ]; then
- echo "${SSH} $rh sudo ${DESTROY} $tfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTDELTA} -gt "0" ]; then
- echo "${SSH} $rh sudo ${DESTROY} $tfs$r_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ "$r" != "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$r_old|$r_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$r_old|$r_new"); do
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- ${SSH} $rh sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted remote target snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- if [ $(su replicator -c "${SSH} $rh zfs list -H -o name -r $tfs 2>/dev/null | awk 'END{print NR}'") -gt "0" ]; then
- echo "${SSH} $rh sudo ${DESTROY} $tfs 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target filesystem destroyed\" >> $log" >> ${cmd}
- fi
- echo "sudo ${SNAPSHOT} $lfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Base snapshot(s) created\" >> $log" >> ${cmd}
- echo "sudo ${SEND} $lfs$r_old 2>> ${ERR} | ${SSH} $rh sudo zfs recv -du $rp/$lh 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Data replicated\" >> $log" >> ${cmd}
- echo "echo \"\`date\`: Rebaseline complete\" >> $log" >> ${cmd}
- echo "sudo ${SNAPSHOT} $lfs$r_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Delta snapshot(s) created\" >> $log" >> ${cmd}
- }
- dryrun()
- {
- DRYRUNOUT=$(mktemp /tmp/replicate.dryrun.XXXXXX)
- if [ "$r" = "yes" ]
- then
- DODRYRUN=`zfs send -vRi $lfs$r_old $lfs$r_new 2> ${DRYRUNOUT} | ${SSH} -i ${REPID} replicator@$rh sudo zfs recv -vdn $rp/$lh 2>> ${DRYRUNOUT}`
- else
- DODRYRUN=`zfs send -vi $lfs$r_old $lfs$r_new 2> ${DRYRUNOUT} | ${SSH} -i ${REPID} replicator@$rh sudo zfs recv -vdn $rp/$lh 2>> ${DRYRUNOUT}`
- fi
- DRYRUNOK=`egrep '(could not send|cannot receive)' ${DRYRUNOUT} | wc -l | sed 's/^[ \t]*//'`
- rm ${DRYRUNOUT}; echo ${DRYRUNOK}
- }
- if [ ${SOURCEBASE} -gt "0" ]
- then
- if [ ${SOURCEDELTA} -gt "0" ]
- then
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${DESTDELTA} = ${DESTBASE} ]
- then
- echo "`date`: Probably interrupted while destroying target .base(s)" >> $log
- ${SSH} -i ${REPID} replicator@$rh sudo ${DESTROY} $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .base snapshot(s) destroyed" >> $log
- ${SSH} -i ${REPID} replicator@$rh sudo ${RENAME} $tfs$r_new $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${DESTROY} $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .base snapshot(s) destroyed" >> $log
- ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful" >> $log
- echo "`date`: Probably interrupted while destroying source .base(s)" >> $log
- ${DESTROY} $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .base snapshot(s) destroyed" >> $log
- ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- echo "`date`: Dry run successful" >> $log
- echo "`date`: Probably interrupted while transferring, resending" >> $log
- fi
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEDELTA} = ${DESTDELTA} ]
- then
- echo "`date`: Probably interrupted while renaming target .delta to .base" >> $log
- ${SSH} -i ${REPID} replicator@$rh sudo ${RENAME} $tfs$r_new $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${DESTROY} $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .base snapshot(s) destroyed" >> $log
- ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- rebaseline
- fi
- fi
- else
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- ${SSH} -i ${REPID} replicator@$rh sudo ${DESTROY} $tfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) found and destroyed" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- else
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEBASE} = ${DESTDELTA} ]
- then
- echo "`date`: No target .base found, but source .base matches target delta. Renaming target .delta to .base" >> $log
- ${SSH} -i ${REPID} replicator@$rh sudo ${RENAME} $tfs$r_new $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- rebaseline
- fi
- fi
- fi
- else
- if [ ${SOURCEDELTA} -gt "0" ]
- then
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEDELTA} = ${DESTDELTA} ]
- then
- echo "`date`: Probably interrupted while destroying target .base(s)" >> $log
- ${SSH} -i ${REPID} replicator@$rh sudo ${DESTROY} $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .base snapshot(s) destroyed" >> $log
- ${SSH} -i ${REPID} replicator@$rh sudo ${RENAME} $tfs$r_new $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- if [ ${SOURCEDELTA} = ${DESTBASE} ]
- then
- echo "`date`: Probably interrupted while renaming source .delta to .base" >> $log
- ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- if [ ${SOURCEDELTA} = ${DESTDELTA} ]
- then
- echo "`date`: No source or target base, but source and target delta matches. Can try to rename them to base and test a resend"
- ${SSH} -i ${REPID} replicator@$rh sudo ${RENAME} $tfs$r_new $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Target .delta snapshot(s) renamed .base" >> $log
- ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}
- errorcheck
- echo "`date`: Source .delta snapshot(s) renamed .base" >> $log
- ${SNAPSHOT} $lfs$r_new 2>> ${ERR}
- errorcheck
- echo "`date`: New source .delta snapshot(s) created, proceeding" >> $log
- if [ `dryrun` -gt "0" ]
- then
- echo "`date`: Dry run unsuccessful, rebaselining" >> $log
- rebaseline
- else
- echo "`date`: Dry run successful, OK to resend" >> $log
- fi
- else
- rebaseline
- fi
- else
- rebaseline
- fi
- fi
- else
- if [ ${DESTBASE} -gt "0" ]
- then
- if [ ${DESTDELTA} -gt "0" ]
- then
- rebaseline
- else
- rebaseline
- fi
- else
- if [ ${DESTDELTA} -gt "0" ]
- then
- rebaseline
- else
- rebaseline
- fi
- fi
- fi
- fi
- # Replicate data:
- echo "sudo ${SEND} -i $lfs$r_old $lfs$r_new 2>> ${ERR} | ${SSH} $rh sudo zfs recv -du $rp/$lh 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Data replicated\" >> $log" >> ${cmd}
- # Destroy target .base snapshot(s):
- if [ "$r" = "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.base)" -gt "0" ]; then
- ${SSH} $rh sudo ${DESTROY} $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "\$(date): Target .base snapshot(s) destroyed" >> $log
- fi
- EOF
- else
- cat >> ${cmd} << EOF
- if [ "\$(${SSH} $rh zfs list -H -t snapshot -o name $tfs$r_old 2>/dev/null | awk 'END{print NR}')" -gt "0" ]; then
- ${SSH} $rh sudo ${DESTROY} $tfs$r_old 2>> ${ERR}
- errorcheck
- echo "\$(date): Target .base snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- # Rename target .delta snapshot(s) to .base:
- echo "${SSH} $rh sudo ${RENAME} $tfs$r_new $tfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target .delta snapshot(s) renamed .base\" >> $log" >> ${cmd}
- # Destroy source .base snapshot(s):
- echo "sudo ${DESTROY} $lfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Source .base snapshot(s) destroyed\" >> $log" >> ${cmd}
- # Rename source .delta snapshot(s) to .base:
- echo "sudo ${RENAME} $lfs$r_new $lfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Source .delta snapshot(s) renamed .base\" >> $log" >> ${cmd}
- echo "echo \"\`date\`: Remote incremental replication sequence finished on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- echo "echo \"\" >> $log" >> ${cmd}
- echo "exit 0" >> ${cmd}
- }
- l_clean()
- {
- ##
- ## Cleans locally replicated file system
- ##
- if zpool status `echo $lfs | cut -f1 -d /` | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on source pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif zpool status $lp | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on destination pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- tfs=`echo $lfs | cut -f 2-512 -d / | sed "s/^/$lp\//"`
- if [ "$r" = "yes" ]; then
- SOURCEBASE=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.base)
- SOURCEDELTA=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.delta)
- DESTBASE=$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.base)
- DESTDELTA=$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.delta)
- SNAPSHOT="zfs snapshot -r"
- SEND="zfs send -R"
- DESTROY="zfs destroy -r"
- RENAME="zfs rename -r"
- else
- SOURCEBASE=$(zfs list -H -t snapshot -o name $lfs$r_old 2>/dev/null | awk 'END{print NR}')
- SOURCEDELTA=$(zfs list -H -t snapshot -o name $lfs$r_new 2>/dev/null | awk 'END{print NR}')
- DESTBASE=$(zfs list -H -t snapshot -o name $tfs$r_old 2>/dev/null | awk 'END{print NR}')
- DESTDELTA=$(zfs list -H -t snapshot -o name $tfs$r_new 2>/dev/null | awk 'END{print NR}')
- SNAPSHOT="zfs snapshot"
- SEND="zfs send -p"
- DESTROY="zfs destroy"
- RENAME="zfs rename"
- fi
- echo "echo \"\`date\`: Beginning local cleaning process on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- if [ ${SOURCEBASE} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${SOURCEDELTA} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$l_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTBASE} -gt "0" ]; then
- echo "sudo ${DESTROY} $tfs$l_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTDELTA} -gt "0" ]; then
- echo "sudo ${DESTROY} $tfs$l_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ "$r" != "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$l_old|$l_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$l_old|$l_new"); do
- if [ "\$(zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted local target snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- if [ $(zfs list -H -o name -r $tfs 2>/dev/null | awk 'END{print NR}') -gt "0" ]; then
- echo "sudo ${DESTROY} $tfs 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target filesystem destroyed\" >> $log" >> ${cmd}
- fi
- echo "echo \"\`date\`: Local cleanup complete on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- echo "echo \"\" >> $log" >> ${cmd}
- echo "" >> ${cmd}
- }
- r_clean()
- {
- ##
- ## Cleans remotely replicated file systems
- ##
- SSH="ssh"
- if [ "${compress}" = "yes" ]; then
- SSH="ssh -C"
- fi
- if [ ! -z ${port} ]; then
- SSH="${SSH} -p ${port}"
- else
- SSH="${SSH} -p 22"
- fi
- if [ `ping -c 1 -W 1000 $rh | grep -oe "[0-9] packets received" | awk '{print $1}'` -eq "0" ]; then
- echo "`date`: Remote cleanup aborted on \"$lfs\"! No response from \"$rh\"." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif zpool status `echo $lfs | cut -f1 -d /` | grep "scan:" | egrep -qo "(scrub in progress|resilver in progress)"; then
- echo "`date`: A Scrub or Resilver is currently in progress on source pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- elif su replicator -c "${SSH} $rh zpool status $rp | grep \"scan:\" | egrep -qo '(scrub in progress|resilver in progress)'"; then
- echo "`date`: A Scrub or Resilver is currently in progress on destination pool, aborting." >> $log
- echo "" >> $log
- rm ${pid}
- exit 1
- fi
- tfs=`echo $lfs | cut -f 2-512 -d / | sed "s/^/$rp\/$lh\//"`
- if [ "$r" = "yes" ]; then
- SOURCEBASE=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.base)
- SOURCEDELTA=$(zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep -c replicate.delta)
- DESTBASE=$(su replicator -c "${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.base")
- DESTDELTA=$(su replicator -c "${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c replicate.delta")
- SNAPSHOT="zfs snapshot -r"
- SEND="zfs send -R"
- DESTROY="zfs destroy -r"
- RENAME="zfs rename -r"
- else
- SOURCEBASE=$(zfs list -H -t snapshot -o name $lfs$r_old 2>/dev/null | awk 'END{print NR}')
- SOURCEDELTA=$(zfs list -H -t snapshot -o name $lfs$r_new 2>/dev/null | awk 'END{print NR}')
- DESTBASE=$(su replicator -c "${SSH} $rh zfs list -H -t snapshot -o name $tfs$r_old 2>/dev/null | awk 'END{print NR}'")
- DESTDELTA=$(su replicator -c "${SSH} $rh zfs list -H -t snapshot -o name $tfs$r_new 2>/dev/null | awk 'END{print NR}'")
- SNAPSHOT="zfs snapshot"
- SEND="zfs send -p"
- DESTROY="zfs destroy"
- RENAME="zfs rename"
- fi
- echo "echo \"\`date\`: Beginning remote cleaning process on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- if [ ${SOURCEBASE} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${SOURCEDELTA} -gt "0" ]; then
- echo "sudo ${DESTROY} $lfs$r_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Local delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTBASE} -gt "0" ]; then
- echo "${SSH} $rh sudo ${DESTROY} $tfs$r_old 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target base snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ ${DESTDELTA} -gt "0" ]; then
- echo "${SSH} $rh sudo ${DESTROY} $tfs$r_new 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target delta snapshot destroyed\" >> $log" >> ${cmd}
- fi
- if [ "$r" != "yes" ]; then
- cat >> ${cmd} << EOF
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$r_old|$r_new" | awk 'END{print NR}')" -gt "0" ]; then
- for SNAPSHOT in \$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep "${tfs}@" | egrep -v "$r_old|$r_new"); do
- if [ "\$(${SSH} $rh zfs list -H -r -t snapshot -o name $tfs 2>/dev/null | grep -c "\${SNAPSHOT}")" -gt "0" ]; then
- ${SSH} $rh sudo zfs destroy \${SNAPSHOT} 2>> ${ERR}
- errorcheck
- fi
- done
- echo "\$(date): Unwanted remote target snapshot(s) destroyed" >> $log
- fi
- EOF
- fi
- if [ $(su replicator -c "${SSH} $rh zfs list -H -o name -r $tfs 2>/dev/null | awk 'END{print NR}'") -gt "0" ]; then
- echo "${SSH} $rh sudo ${DESTROY} $tfs 2>> ${ERR}" >> ${cmd}
- echo errorcheck >> ${cmd}
- echo "echo \"\`date\`: Target filesystem destroyed\" >> $log" >> ${cmd}
- fi
- echo "echo \"\`date\`: Remote cleanup complete on \\\"$lfs\\\"\" >> ${log}" >> ${cmd}
- echo "echo \"\" >> $log" >> ${cmd}
- echo "" >> ${cmd}
- }
- errorcheck()
- {
- if [ "$?" -ne "0" ]; then
- tail -2 ${ERR} >> $log
- tail -10 $log > ${mail}
- mail -s "$subject" $address < ${mail}
- cat /dev/null > ${mail}
- exit 1
- fi
- }
- usenonecipher()
- {
- sed -i '' -e "s/${SSH} $rh sudo zfs recv/${SSH} -oNoneEnabled=yes -oNoneSwitch=yes $rh sudo zfs recv/" ${cmd}
- }
- sanity()
- {
- if [ -e $pid ]; then
- CMD_BASE=$(echo ${cmd} | sed -E 's/\.[[:alnum:]]*$/\./')
- # Since replicate has fired again (that is why it is running now), it has
- # created a new job for _this_ run. So when searching for latest job, we
- # scroll back two steps, instead of just one, which we already know is going
- # to be empty any way:
- LAST_RUN_JOB=$(ls -lU -D %y-%m-%d_%H-%M-%S ${CMD_BASE}* | egrep -o "([0-9]|\-|\_){17}.*$" | sort -n -t '_' -k 1,8 | tail -2 | head -1 | cut -d ' ' -f 2)
- COMMANDS_IN_JOB=$(sed -E -e 's/ \$\{.*\}//' -e 's/^\ {4}if \[ "\$\(//' -e 's# 2>/dev/null.*$##' ${LAST_RUN_JOB} | egrep -v '^(echo|errorcheck|exit|if|fi|for|done|^#|^$)|^\ (\{|\})|^\ {2}(echo|errorcheck|if|fi|for|done)|^\ {4}(tail|mail|cat|exit|errorcheck|if|fi)|^\ {6}errorcheck' | tr '|' '\n' | sed -E -e 's/^\ *//' -e 's/ 2>>.*$//' | tr '\n' '|' | sed 's/|$//')
- if [ $(echo "${COMMANDS_IN_JOB}" | wc -w) -le 0 ]; then
- for JOB in $(ls -lU -D %y-%m-%d_%H-%M-%S ${CMD_BASE}* | egrep -o "([0-9]|\-|\_){17}.*$" | sort -r -n -t '_' -k 1,8 | cut -d ' ' -f 2); do
- COMMANDS_IN_JOB=$(sed -E -e 's/ \$\{.*\}//' -e 's/^\ {4}if \[ "\$\(//' -e 's# 2>/dev/null.*$##' ${JOB} | egrep -v '^(echo|errorcheck|exit|if|fi|for|done|^#|^$)|^\ (\{|\})|^\ {2}(echo|errorcheck|if|fi|for|done)|^\ {4}(tail|mail|cat|exit|errorcheck|if|fi)|^\ {6}errorcheck' | tr '|' '\n' | sed -E -e 's/^\ *//' -e 's/ 2>>.*$//' | tr '\n' '|' | sed 's/|$//')
- if [ $(echo "${COMMANDS_IN_JOB}" | wc -w) -ne 0 ]; then
- LAST_RUN_JOB=${JOB}
- break
- else
- LAST_RUN_JOB=""
- fi
- done
- fi
- replicate_cleanup() {
- REPLICATE_PID_LOOP=$(printf "${REPLICATE_PROCESSES}" | awk '{print$1}')
- for REPLICATE_PID in ${REPLICATE_PID_LOOP}; do
- USED_CPU=$(ps -a -x -o pid,%cpu,command | grep "${REPLICATE_PID}" | grep -v grep | awk '{sub(/\./,"");print$2}')
- if [ $(echo "${USED_CPU}" | wc -w) -ne 0 ]; then
- # OK, so there is at least a process there:
- if [ $(printf "${USED_CPU}" | wc -l) -gt 1 ]; then
- USED_CPU=$(printf "${USED_CPU}" | awk '{if($1>a)a=$1};{if(a=="")a="00"};END{print a}')
- fi
- else
- USED_CPU="00"
- fi
- if [ "${USED_CPU}" = "00" ]; then
- USED_CPU="0"
- else
- USED_CPU=$(echo "${USED_CPU}" | sed 's/0//g')
- fi
- if [ ${USED_CPU} -ne 0 ]; then
- RUNNING_PROCESSES="${RUNNING_PROCESSES} ${REPLICATE_PID}"
- else
- UNKNOWN_STATUS_PROCESSES="${UNKNOWN_STATUS_PROCESSES} ${REPLICATE_PID}"
- fi
- done
- if [ $(echo "${RUNNING_PROCESSES}" | wc -w) -ne 0 ]; then
- echo "$(date): Started a new process, but previous \"replicate\" processes are still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- if [ $(echo "${UNKNOWN_STATUS_PROCESSES}" | wc -w) -ne 0 ]; then
- for UNKNOWN_STATUS_PROCESS in ${UNKNOWN_STATUS_PROCESSES}; do
- if [ $(ps ax | grep "${UNKNOWN_STATUS_PROCESS}" | grep -v grep | egrep -c ' D.* ') -ne 0 ]; then
- ERROR_MESSAGE="The previous replicate command set has been found with no running processes and seems to be stuck. A process from the last run has been found in \"D\" state which can not be killed, reboot required"
- echo "${ERROR_MESSAGE}" >> ${mail}
- echo "$(ps ax | grep "${UNKNOWN_STATUS_PROCESS}" | grep -v grep | egrep ' D.* ')" >> ${mail}
- mail -s "$subject" $address < ${mail}
- echo "$(date): ${ERROR_MESSAGE}" >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- kill ${UNKNOWN_STATUS_PROCESS}
- echo "$(date): No process from previous replicate run found running. Killed idle process \"${UNKNOWN_STATUS_PROCESS}\" as part of the cleanup before trying to start again." >> $log
- echo "" >> $log
- fi
- done
- else
- echo "$(date): No idle or running processes from previous replicate run found running." >> $log
- echo "" >> $log
- fi
- fi
- }
- confirm_activity() {
- while [ "$#" -gt "0" ]; do
- case "$1" in
- "-r")
- MODE="$1"
- ;;
- "-d")
- DESTROYING="$1"
- ;;
- *)
- echo "Unknown argument '$1'" >&2
- ;;
- esac
- shift
- done
- if [ "${MODE}" = "-r" ]; then
- if [ "${DESTROYING}" = "-d" ]; then
- USED_CPU=$(printf "${REPLICATE_PROCESSES}" | grep 'ssh' | egrep 'zfs destroy|zfs list' | awk '{sub(/\./,"");print$2}')
- else
- USED_CPU=$(printf "${REPLICATE_PROCESSES}" | grep 'ssh' | grep 'zfs recv' | awk '{sub(/\./,"");print$2}')
- fi
- else
- if [ "${DESTROYING}" = "-d" ]; then
- USED_CPU=$(printf "${REPLICATE_PROCESSES}" | egrep 'zfs destroy|zfs list' | awk '{sub(/\./,"");print$2}')
- else
- USED_CPU=$(printf "${REPLICATE_PROCESSES}" | grep 'zfs recv' | awk '{sub(/\./,"");print$2}')
- fi
- fi
- if [ $(echo "${USED_CPU}" | wc -w) -ne 0 ]; then
- # OK, so there is at least a process there:
- if [ $(printf "${USED_CPU}" | wc -l) -gt 1 ]; then
- USED_CPU=$(printf "${USED_CPU}" | awk '{if($1>a)a=$1};{if(a=="")a="00"};END{print a}')
- fi
- else
- USED_CPU="00"
- fi
- if [ ${USED_CPU} = "00" ]; then
- USED_CPU="0"
- else
- USED_CPU=$(echo "${USED_CPU}" | sed 's/0//g')
- fi
- if [ ${USED_CPU} -ne 0 ]; then
- # Found running process:
- echo "$(date): Started a new process, but the previous remote \"replicate\" is still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- if [ "${MODE}" = "-r" ]; then
- # Found 'zfs recv' process but considered idle. Need to check if
- # still active on receiving end.
- SSH="ssh"
- if [ ! -z ${port} ]; then
- SSH="${SSH} -p ${port}"
- else
- SSH="${SSH} -p 22"
- fi
- REPID="$(awk -F':' '{print $6}' /etc/passwd | grep replicator)/.ssh/id_rsa"
- REMOTE_REPLICATE_COMMANDS=$(printf "${COMMANDS_IN_JOB}" | tr '|' '\n' | grep 'ssh' | sed -E -e "s/${SSH} ${rh}//" -e 's/.* sudo//' -e 's/^ //' | tr '\n' '|' | sed -E "s/\|$//")
- REMOTE_REPLICATE_PROCESSES=$(${SSH} -i ${REPID} replicator@$rh ps -a -x -o pid,%cpu,command | egrep "zfs send -vRi|zfs recv -vdn|${REMOTE_REPLICATE_COMMANDS}" | egrep -v 'egrep| sudo ')
- if [ "${DESTROYING}" = "-d" ]; then
- USED_CPU=$(printf "${REMOTE_REPLICATE_PROCESSES}" | egrep 'zfs destroy|zfs list' | awk '{sub(/\./,"");print$2}')
- else
- USED_CPU=$(printf "${REMOTE_REPLICATE_PROCESSES}" | grep 'zfs recv' | awk '{sub(/\./,"");print$2}')
- fi
- if [ $(echo "${USED_CPU}" | wc -w) -ne 0 ]; then
- # OK, so there is at least a process there:
- if [ $(printf "${USED_CPU}" | wc -l) -gt 1 ]; then
- USED_CPU=$(printf "${USED_CPU}" | awk '{if($1>a)a=$1};{if(a=="")a="00"};END{print a}')
- fi
- else
- USED_CPU="00"
- fi
- if [ ${USED_CPU} = "00" ]; then
- USED_CPU="0"
- else
- USED_CPU=$(echo "${USED_CPU}" | sed 's/0//g')
- fi
- if [ ${USED_CPU} -ne 0 ]; then
- # Found running process:
- echo "$(date): Started a new process, but the previous remote \"replicate\" is still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- # But for crying out loud, it isn't using any CPU time either?
- # OK, what is left to check then, is the size changing?
- LAST_RUN_FILESYSTEM=$(printf "${COMMANDS_IN_JOB}" | tr '|' '\n' | grep 'zfs send' | awk '{print $NF}' | cut -d '@' -f 1)
- TARGET_FILESYSTEM=$(echo ${LAST_RUN_FILESYSTEM} | cut -f 2-512 -d / | sed "s/^/$rp\/$lh\//")
- check_target_size() {
- ${SSH} -i ${REPID} replicator@$rh zfs get -H -p -o value used ${TARGET_FILESYSTEM}
- }
- SIZE_BEFORE=$(check_target_size)
- sleep 120
- SIZE_AFTER=$(check_target_size)
- if [ "${SIZE_BEFORE}" -ne "${SIZE_AFTER}" ]; then
- # Finally, a hit! Then it should at least be doing something.
- echo "$(date): Started a new process, but the previous remote \"replicate\" is still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- if [ "${DESTROYING}" = "-d" ]; then
- # Hmm, so size hasn't changed on the filesystem either, jeez... OK, last check; is the number of snapshots changing?
- check_number_of_snapshots() {
- ${SSH} -i ${REPID} replicator@$rh zfs list -H -t snapshot -o name -r ${TARGET_FILESYSTEM} 2>/dev/null | awk 'END{print NR}'
- }
- SNAPSHOTS_NUMBER_BEFORE=$(check_number_of_snapshots)
- sleep 120
- SNAPSHOTS_NUMBER_AFTER=$(check_number_of_snapshots)
- if [ "${SNAPSHOTS_NUMBER_BEFORE}" -gt "${SNAPSHOTS_NUMBER_AFTER}" ]; then
- # Epic win! So it's probably removing snapshots, good grief what a hassle:)
- echo "$(date): Started a new process, but the previous remote \"replicate\" is still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- replicate_cleanup
- fi
- else
- replicate_cleanup
- fi
- fi
- fi
- else
- # But for crying out loud, it isn't using any CPU time either?
- # OK, what is left to check then, is the size changing?
- LAST_RUN_FILESYSTEM=$(printf "${COMMANDS_IN_JOB}" | tr '|' '\n' | grep 'zfs send' | awk '{print $NF}' | cut -d '@' -f 1)
- TARGET_FILESYSTEM=$(echo ${LAST_RUN_FILESYSTEM} | cut -f 2-512 -d / | sed "s/^/$lp\//")
- check_target_size() {
- zfs get -H -p -o value used ${TARGET_FILESYSTEM}
- }
- SIZE_BEFORE=$(check_target_size)
- sleep 120
- SIZE_AFTER=$(check_target_size)
- if [ "${SIZE_BEFORE}" -ne "${SIZE_AFTER}" ]; then
- # Finally, a hit! Then it should at least be doing something.
- echo "$(date): Started a new process, but the previous local \"replicate\" is still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- if [ "${DESTROYING}" = "-d" ]; then
- # Hmm, so size hasn't changed on the filesystem either, jeez... OK, last check; is the number of snapshots changing?
- check_number_of_snapshots() {
- zfs list -H -t snapshot -o name -r ${TARGET_FILESYSTEM} 2>/dev/null | awk 'END{print NR}'
- }
- SNAPSHOTS_NUMBER_BEFORE=$(check_number_of_snapshots)
- sleep 120
- SNAPSHOTS_NUMBER_AFTER=$(check_number_of_snapshots)
- if [ "${SNAPSHOTS_NUMBER_BEFORE}" -gt "${SNAPSHOTS_NUMBER_AFTER}" ]; then
- # Epic win! So it's probably removing snapshots, good grief what a hassle:)
- echo "$(date): Started a new process, but the previous local \"replicate\" is still running, aborting." >> $log
- echo "" >> $log
- rm ${ERR}; rm ${cmd}; rm ${mail}; exit 1
- else
- replicate_cleanup
- fi
- else
- replicate_cleanup
- fi
- fi
- fi
- fi
- }
- confirm_active_recv() {
- if [ ! -z ${rh} ]; then
- # Means it is a remote replication job:
- if [ $(printf "${REPLICATE_PROCESSES}" | grep -c 'ssh') -ne 0 ]; then
- # Found active 'ssh' transfer:
- if [ $(printf "${REPLICATE_PROCESSES}" | grep 'ssh' | grep -c 'zfs recv') -ne 0 ]; then
- # Found active 'zfs recv':
- confirm_activity -r
- else
- # No active 'zfs recv' found running. Is it destroying?
- if [ $(printf "${REPLICATE_PROCESSES}" | grep 'ssh' | egrep -c 'zfs destroy|zfs list') -ne 0 ]; then
- # It's supposed to be destroying snapshots at the moment. Let's make
- # sure:
- confirm_activity -r -d
- else
- replicate_cleanup
- fi
- fi
- else
- # No active 'ssh' transfer found running when set as remote:
- replicate_cleanup
- fi
- else
- # If not remote, then it is a local replication job:
- if [ $(printf "${REPLICATE_PROCESSES}" | grep -c 'zfs recv') -ne 0 ]; then
- # Found active 'zfs recv':
- confirm_activity
- else
- # No active 'zfs recv' found running. Is it destroying?
- if [ $(printf "${REPLICATE_PROCESSES}" | egrep -c 'zfs destroy|zfs list') -ne 0 ]; then
- # It's supposed to be destroying snapshots at the moment. Let's make
- # sure:
- confirm_activity -d
- else
- replicate_cleanup
- fi
- fi
- fi
- }
- confirm_replicate_status() {
- if [ $(printf "${REPLICATE_PROCESSES}" | wc -w) -ne 0 ]; then
- if [ $(printf "${REPLICATE_PROCESSES}" | egrep -c 'zfs send|zfs recv|zfs destroy|zfs list') -ne 0 ]; then
- if [ $(printf "${REPLICATE_PROCESSES}" | grep -c 'zfs send') -ne 0 ]; then
- # Found active 'zfs send':
- confirm_active_recv
- else
- # No active 'zfs send' found running:
- confirm_active_recv
- fi
- else
- # No active 'zfs send' or 'zfs recv' found running. If remote, it
- # might still be working on the receiving end.
- if [ "$(printf "${COMMANDS_IN_JOB}" | tr '|' '\n' | grep -c 'ssh')" -ne "0" ]; then
- confirm_activity -r -d
- else
- replicate_cleanup
- fi
- fi
- else
- # No processes left running. Starting new job.
- :
- fi
- }
- if [ $(echo ${LAST_RUN_JOB} | wc -w) -ne 0 ]; then
- if [ $(ps ax | egrep "${LAST_RUN_JOB}" | grep -v egrep -c) -ne 0 ]; then
- REPLICATE_PROCESSES=$(ps -a -x -o pid,%cpu,command | egrep "zfs send -vRi|zfs recv -vdn|${LAST_RUN_JOB}|${COMMANDS_IN_JOB}" | grep -v egrep)
- confirm_replicate_status
- else
- # The last known job to have commands is not running any more:
- replicate_cleanup
- fi
- else
- # No previous job found with valid commands. Retrying with broadened
- # search criteria:
- REPLICATE_PROCESSES=$(ps -a -x -o pid,%cpu,command | egrep 'zfs send|zfs recv|zfs snapshot|zfs rename|zfs destroy|zfs list' | egrep -v 'egrep|zfSnap')
- confirm_replicate_status
- fi
- fi
- chown replicator ${mail}; chmod 600 ${mail}
- chown replicator ${ERR}; chmod 600 ${ERR}
- chown replicator ${cmd}; chmod 700 ${cmd}
- cat > ${cmd} << EOF
- #!/bin/sh
- errorcheck()
- {
- if [ "\$?" -ne "0" ]; then
- tail -2 ${ERR} >> $log
- tail -10 $log > ${mail}
- mail -s "$subject" $address < ${mail}
- cat /dev/null > ${mail}
- exit 1
- fi
- }
- EOF
- }
- autoclean()
- {
- ##
- ## Find and destroy all automatically taken snapshots
- ##
- zfs list -t snapshot -o name | grep auto > ${cmd}
- cat ${cmd}
- sed -i '' 's/^/sudo zfs destroy /' ${cmd}
- }
- allow()
- {
- sudoers="/usr/local/etc/sudoers"
- if [ `grep "ssh" ${cmd} | wc -l` -gt "0" ]
- then
- allows=`grep zfs ${cmd} | cut -f 1 -d ">" | tr '|' '\n' | sed -e 's/^ //' -e 's/ 2$//' | sed -e 's/sudo //' -e 's/^ //' -e 's/^/replicator ALL=(ALL) NOPASSWD: \/sbin\//' | grep -v ssh`
- else
- allows=`grep zfs ${cmd} | cut -f 1 -d ">" | tr '|' '\n' | sed -e 's/^ //' -e 's/ 2$//' | sed -e 's/sudo //' -e 's/^ //' -e 's/^/replicator ALL=(ALL) NOPASSWD: \/sbin\//'`
- fi
- if [ `grep "replicator" $sudoers | wc -l` -gt "0" ]; then
- sed -i '' '/replicator/d' $sudoers
- fi
- echo "$allows" >> $sudoers
- }
- disallow()
- {
- if [ `grep "replicator" $sudoers | wc -l` -gt "0" ]; then
- sed -i '' '/replicator/d' $sudoers
- fi
- }
- ##
- ## Initial preparation
- ##
- case "$1" in
- "")
- ##
- ## If no jobname is specified, it will find all jobs in config directory and
- ## process them one by one
- ##
- for job in $jobs
- do
- . $job
- sanity
- touch $pid
- if [ -z "$rh" ]
- then
- if [ `zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep @local_replicate | wc -l | sed 's/^[ \t]*//'` -gt "0" ]
- then
- l_inc
- else
- l_base
- fi
- else
- if [ `zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep @remote_replicate | wc -l | sed 's/^[ \t]*//'` -gt "0" ]
- then
- r_inc
- if [ "$none" = "yes" ]; then
- usenonecipher
- fi
- else
- r_base
- if [ "$none" = "yes" ]; then
- usenonecipher
- fi
- fi
- fi
- allow
- su replicator -c ${cmd}
- disallow
- rm $pid
- done
- ;;
- -c)
- ##
- ## When cleaning, if no jobname is specified, it will find all jobs in
- ## config directory and process them one by one
- ##
- if [ "$2" = "auto" ]
- then
- else
- echo ""
- echo "Starting off by deleting replication snapshot(s) and cleaning the entire"
- echo "target pool zfs filesystem. This can take a while, depending on how much"
- echo "is stored."
- sleep 10
- fi
- if [ "$2" = "" ]; then
- for job in `find $path -type f ! -iname sample_* ! -iname noauto_* | sort -rd`
- do
- . $job
- sanity
- touch $pid
- if [ -z "$rh" ]
- then
- l_clean
- else
- r_clean
- fi
- allow
- su replicator -c ${cmd}
- disallow
- rm $pid
- done
- exit
- fi
- ##
- ## Also when cleaning, if you type in shorthand jobname, it will only clean
- ## specified job
- ##
- if [ -e ${path}$2 ]; then
- . $path$2
- sanity
- touch $pid
- if [ -z "$rh" ]
- then
- l_clean
- else
- r_clean
- fi
- allow
- su replicator -c ${cmd}
- disallow
- rm $pid
- else
- ##
- ## If you type "auto" when cleaning, it finds and destroys all snapshots with
- ## the word "auto" in them.
- ##
- if [ "$2" = "auto" ]
- then
- sanity
- touch $pid
- autoclean
- while true
- do
- read -r -p 'These snapshot(s) will destroyed. Confirm? "Y|n"' choice
- case "$choice" in
- y|Y) allow
- su replicator -c ${cmd}
- disallow
- rm $pid
- check=`zfs list -t snapshot`
- result="no datasets available"
- if [ "$check" = "$result" ]; then
- echo "Seems clean enough"
- else
- echo "Seems there are snaps left:"
- zfs list -t snapshot
- fi; break ;;
- n|N) echo "Suit yourself..." ; break ;;
- *) echo "Suit yourself..." ; break ;;
- esac
- done
- else
- echo ""
- echo "### Error! ###"
- echo "Jobname \"$2\" does not exist"
- usage
- fi
- fi
- ;;
- -h)
- usage
- ;;
- *)
- ##
- ## If you type in shorthand jobname, it will only process specified job
- ##
- if [ -e ${path}$1 ]
- then
- . $path$1
- sanity
- touch $pid
- if [ -z "$rh" ]
- then
- if [ `zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep @local_replicate | wc -l | sed 's/^[ \t]*//'` -gt "0" ]
- then
- l_inc
- else
- l_base
- fi
- else
- if [ `zfs list -H -r -t snapshot -o name $lfs 2>/dev/null | grep @remote_replicate | wc -l | sed 's/^[ \t]*//'` -gt "0" ]
- then
- r_inc
- if [ "$none" = "yes" ]; then
- usenonecipher
- fi
- else
- r_base
- if [ "$none" = "yes" ]; then
- usenonecipher
- fi
- fi
- fi
- allow
- su replicator -c ${cmd}
- disallow
- rm $pid
- else
- echo ""
- echo "### Error! ###"
- echo "Jobname \"$1\" does not exist"
- usage
- fi
- ;;
- esac
- ##
- ## Final cleanup
- ##
- rm -f /tmp/replicate.*
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement