#!/bin/bash
#
# zfs           This script will mount/umount the zfs filesystems.
#
# chkconfig:    2345 01 99
# description:  This script will mount/umount the zfs filesystems during
#               system boot/shutdown.  Configuration of which filesystems
#               should be mounted is handled by the zfs 'mountpoint' and
#               'canmount' properties.  See the zfs(8) man page for details.
#               It is also responsible for all userspace zfs services.
#
### BEGIN INIT INFO
# Provides: zfs
# Required-Start:
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 1
# Short-Description: Mount/umount the zfs filesystems
# Description: ZFS is an advanced filesystem designed to simplify managing
#              and protecting your data.  This service mounts the ZFS
#              filesystems and starts all related zfs services.
### END INIT INFO

export PATH=/usr/local/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin

if [ -z "$init" ]; then
    # Not interactive
    grep -Eqi 'zfs=off|zfs=no' /proc/cmdline && exit 3
fi

# Source function library & LSB routines
. /etc/rc.d/init.d/functions

# script variables
RETVAL=0
ZFS="@sbindir@/zfs"
ZPOOL="@sbindir@/zpool"
ZPOOL_CACHE="@sysconfdir@/zfs/zpool.cache"
servicename=zfs
LOCKFILE=/var/lock/subsys/$servicename

# functions
zfs_installed() {
	modinfo zfs > /dev/null 2>&1 || return 5
	$ZPOOL  > /dev/null 2>&1
	[ $? == 127 ] && return 5
	$ZFS    > /dev/null 2>&1
	[ $? == 127 ] && return 5
	return 0
}

# i need a bash guru to simplify this, since this is copy and paste, but donno how
# to correctly dereference variable names in bash, or how to do this right

# first parameter is a regular expression that filters fstab
read_fstab() {
        unset FSTAB
	n=0
        while read -r fs mntpnt fstype opts blah ; do
                fs=`printf '%b\n' "$fs"`
                FSTAB[$n]=$fs
		let n++
        done < <(egrep "$1" /etc/fstab)
}

start()
{
	# Disable lockfile check
	# if [ -f "$LOCKFILE" ] ; then return 0 ; fi

	# check if ZFS is installed.  If not, comply to FC standards and bail
	zfs_installed || {
		action $"Checking if ZFS is installed: not installed" /bin/false
		return 5
	}

        # Requires selinux policy which has not been written.
        if [ -r "/selinux/enforce" ] &&
           [ "$(cat /selinux/enforce)" = "1" ]; then
                action $"SELinux ZFS policy required: " /bin/false || return 6
        fi

	# Delay until all required block devices are present.
	if [ -x /sbin/udevadm ]; then
		/sbin/udevadm settle
	elif [ -x /sbin/udevsettle ]; then
		/sbin/udevsettle
	fi

	# load kernel module infrastructure
	if ! grep -q zfs /proc/modules ; then
		action $"Loading kernel ZFS infrastructure: " modprobe zfs || return 5
	fi
	sleep 1

	action $"Mounting automounted ZFS filesystems: " $ZFS mount -a || return 152

	action $"Exporting ZFS filesystems: " $ZFS share -a || return 153

	# Read fstab, try to mount zvols ignoring error
	read_fstab "^/dev/(zd|zvol)"
	template=$"Mounting volume %s registered in fstab: "
	for volume in "${FSTAB[@]}" ; do
		string=`printf "$template" "$volume"`
		action "$string" mount "$volume" 2>/dev/null || /bin/true
	done

	# touch "$LOCKFILE"
}

stop()
{
	# Disable lockfile check
	# if [ ! -f "$LOCKFILE" ] ; then return 0 ; fi

	# check if ZFS is installed.  If not, comply to FC standards and bail
	zfs_installed || {
		action $"Checking if ZFS is installed: not installed" /bin/false
		return 5
	}

	# the poweroff of the system takes care of this
	# but it never unmounts the root filesystem itself
	# shit

	action $"Syncing ZFS filesystems: " sync
	     # about the only thing we can do, and then we
	     # hope that the umount process will succeed
	     # unfortunately the umount process does not dismount
	     # the root file system, there ought to be some way
	     # we can tell zfs to just flush anything in memory
	     # when a request to remount,ro comes in

	#echo -n $"Unmounting ZFS filesystems: "
	#$ZFS umount -a
	#RETVAL=$?
	#if [ $RETVAL -ne 0 ]; then
	#	failure

	#	return 8
	#fi
	#success

	rm -f "$LOCKFILE"
}

# See how we are called
case "$1" in
	start)
		start
		RETVAL=$?
		;;
	stop)
		stop
		RETVAL=$?
		;;
	status)
		lsmod | grep -q zfs || RETVAL=3
		$ZPOOL status && echo && $ZFS list || {
			[ -f "$LOCKFILE" ] && RETVAL=2 || RETVAL=4
		}
		;;
	restart)
		stop
		start
		;;
	condrestart)
		if [ -f "$LOCKFILE" ] ; then
			stop
			start
		fi
		;;
	*)
		echo $"Usage: $0 {start|stop|status|restart|condrestart}"
		RETVAL=3
		;;
esac

exit $RETVAL