[Pm-utils] [PATCH 7/7] Split functionality from functions to functions and pm-functions

Victor Lowther victor.lowther at gmail.com
Sat Feb 9 21:24:51 PST 2008


The goal of this patch series is to make it easier to split the hooks out of
pm-utils at some point in the future, and to make it easier to isolate the
hooks from eachother.  To accomplish that goal, this patch does the following:

* Stop loading all config files every time functions is sourced.
  This gave every hook and every pm-utils script visibility to all config
  variables, and we needlessly reexported them all everytime functions was
  sourced.

  With the changes in this patch, we only source configuration files based
  on the name of the script that is running, and we do not export variables
  set this way.

* Isolate functionality that only pm-utils scripts should have access to.
  Hooks don't need to know how to run hooks or know the details on how the
  system will suspend.  Instead, they just have access to the functions
  outlined in HOWTO.hooks.

Note that the isolation at this point is neither complete nor perfect --
we still handle all the video options in pm-action.  A mechanism to have the
video hooks directly query HAL for the video quirks would be useful to have.
---
 pm/functions.in    |  178 ++++++++++++++--------------------------------------
 pm/pm-functions.in |  142 ++----------------------------------------
 test-pm-utils      |    2 +-
 3 files changed, 53 insertions(+), 269 deletions(-)

diff --git a/pm/functions.in b/pm/functions.in
index 1a9a581..423858b 100644
--- a/pm/functions.in
+++ b/pm/functions.in
@@ -1,46 +1,55 @@
 #!/bin/sh
 # vim:noexpandtab
 
+# This file contains functionality for the hooks.
 
-# Default values go here.  It is important to _not_ initialize some
-# variables here.  They are:
-#
-# PM_CMDLINE
-# RESUME_MODULES
-#
 # for great debugging!
 [ "${PM_DEBUG}" = "true" ] && set -x
-set -a
+
+# environment variables needed by the hooks.
 PM_UTILS_LIBDIR="@PM-UTILS-LIBDIR@"
 PM_UTILS_ETCDIR="@PM-UTILS-SYSCONFDIR@"
 PM_UTILS_RUNDIR="/var/run/pm-utils"
-
-PATH=/sbin:/usr/sbin:/bin:/usr/bin:"${PM_UTILS_LIBDIR}"/bin
-HIBERNATE_MODE="platform"
-HIBERNATE_RESUME_POST_VIDEO=no
-INHIBIT="${PM_UTILS_RUNDIR}/inhibit"
-PM_LOGFILE="${PM_LOGFILE:=/var/log/pm-suspend.log}"
-SUSPEND_MODULES=""
-TEMPORARY_CPUFREQ_GOVERNOR="performance"
+SCRIPT="${0##*/}"
 LOCKDIR="${PM_UTILS_RUNDIR}/locks"
 STORAGEDIR="${PM_UTILS_RUNDIR}/storage"
-SLEEP_MODULE="kernel"
-SLEEP_FUNCTIONS="${PM_UTILS_LIBDIR}/module.d/${SLEEP_MODULE}"
-
-# Use c sort order
-export LC_COLLATE=C
-
-[ -O "${PM_UTILS_LIBDIR}"/defaults ] && . "${PM_UTILS_LIBDIR}"/defaults
-set +a
-
 
