xref: /freebsd/sys/contrib/openzfs/scripts/zfs.sh (revision 716fd348e01c5f2ba125f878a634a753436c2994)
1eda14cbcSMatt Macy#!/bin/sh
2eda14cbcSMatt Macy#
3eda14cbcSMatt Macy# A simple script to load/unload the ZFS module stack.
4eda14cbcSMatt Macy#
5eda14cbcSMatt Macy
6*716fd348SMartin MatuskaBASE_DIR=${0%/*}
7eda14cbcSMatt MacySCRIPT_COMMON=common.sh
8eda14cbcSMatt Macyif [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then
9eda14cbcSMatt Macy	. "${BASE_DIR}/${SCRIPT_COMMON}"
10eda14cbcSMatt Macyelse
11eda14cbcSMatt Macy	echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
12eda14cbcSMatt Macyfi
13eda14cbcSMatt Macy
14eda14cbcSMatt MacyVERBOSE="no"
15eda14cbcSMatt MacyUNLOAD="no"
162faf504dSMartin MatuskaLOAD="yes"
17eda14cbcSMatt MacySTACK_TRACER="no"
18eda14cbcSMatt Macy
19eda14cbcSMatt MacyZED_PIDFILE=${ZED_PIDFILE:-/var/run/zed.pid}
20eda14cbcSMatt MacyLDMOD=${LDMOD:-/sbin/modprobe}
21*716fd348SMartin MatuskaDELMOD=${DELMOD:-/sbin/rmmod}
22eda14cbcSMatt Macy
23eda14cbcSMatt MacyKMOD_ZLIB_DEFLATE=${KMOD_ZLIB_DEFLATE:-zlib_deflate}
24eda14cbcSMatt MacyKMOD_ZLIB_INFLATE=${KMOD_ZLIB_INFLATE:-zlib_inflate}
25eda14cbcSMatt MacyKMOD_SPL=${KMOD_SPL:-spl}
26eda14cbcSMatt MacyKMOD_ZFS=${KMOD_ZFS:-zfs}
27eda14cbcSMatt MacyKMOD_FREEBSD=${KMOD_FREEBSD:-openzfs}
28eda14cbcSMatt Macy
29eda14cbcSMatt Macy
30eda14cbcSMatt Macyusage() {
31eda14cbcSMatt Macy	cat << EOF
32eda14cbcSMatt MacyUSAGE:
33*716fd348SMartin Matuska$0 [hvudS]
34eda14cbcSMatt Macy
35eda14cbcSMatt MacyDESCRIPTION:
36eda14cbcSMatt Macy	Load/unload the ZFS module stack.
37eda14cbcSMatt Macy
38eda14cbcSMatt MacyOPTIONS:
39eda14cbcSMatt Macy	-h	Show this message
40eda14cbcSMatt Macy	-v	Verbose
412faf504dSMartin Matuska	-r	Reload modules
42eda14cbcSMatt Macy	-u	Unload modules
43eda14cbcSMatt Macy	-S	Enable kernel stack tracer
44eda14cbcSMatt MacyEOF
45*716fd348SMartin Matuska	exit 1
46eda14cbcSMatt Macy}
47eda14cbcSMatt Macy
482faf504dSMartin Matuskawhile getopts 'hvruS' OPTION; do
49eda14cbcSMatt Macy	case $OPTION in
50eda14cbcSMatt Macy	v)
51eda14cbcSMatt Macy		VERBOSE="yes"
52eda14cbcSMatt Macy		;;
532faf504dSMartin Matuska	r)
542faf504dSMartin Matuska		UNLOAD="yes"
552faf504dSMartin Matuska		LOAD="yes"
562faf504dSMartin Matuska		;;
57eda14cbcSMatt Macy	u)
58eda14cbcSMatt Macy		UNLOAD="yes"
592faf504dSMartin Matuska		LOAD="no"
60eda14cbcSMatt Macy		;;
61eda14cbcSMatt Macy	S)
62eda14cbcSMatt Macy		STACK_TRACER="yes"
63eda14cbcSMatt Macy		;;
64e92ffd9bSMartin Matuska	*)
65*716fd348SMartin Matuska		usage
66e92ffd9bSMartin Matuska		;;
67eda14cbcSMatt Macy	esac
68eda14cbcSMatt Macydone
69*716fd348SMartin Matuskashift $(( OPTIND - 1 ))
70*716fd348SMartin Matuska[ $# -eq 0 ] || usage
71eda14cbcSMatt Macy
72eda14cbcSMatt Macykill_zed() {
73eda14cbcSMatt Macy	if [ -f "$ZED_PIDFILE" ]; then
74*716fd348SMartin Matuska		read -r PID <"$ZED_PIDFILE"
75eda14cbcSMatt Macy		kill "$PID"
76eda14cbcSMatt Macy	fi
77eda14cbcSMatt Macy}
78eda14cbcSMatt Macy
79eda14cbcSMatt Macycheck_modules_linux() {
80eda14cbcSMatt Macy	LOADED_MODULES=""
81eda14cbcSMatt Macy	MISSING_MODULES=""
82eda14cbcSMatt Macy
83*716fd348SMartin Matuska	for KMOD in $KMOD_SPL $KMOD_ZFS; do
84dae17134SMartin Matuska		NAME="${KMOD##*/}"
85dae17134SMartin Matuska		NAME="${NAME%.ko}"
86eda14cbcSMatt Macy
87eda14cbcSMatt Macy		if lsmod | grep -E -q "^${NAME}"; then
88eda14cbcSMatt Macy			LOADED_MODULES="$LOADED_MODULES\t$NAME\n"
89eda14cbcSMatt Macy		fi
90eda14cbcSMatt Macy
91eda14cbcSMatt Macy		if ! modinfo "$KMOD" >/dev/null 2>&1; then
92eda14cbcSMatt Macy			MISSING_MODULES="$MISSING_MODULES\t${KMOD}\n"
93eda14cbcSMatt Macy		fi
94eda14cbcSMatt Macy	done
95eda14cbcSMatt Macy
96eda14cbcSMatt Macy	if [ -n "$LOADED_MODULES" ]; then
97*716fd348SMartin Matuska		printf "Unload the kernel modules by running '%s -u':\n" "$0"
98eda14cbcSMatt Macy		printf "%b" "$LOADED_MODULES"
99eda14cbcSMatt Macy		exit 1
100eda14cbcSMatt Macy	fi
101eda14cbcSMatt Macy
102eda14cbcSMatt Macy	if [ -n "$MISSING_MODULES" ]; then
103eda14cbcSMatt Macy		printf "The following kernel modules can not be found:\n"
104eda14cbcSMatt Macy		printf "%b" "$MISSING_MODULES"
105eda14cbcSMatt Macy		exit 1
106eda14cbcSMatt Macy	fi
107eda14cbcSMatt Macy
108eda14cbcSMatt Macy	return 0
109eda14cbcSMatt Macy}
110eda14cbcSMatt Macy
111eda14cbcSMatt Macyload_module_linux() {
112eda14cbcSMatt Macy	KMOD=$1
113eda14cbcSMatt Macy
114*716fd348SMartin Matuska	FILE=$(modinfo "$KMOD" 2>&1 | awk 'NR == 1 && /zlib/ && /not found/ {print "(builtin)"; exit}  /^filename:/ {print $2}')
115*716fd348SMartin Matuska	[ "$FILE" = "(builtin)" ] && return
116eda14cbcSMatt Macy
117eda14cbcSMatt Macy	if [ "$VERBOSE" = "yes" ]; then
118*716fd348SMartin Matuska		VERSION=$(modinfo "$KMOD" | awk '/^version:/ {print $2}')
119eda14cbcSMatt Macy		echo "Loading: $FILE ($VERSION)"
120eda14cbcSMatt Macy	fi
121eda14cbcSMatt Macy
12216038816SMartin Matuska	if ! $LDMOD "$KMOD" >/dev/null 2>&1; then
123eda14cbcSMatt Macy		echo "Failed to load $KMOD"
124eda14cbcSMatt Macy		return 1
125eda14cbcSMatt Macy	fi
126eda14cbcSMatt Macy
127eda14cbcSMatt Macy	return 0
128eda14cbcSMatt Macy}
129eda14cbcSMatt Macy
130eda14cbcSMatt Macyload_modules_freebsd() {
131eda14cbcSMatt Macy	kldload "$KMOD_FREEBSD" || return 1
132eda14cbcSMatt Macy
133eda14cbcSMatt Macy	if [ "$VERBOSE" = "yes" ]; then
134eda14cbcSMatt Macy		echo "Successfully loaded ZFS module stack"
135eda14cbcSMatt Macy	fi
136eda14cbcSMatt Macy
137eda14cbcSMatt Macy	return 0
138eda14cbcSMatt Macy}
139eda14cbcSMatt Macy
140eda14cbcSMatt Macyload_modules_linux() {
141eda14cbcSMatt Macy	mkdir -p /etc/zfs
142eda14cbcSMatt Macy
143*716fd348SMartin Matuska	for KMOD in "$KMOD_ZLIB_DEFLATE" "$KMOD_ZLIB_INFLATE" $KMOD_SPL $KMOD_ZFS; do
144eda14cbcSMatt Macy		load_module_linux "$KMOD" || return 1
145eda14cbcSMatt Macy	done
146eda14cbcSMatt Macy
147eda14cbcSMatt Macy	if [ "$VERBOSE" = "yes" ]; then
148eda14cbcSMatt Macy		echo "Successfully loaded ZFS module stack"
149eda14cbcSMatt Macy	fi
150eda14cbcSMatt Macy
151eda14cbcSMatt Macy	return 0
152eda14cbcSMatt Macy}
153eda14cbcSMatt Macy
154eda14cbcSMatt Macyunload_modules_freebsd() {
155eda14cbcSMatt Macy	kldunload "$KMOD_FREEBSD" || echo "Failed to unload $KMOD_FREEBSD"
156eda14cbcSMatt Macy
157eda14cbcSMatt Macy	if [ "$VERBOSE" = "yes" ]; then
158eda14cbcSMatt Macy		echo "Successfully unloaded ZFS module stack"
159eda14cbcSMatt Macy	fi
160eda14cbcSMatt Macy
161eda14cbcSMatt Macy	return 0
162eda14cbcSMatt Macy}
163eda14cbcSMatt Macy
164eda14cbcSMatt Macyunload_modules_linux() {
165*716fd348SMartin Matuska	legacy_kmods="icp zzstd zlua zcommon zunicode znvpair zavl"
166*716fd348SMartin Matuska	for KMOD in "$KMOD_ZFS" $legacy_kmods "$KMOD_SPL"; do
167dae17134SMartin Matuska		NAME="${KMOD##*/}"
168dae17134SMartin Matuska		NAME="${NAME%.ko}"
169*716fd348SMartin Matuska		! [ -d "/sys/module/$NAME" ] || $DELMOD "$NAME" || return
170eda14cbcSMatt Macy	done
171eda14cbcSMatt Macy
172eda14cbcSMatt Macy	if [ "$VERBOSE" = "yes" ]; then
173eda14cbcSMatt Macy		echo "Successfully unloaded ZFS module stack"
174eda14cbcSMatt Macy	fi
175eda14cbcSMatt Macy}
176eda14cbcSMatt Macy
177eda14cbcSMatt Macystack_clear_linux() {
178eda14cbcSMatt Macy	STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size
179eda14cbcSMatt Macy	STACK_TRACER_ENABLED=/proc/sys/kernel/stack_tracer_enabled
180eda14cbcSMatt Macy
181eda14cbcSMatt Macy	if [ "$STACK_TRACER" = "yes" ] && [ -e "$STACK_MAX_SIZE" ]; then
182eda14cbcSMatt Macy		echo 1 >"$STACK_TRACER_ENABLED"
183eda14cbcSMatt Macy		echo 0 >"$STACK_MAX_SIZE"
184eda14cbcSMatt Macy	fi
185eda14cbcSMatt Macy}
186eda14cbcSMatt Macy
187eda14cbcSMatt Macystack_check_linux() {
188eda14cbcSMatt Macy	STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size
189eda14cbcSMatt Macy	STACK_TRACE=/sys/kernel/debug/tracing/stack_trace
190eda14cbcSMatt Macy	STACK_LIMIT=15362
191eda14cbcSMatt Macy
192eda14cbcSMatt Macy	if [ -e "$STACK_MAX_SIZE" ]; then
193*716fd348SMartin Matuska		read -r STACK_SIZE <"$STACK_MAX_SIZE"
194eda14cbcSMatt Macy		if [ "$STACK_SIZE" -ge "$STACK_LIMIT" ]; then
195eda14cbcSMatt Macy			echo
196eda14cbcSMatt Macy			echo "Warning: max stack size $STACK_SIZE bytes"
197eda14cbcSMatt Macy			cat "$STACK_TRACE"
198eda14cbcSMatt Macy		fi
199eda14cbcSMatt Macy	fi
200eda14cbcSMatt Macy}
201eda14cbcSMatt Macy
202eda14cbcSMatt Macyif [ "$(id -u)" != 0 ]; then
203eda14cbcSMatt Macy	echo "Must run as root"
204eda14cbcSMatt Macy	exit 1
205eda14cbcSMatt Macyfi
206eda14cbcSMatt Macy
207*716fd348SMartin MatuskaUNAME=$(uname)
208eda14cbcSMatt Macy
209eda14cbcSMatt Macyif [ "$UNLOAD" = "yes" ]; then
210eda14cbcSMatt Macy	kill_zed
211eda14cbcSMatt Macy	umount -t zfs -a
212eda14cbcSMatt Macy	case $UNAME in
213eda14cbcSMatt Macy		FreeBSD)
214eda14cbcSMatt Macy		   unload_modules_freebsd
215eda14cbcSMatt Macy		   ;;
216eda14cbcSMatt Macy		Linux)
217eda14cbcSMatt Macy		   stack_check_linux
218eda14cbcSMatt Macy		   unload_modules_linux
219eda14cbcSMatt Macy		   ;;
220e92ffd9bSMartin Matuska		*)
221e92ffd9bSMartin Matuska		   echo "unknown system: $UNAME" >&2
222e92ffd9bSMartin Matuska		   exit 1
223e92ffd9bSMartin Matuska		   ;;
224eda14cbcSMatt Macy	esac
2252faf504dSMartin Matuskafi
2262faf504dSMartin Matuskaif [ "$LOAD" = "yes" ]; then
227eda14cbcSMatt Macy	case $UNAME in
228eda14cbcSMatt Macy		FreeBSD)
229eda14cbcSMatt Macy		   load_modules_freebsd
230eda14cbcSMatt Macy		   ;;
231eda14cbcSMatt Macy		Linux)
232eda14cbcSMatt Macy		   stack_clear_linux
233eda14cbcSMatt Macy		   check_modules_linux
234*716fd348SMartin Matuska		   load_modules_linux
235eda14cbcSMatt Macy		   udevadm trigger
236eda14cbcSMatt Macy		   udevadm settle
237eda14cbcSMatt Macy		   ;;
238e92ffd9bSMartin Matuska		*)
239e92ffd9bSMartin Matuska		   echo "unknown system: $UNAME" >&2
240e92ffd9bSMartin Matuska		   exit 1
241e92ffd9bSMartin Matuska		   ;;
242eda14cbcSMatt Macy	esac
243eda14cbcSMatt Macyfi
244eda14cbcSMatt Macy
245eda14cbcSMatt Macyexit 0
246