#!/bin/sh
#
# zfs-import    This script will import/export zfs pools.
#
# chkconfig:    2345 01 99
# description:  This script will import/export zfs pools during system
#               boot/shutdown.
#               It is also responsible for all userspace zfs services.
# probe: true
#
### BEGIN INIT INFO
# Provides:          zfs-import
# Required-Start:    mtab
# Required-Stop:     $local_fs mtab
# Default-Start:     S
# Default-Stop:      0 1 6
# X-Start-Before:    checkfs
# X-Stop-After:      zfs-mount
# Short-Description: Import ZFS pools
# Description: Run the `zpool import` or `zpool export` commands.
### END INIT INFO
#
# NOTE: Not having '$local_fs' on Required-Start but only on Required-Stop
#       is on purpose. If we have '$local_fs' in both (and X-Start-Before=checkfs)
#       we get conflicts - import needs to be started extremely early,
#       but not stopped too late.
#
# Released under the 2-clause BSD license.
#
# The original script that acted as a template for this script came from
# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
# licensing stansa) in the commit dated Mar 24, 2011:
#   https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a

# Source the common init script
. /etc/zfs/zfs-functions

# ----------------------------------------------------

do_depend()
{
	after sysfs udev
	keyword -lxc -openvz -prefix -vserver
}

# Import all pools
do_import()
{
	local already_imported available_pools pool npools
	local exception dir ZPOOL_IMPORT_PATH RET=0 r=1

	# In case not shutdown cleanly.
	[ -n "${init}" ] && rm -f /etc/dfs/sharetab

	# Just simplify code later on.
	if [ -n "${USE_DISK_BY_ID}" ] && ! check_boolean "${USE_DISK_BY_ID}"
	then
		# It's something, but not 'yes' so it's no good to us.
		unset USE_DISK_BY_ID
	fi

	# Find list of already imported pools.
	POOLS="$(get_pools)"

	# Mount all availible pools (except those set in ZFS_POOL_EXCEPTIONS.
	#
	# If not interactive (run from init - variable init='/sbin/init')
	# we get ONE line for all pools being imported, with just a dot
	# as status for each pool.
	# Example: Importing ZFS pool(s)...                             [OK]
	#
	# If it IS interactive (started from the shell manually), then we
	# get one line per pool importing.
	# Example: Importing ZFS pool pool1                             [OK]
	#          Importing ZFS pool pool2                             [OK]
	#          [etc]
	[ -n "${init}" ] && zfs_log_begin_msg "Importing ZFS pool(s)"
	OLD_IFS="${IFS}" ; IFS=";"
	for pool in ${POOLS}
	do
		[ -z "${pool}" ] && continue

		# We have pools that haven't been imported - import them
		if [ -n "${init}" ]
		then
			# Not interactive - a dot for each pool.
			# Except on Gentoo where this doesn't work.
			zfs_log_progress_msg "."
		else
			# Interactive - one 'Importing ...' line per pool
			zfs_log_begin_msg "Importing ZFS pool ${pool}"
		fi

		# Import by using ZPOOL_IMPORT_PATH (either set above or in
		# the config file) _or_ with the 'built in' default search
		# paths. This is the prefered way.
		import_pool "${pool}"
		r="$?" ; RET=$((RET + r))
		if [ "${r}" -eq 0 ]
		then
			# Output success and process the next pool
			[ -z "${init}" ] && zfs_log_end_msg 0
			continue
		fi
		zfs_log_end_msg "${RET}"
	done
	[ -n "${init}" ] && zfs_log_end_msg "${RET}"

	IFS="${OLD_IFS}"

	return "${RET}"
}

# Export all pools
do_export()
{
	local already_imported pool root_pool RET r
	RET=0

	root_pool="$(get_root_pool)"

	[ -n "${init}" ] && zfs_log_begin_msg "Exporting ZFS pool(s)"

	# Find list of already imported pools.
	already_imported="$(find_pools "${ZPOOL}" list -H -oname)"

	OLD_IFS="${IFS}" ; IFS=";"
	for pool in ${already_imported}; do
		[ "${pool}" = "${root_pool}" ] && continue

		if [ -z "${init}" ]
		then
			# Interactive - one 'Importing ...' line per pool
			zfs_log_begin_msg "Exporting ZFS pool ${pool}"
		else
			# Not interactive - a dot for each pool.
			zfs_log_progress_msg "."
		fi

		"${ZPOOL}" export "${pool}"
		r="$?" ; RET="$((RET + r))"
		[ -z "${init}" ] && zfs_log_end_msg "${r}"
	done
	IFS="${OLD_IFS}"

	[ -n "${init}" ] && zfs_log_end_msg "${RET}"

	return "${RET}"
}

# Output the status and list of pools
do_status()
{
	check_module_loaded "zfs" || exit 0

	"${ZPOOL}" status && echo "" && "${ZPOOL}" list
}

do_start()
{
	if check_boolean "${VERBOSE_MOUNT}"
	then
	    zfs_log_begin_msg "Checking if ZFS userspace tools present"
	fi

	if checksystem
	then
		check_boolean "${VERBOSE_MOUNT}" && zfs_log_end_msg 0

		check_boolean "${VERBOSE_MOUNT}" && \
			zfs_log_begin_msg "Loading kernel ZFS infrastructure"

		if ! load_module "zfs"
		then
			check_boolean "${VERBOSE_MOUNT}" && zfs_log_end_msg 1
			return 5
		fi
		check_boolean "${VERBOSE_MOUNT}" && zfs_log_end_msg 0

		do_import && udev_trigger # just to make sure we get zvols.

		return 0
	else
		return 1
	fi
}

do_stop()
{
	# Check to see if the module is even loaded.
	check_module_loaded "zfs" || exit 0

	do_export
}

# ----------------------------------------------------

if [ ! -e /etc/gentoo-release ]
then
	case "$1" in
		start)
			do_start
			;;
		stop)
			do_stop
			;;
		status)
			do_status
			;;
		force-reload|condrestart|reload|restart)
			# no-op
			;;
		*)
			[ -n "$1" ] && echo "Error: Unknown command $1."
			echo "Usage: $0 {start|stop|status}"
			exit 3
			;;
	esac

	exit $?
else
	# Create wrapper functions since Gentoo don't use the case part.
	depend() { do_depend; }
	start() { do_start; }
	stop() { do_stop; }
	status() { do_status; }
fi
