]>
Commit | Line | Data |
---|---|---|
c8f9061f BB |
1 | #!/bin/sh |
2 | # | |
3 | # A simple script to load/unload the ZFS module stack. | |
c9c0d073 | 4 | # |
c9c0d073 | 5 | |
c8f9061f | 6 | BASE_DIR=$(dirname "$0") |
c9c0d073 | 7 | SCRIPT_COMMON=common.sh |
c8f9061f BB |
8 | if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then |
9 | . "${BASE_DIR}/${SCRIPT_COMMON}" | |
c9c0d073 | 10 | else |
c8f9061f | 11 | echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 |
c9c0d073 BB |
12 | fi |
13 | ||
14 | PROG=zfs.sh | |
c8f9061f BB |
15 | VERBOSE="no" |
16 | UNLOAD="no" | |
ef57371a | 17 | STACK_TRACER="no" |
c8f9061f BB |
18 | |
19 | ZED_PIDFILE=${ZED_PIDFILE:-/var/run/zed.pid} | |
20 | LDMOD=${LDMOD:-/sbin/modprobe} | |
21 | ||
22 | KMOD_ZLIB_DEFLATE=${KMOD_ZLIB_DEFLATE:-zlib_deflate} | |
23 | KMOD_ZLIB_INFLATE=${KMOD_ZLIB_INFLATE:-zlib_inflate} | |
24 | KMOD_SPL=${KMOD_SPL:-spl} | |
c8f9061f BB |
25 | KMOD_ZAVL=${KMOD_ZAVL:-zavl} |
26 | KMOD_ZNVPAIR=${KMOD_ZNVPAIR:-znvpair} | |
27 | KMOD_ZUNICODE=${KMOD_ZUNICODE:-zunicode} | |
28 | KMOD_ZCOMMON=${KMOD_ZCOMMON:-zcommon} | |
d99a0153 | 29 | KMOD_ZLUA=${KMOD_ZLUA:-zlua} |
c8f9061f BB |
30 | KMOD_ICP=${KMOD_ICP:-icp} |
31 | KMOD_ZFS=${KMOD_ZFS:-zfs} | |
a3640486 | 32 | KMOD_FREEBSD=${KMOD_FREEBSD:-openzfs} |
c8f9061f | 33 | |
c9c0d073 BB |
34 | |
35 | usage() { | |
36 | cat << EOF | |
37 | USAGE: | |
ef57371a | 38 | $0 [hvudS] [module-options] |
c9c0d073 BB |
39 | |
40 | DESCRIPTION: | |
41 | Load/unload the ZFS module stack. | |
42 | ||
43 | OPTIONS: | |
44 | -h Show this message | |
45 | -v Verbose | |
46 | -u Unload modules | |
ef57371a | 47 | -S Enable kernel stack tracer |
c9c0d073 BB |
48 | EOF |
49 | } | |
50 | ||
ef57371a | 51 | while getopts 'hvuS' OPTION; do |
c9c0d073 BB |
52 | case $OPTION in |
53 | h) | |
54 | usage | |
55 | exit 1 | |
56 | ;; | |
57 | v) | |
c8f9061f | 58 | VERBOSE="yes" |
c9c0d073 BB |
59 | ;; |
60 | u) | |
c8f9061f | 61 | UNLOAD="yes" |
c9c0d073 | 62 | ;; |
ef57371a TN |
63 | S) |
64 | STACK_TRACER="yes" | |
65 | ;; | |
c9c0d073 BB |
66 | ?) |
67 | usage | |
68 | exit | |
69 | ;; | |
70 | esac | |
71 | done | |
72 | ||
c8f9061f BB |
73 | kill_zed() { |
74 | if [ -f "$ZED_PIDFILE" ]; then | |
75 | PID=$(cat "$ZED_PIDFILE") | |
76 | kill "$PID" | |
77 | fi | |
78 | } | |
79 | ||
a3640486 | 80 | check_modules_linux() { |
ea49beba GDN |
81 | LOADED_MODULES="" |
82 | MISSING_MODULES="" | |
c8f9061f | 83 | |
93ce2b4c | 84 | for KMOD in $KMOD_SPL $KMOD_ZAVL $KMOD_ZNVPAIR \ |
d99a0153 | 85 | $KMOD_ZUNICODE $KMOD_ZCOMMON $KMOD_ZLUA $KMOD_ICP $KMOD_ZFS; do |
c8f9061f BB |
86 | NAME=$(basename "$KMOD" .ko) |
87 | ||
3da3488e | 88 | if lsmod | grep -E -q "^${NAME}"; then |
c8f9061f BB |
89 | LOADED_MODULES="$LOADED_MODULES\t$NAME\n" |
90 | fi | |
91 | ||
92 | if ! modinfo "$KMOD" >/dev/null 2>&1; then | |
93 | MISSING_MODULES="$MISSING_MODULES\t${KMOD}\n" | |
94 | fi | |
95 | done | |
96 | ||
97 | if [ -n "$LOADED_MODULES" ]; then | |
98 | printf "Unload the kernel modules by running '%s -u':\n" "$PROG" | |
99 | printf "%b" "$LOADED_MODULES" | |
100 | exit 1 | |
101 | fi | |
102 | ||
103 | if [ -n "$MISSING_MODULES" ]; then | |
104 | printf "The following kernel modules can not be found:\n" | |
105 | printf "%b" "$MISSING_MODULES" | |
106 | exit 1 | |
107 | fi | |
108 | ||
109 | return 0 | |
110 | } | |
111 | ||
a3640486 | 112 | load_module_linux() { |
ea49beba | 113 | KMOD=$1 |
c8f9061f BB |
114 | |
115 | FILE=$(modinfo "$KMOD" | awk '/^filename:/ {print $2}') | |
116 | VERSION=$(modinfo "$KMOD" | awk '/^version:/ {print $2}') | |
117 | ||
118 | if [ "$VERBOSE" = "yes" ]; then | |
119 | echo "Loading: $FILE ($VERSION)" | |
120 | fi | |
121 | ||
122 | $LDMOD "$KMOD" >/dev/null 2>&1 | |
3da3488e | 123 | # shellcheck disable=SC2181 |
c8f9061f BB |
124 | if [ $? -ne 0 ]; then |
125 | echo "Failed to load $KMOD" | |
126 | return 1 | |
127 | fi | |
128 | ||
129 | return 0 | |
130 | } | |
131 | ||
a3640486 RM |
132 | load_modules_freebsd() { |
133 | kldload "$KMOD_FREEBSD" || return 1 | |
134 | ||
135 | if [ "$VERBOSE" = "yes" ]; then | |
136 | echo "Successfully loaded ZFS module stack" | |
137 | fi | |
138 | ||
139 | return 0 | |
140 | } | |
141 | ||
142 | load_modules_linux() { | |
c8f9061f BB |
143 | mkdir -p /etc/zfs |
144 | ||
133a5c65 BB |
145 | if modinfo "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1; then |
146 | modprobe "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1 | |
147 | fi | |
148 | ||
149 | if modinfo "$KMOD_ZLIB_INFLATE">/dev/null 2>&1; then | |
150 | modprobe "$KMOD_ZLIB_INFLATE" >/dev/null 2>&1 | |
151 | fi | |
c8f9061f | 152 | |
93ce2b4c | 153 | for KMOD in $KMOD_SPL $KMOD_ZAVL $KMOD_ZNVPAIR \ |
d99a0153 | 154 | $KMOD_ZUNICODE $KMOD_ZCOMMON $KMOD_ZLUA $KMOD_ICP $KMOD_ZFS; do |
a3640486 | 155 | load_module_linux "$KMOD" || return 1 |
c8f9061f BB |
156 | done |
157 | ||
158 | if [ "$VERBOSE" = "yes" ]; then | |
159 | echo "Successfully loaded ZFS module stack" | |
160 | fi | |
161 | ||
162 | return 0 | |
163 | } | |
164 | ||
a3640486 | 165 | unload_module_linux() { |
ea49beba | 166 | KMOD=$1 |
c8f9061f BB |
167 | |
168 | NAME=$(basename "$KMOD" .ko) | |
169 | FILE=$(modinfo "$KMOD" | awk '/^filename:/ {print $2}') | |
170 | VERSION=$(modinfo "$KMOD" | awk '/^version:/ {print $2}') | |
171 | ||
172 | if [ "$VERBOSE" = "yes" ]; then | |
173 | echo "Unloading: $KMOD ($VERSION)" | |
174 | fi | |
175 | ||
176 | rmmod "$NAME" || echo "Failed to unload $NAME" | |
177 | ||
178 | return 0 | |
179 | } | |
180 | ||
a3640486 RM |
181 | unload_modules_freebsd() { |
182 | kldunload "$KMOD_FREEBSD" || echo "Failed to unload $KMOD_FREEBSD" | |
183 | ||
184 | if [ "$VERBOSE" = "yes" ]; then | |
185 | echo "Successfully unloaded ZFS module stack" | |
186 | fi | |
187 | ||
188 | return 0 | |
189 | } | |
190 | ||
191 | unload_modules_linux() { | |
d99a0153 | 192 | for KMOD in $KMOD_ZFS $KMOD_ICP $KMOD_ZLUA $KMOD_ZCOMMON $KMOD_ZUNICODE \ |
93ce2b4c | 193 | $KMOD_ZNVPAIR $KMOD_ZAVL $KMOD_SPL; do |
c8f9061f | 194 | NAME=$(basename "$KMOD" .ko) |
3da3488e | 195 | USE_COUNT=$(lsmod | grep -E "^${NAME} " | awk '{print $3}') |
c8f9061f BB |
196 | |
197 | if [ "$USE_COUNT" = "0" ] ; then | |
a3640486 | 198 | unload_module_linux "$KMOD" || return 1 |
c8f9061f BB |
199 | fi |
200 | done | |
201 | ||
133a5c65 BB |
202 | if modinfo "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1; then |
203 | modprobe -r "$KMOD_ZLIB_DEFLATE" >/dev/null 2>&1 | |
204 | fi | |
205 | ||
206 | if modinfo "$KMOD_ZLIB_INFLATE">/dev/null 2>&1; then | |
207 | modprobe -r "$KMOD_ZLIB_INFLATE" >/dev/null 2>&1 | |
208 | fi | |
209 | ||
c8f9061f BB |
210 | if [ "$VERBOSE" = "yes" ]; then |
211 | echo "Successfully unloaded ZFS module stack" | |
212 | fi | |
213 | ||
214 | return 0 | |
215 | } | |
216 | ||
a3640486 | 217 | stack_clear_linux() { |
ea49beba GDN |
218 | STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size |
219 | STACK_TRACER_ENABLED=/proc/sys/kernel/stack_tracer_enabled | |
c8f9061f | 220 | |
ef57371a | 221 | if [ "$STACK_TRACER" = "yes" ] && [ -e "$STACK_MAX_SIZE" ]; then |
c8f9061f BB |
222 | echo 1 >"$STACK_TRACER_ENABLED" |
223 | echo 0 >"$STACK_MAX_SIZE" | |
224 | fi | |
225 | } | |
226 | ||
a3640486 | 227 | stack_check_linux() { |
ea49beba GDN |
228 | STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size |
229 | STACK_TRACE=/sys/kernel/debug/tracing/stack_trace | |
a7ed98d8 | 230 | STACK_LIMIT=15362 |
c8f9061f BB |
231 | |
232 | if [ -e "$STACK_MAX_SIZE" ]; then | |
233 | STACK_SIZE=$(cat "$STACK_MAX_SIZE") | |
234 | ||
235 | if [ "$STACK_SIZE" -ge "$STACK_LIMIT" ]; then | |
236 | echo | |
237 | echo "Warning: max stack size $STACK_SIZE bytes" | |
238 | cat "$STACK_TRACE" | |
239 | fi | |
240 | fi | |
241 | } | |
242 | ||
c552fbc5 | 243 | if [ "$(id -u)" != 0 ]; then |
c8f9061f BB |
244 | echo "Must run as root" |
245 | exit 1 | |
c9c0d073 BB |
246 | fi |
247 | ||
a3640486 RM |
248 | UNAME=$(uname -s) |
249 | ||
c8f9061f | 250 | if [ "$UNLOAD" = "yes" ]; then |
9e246ac3 | 251 | kill_zed |
b9f6a490 | 252 | umount -t zfs -a |
a3640486 RM |
253 | case $UNAME in |
254 | FreeBSD) | |
255 | unload_modules_freebsd | |
256 | ;; | |
257 | Linux) | |
258 | stack_check_linux | |
259 | unload_modules_linux | |
260 | ;; | |
261 | esac | |
c9c0d073 | 262 | else |
a3640486 RM |
263 | case $UNAME in |
264 | FreeBSD) | |
265 | load_modules_freebsd | |
266 | ;; | |
267 | Linux) | |
268 | stack_clear_linux | |
269 | check_modules_linux | |
270 | load_modules_linux "$@" | |
271 | udevadm trigger | |
272 | udevadm settle | |
273 | ;; | |
274 | esac | |
c9c0d073 BB |
275 | fi |
276 | ||
277 | exit 0 |