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