#!/bin/ksh

# A rather simple SMF method script for
# svc:/application/time-slider:default
# It's sole purpose is to set the correct SMF property value of it's
# direct "auto-snapshot:<schedule>" dependencies: zfs/fs-name = '//'

. /lib/svc/share/smf_include.sh

FMRI="svc:/application/time-slider:default"
SMF_FMRI="svc:/application/time-slider:default"
CLEANUP_PROG="/usr/lib/time-slider-cleanup -y"

# This function sets the appropriate svc configuration property for all
# dependent auto-snapshot:<schedule> instances if necessary
function update_service_props {
	set -x
	DEPENDENCIES=$(svcs -d  -H -o fmri $SMF_FMRI|grep auto-snapshot)
	for dependency in ${DEPENDENCIES} ; do
		if [ "$(svcprop -p zfs/fs-name $dependency)" != "//" ] ; then
			svccfg -s $dependency setprop zfs/fs-name = astring: "//"
			svcadm refresh $dependency
		fi
	done
}

# Given the exit status of a command, an integer, 0 if the command completed
# without errors. If the command exited with errors we degrade the
# state of this service into maintenance mode. If a 3rd argument is presented
# we don't degrade the service. We also log an error message as passed into
# this function.
#
function check_failure { # integer exit status, error message to display, be fatal

	typeset RESULT=$1
	typeset ERR_MSG=$2
	typeset NON_FATAL=$3

	if [ $RESULT -ne 0 ] ; then
	    print_log "Error: $ERR_MSG"
	    print_log "Moving service $FMRI to maintenance mode."
	    if [ -z "${NON_FATAL}" ] ; then
		print_log "Moving service $FMRI to maintenance mode."
	        svcadm mark maintenance $FMRI
	    fi
	fi

}

# A function we use to emit output. Right now, this goes to syslog via logger(1)
# but it would be much nicer to be able to print it to the svc log file for
# each individual service instance - tricky because we're being called from
# cron, most of the time and are detached from smf. Working around this by
# appending to the $LOG file
function print_log { # message to display
	logger -t time-slider -p daemon.notice $*
	#echo $(date) $* >> $LOG
}



function add_cleanup_cronjob {
	# Call every 15 minutes, but 5 minutes after the smf snapshot
	# schedules which fall on the hour eg. (0, 15, 30, 45)
	SCHEDULE="5,20,35,50 * * * *"

	# adding a cron job is essentially just looking for an existing entry,
	# removing it, and appending a new one. Neato.
	crontab -l | grep -v "${CLEANUP_PROG}" \
	    > /tmp/saved-crontab.$$

	echo "${SCHEDULE} ${CLEANUP_PROG}" \
	    >> /tmp/saved-crontab.$$

	crontab /tmp/saved-crontab.$$
	check_failure $? "Unable to add cron job!"

	rm /tmp/saved-crontab.$$
	return 0
}

function remove_cleanup_cronjob {

	crontab -l | grep -v "${CLEANUP_PROG}" \
	    > /tmp/saved-crontab.$$

	crontab /tmp/saved-crontab.$$
	check_failure $? "Unable to unschedule snapshots for $FMRI"

	rm /tmp/saved-crontab.$$

	# finally, check our status before we return
	STATE=$(svcprop -p restarter/state $FMRI)
	if [ "${STATE}" == "maintenance" ] ; then
	    STATE=1
	else
	    STATE=0
	fi
}

case $SMF_METHOD in
"start")
	update_service_props
	add_cleanup_cronjob
	;;
"stop")
	remove_cleanup_cronjob
	;;
*)
	echo "Command line invocation of ${0} unsupported."
	echo "This script is intended for smf(5) invocation only"
	exit $SMF_EXIT_ERR_NOSMF
	;;
esac
exit $SMF_EXIT_OK
