Messages in this thread | | | Subject | [CFT][RFC] Module auto-unloading solution. | From | Steve Youngs <> | Date | Wed, 17 Dec 2003 16:19:15 +1000 |
| |
Hi Folks!
Modules don't auto-unload, they haven't since the introduction of kmod. Whether that's right or wrong is _not_ what this post is about.
I do know that there are a lot of people out there using Linux who like to have their unused modules silently and cleanly automatically unload. For that reason, I put together the script at the end of this post. So people have the option if they want it.
Before I offer it to the general public, it'd be fantastic if some of you could look it over, kick the tyres and take it for a spin around the block. All comments etc would be very welcome and greatly appreciated.
Thanks.
--------------------------------------------------- #!/bin/bash
## Copyright (C) 2003 Steve Youngs
## RCS: $Id: auto-rmmod.sh,v 1.7 2003-12-17 15:34:51+10 steve Exp $ ## Author: Steve Youngs <sryoungs@bigpond.net.au> ## Maintainer: Steve Youngs <sryoungs@bigpond.net.au> ## Created: <2003-11-25> ## Last-Modified: <2003-12-17 15:34:33 (steve)> ## Homepage: None yet. For now, email the Maintainer for the latest ## version
## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## 3. Neither the name of the author nor the names of any contributors ## may be used to endorse or promote products derived from this ## software without specific prior written permission. ## ## THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR ## IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ## DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR PROFITS OR ## BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE ## OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN ## IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
### Commentary: ## ## This script is for people who want their kernel modules auto-unloaded ## when they are not in use. It won't try to unload ethernet drivers ## because these modules don't set the "in-use" property. If you want ## to unload your ethernet drivers just do so manually with ## `modprobe -r module'. ## ## If you have any modules that you don't want this script to unload ## you can specify a regular expression of modules on the command ## line. See `auto-rmmod.sh --help' for details. ## ## *************************** W A R N I N G *************************** ## * * ## * Even though I have taken considerable care to ensure that ONLY * ## * unused modules are ever unloaded you should thoroughly test this * ## * script BEFORE putting it to use. * ## * * ## * For testing purposes you can use: `auto-rmmod.sh [REGEXP] --test' * ## * * ## *********************************************************************
## Setup and Usage: ## ## Check the paths in the variables listed after "### Code:", ensure ## that they are correct. ## ## Test with `auto-rmmod.sh [REGEXP] --test' until you're happy with ## what is going on. ## ## Next add a cron entry similar to this one to root's crontab: ## ## 0-59/10 * * * * exec /path/to/auto-rmmod.sh [REGEXP] ## ## That will run the script once every ten minutes. Now you can sit ## back and enjoy the wonders of automatic loading and unloading of ## your kernel modules.
## Note: Modules that don't want to auto-load: ## ## The loading mechanism for character device modules changed in ## 2.6.0-test10. In pre -test10 kernels these modules were called ## with `char-major-<major>', in -test10 and later kernels they are ## now called with `char-major-<major>-<minor>'. The modules, ## themselves, are supposed to export these chardev aliases, but as ## yet, not many of them do. To work around this until your module ## has been fixed put `alias char-major-<major>-<minor> module' or ## `alias char-major-<major>-* module' into your ## `/etc/modprobe.conf'. This will also be true of block devices, ## but as at -test11 it still hasn't been implemented.
## Feedback, bug reports and patches etc: ## ## All are welcome. Send them to the address listed at "Maintainer" ## at the top of this file.
### Todo: ## ##
### Code:
## Ensure that all of these are correct for your system. BASENAME=/usr/bin/basename CAT=/usr/bin/cat CUT=/usr/bin/cut FIND=/usr/bin/find GREP=/usr/bin/grep ID=/usr/bin/id MODPROBE=/sbin/modprobe SED=/usr/bin/sed TR=/usr/bin/tr XARGS=/usr/bin/xargs
############################################################ # Nothing Configurable Beyond this point # ############################################################
currentkernel=`uname -r` ethernetdir=/lib/modules/$currentkernel/kernel/drivers/net opts=$1
# Check to see if this is a test run. if [ "$opts" == "--test" -o "$2" == "--test" ]; then if [ "$opts" == "--test" ]; then unset opts fi MODPROBE="$MODPROBE --dry-run --verbose" fi
# There's no point in running this unless we're root. function chkuser() { if [ `$ID --user` -ne 0 ]; then echo "Error: You must be root to run this." exit 1 fi }
function buildregexp() { # Create a regexp of ethernet modules. $FIND $ethernetdir -type f -name \*.ko > /dev/null 2>&1 if [ $? -eq 0 ]; then for file in `ls /lib/modules/$currentkernel/kernel/drivers/net/`; do convertedname=`$BASENAME $file .ko|$SED s/-/_/` if [ $internalpersist ]; then internalpersist="$convertedname\|$internalpersist" else internalpersist="$convertedname" fi done # Need to truncate a trailing '\|'. internalpersist=`expr match "$internalpersist" '\(.*[^\\\\|]\)'` fi
# Set the list of persistant modules to any ethernet modules. if [ $internalpersist ]; then persistantmods="$internalpersist" fi
# Add any user supplied regexp to the list of modules to NOT unload. if [[ $opts && $persistantmods ]]; then persistantmods="$persistantmods\|$opts" elif [ $opts ]; then persistantmods="$opts" fi }
# The actual guts of this has to run 2 or 3 times to clean up all the # modules. The reason behind this is that removing one module can # free up another, so we take a couple of extra passes at it. function doit() { i=1 while [ $i -le 3 ]; do if [ $persistantmods ]; then $CAT /proc/modules | $GREP -v $persistantmods | \ $CUT -d ' ' -f 1,3 | $GREP ' 0$' | $CUT -d ' ' -f 1 | \ $TR '\n' ' ' | $XARGS $MODPROBE --remove i=$[ i + 1 ] else $CAT /proc/modules | $CUT -d ' ' -f 1,3 | $GREP ' 0$' | \ $CUT -d ' ' -f 1 | $TR '\n' ' ' | $XARGS $MODPROBE --remove i=$[ i + 1 ] fi done }
function usage() { cat<<EOF `$BASENAME $0` `$BASENAME $0` [REGEXP] `$BASENAME $0` [OPTION]
REGEXP
Is a regular expression of module names that you DO NOT want this script to unload. Be aware that the kernel converts dashes ('-') to underscores ('_') in module names. Also note that you should NOT include the suffix '.ko'.
Example: If you never want this script to unload 'foo-bar.ko', 'foo-baz.ko', and 'widgets.ko', the REGEXP would be 'foo_ba[rz]\|widgets'. Be sure to surround your REGEXP in single quotes to avoid unexpected results.
See grep(1) for the format of REGEXP.
OPTION
-h|--help|--usage ..... Display this usage text.
--test ................ Run in "test mode". Display the modules to be removed, but do not actually remove them. EOF }
case $opts in \?|-\?|h|-h|--help|--usage) usage exit 0 ;; *) chkuser buildregexp doit exit 0 ;; esac
### auto-rmmod.sh ends here
## $Log: auto-rmmod.sh,v $ ## Revision 1.7 2003-12-17 15:34:51+10 steve ## Doc fix. ## ## Revision 1.6 2003-12-17 14:59:05+10 steve ## Major rewrite, getting ready for general consumption. ## Added a "usage" function, command line options, and the option to run ## in "test" mode. ## ## Revision 1.5 2003-12-15 16:08:20+10 steve ## Even more doc fixes. ## ## Revision 1.4 2003-12-15 15:35:40+10 steve ## Rename to `auto-rmmod.sh' ## ## Revision 1.3 2003-12-15 15:33:06+10 steve ## Doc fixes. ## ## Revision 1.2 2003-11-25 09:54:46+10 steve ## Don't use an external file with the `-f' switch, just use a regexp ## directly from the script. ##
#Local Variables: #time-stamp-start: "Last-Modified:[ ]+\\\\?[\"<]+" #time-stamp-end: "\\\\?[\">]" #time-stamp-line-limit: 10 #time-stamp-format: "%4y-%02m-%02d %02H:%02M:%02S (%u)" #End:
-- |---<Steve Youngs>---------------<GnuPG KeyID: A94B3003>---| | Ashes to ashes, dust to dust. | | The proof of the pudding, is under the crust. | |------------------------------<sryoungs@bigpond.net.au>---| [unhandled content-type:application/pgp-signature] | |