#!/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:    zfs-zed
# Required-Stop:     zfs-zed
# 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
#
# 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 zfs-zed
	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" -a "$USE_DISK_BY_ID" != 'yes' ]
	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"
	[ -n "$already_imported" -a -z "$available_pools" ] && return 0

	return "$RET"
}

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

	root_pool=$(get_root_pool)

	[ -n "$init" ] && zfs_log_begin_msg "Exporting ZFS pool(s)"
	TMPFILE=$(mktemp --tmpdir=/var/tmp zpool.XXXXX)
	"$ZPOOL" list -H -oname > "$TMPFILE"
	while read pool; 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 < "$TMPFILE"
	rm -f "$TMPFILE"
	[ -n "$init" ] && zfs_log_end_msg "$RET"
}

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

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

do_start()
{
	if [ "$VERBOSE_MOUNT" = 'yes' ]
	then
	    zfs_log_begin_msg "Checking if ZFS userspace tools present"
	fi

	if checksystem
	then
		[ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0

		if [ "$VERBOSE_MOUNT" = 'yes' ]
		then
		    zfs_log_begin_msg "Loading kernel ZFS infrastructure"
		fi

		if ! load_module
		then
			[ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 1
			return 5
		fi
		[ "$VERBOSE_MOUNT" = 'yes' ] && 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 || 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
