X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fscripts%2Flustre_rmmod;h=53c8ae2a5e7c6ddaee9624ff8106147375ebf53f;hb=2b5b551b15d96588f8f309b5a08c11cab203efeb;hp=2f6b6c29a2c99d844cc0feb0a0123b5ffb2dc1b7;hpb=d2d56f38da01001c92a09afc6b52b5acbd9bc13c;p=fs%2Flustre-release.git diff --git a/lustre/scripts/lustre_rmmod b/lustre/scripts/lustre_rmmod index 2f6b6c2..53c8ae2 100755 --- a/lustre/scripts/lustre_rmmod +++ b/lustre/scripts/lustre_rmmod @@ -1,12 +1,60 @@ -#!/bin/sh +#!/bin/bash # -# remove all lustre modules. Won't succeed if they're in use, or if you -# manually did a 'lctl network up'. +# Takes a list of modules and unloads them and all dependent modules. +# If a module cannot be unloaded (e.g. it's in use), an error is +# returned. ############################################################################### -SRCDIR=`dirname $0` -PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$PATH +# Unload all modules dependent on $1 (exclude removal of $1) +unload_dep_modules_exclusive() { + local MODULE=$1 + local DEPS="$(lsmod | awk '($1 == "'$MODULE'") { print $4 }')" + for SUBMOD in $(echo $DEPS | tr ',' ' '); do + unload_dep_modules_inclusive $SUBMOD || return 1 + done + return 0 +} -lctl modules | awk '{ print $2 }' | xargs rmmod >/dev/null 2>&1 -# do it again, in case we tried to unload the lnd's too early -lsmod | grep lnet > /dev/null && lctl modules | awk '{ print $2 }' | xargs rmmod +# Unload all modules dependent on $1 (include removal of $1) +unload_dep_modules_inclusive() { + local MODULE=$1 + + # if $MODULE not loaded, return 0 + lsmod | egrep -q "^\<$MODULE\>" || return 0 + unload_dep_modules_exclusive $MODULE || return 1 + rmmod $MODULE || return 1 + return 0 +} + +modules="$@" + +# To maintain backwards compatibility, ldiskfs and libcfs must be +# unloaded if no parameters are given, or if only the ldiskfs parameter +# is given. It's ugly, but is needed to emulate the prior functionality +if [ -z "$modules" ] || [ "$modules" = "ldiskfs" ]; then + modules="ptlrpc lnet_selftest ldiskfs libcfs" +fi + +if [ -f /sys/kernel/debug/kmemleak ] ; then + cat /proc/modules >/tmp/kmemleak-modules-list.txt + echo scan > /sys/kernel/debug/kmemleak + cat /sys/kernel/debug/kmemleak > /tmp/kmemleak-before-unload.txt + test -s /tmp/kmemleak-before-unload.txt && logger -t leak-pre -f /tmp/kmemleak-before-unload.txt + rm /tmp/kmemleak-before-unload.txt + # Clear everything here so that only new leaks show up + # after module unload + echo clear > /sys/kernel/debug/kmemleak +fi + +for mod in $modules; do + unload_dep_modules_inclusive $mod || exit 1 +done + +if [ -f /sys/kernel/debug/kmemleak ] ; then + echo scan > /sys/kernel/debug/kmemleak + cat /sys/kernel/debug/kmemleak > /tmp/kmemleak-after-unload.txt + test -s /tmp/kmemleak-after-unload.txt && logger -t leak-mods -f /tmp/kmemleak-modules-list.txt && logger -t leak-post -f /tmp/kmemleak-after-unload.txt + rm -f /tmp/kmemleak-after-unload.txt /tmp/kmemleak-modules-list.txt +fi + +exit 0