[Pm-utils] [PATCH] unload modules recursively

Peter Jones pjones at redhat.com
Sat Oct 21 12:42:50 PDT 2006


On Thu, 2006-10-05 at 18:05 +0200, Stefan Seyfried wrote:
> Hi.
> 
> Sometimes it is usefull to unload a complete stack of modules.
> This patch implements that:

merging as:

Index: pm/functions
===================================================================
RCS file: /cvs/pm-utils/pm-utils/pm/functions,v
retrieving revision 1.23
diff -u -p -r1.23 functions
--- pm/functions	21 Oct 2006 19:18:19 -0000	1.23
+++ pm/functions	21 Oct 2006 19:40:10 -0000
@@ -5,16 +5,22 @@ export PATH=/sbin:/usr/sbin:/bin:/usr/bi
 # default values go here
 HIBERNATE_RESUME_POST_VIDEO=no
 SUSPEND_MODULES=""
+RESUME_MODULES=""
 LOGFILE=/var/log/pm-suspend.log
 
 [ -f /etc/pm/config ] && . /etc/pm/config
 
-# export them all here
-export HIBERNATE_RESUME_POST_VIDEO
-export SUSPEND_MODULES
-export LOGFILE
+GLOBAL_CONFIG_VARIABLES=""
+add_global() {
+	export $1
+	GLOBAL_CONFIG_VARIABLES="$GLOBAL_CONFIG_VARIABLES $1"
+}
 
-GLOBAL_CONFIG_VARIABLES="HIBERNATE_RESUME_POST_VIDEO SUSPEND_MODULES LOGFILE"
+# export them all here
+add_global HIBERNATE_RESUME_POST_VIDEO
+add_global SUSPEND_MODULES
+add_global RESUME_MODULES
+add_global LOGFILE
 
 source_configs()
 {
@@ -134,13 +140,51 @@ pm_main()
 	return 0
 }
 
+_rmmod() {
+	if rmmod $1; then
+		echo "export RESUME_MODULES=\"$1 \$RESUME_MODULES\"" \
+						>> /var/run/pm-suspend
+		return 0
+	else
+		echo "# could not unload '$1', usage count was $2"
+		return 1
+	fi
+}
+
+# this recursively unloads the given modules and all that depend on it
+# first parameter is the module to be unloaded
 modunload()
 {
-	lsmod 2>/dev/null | grep -q "$1"
-	if [ "$?" == "0" ]; then
-		echo "export ${1}_MODULE_LOAD=yes" >> /var/run/pm-suspend
-		modprobe -r "$1" >/dev/null 2>&1
-	fi
+	local MOD D C USED MODS I
+	local UNL=$1 RET=1
+	# RET is the return code.
+	# If at least one module was unloaded, return 0.
+	# if the module was not loaded, also return 0 since this is no error.
+	# if no module was unloaded successfully, return 1
+	while read MOD D C USED D; do
+		[ "$MOD" != "$UNL" ] && continue
+		if [ "$USED" == "-" ]; then
+			_rmmod $UNL $C
+			RET=$?
+		else
+			USED=${USED//,/ }
+			MODS=($USED)
+			# it seems slightly more likely to rmmod in one pass,
+			# if we try backwards.
+			for I in `seq $[${#MODS[@]}-1] -1 0`; do
+				MOD=${MODS[$I]}
+				modunload $MOD && RET=0
+			done
+			# if we unloaded at least one module, then let's
+			# try again!
+			[ $RET -eq 0 ] && modunload $UNL
+			RET=$?
+		fi
+		return $RET
+	done < /proc/modules
+	# if we came this far, there was nothing to do, 
+	# the module is no longer loaded.
+	return 0
 }
 
 modreload()
Index: pm/hooks/50modules
===================================================================
RCS file: /cvs/pm-utils/pm-utils/pm/hooks/50modules,v
retrieving revision 1.5
diff -u -p -r1.5 50modules
--- pm/hooks/50modules	17 Apr 2006 19:00:07 -0000	1.5
+++ pm/hooks/50modules	21 Oct 2006 19:40:10 -0000
@@ -13,11 +13,10 @@ suspend_modules()
 
 resume_modules()
 {
-	[ -z "$SUSPEND_MODULES" ] && return 0
-	for x in $SUSPEND_MODULES ; do
-		modreload $x
+	[ -z "$RESUME_MODULES" ] && return 0
+	for x in $RESUME_MODULES ; do
+		modprobe $x
 	done
-	return 0
 }
 
 case "$1" in

-- 
  Peter


More information about the Pm-utils mailing list