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