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