#!/bin/sh
# If a module fails to load, it may leave unused dependencies around.
# This wrapper attempts to clean up those orphans, reclaiming memory
set -e
modprobe=/sbin/modprobe
statefile=/tmp/modules.$$
save_state() {
rm -f $statefile
if [ -f /proc/modules ]; then
cp /proc/modules $statefile
fi
}
is_cleanable() {
mod=$1
if [ -f $statefile ] && ! grep -q "^${mod} " $statefile; then
return 0
fi
return 1
}
clean() {
if [ ! -f $statefile ]; then
return 0
fi
while read mod size refcount tail; do
if is_cleanable $mod && [ "$refcount" = "0" ]; then
modprobe -r $mod || continue
# /proc/modules was altered; need to restart
return 0
fi
done < /proc/modules ## should we process a static copy instead?
# nothing left to remove
return 1
}
save_state
if ! $modprobe $*; 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"
safety=$(expr $safety + 1)
if clean; then
progressing="true"
fi
done
fi
rm -f $statefile
|