#!/bin/bash export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/lib/pm-utils/bin # Default values go here. It is important to _not_ initialize some # variables here. They are: # # PM_CMDLINE # RESUME_MODULES # S2RAM_OPTS # set -a HIBERNATE_RESUME_POST_VIDEO=no INHIBIT=/var/run/pm-utils.inhibit PM_LOGFILE=${PM_LOGFILE:=/var/log/pm-suspend.log} SUSPEND_MODULES="" HIBERNATE_METHOD="" S2DISK_BIN=/usr/sbin/s2disk S2DISK_CONF=/etc/uswsusp.conf [ -f /usr/lib/pm-utils/defaults ] && . /usr/lib/pm-utils/defaults set +a source_configs() { cfgs="/etc/pm/config.d/*[^~]" for cfg in $cfgs ; do [ -f $cfgs ] || continue set -a . $cfg set +a done } source_configs take_suspend_lock() { VT=$(fgconsole) chvt 63 if [ -f /.suspended ]; then read pid < /.suspended if [ -d /proc/$pid ]; then return 1 fi fi echo "$$" > /.suspended rm -f /var/run/pm-suspend touch /var/run/pm-suspend return 0 } remove_suspend_lock() { rm -f /var/run/pm-suspend chvt 1 chvt $VT openvt -- sh -c "sleep $1 ; rm -f /.suspended >/dev/null 2>&1 0<&1" >/dev/null 2>&1 0<&1 & } find_sleepd_files() { flist="/etc/pm/sleep.d/*[^~] /usr/lib/pm-utils/sleep.d/*[^~]" bases=$(for file in $flist ; do echo $(basename $file) ; done | sort -n) for base in $bases ; do if [ -e "/etc/pm/sleep.d/$base" ]; then if [ -x "/etc/pm/sleep.d/$base" ]; then echo /etc/pm/sleep.d/$base fi elif [ -x "/usr/lib/pm-utils/sleep.d/$base" ]; then echo /usr/lib/pm-utils/sleep.d/$base fi done } run_hooks() { [ -z "$1" ] && return 0 [ -f /var/run/pm-suspend ] && . /var/run/pm-suspend rm -f /var/run/pm-suspend echo "$(date): running $1 hooks." files=$(find_sleepd_files) if [ "$2" = "reverse" ]; then filea=($files) filen=${#filea[*]} while [ "$filen" -gt 0 ]; do let filen-- file="${filea[$filen]}" echo "===== $(date): running hook: $file =====" $file $1 done else for file in $files ; do echo "===== $(date): running hook: $file =====" $file $1 done fi echo "$(date): done running $1 hooks." } get_power_status() { RETVAL=0 on_ac_power case "$?" in "0") echo "ac" ;; "1") echo "battery" ;; "255") echo "error" RETVAL=1 ;; esac return $RETVAL } do_suspend() { if [ -x /usr/sbin/s2ram ]; then if [ -n "$S2RAM_OPTS" ]; then # Trust HAL or the user to pass the correct options /usr/sbin/s2ram $S2RAM_OPTS elif /usr/sbin/s2ram --test > /dev/null ; then # Trust s2ram's internal whitelist /usr/sbin/s2ram else # Unknown machine echo "This machine is unkown, please try to find out how to suspend this machine. See s2ram(8)." fi else echo -n "mem" > /sys/power/state fi } do_hibernate() { if [ -z "$HIBERNATE_METHOD" ]; then if [ -x $S2DISK_BIN -a -c /dev/snapshot ]; then HIBERNATE_METHOD="userspace" else HIBERNATE_METHOD="kernel" fi fi case $HIBERNATE_METHOD in userspace) $S2DISK_BIN -f $S2DISK_CONF ;; kernel) echo -n "platform" > /sys/power/disk echo -n "disk" > /sys/power/state ;; esac } do_suspend_hybrid() { if [ -x /usr/sbin/s2both ]; then /usr/sbin/s2both -f $S2DISK_CONF $S2RAM_OPTS else exit 1; fi } pm_main() { if [ -n "$PM_LOGFILE" ]; then [ -f "$PM_LOGFILE" ] && rm -f "$PM_LOGFILE" exec > "$PM_LOGFILE" 2>&1 fi take_suspend_lock || exit 1 rm -f "$INHIBIT" run_hooks "$1" if [ ! -e "$INHIBIT" -a "$(type -t "do_$1")" == "function" ]; then sync ; sync ; sync "do_$1" fi run_hooks "$2" reverse remove_suspend_lock 0.0002 return 0 } _rmmod() { if modprobe -r $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() { local MOD D C USED MODS I local UNL=$1 RET=1 UNL=$(echo $UNL | sed -e 's/[_-]/\[_-\]/g') # 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 $MOD $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 $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 } modreload() { if [ "$(eval echo \$${1//-/_}_MODULE_LOAD)" == "yes" ]; then modprobe "$1" >/dev/null 2>&1 fi } stopservice() { if [ -x "/etc/init.d/$1" ]; then echo "export ${1//-/_}_SERVICE_ACTIVATE=yes" >> /var/run/pm-suspend invoke-rc.d "$1" stop 2>&1 fi } restartservice() { if [ "x$(eval echo \$${1//-/_}_SERVICE_ACTIVATE)" == "xyes" \ -a -x "/etc/init.d/$1" ]; then invoke-rc.d "$1" start 2>&1 fi } savestate() { echo "export ${1//-/_}_STATE=$2" >> /var/run/pm-suspend } restorestate() { eval echo \$${1//-/_}_STATE }