#!/bin/sh
# Unload unused modules after a modprobe run
set -e
# policy
# minimal - cleanup modules we loaded, but only if modprobe failed
# (i.e., dependencies of the failed module)
# restricted - only cleanup modules we loaded
# aggressive - try and remove all unused modules - use with caution,
# this could very well remove drivers for in-use devices
policy="minimal"
modprobe=/sbin/modprobe
is_cleanable() {
mod=$1
if [ "$policy" = "aggressive" ]; then
return 0
elif [ -f /tmp/modules.$$ ] && ! grep -q "^${mod} " /tmp/modules.$$; then
return 0
fi
return 1
}
if [ -f /proc/modules ]; then
cp /proc/modules /tmp/modules.$$
fi
if ! $modprobe $* || [ "$policy" = "aggressive" ] || \
[ "$policy" = "restricted" ]; then
safety=0 # just in case we get stuck in an infinite loop somehow
progressing=true
while [ "$progressing" = "true" ] && [ $safety -lt 10 ]; do
progressing="false"
while read mod size refcount tail; do
mod=$(printf "$mod" | tr '-' '_')
if is_cleanable $mod && [ "$refcount" = "0" ]; then
modprobe -r $mod || /bin/true
# /proc/modules was altered; need to re-read
progressing="true"
safety=$(expr $safety + 1)
break
fi
done < /proc/modules ## should we process a static copy instead?
done
fi
rm -f /tmp/modules.$$
|