+# source potential config files in the following order:
+# $PM_UTILS_LIBDIR/config.d/scriptname-without-leading-digits
+# $PM_UTILS_LIBDIR/config.d/scriptname-without-leading-digits.d/*
+# $PM_UTILS_ETCDIR/config.d/scriptname-without-leading-digits
+# $PM_UTILS_ETCDIR/config.d/scriptname-without-leading-digits.d/*
+# $PM_UTILS_LIBDIR/config.d/scriptname
+# $PM_UTILS_LIBDIR/config.d/scriptname.d/*
+# $PM_UTILS_ETCDIR/config.d/scriptname
+# $PM_UTILS_ETCDIR/config.d/scriptname.d/*
+# It seems baroque, but should cover all the bases.
 source_configs()
 {
-	for cfg in "${PM_UTILS_ETCDIR}"/config.d/*[!~] ; do
-		[ -O "$cfg" ] || continue
-		set -a
-		. "${cfg}"
-		set +a
+	local cfg
+	local f
+	local sf
+	for cfg in "${SCRIPT#[0-9][0-9]}" "${SCRIPT}"; do
+		f="${PM_UTILS_LIBDIR}/config.d/${cfg##*/}"
+		# if we have a single appropriatly named file, source it.
+		[ -O "$f" -a -f "$f" ] && ."$f"
+		# if we have an appropriately named directory, 
+		# source everything in it.
+		[ -O "${f}.d" -a -d "${f}.d" ] && {
+			for sf in "$f.d"/*[!~]; do
+				[ -O "$sf" -a -f "$sf" ] && . "$sf"
+			done
+		}
+		f="${PM_UTILS_ETCDIR}/config.d/${cfg##*/}"
+		# if we have a single appropriatly named file, source it.
+		[ -O "$f" -a -f "$f" ] && ."$f"
+		# if we have an appropriately named directory, 
+		# source everything in it.
+		[ -O "${f}.d" -a -d "${f}.d" ] && {
+			for sf in "$f.d"/*[!~]; do
+				[ -O "$sf" -a -f "$sf" ] && . "$sf"
+			done
+		}
 	done
 }
 
@@ -54,7 +63,7 @@ try_lock()
 	#               extra newline will be appended
 	# make sure the directory where the lockfile should be exists
 	mkdir -p "${LOCKDIR}"
-	local lock="${LOCKDIR}/${1##*/}"
+	local lock="${LOCKDIR}/${SCRIPT}-${1##*/}"
 	# we use noclobber to make sure there are no race conditions
 	(set -o noclobber; echo "${2}" > "${lock}") 2> /dev/null || return 1
 	return 0
@@ -79,30 +88,11 @@ release_lock()
 {
 	# $1 = lockfile
 	# make sure it is ours first.i
-	local lock="${LOCKDIR}/${1##*/}"
+	local lock="${LOCKDIR}/${SCRIPT}-${1##*/}"
 	rm -f "${lock}"
 	return $?
 }
 
-
-take_suspend_lock()
-{
-	VT=$(fgconsole)
-	chvt 63
-	try_lock "pm-utils.lock" || return 1
-	mkdir -p "${STORAGEDIR}"
-	return 0
-}
-
-remove_suspend_lock()
-{
-	rm -rf "${STORAGEDIR}"
-	chvt 1
-	chvt $VT
-	release_lock "pm-utils.lock"
-}
-
-
 command_exists()
 {
 	# $1 = command to test for.  It can be an executable in the path,
@@ -111,39 +101,6 @@ command_exists()
 	return $?
 }
 
-run_hooks() {
-	# $1 = type of hook to find.  
-	# $2 = paramaters to pass to hooks.
-	# $3 = if present and equal to "reverse", run hooks backwards.
-	# Currently only power and sleep are meaningful.
-	local syshooks="${PM_UTILS_ETCDIR}/$1.d"
-	local phooks="${PM_UTILS_LIBDIR}/$1.d"
-	local sort="sort"
-	local base
-	local hook
-	local oifs="${IFS}"
-	# the next two lines are not a typo or a formatting error!
-	local nifs="
-"
-	IFS="${nifs}" # tolerate spaces in filenames.
-	[ "$3" = "reverse" ] && sort="sort -r"
-	for base in $(IFS="${oifs}"; for f in $syshooks/*[!~] $phooks/*[!~];
-		do [ -f "$f" ] && echo ${f##*/} ; done | ${sort} | uniq) ;
-	do
-		if [ -f "$syshooks/$base" ]; then
-			hook="$syshooks/$base"
-		elif [ -f "$phooks/$base" ]; then
-			hook="$phooks/$base"
-		fi
-		[ -x "${hook}" ] && (
-			IFS="${oifs}"
-			echo "$(date): running ${hook} $2"
-			"${hook}" $2
-		)
-	done
-	IFS="${oifs}"
-}
-
 get_power_status()
 {
 	RETVAL=0
@@ -163,51 +120,9 @@ get_power_status()
 	return $RETVAL
 }
 
