#!/bin/sh
#
# A simple script to load/unload the ZFS module stack.
#

BASE_DIR=$(dirname "$0")
SCRIPT_COMMON=common.sh
if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then
	. "${BASE_DIR}/${SCRIPT_COMMON}"
else
	echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
fi

PROG=zfs.sh
VERBOSE="no"
UNLOAD="no"
STACK_TRACER="no"

ZED_PIDFILE=${ZED_PIDFILE:-/var/run/zed.pid}
LDMOD=${LDMOD:-/sbin/modprobe}

KMOD_ZLIB_DEFLATE=${KMOD_ZLIB_DEFLATE:-zlib_deflate}
KMOD_ZLIB_INFLATE=${KMOD_ZLIB_INFLATE:-zlib_inflate}
KMOD_SPL=${KMOD_SPL:-spl}
KMOD_ZAVL=${KMOD_ZAVL:-zavl}
KMOD_ZNVPAIR=${KMOD_ZNVPAIR:-znvpair}
KMOD_ZUNICODE=${KMOD_ZUNICODE:-zunicode}
KMOD_ZCOMMON=${KMOD_ZCOMMON:-zcommon}
KMOD_ZLUA=${KMOD_ZLUA:-zlua}
KMOD_ICP=${KMOD_ICP:-icp}
KMOD_ZFS=${KMOD_ZFS:-zfs}


usage() {
cat << EOF
USAGE:
$0 [hvudS] [module-options]

DESCRIPTION:
	Load/unload the ZFS module stack.

OPTIONS:
	-h      Show this message
	-v      Verbose
	-u      Unload modules
	-S      Enable kernel stack tracer
EOF
}

while getopts 'hvuS' OPTION; do
	case $OPTION in
	h)
		usage
		exit 1
		;;
	v)
		VERBOSE="yes"
		;;
	u)
		UNLOAD="yes"
		;;
	S)
		STACK_TRACER="yes"
		;;
	?)
		usage
		exit
		;;
	esac
done

kill_zed() {
	if [ -f "$ZED_PIDFILE" ]; then
		PID=$(cat "$ZED_PIDFILE")
		kill "$PID"
	fi
}

check_modules() {
	LOADED_MODULES=""
	MISSING_MODULES=""

	for KMOD in $KMOD_SPL $KMOD_ZAVL $KMOD_ZNVPAIR \
	    $KMOD_ZUNICODE $KMOD_ZCOMMON $KMOD_ZLUA $KMOD_ICP $KMOD_ZFS; do
		NAME=$(basename "$KMOD" .ko)

		if lsmod | grep -E -q "^${NAME}"; then
			LOADED_MODULES="$LOADED_MODULES\t$NAME\n"
		fi

		if ! modinfo "$KMOD" >/dev/null 2>&1; then
			MISSING_MODULES="$MISSING_MODULES\t${KMOD}\n"
		fi
	done

	if [ -n "$LOADED_MODULES" ]; then
		printf "Unload the kernel modules by running '%s -u':\n" "$PROG"
		printf "%b" "$LOADED_MODULES"
		exit 1
	fi

	if [ -n "$MISSING_MODULES" ]; then
		printf "The following kernel modules can not be found:\n"
		printf "%b" "$MISSING_MODULES"
		exit 1
	fi

	return 0
}

load_module() {
	KMOD=$1

	FILE=$(modinfo "$KMOD" | awk '/^filename:/ {print $2}')
	VERSION=$(modinfo "$KMOD" | awk '/^version:/ {print $2}')

	if [ "$VERBOSE" = "yes" ]; then
		echo "Loading: $FILE ($VERSION)"
	fi

	$LDMOD "$KMOD" >/dev/null 2>&1
	# shellcheck disable=SC2181
	if [ $? -ne 0 ]; then
		echo "Failed to load $KMOD"
		return 1
	fi

	return 0
}

load_modules() {
	mkdir -p /etc/zfs

	if modinfo "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1; then
		modprobe "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1
	fi

	if modinfo "$KMOD_ZLIB_INFLATE">/dev/null 2>&1; then
		modprobe "$KMOD_ZLIB_INFLATE" >/dev/null 2>&1
	fi

	for KMOD in $KMOD_SPL $KMOD_ZAVL $KMOD_ZNVPAIR \
	    $KMOD_ZUNICODE $KMOD_ZCOMMON $KMOD_ZLUA $KMOD_ICP $KMOD_ZFS; do
		load_module "$KMOD" || return 1
	done

	if [ "$VERBOSE" = "yes" ]; then
		echo "Successfully loaded ZFS module stack"
	fi

	return 0
}

unload_module() {
	KMOD=$1

	NAME=$(basename "$KMOD" .ko)
	FILE=$(modinfo "$KMOD" | awk '/^filename:/ {print $2}')
	VERSION=$(modinfo "$KMOD" | awk '/^version:/ {print $2}')

	if [ "$VERBOSE" = "yes" ]; then
		echo "Unloading: $KMOD ($VERSION)"
	fi

	rmmod "$NAME" || echo "Failed to unload $NAME"

	return 0
}

unload_modules() {
	for KMOD in $KMOD_ZFS $KMOD_ICP $KMOD_ZLUA $KMOD_ZCOMMON $KMOD_ZUNICODE \
	    $KMOD_ZNVPAIR  $KMOD_ZAVL $KMOD_SPL; do
		NAME=$(basename "$KMOD" .ko)
		USE_COUNT=$(lsmod | grep -E "^${NAME} " | awk '{print $3}')

		if [ "$USE_COUNT" = "0" ] ; then
			unload_module "$KMOD" || return 1
		fi
	done

	if modinfo "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1; then
		modprobe -r "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1
	fi

	if modinfo "$KMOD_ZLIB_INFLATE">/dev/null 2>&1; then
		modprobe -r "$KMOD_ZLIB_INFLATE" >/dev/null 2>&1
	fi

	if [ "$VERBOSE" = "yes" ]; then
		echo "Successfully unloaded ZFS module stack"
	fi

	return 0
}

stack_clear() {
	STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size
	STACK_TRACER_ENABLED=/proc/sys/kernel/stack_tracer_enabled

	if [ "$STACK_TRACER" = "yes" ] && [ -e "$STACK_MAX_SIZE" ]; then
		echo 1 >"$STACK_TRACER_ENABLED"
		echo 0 >"$STACK_MAX_SIZE"
	fi
}

stack_check() {
	STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size
	STACK_TRACE=/sys/kernel/debug/tracing/stack_trace
	STACK_LIMIT=15362

	if [ -e "$STACK_MAX_SIZE" ]; then
		STACK_SIZE=$(cat "$STACK_MAX_SIZE")

		if [ "$STACK_SIZE" -ge "$STACK_LIMIT" ]; then
			echo
			echo "Warning: max stack size $STACK_SIZE bytes"
			cat "$STACK_TRACE"
		fi
	fi
}

if [ "$(id -u)" != 0 ]; then
	echo "Must run as root"
	exit 1
fi

if [ "$UNLOAD" = "yes" ]; then
	kill_zed
	umount -t zfs -a
	stack_check
	unload_modules
else
	stack_clear
	check_modules
	load_modules "$@"
	udevadm trigger
	udevadm settle
fi

exit 0
