All pastes #410529 Raw Edit

Stuff

public shellscript v1 · immutable
#410529 ·published 2007-03-26 13:49 UTC
rendered paste body
#!/bin/bash############################################################################                                                                         ##                         Powersave Daemon                                ##                                                                         ##          Copyright (C) 2004,2005 SUSE Linux Products GmbH               ##                                                                         ## This program is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by the   ## Free Software Foundation; either version 2 of the License, or (at you   ## option) any later version.                                              ##                                                                         ## This program is distributed in the hope that it will be useful, but     ## WITHOUT ANY WARRANTY; without even the implied warranty of              ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ## General Public License for more details.                                ##                                                                         ## You should have received a copy of the GNU General Public License along ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA                  ##                                                                         ############################################################################. $SYSCONF_DIR/sleep# the statefiles are used to record the system state before the sleep state# and restore it after resume. Stopped services, unloaded modules etc. are# recorded in these files.STATE1=/var/lib/suspend2disk-state   # statefile for suspend-to-diskSTATE2=/var/lib/suspend2ram-state    # statefile for suspend-to-ramSTATE3=/var/lib/standby-state        # statefile for standby# the logfiles log information (such as the output of rc-scripts) in addition# to the statefiles to aid users in debugging suspend failures.LSMOD_LOG1=/var/log/suspend2disk.log # logfile for suspend-to-diskLSMOD_LOG2=/var/log/suspend2ram.log  # logfile for suspend-to-ramLSMOD_LOG3=/var/log/standby.log      # logfile for standbyPOWERSAVE="$BIN_DIR/powersave"PCCARDCTL="/sbin/pccardctl"# if you still have cardmgr, use "/sbin/cardctl"test -x "$PCCARDCTL" || PCCARDCTL="/sbin/cardctl"GRUBONCE="/usr/sbin/grub-set-default"# this recursively unloads the given modules and all that depend on it# first parameter is the module to be unloaded# second parameter is the state file, where all unloaded modules are#        recorded for reloading after resume.# third parameter is the log file for the user.unload_module(){    local LOGFILE STATEFILE    local MOD D C USED MODS I    local UNL=$1 RET=1    # we need the statefile to be set    [ -z "$2" ] && DEBUG "no STATEFILE set in unload_module" ERROR && return 255    [ -n "$3" ] && LOGFILE="$3" || LOGFILE=/dev/null    STATEFILE="$2"    # RET is the return code. If at least one module was unloaded, return 0.    #     if no module was unloaded successfully, return 1    #     if there was no module to unload, SUCCESS!, return 0    while read MOD D C USED D; do        [ "$MOD" != "$UNL" ] && continue        if [ "$USED" == "-" ]; then            if [ $C -eq 0 ]; then                progress "${_M08} $UNL"                echo "# trying to unload: $UNL" >> $STATEFILE                echo "# trying to unload: $UNL" >> $LOGFILE                if rmmod $UNL; then                    echo "unloaded: $UNL" >> $STATEFILE                    echo "unloaded: $UNL" >> $LOGFILE                    RET=0                else                    DEBUG "could not unload module '$UNL'" WARN                    echo "could not unload module '$UNL', usage count was 0." >> $LOGFILE                fi            else                echo "could not unload module '$UNL', usage count: $C" >> $LOGFILE            fi        else            USED=${USED//,/ }            MODS=($USED)            # it is slightly more likely to rmmod in one pass, if we try backwards.            # is this really true? I don't know, but it doesn't hurt either.            for I in `seq $[${#MODS[@]}-1] -1 0`; do                MOD=${MODS[$I]}                unload_module $MOD $STATEFILE $LOGFILE && RET=0            done            # if we unloaded at least one module, then let's try again!            [ $RET -eq 0 ] && unload_module $UNL $STATEFILE $LOGFILE            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}######################################################## unmount_fatfs function# unmounts all (v)fat/ntfs partitions if possible.#unmount_fatfs(){    local I J K # counters    local D E   # dummies    local RET  DEV MNT OPT TYPE MESSAGE MTAB    declare -a DEV MNT OPT TYPE # arrays for the mtab entries    progress "${_M04}"    echo "== Unmounting FAT/NTFS filesystems: ==" >> $LSMOD_LOG    MESSAGE=""; K=0    MTAB=/etc/mtab # or /proc/mounts? which one is better?    exec 2>&1   # why?    # ugh, this is ugly. But remember, we could be having a mountpoint named    # "/mnt/mount point name with whitespace in it"    # yes, ugly quoting hell.    eval `awk '    BEGIN {X=0}    { if (($3=="ntfs")||($3=="vfat")||($3==fat)) {        Y=$2; gsub("\\\\\\\\", "\\\\\\\\\\\\", Y);        print "DEV["X"]="$1;        print "MNT["X"]=$(echo -e "Y")";        print "TYP["X"]="$3;        print "OPT["X"]="$4;        X++}    }' $MTAB`    echo "Checking for mounted fat/ntfs filesystems:"    # now do something with the list of devices / mountpoints...    for (( I=0; ${#DEV[$I]}; I++ )); do        echo "  device ${DEV[$I]} mounted on '${MNT[$I]}'" >> $LSMOD_LOG        # stderr is additional information from fuser which we have to drop.        # We need only the PIDs. They are on stdout.        for J in $(fuser -m "${MNT[$I]}" 2>/dev/null);do            while read D E; do                case $D in                    Name:)                        if [ "$E" != "prepare_suspend" ]; then                            MESSAGE=$MESSAGE" $E($J)"                            echo "    is accessed by $E($J)" >> $LSMOD_LOG                            let K++                        fi                        break ;;                    *)  ;;                esac            done < /proc/$J/status        done    done    [ $I -eq 0 ] && echo "  none found in $MTAB" >> $LSMOD_LOG    exec 3>&2   # why?    if [ $K -ne 0 ];then # one or more filesystems in use        echo "  filesystems in use, asking user..." >> $LSMOD_LOG        case $K in            1)  MESSAGE="Process $MESSAGE is" ;;            *)  MESSAGE="Processes $MESSAGE are" ;;        esac        MESSAGE=$MESSAGE" accessing an ntfs/fat mountpoint. \Please make sure fat/ntfs mountpoints are unmountable before proceeding."        question "$MESSAGE" "1"        RET=$?        if [ $RET -ne 0 ]; then            echo "  user does not want to continue. aborting suspend" >> $LSMOD_LOG            progress_finish            $SCRIPT_RETURN $EV_ID 1 "prepare_sleep failed ($1): $MESSAGE"            restore_after_sleep "$1"            EXIT 1;        fi        echo "  user wants to continue anyway. Good luck." >> $LSMOD_LOG    fi    # no filesystem in use. Or user answered "proceed anyway".    # umount ntfs/fat mount points ...    for (( I=0; ${#DEV[$I]}; I++ )); do        echo "# trying to umount device: ${DEV[$I]}" >> $STATE        echo "trying to umount device: '${DEV[$I]}' '${MNT[$I]}' -t '${TYP[$I]}' -o '${OPT[$I]}'" >> $LSMOD_LOG        umount ${MNT[$I]}; RET=$?        if [ $RET -eq 0 ]; then            # very verbose, but we have the whole mount command line ready for remount.            # every variable in one line, makes it easier to re-parse (remember:            # whitespace danger!)            echo "unmounted: ${DEV[$I]}"              >> $STATE            echo "# mountpoint unmounted: ${MNT[$I]}" >> $STATE            echo "# fstype unmounted: -t ${TYP[$I]}"  >> $STATE            echo "# options unmounted: -o ${OPT[$I]}" >> $STATE            echo "  success." >> $LSMOD_LOG        else            echo "umount failed. Asking user what to do." >> $LSMOD_LOG            MESSAGE="Unable to unmount device ${DEV[$I]}."            DEBUG "$MESSAGE Asking the user" ERROR            question "$MESSAGE Proceed anyway?" "1"            RET=$?            if [ $RET -ne 0 ]; then                echo "user does not want to continue (good). Aborting suspend." >> $LSMOD_LOG                progress_finish                $SCRIPT_RETURN $EV_ID 1 "prepare_sleep failed ($1): $MESSAGE"                restore_after_sleep "$1"                EXIT 1;            fi            echo "user wants to continue anyway. Good luck." >> $LSMOD_LOG        fi    done    echo "== FAT/NTFS filesystems unmounted ==" >> $LSMOD_LOG}   ##### unmount_fatfs()######################################################### remount_fatfs function# remounts the filesystems that were unmounted by# unmount_fatfs()remount_fatfs(){    local D I   # dummy, counter    local      DEV MNT TYP OPT    declare -a DEV MNT TYP OPT        echo >> $LSMOD_LOG    echo "Remounting filesystems:" >> $LSMOD_LOG    I=0    while read DEV[$I]; do        read MNT[$I]        read TYP[$I]        read OPT[$I]        let I++    done < <(awk -F 'unmounted: ' '/^unmounted:/ {                print $2; getline;                print $2; getline;                print $2; getline;                print $2 }' ${STATE}.resume )    [ $I -eq 0 ] && echo "  not necessary." >> $LSMOD_LOG    let I-- # incremented once too many times    # we remount in reverse order...    for (( ; I>=0 ; I-- )) ; do        mount ${DEV[$I]} ${MNT[$I]} ${OPT[$I]} ; D=$?        if [ $D -eq 0 ];then            DEBUG "remounted ${DEV[$I]}" DIAG            echo "  mounted '${DEV[$I]}' to '${MNT[$I]}', options '${OPT[$I]}'" >> $LSMOD_LOG        else            DEBUG "unable to remount ${DEV[$I]}" WARN            echo "  could not mount '${DEV[$I]}' to '${MNT[$I]}', options '${OPT[$I]}', error $D" >> $LSMOD_LOG        fi    done    echo >> $LSMOD_LOG    }   # remount_fatfs######################################################## set_variables func## function to set the variables according to what# we are going to do.# internally, use only in sleep_helper_functionsDEFAULT_S2D_UNLOAD="usb_storage sbp2 ohci_hcd uhci_hcd stir4200 ohci1394 rt2500 prism54 ath_pci r8169 lt_modem Intel536 Intel537 ndiswrapper"DEFAULT_S2R_UNLOAD="usb_storage sbp2 ohci_hcd uhci_hcd stir4200 ohci1394 rt2500 prism54 ath_pci r8169 lt_modem Intel536 Intel537 ndiswrapper"DEFAULT_STB_UNLOAD="usb_storage sbp2 ohci_hcd uhci_hcd stir4200 ohci1394 rt2500 prism54 ath_pci r8169 lt_modem Intel536 Intel537 ndiswrapper"DEFAULT_S2D_RESTART="slmodemd irda upsd apcupsd"DEFAULT_S2R_RESTART="slmodemd irda upsd apcupsd"DEFAULT_STB_RESTART="slmodemd irda upsd apcupsd"set_variables(){    case "$1" in        suspend2disk)            STATE=$STATE1            LSMOD_LOG=$LSMOD_LOG1            EJECT_PCMCIA=$SUSPEND2DISK_EJECT_PCMCIA            MODULES_TO_UNLOAD="${UNLOAD_MODULES_BEFORE_SUSPEND2DISK:-$DEFAULT_S2D_UNLOAD}"            SERVICES_TO_RESTART="${SUSPEND2DISK_RESTART_SERVICES:-$DEFAULT_S2D_RESTART}"            UNMOUNT_FATFS="${SUSPEND2DISK_UNMOUNT_FATFS:-yes}"            SWITCH_VT="$SUSPEND2DISK_SWITCH_VT"            ;;        suspend2ram)            STATE=$STATE2            LSMOD_LOG=$LSMOD_LOG2            EJECT_PCMCIA=$SUSPEND2RAM_EJECT_PCMCIA            MODULES_TO_UNLOAD="${UNLOAD_MODULES_BEFORE_SUSPEND2RAM:-$DEFAULT_S2R_UNLOAD}"            SERVICES_TO_RESTART="${SUSPEND2RAM_RESTART_SERVICES:-$DEFAULT_S2R_RESTART}"            UNMOUNT_FATFS="${SUSPEND2RAM_UNMOUNT_FATFS:-no}"            SWITCH_VT="$SUSPEND2RAM_SWITCH_VT"            ;;        standby)            STATE=$STATE3            LSMOD_LOG=$LSMOD_LOG3            EJECT_PCMCIA=$STANDBY_EJECT_PCMCIA            MODULES_TO_UNLOAD="${UNLOAD_MODULES_BEFORE_STANDBY:-$DEFAULT_STB_UNLOAD}"            SERVICES_TO_RESTART="${STANDBY_RESTART_SERVICES:-$DEFAULT_STB_RESTART}"            UNMOUNT_FATFS="${STANDBY_UNMOUNT_FATFS:-no}"            SWITCH_VT="$STANDBY_SWITCH_VT"            ;;        *)            echo "Wrong parameter '$1' in set_variables function in sleep_helper_functions script"            return            ;;    esac}######################################################## prepare the logfiles# parameter: sleep typeprepare_logs() {    # here we prepare the statefile that records what we have done    # and the logfile for users to troubleshoot.    rm -f $STATE    rm -f $LSMOD_LOG    # there should be at least one line in $STATE or we will get an    # harmless but ugly error in restore_after_sleep.    echo "# this file records the system state at entering $1." > $STATE    echo "$1 initiated: `date +'%F %X'`" > $LSMOD_LOG    echo "Debug info follows here, please include in your bug reports. Thanks." >> $LSMOD_LOG    echo "--------------------------------------------------------------------" >> $LSMOD_LOG    echo "Loaded modules:" >> $LSMOD_LOG    lsmod >> $LSMOD_LOG    echo >> $LSMOD_LOG    echo "Memory info:" >> $LSMOD_LOG    free >> $LSMOD_LOG    echo >> $LSMOD_LOG    echo "/proc/cmdline: `cat /proc/cmdline`" >> $LSMOD_LOG    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG    echo "========we are going to sleep, preparing.========" >> $LSMOD_LOG}######################################################## Function to unload modules and stop services for# the upcoming sleep mode## first parameter is the sleep type:# - suspend2disk# - suspend2ram# - standbyprepare_sleep(){    local D E X # dummies,counters    local RET TYPE        [ -z $1 ] && echo "Do not invoke this script from console, it is automatically invoked by the powersave daemon" && EXIT 1    DEBUG "Stop services: $SERVICES_TO_RESTART" DEBUG    DEBUG "Modules to unload: $MODULES_TO_UNLOAD" DEBUG    ####### first check if the machine is shutting down right now.    echo "== checking runlevel ==" >> $LSMOD_LOG    D=`runlevel`    case $D in        *0|*6)            echo "  system is shutting down or rebooting. Not suspending. '$D'" >> $LSMOD_LOG            notify "Shutdown or reboot in progress, not suspending." ERROR CONTINUE $EV_ID            progress_finish            $SCRIPT_RETURN $EV_ID 1 "Shutdown/reboot in progress, not suspending"            EXIT 1            ;;    esac    echo "  no shutdown/reboot in progress, good." >> $LSMOD_LOG    ####### Check for devices which need to be remounted after suspend #######    let PERCENT+=$STEP    [ "$UNMOUNT_FATFS" == "yes" ] && unmount_fatfs "$1" "$EV_ID"    ####### S t o p   S e r v i c e s   ##########    let PERCENT+=$STEP    progress "${_M05}"    D="$SERVICES_TO_RESTART"    E=${D:+\'}${D:-none}${D:+\'}    echo "Stopping services: ($E configured)" >> $LSMOD_LOG    D=true    if [ "$SERVICES_TO_RESTART" != "NONE" ]; then        D=false        for X in $SERVICES_TO_RESTART; do	    if [ -x "/etc/init.d/$X" ]; then                echo "stopping $X:" >> $LSMOD_LOG                progress "${_M06} $X"                /etc/init.d/$X stop 2>&1 | awk '{print "##  "$0}' >> $LSMOD_LOG                echo "stopped: $X" >> $STATE                DEBUG "Service $X stopped" DIAG                D=true	    fi        done    fi    $D || echo "none running." >> $LSMOD_LOG    ####### S t o p   S e r v i c e s   ##########    ####### Eject PCMCIA cards          ##########    let PERCENT+=$STEP    if [ "$EJECT_PCMCIA" == "yes" ]; then        progress "${_M03}"        echo "ejecting PCMCIA cards..." >> $LSMOD_LOG        $PCCARDCTL eject    fi    ####### U n l o a d   M o d u l e s ##########    let PERCENT+=$STEP    progress "${_M07}"    echo >> $LSMOD_LOG    D="$MODULES_TO_UNLOAD"    E=${D:+\'}${D:-none}${D:+\'}    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG    echo "Unloading modules: ($E configured)" >> $LSMOD_LOG    if [ "$MODULES_TO_UNLOAD" ]; then        for module in $MODULES_TO_UNLOAD; do            [ "$module" == "NONE" ] && continue            echo "checking $module" >> $LSMOD_LOG            # unload_module handles not-loaded modules gracefully.            if ! unload_module $module $STATE $LSMOD_LOG; then                MESSAGE="$1 failed on unloading '$module'."                if [ "$UNL" != "$module" -a -n "$UNL" ]; then                    MESSAGE="$MESSAGE The module that refused to unload was '$UNL'."                fi                MESSAGE="$MESSAGE Trying to recover..."                DEBUG "$MESSAGE" ERROR                notify "$MESSAGE" ERROR CONTINUE $EV_ID                progress_finish                $SCRIPT_RETURN $EV_ID 1 "$MESSAGE"                restore_after_sleep "$1"                EXIT 1            fi        done        DEBUG "Modules unloaded" DIAG    fi    ####### U n l o a d   M o d u l e s ##########    let PERCENT+=$STEP    progress ""    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG    echo "prepare_sleep finished for $1" >> $LSMOD_LOG    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG}######################################################### restore_after_sleep FUNC## Function to load previously unloaded modules and start# the stopped services for after resuming from a sleep# sleep mode. Modules are loaded in reverse unloading# order, services are started in reverse stopping order.# Only hotplug is an exception: it is always started# first to handle hotplug events generated by module loading.## give first param:# suspend2disk# suspend2ram# standbyrestore_after_sleep() {    local D X    [ -z $1 ] && echo "Do not invoke this script from console, it is automatically invoked by the powersave daemon" && EXIT 1    echo >> $LSMOD_LOG    echo "== restore_after_sleep: restart and reload everything ==" >> $LSMOD_LOG        # sanity check. We had this once...    if [ ! -e $STATE ]; then        echo "WARNING: Statefile '$STATE' disappeared during suspend!" >> $LSMOD_LOG        DEBUG "Statefile '$STATE' disappeared during suspend." ERROR    fi    # clean up after ourselves..    touch $STATE                        # if it is not there for any reason, create it.    mv -f $STATE ${STATE}.resume        # now move it out of the way.    echo >> $LSMOD_LOG    echo "Resuming:" >> $LSMOD_LOG    echo "---------" >> $LSMOD_LOG    switch_to_X    kick_fan    # special case: hotplug should be started before inserting modules    if D=`awk 'BEGIN {X=1} /^stopped: (boot\.|)hotplug/ {print $2; X=0} END {exit X}' ${STATE}.resume`; then        echo "first starting $D:" >> $LSMOD_LOG        /etc/init.d/$D start 2>&1 | awk '{print "##  "$0}' >> $LSMOD_LOG        DEBUG "Service $D started again" DIAG    fi#    echo $STATE    echo >> $LSMOD_LOG    echo "Reloading modules:" >> $LSMOD_LOG    ####### L o a d   M o d u l e s       ##########    if [ "$MODULES_TO_UNLOAD" -a -s "${STATE}.resume" ]; then        for module in `tac ${STATE}.resume| awk '/^unloaded:/ { print $2 }'`; do            echo "  $module" >> $LSMOD_LOG            modprobe $module        done        DEBUG "Modules loaded" DIAG    fi    # rm ${STATE}.resume # disabled for debugging    ####### L o a d   M o d u l e s       ##########    ####### reinsert PCMCIA cards         ##########    if [ "$EJECT_PCMCIA" == "yes" ]; then        echo "inserting PCMCIA cards..." >> $LSMOD_LOG        $PCCARDCTL insert    fi    echo >> $LSMOD_LOG    echo "Restarting services:" >> $LSMOD_LOG    ####### S t a r t   S e r v i c e s  (but not hotplug or boot.hotplug)  ##########    if [ "$SERVICES_TO_RESTART" -a -s "${STATE}.resume" ]; then        for X in `tac ${STATE}.resume | awk '/^stopped:/ { if (($2!="hotplug")&&($2!="boot.hotplug")) print $2 }'`; do            echo "starting $X:" >> $LSMOD_LOG            /etc/init.d/$X start 2>&1 | awk '{print "##  "$0}' >> $LSMOD_LOG            DEBUG "Service $X started again" DIAG        done    fi    ####### S t a r t   S e r v i c e s   ##########    ####### remount previously unmounted devices #######    remount_fatfs    $SCRIPT_RETURN $EV_ID 0 "restore_after_$1 finished"    return 0}###################################################################### get_kernels# gets a list of available kernels from /boot/grub/menu.lst# kernels are in the array $KERNELS, output to stdout to be eval-ed.get_kernels(){    DEBUG "Running get_kernels()" INFO    local MENU_LST="/boot/grub/menu.lst"    local I DUMMY    declare -i I=0 J=-1    # build an array KERNELS with all the kernels in /boot/grub/menu.lst    # the array MENU_ENTRIES contains the corresponding menu entry numbers    # DEFAULT_BOOT contains the default entry.    while read LINE; do        case $LINE in        title*)            let J++ # increase for every menu entry, even for non-linux            DEBUG "Found grub menu entry #${J}: '${LINE}'" INFO            ;;        default*)            DUMMY=($LINE)                   # "default 0 #maybe a comment"            echo "DEFAULT_BOOT=${DUMMY[1]}" #  ^^[0]^^ 1 ^^[2]^ 3 ^^[4]^^            DEBUG "Default boot entry is '${DUMMY[1]}'" INFO            ;;        kernel*)            DUMMY=($LINE) # kernel (hd0,1)/boot/vmlinuz-ABC root=/dev/hda2            echo "KERNELS[$I]='${DUMMY[1]##*/}'" # vmlinuz-ABC            echo "MENU_ENTRIES[$I]=$J"            DEBUG "Found kernel entry #${I}: '${DUMMY[1]##*/}'" INFO            let I++            ;;        *)  ;;        esac    done < $MENU_LST}############################################################## grub-once()# runs grubonce from the grub package to select which kernel# to boot on next startupgrub-once() {    if [ -x "$GRUBONCE" ]; then        default=$(awk '/^default/ {print $2}' /boot/grub/menu.lst)	if [ "$default" = "saved" ]; then            echo "running '$GRUBONCE $1'" >> $LSMOD_LOG            $GRUBONCE $1	else	    echo "/boot/grub/menu.lst: default is not set to saved, not preparing bootloader" >> $LSMOD_LOG	fi    else        echo "$GRUBONCE not found, not preparing bootloader" >> $LSMOD_LOG    fi}############################################################## grub-once-restore()# restore grub default after (probably failed) resumegrub-once-restore() {    # noop    :}############################################################## progress# pops up and updates a progress bar.# needs global variables:#  PERCENT#  EV_ID# takes one argument: the message.progress() {    if [ -z "$PERCENT" -o -z "$EV_ID" -o -z "$SCRIPT_RETURN" ]; then        DEBUG "progress called without variables set." ERROR        return 1    fi    $SCRIPT_RETURN $EV_ID 4 "${PERCENT}${1:+|$1}"}############################################################## progress_finish# closes the progress barprogress_finish() {    PERCENT=101    progress ""}############################################################## switch_to_vt# switches to text console 1switch_to_vt() {    if [ "$SWITCH_VT" = "yes" ]; then        echo "console no: `fgconsole`" >> $STATE        chvt 1    fi}############################################################## switch_to_X# switches back to the console we were before suspendswitch_to_X() {    if [ "$SWITCH_VT" = "yes" ]; then        local CONS        CONS=$(awk -F : '/^console no:/ {print $2}' ${STATE}.resume)        [ -n "$CONS" ] && chvt $CONS        echo "switched back to console: '$CONS'" >> $LSMOD_LOG    fi}############################################################## kick_fan# triggers the ACPI fan(s) after resume. Since ACPI drivers# have no suspend support, this is sometimes necessary.# see http://article.gmane.org/gmane.linux.acpi.devel/16643kick_fan() {    local FAN DUMMY STATE     for FAN in /proc/acpi/fan/*/state; do        [ ! -e $FAN ] && continue        read DUMMY STATE < $FAN        if [ "$STATE" = "on" ]; then            DUMMY=${FAN#/proc/acpi/fan/}            echo "reactivating ACPI fan ${DUMMY%/state}" >> $LSMOD_LOG            echo -n 3 > $FAN            echo -n 0 > $FAN        fi    done}