-[ -O "${SLEEP_FUNCTIONS}" ] || { 
-	echo "Requested sleep module $SLEEP_MODULE not available."
-	exit 1
-}
-
-. "${SLEEP_FUNCTIONS}"
-
-init_logfile() {
-	if [ -h "$1" ]; then
-		echo "$1 is a symbolic link, refusing to overwrite."
-		return 1
-	elif [ -O "$1" ]; then
-		echo "We do not own $1, refusing to overwrite."
-		return 1
-	elif [ -z "$1" ]; then
-		echo "Please pass a filename to init_logfile."
-		return 1
-	fi
-	exec > "$1" 2>&1
-}
-
-pm_main()
-{
-	"check_$1" || {
-		echo "System does not support $1 sleep."
-		return 1
-	}
-	take_suspend_lock || exit 1
-	# make sure that our locks are unlocked no matter how the script exits
-	trap remove_suspend_lock 0
-	init_logfile "$PM_LOGFILE" 
-	rm -f "$INHIBIT"
-
-	run_hooks sleep "$1" 
-	command_exists "do_$1" && [ ! -e "${INHIBIT}" ] && { \
-		sync; "do_$1"
-	}
-	run_hooks sleep "$2" reverse
-
-	return 0
-}
-
 _rmmod() {
 	if modprobe -r "$1"; then
-		touch "${STORAGEDIR}/module:$1"
+		touch "${STORAGEDIR}/${SCRIPT}-module:$1"
 		return 0
 	else
 		echo "# could not unload '$1', usage count was $2"
@@ -253,7 +168,7 @@ modunload()
 # reload all the modules in no particular order.
 modreload()
 {
-	for x in "${STORAGEDIR}"/module:* ; do
+	for x in "${STORAGEDIR}/${SCRIPT}"-module:* ; do
 		[ -O "${x}" ] && modprobe "${x##*:}" >/dev/null 2>&1
 	done
 }
@@ -274,22 +189,23 @@ fi
 stopservice()
 {
 	if service "$1" status 2>/dev/null | grep -c -q running; then
-		touch "${STORAGEDIR}/service:$1"
+		touch "${STORAGEDIR}/${SCRIPT}-service:$1"
 		service "$1" stop
 	fi
 }
 
 restartservice()
 {
-	[ -O "${STORAGEDIR}/service:$1" ] && service "$1" start
+	[ -O "${STORAGEDIR}/${SCRIPT}-service:$1" ] && service "$1" start
 }
 
 savestate()
 {
-	echo "$2" > "${STORAGEDIR}/state:$1"
+	echo "$2" > "${STORAGEDIR}/${SCRIPT}-state:$1"
 }
 
 restorestate()
 {
-	[ -O "${STORAGEDIR}/state:${1}" ] && cat "${STORAGEDIR}/state:${1}"
+	[ -O "${STORAGEDIR}/${SCRIPT}-state:${1}" ] && \
+		cat "${STORAGEDIR}/${SCRIPT}-state:${1}"
 }
diff --git a/pm/pm-functions.in b/pm/pm-functions.in
index e44dff3..efc5e77 100644
--- a/pm/pm-functions.in
+++ b/pm/pm-functions.in
@@ -35,19 +35,8 @@ export LC_COLLATE=C
 set +a
 
 
-source_configs()
-{
-	for cfg in "${PM_UTILS_ETCDIR}"/config.d/*[!~] ; do
-		[ -O "$cfg" ] || continue
-		set -a
-		. "${cfg}"
-		set +a
-	done
-}
-
-source_configs
-
 # try to take the lock.  Fail if we cannot get it.
+# This overrides the functionality from functions.
 try_lock()
 {
 	# $1 = file to use as lockfile
@@ -61,21 +50,8 @@ try_lock()
 	return 0
 }
 
-# spin waiting for the lock with optional timeout.  
-# return once we have it, or the timeout has expired
-spin_lock()
-{
-	# $1 = lockfile
-	# $2 = optional timeout
-	local elapsed=0
-	while ! try_lock $1; do
-		[ "x$2" != "x" ] && [ $(( $elapsed == $2 )) -ne 0 ] && return 1
-		elapsed=$(($elapsed + 1))
-		sleep 1;
-	done
-}
-
 # release the lock
+# This overrides the functionality from functions.
 release_lock()
 {
 	# $1 = lockfile
@@ -103,7 +79,6 @@ remove_suspend_lock()
 	release_lock "pm-utils.lock"
 }
 
-
 command_exists()
 {
 	# $1 = command to test for.  It can be an executable in the path,
@@ -128,12 +103,12 @@ run_hooks() {
 "
 	IFS="${nifs}" # tolerate spaces in filenames.
 	[ "$3" = "reverse" ] && sort="sort -r"
-	for base in $(IFS="${oifs}"; for f in $syshooks/*[!~] $phooks/*[!~];
+	for base in $(IFS="${oifs}"; for f in "$syshooks/"*[!~] "$phooks/"*[!~];
 		do [ -f "$f" ] && echo ${f##*/} ; done | ${sort} | uniq) ;
 	do
