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