-		if [ -f "$syshooks/$base" ]; then
+		if [ -O "$syshooks/$base" ]; then
 			hook="$syshooks/$base"
-		elif [ -f "$phooks/$base" ]; then
+		elif [ -O "$phooks/$base" ]; then
 			hook="$phooks/$base"
 		fi
 		[ -x "${hook}" ] && (
@@ -145,25 +120,6 @@ run_hooks() {
 	IFS="${oifs}"
 }
 
-get_power_status()
-{
-	RETVAL=0
-	on_ac_power
-	case "$?" in
-		"0")
-			echo "ac"
-			;;
-		"1")
-			echo "battery"
-			;;
-		"255")
-			echo "error"
-			RETVAL=1
-			;;
-	esac
-	return $RETVAL
-}
-
 [ -O "${SLEEP_FUNCTIONS}" ] || { 
 	echo "Requested sleep module $SLEEP_MODULE not available."
 	exit 1
@@ -206,91 +162,3 @@ pm_main()
 	return 0
 }
 
-_rmmod() {
-	if modprobe -r "$1"; then
-		touch "${STORAGEDIR}/module:$1"
-		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()
-{
-	local MOD D C USED MODS I
-	local UNL="$(echo $1 |tr - _)" RET=1 
-
-	while read MOD D C USED D; do
-		[ "$MOD" = "$UNL" ] || continue
-		if [ "$USED" = "-" ]; then
-			# no dependent modules, just try to remove this one.
-			_rmmod "$MOD" $C
-			RET=$?
-		else
-			# modules depend on this one.  try to remove them first.
-			MODS="${USED%%*,}"
-			while [ -n "${MODS}" ]; do
-				# try to unload the last one first
-				MOD="${MODS##*,}"
-				modunload $MOD && RET=0
-				# prune the last one from the list
-				MODS="${MODS%,*}"
-			done
-			# if we unloaded at least one module, then let's
-			# try again!
-			[ $RET -eq 0 ] && modunload $MOD
-			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
-}
-
-# reload all the modules in no particular order.
-modreload()
-{
-	for x in "${STORAGEDIR}"/module:* ; do
-		[ -O "${x}" ] && modprobe "${x##*:}" >/dev/null 2>&1
-	done
-}
-
-if ! command_exists service; then
-	service() {
-		if [ -x "/etc/init.d/$1" ]; then
-			svc="$1"
-			shift
-			"/etc/init.d/$svc" "$@"
-		else
-			echo "$1" $": unrecognized service" 1>&2
-			return 1
-		fi
-	}
-fi
-
-stopservice()
-{
-	if service "$1" status 2>/dev/null | grep -c -q running; then
-		touch "${STORAGEDIR}/service:$1"
-		service "$1" stop
-	fi
-}
-
-restartservice()
-{
-	[ -O "${STORAGEDIR}/service:$1" ] && service "$1" start
-}
-
-savestate()
-{
-	echo "$2" > "${STORAGEDIR}/state:$1"
-}
-
-restorestate()
-{
-	[ -O "${STORAGEDIR}/state:${1}" ] && cat "${STORAGEDIR}/state:${1}"
-}
diff --git a/test-pm-utils b/test-pm-utils
index 1f834a0..e3e9622 100755
--- a/test-pm-utils
+++ b/test-pm-utils
@@ -8,7 +8,7 @@ cp -t "$tgt" -a "${opwd}"/* && \
 autoreconf --install && \
 ./configure "--prefix=$tgt/target" && \
 make && \
-make install &&  {
+sudo make install &&  {
 	echo "Build sucessfull.  Dropping to a shell to test."
 	echo "Files were installed in $tgt/target"
 } || echo "Build failed.  Dropping to a shell so you can see what happened."
-- 
1.5.3.8



More information about the Pm-utils mailing list