with LSB standard (#237771) Fixed starting of anacron after resume (#83770) Fixed X_LOCK (#127318) Included laptopmode script (#91878) Fixed restarting network (#357381)
398 lines
14 KiB
Bash
Executable file
398 lines
14 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Red Hat APM suspend/resume script
|
|
# $Id: apmscript,v 1.17 2003/10/22 21:08:00 notting Exp $
|
|
# (c) 1999-2002 Bernhard Rosenkraenzer <bero@redhat.com>
|
|
# (c) 2003 Red Hat, Inc.
|
|
#
|
|
# DO NOT EDIT THIS SCRIPT, CREATE AND EDIT apmcontinue IN THIS DIRECTORY; you
|
|
# can put your stuff into apmcontinue for every link you create to apmscript;
|
|
# for a start and definitely enough for most laptops we have two links and
|
|
# according subroutines defined here: suspend and resume; all other links
|
|
# will be redirected directly to apmcontinue which you can create; also
|
|
# suspend and resume call apmscript, so you can also do other things (like
|
|
# reinitialising some PCMCIA-Card) there; apmcontinue will get the name
|
|
# as which it was called as $1; for debugging see the logfiles
|
|
#
|
|
# If you think something in this script needs to be changed anyway, please
|
|
# report it to http://bugzilla.redhat.com/bugzilla/
|
|
#
|
|
# This script can be controlled by editing /etc/sysconfig/apmd.
|
|
|
|
PROG="$1"
|
|
LOCKFILE=/var/lock/subsys/resume
|
|
LANG="C"
|
|
export NOLOCALE=1
|
|
[ -e /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
|
|
[ -e /etc/sysconfig/apmd ] && . /etc/sysconfig/apmd
|
|
[ -e /etc/sysconfig/clock ] && . /etc/sysconfig/clock
|
|
[ -z "$UTC" ] && UTC="no"
|
|
[ -z "$CHANGEVT" ] && CHANGEVT="0"
|
|
[ -z "$CLOCK_SYNC" ] && CLOCK_SYNC="no"
|
|
[ -z "$CPUFREQ" ] && CPUFREQ="no"
|
|
if [ -n "`/sbin/pidof X`" -o -n "`/sbin/pidof Xorg`" ]; then
|
|
X_RUNNING=1
|
|
fi
|
|
|
|
if [ ! -f /proc/cpufreq ]; then
|
|
CPUFREQ="no"
|
|
fi
|
|
|
|
CLOCK="--localtime"
|
|
[ "$UTC" = "yes" -o "$UTC" = "true" -o "$UTC" = 1 ] && CLOCK="--utc"
|
|
|
|
case "$PROG" in
|
|
suspend|standby)
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue-pre ] && /etc/sysconfig/apm-scripts/apmcontinue-pre "$@"
|
|
# Stop services that might break
|
|
echo "#!/bin/sh" >/var/run/apm-resume-post
|
|
# Remove sound progs and modules if requested
|
|
if [ "$RESTORESOUND" = "yes" -o "$RESTORESOUNDPROGS" = "yes" ]; then
|
|
# Find all programs using sound and kill them...
|
|
rm -rf /var/run/apm-soundprogs
|
|
if [ -c /dev/sndstat ]; then
|
|
for n in `cat /dev/sndstat 2>/dev/null| LC_ALL=C grep Open\ by|awk {'print $3'}|uniq`; do
|
|
SOUNDPROG=`echo $n|awk -F / {'print $2'}`
|
|
SOUNDPID=`echo $n|awk -F / {'print $1'}`
|
|
SOUNDUSER=`ls -ld /proc/$SOUNDPID |awk {'print $3'}`
|
|
SOUNDDISPLAY=`perl -e 's/\000/\n/g;' -p /proc/$SOUNDPID/environ| LC_ALL=C grep ^DISPLAY=|cut -d= -f2-`
|
|
|
|
# Make sure nobody is playing foul tricks on us
|
|
SOUNDPROG=`echo $SOUNDPROG |sed -e 's/|.*//'`
|
|
|
|
kill $SOUNDPID
|
|
ps "$SOUNDPID" &>/dev/null && kill -9 $SOUNDPID
|
|
echo "$SOUNDPROG|$SOUNDPID|$SOUNDUSER|$SOUNDDISPLAY" >>/var/run/apm-soundprogs
|
|
logger "apmscript: Program $SOUNDPROG ($SOUNDPID) of user $SOUNDUSER on display $SOUNDDISPLAY terminated."
|
|
done
|
|
fi
|
|
for n in `lsof | LC_ALL=C grep /dev| LC_ALL=C grep ' 14,'|sed -e 's/ \+/|/g'|cut '-d|' -f1-3`; do
|
|
SOUNDPROG=`echo $n |cut '-d|' -f1`
|
|
SOUNDPID=`echo $n |cut '-d|' -f2`
|
|
SOUNDUSER=`echo $n |cut '-d|' -f3`
|
|
SOUNDDISPLAY=`perl -e 's/\000/\n/g;' -p /proc/$SOUNDPID/environ| LC_ALL=C grep ^DISPLAY=|cut -d= -f2-`
|
|
|
|
# Make sure nobody is playing foul tricks on us
|
|
SOUNDPROG=`echo $SOUNDPROG |sed -e 's/|.*//'`
|
|
|
|
kill $SOUNDPID
|
|
ps "$SOUNDPID" &>/dev/null && kill -9 $SOUNDPID
|
|
echo "$SOUNDPROG|$SOUNDPID|$SOUNDUSER|$SOUNDDISPLAY" >>/var/run/apm-soundprogs
|
|
logger "apmscript: Program $SOUNDPROG ($SOUNDPID) of user $SOUNDUSER on display $SOUNDDISPLAY terminated."
|
|
done
|
|
# We unload the modules later to give the driver some time
|
|
# to spin down.
|
|
fi
|
|
|
|
# Some broken disks won't return from a suspend to disk
|
|
# unless they're set to 100% failsafe settings with hdparm.
|
|
# Typically, notebooks with SystemSoft MobilePRO BIOS are
|
|
# affected by this.
|
|
if test "x$HDPARM_AT_SUSPEND" != "x"; then
|
|
for i in /proc/ide/hd*; do
|
|
DRIVE=/dev/`echo $i |sed -e "s,.*/,,g"`
|
|
if test "x`cat $i/media`" = "xdisk"; then
|
|
hdparm $HDPARM_AT_SUSPEND $DRIVE
|
|
fi
|
|
done
|
|
fi
|
|
sync
|
|
|
|
unset NEED_NETFS_START || :
|
|
if [ "$NETFS_RESTART" = "yes" ]; then
|
|
NEED_NETFS_START=yes
|
|
/sbin/service netfs stop
|
|
fi
|
|
if [ "$NET_RESTART" = "yes" ] ; then
|
|
# Make an educated guess at what interfaces need restarting
|
|
NETDEVICES=`LC_ALL=C /etc/init.d/network status | LC_ALL=C grep -A1 "Currently active devices" |tail -n1`
|
|
if [ "$?" = "0" ]; then
|
|
for i in $NETDEVICES; do
|
|
echo "/sbin/ifup $i" >>/var/run/apm-resume-post
|
|
done
|
|
echo "touch /var/lock/subsys/network" >>/var/run/apm-resume-post
|
|
fi
|
|
fi
|
|
if [ -n "$RESTORESERVICES" ]; then
|
|
for i in $RESTORESERVICES; do
|
|
if /sbin/service $i status &>/dev/null; then
|
|
echo "/sbin/service $i start" >>/var/run/apm-resume-post
|
|
/sbin/service $i stop &>/dev/null
|
|
fi
|
|
done
|
|
fi
|
|
if [ "$NET_RESTART" = "yes" ] ; then
|
|
/sbin/service network stop
|
|
fi
|
|
[ -n "$NEED_NETFS_START" ] && echo "/sbin/service netfs start" >>/var/run/apm-resume-post
|
|
[ "$PCMCIARESTART" = "yes" ] && {
|
|
/sbin/pccardctl suspend
|
|
/sbin/pccardctl eject
|
|
}
|
|
if [ "$PCMCIAWAIT" = "yes" ]; then
|
|
until [ `LC_ALL=C grep "Socket .: empty" /var/lib/pcmcia/stab|wc -l` = `LC_ALL=C grep "Socket" /var/lib/pcmcia/stab|wc -l` ]; do
|
|
logger "Waiting for pcmcia-device to be removed..."
|
|
sleep 10
|
|
done
|
|
fi
|
|
|
|
while [ -f "$LOCKFILE" ]; do
|
|
RESUMEPID=`cat "$LOCKFILE"`
|
|
logger "Waiting for resume to be finished ($LOCKFILE gives PID $RESUMEPID)..."
|
|
sleep 10
|
|
done
|
|
|
|
# Don't try to restore the terminal or lock X if X isn't running...
|
|
[ -n "$X_RUNNING" ] && {
|
|
[ "$CHANGEVT" != "0" ] && chvt 1
|
|
[ "x$LOCK_X" = "xyes" -o "x$LOCK_X" = "x1" ] && {
|
|
# Lock X, based on patch from Hannu Martikka
|
|
# <Hannu.Martikka@nokia.com>
|
|
# try to get user and display from utmp
|
|
users=`w |tail -n +3 |awk '{print $1, $2}'| LC_ALL=C grep -v '-'| LC_ALL=C grep : | sort -u`
|
|
# check if we found something
|
|
if [ -z $users ]; then
|
|
# get display
|
|
users=`ps ao args | LC_ALL=C grep -e 'bin/X[org]\?' | LC_ALL=C grep -v grep | LC_ALL=C sed 's_^.*\ \(:[0-9][\.[0-9]*]\?\ \).*$_\1_g'`
|
|
#get user, who is logged into system and ran xsession
|
|
users=`ps axfo user,args | LC_ALL=C grep -A 1 -e 'bin/X[org]\?' | LC_ALL=C grep -v grep | LC_ALL=C sed -e '/--/d' -e '/^.*X[org]\+.*$/d' | awk {'print $1'}`" "$users
|
|
fi
|
|
echo $users | \
|
|
while read line; do
|
|
echo $line > /tmp/apm3
|
|
Usern=`echo $line |awk '{print $1}'`
|
|
XDisp=`echo $line |awk '{print $2}'`
|
|
if [ "x`/sbin/pidof kdesktop`" != "x" ]; then
|
|
# We're running KDE - a dcop call is sufficient.
|
|
su $Usern -c "(DISPLAY=$XDisp dcop kdesktop KScreensaverIface 'lock()' &)"
|
|
elif [ "x`/sbin/pidof gnome-screensaver`" != "x" ]; then
|
|
# We're running Gnome
|
|
P_GSS=`/sbin/pidof gnome-screensaver`
|
|
DBUS_SESSION_BUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/$P_GSS/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//'`
|
|
su $Usern -c "(DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS gnome-screensaver-command --lock &)"
|
|
else
|
|
# Otherwise do some ugly stuff.
|
|
if [ -x /usr/bin/xscreensaver ]; then
|
|
# check if xscreensaver is running
|
|
[ -z "`/sbin/pidof xscreensaver`" ] && (su $Usern -c "xscreensaver -display $XDisp -no-splash &") && sleep 2
|
|
su $Usern -c "(xscreensaver-command -display $XDisp -lock &)" &>/dev/null
|
|
elif [ -x /usr/bin/xlock ]; then
|
|
su $Usern -c "(xlock -display $XDisp &)" &>/dev/null
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
}
|
|
|
|
# Unload sound modules if necessary
|
|
if [ "$RESTORESOUND" = "yes" -o "$RESTORESOUNDPROGS" = "yes" ]; then
|
|
rm -rf /var/run/apm-soundmodules
|
|
SOUNDMODULES=`modprobe -c | awk '/^alias snd-card/ { print $3 }'`
|
|
for m in $SOUNDMODULES; do
|
|
if lsmod | LC_ALL=C grep -q "^$m " &>/dev/null; then
|
|
rmmod $m
|
|
echo $m >>/var/run/apm-soundmodules
|
|
fi
|
|
done
|
|
fi
|
|
sync
|
|
|
|
RL=`runlevel | cut -d" " -f2`;
|
|
CROND=`/sbin/service crond status >/dev/null; [ $? -eq 0 ] && echo on || echo off`
|
|
ANACRON=`/sbin/chkconfig --list anacron | sed 's_^.*'$RL':\(on\|off\).*$_\1_g'`
|
|
|
|
echo "$CROND $ANACRON" > /var/run/apm-resume-anacron
|
|
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue "$@"
|
|
|
|
[ -e /var/run/apm-resume-post ] && chmod 0755 /var/run/apm-resume-post
|
|
|
|
[ -n "$DELAYSUSPEND" ] && sleep $DELAYSUSPEND
|
|
|
|
sync
|
|
;;
|
|
|
|
resume)
|
|
# If HDPARM_AT_RESUME is set, the user has a broken disk.
|
|
# We'd better wake it up manually. :/
|
|
if test "x$HDPARM_AT_RESUME" != "x"; then
|
|
for i in /proc/ide/hd*; do
|
|
DRIVE=/dev/`echo $i |sed -e "s,.*/,,g"`
|
|
if test "x`cat $i/media`" = "xdisk"; then
|
|
hdparm -q -S0 $DRIVE
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Read the hardware clock
|
|
if test $CLOCK_SYNC != "no"; then
|
|
hwclock $CLOCK --hctosys
|
|
fi
|
|
|
|
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue-pre ] && /etc/sysconfig/apm-scripts/apmcontinue-pre "$@"
|
|
|
|
# as some displays don't like being waked up from power-off
|
|
# state directly into graphics mode, we can switch to console
|
|
# 1 during suspend and back to console n (where we assume X11
|
|
# is running) after a resume; also the setting of the console
|
|
# beep and the whole sound system can be confused; see
|
|
# /etc/sysconfig/apm for a detailed description of the
|
|
# variables used here.
|
|
|
|
echo $$ >> "$LOCKFILE"
|
|
if [ -n "$TERMINALBEEP" -a "$TERMINALBEEP" != "no" -a "$TERMINALBEEP" != "n" ]; then
|
|
# first we set the beep-length
|
|
for t in 1 2 3 4 5 6 7 8 9; do
|
|
setterm -blength $BEEPLENGTH >/dev/tty$t
|
|
done
|
|
fi
|
|
if [ "$RESTORESOUND" = "yes" -o "$RESTORESOUNDPROGS" = "yes" ]; then
|
|
# Get the sound modules back up...
|
|
# soundon is from the commercial OSS drivers, don't worry
|
|
# if you don't have it.
|
|
[ -x /usr/bin/soundon ] && /usr/bin/soundon
|
|
[ -x /usr/sbin/soundon ] && /usr/sbin/soundon
|
|
[ -x /usr/local/bin/soundon ] && /usr/local/bin/soundon
|
|
[ -x /usr/local/sbin/soundon ] && /usr/local/sbin/soundon
|
|
for m in `cat /var/run/apm-soundmodules`; do
|
|
modprobe $m
|
|
done
|
|
rm -f /var/run/apm-soundmodules
|
|
fi
|
|
if [ "$RESTORESOUNDPROGS" = "yes" ]; then
|
|
# at least we can restart the programs using sound on
|
|
# the right display
|
|
# If you're using the trial version of OSS, you want to add
|
|
#sleep 5
|
|
# here to wait for the trial text
|
|
for n in `cat /var/run/apm-soundprogs`; do
|
|
SOUNDPROG=`echo $n|cut '-d|' -f1`
|
|
SOUNDPID=`echo $n|cut '-d|' -f2`
|
|
SOUNDUSER=`echo $n|cut '-d|' -f3`
|
|
SOUNDDISPLAY=`echo $n|cut '-d|' -f4`
|
|
su --shell="/bin/bash" - "$SOUNDUSER" -c "source /etc/profile;[ -f ~/.bashrc ] && source ~/.bashrc;[ -f ~/.bash_profile ] && source ~/.bash_profile;export DISPLAY="$SOUNDDISPLAY";$SOUNDPROG &"
|
|
logger "apmscript: Program $SOUNDPROG started as user $SOUNDUSER on display $SOUNDDISPLAY."
|
|
done
|
|
rm -f /var/run/apm-soundprogs
|
|
fi
|
|
|
|
# restore X if necessary
|
|
[ "$CHANGEVT" != "0" ] && [ "x`pidof X`" != x ] && chvt "$CHANGEVT"
|
|
|
|
# Restore network and PCMCIA
|
|
if [ "$PCMCIARESTART" = "yes" ] ; then
|
|
/sbin/pccardctl insert
|
|
/sbin/pccardctl resume
|
|
fi
|
|
|
|
[ "$NET_RESTART" = "yes" ] && /sbin/service network start
|
|
|
|
[ "$NETFS_RESTART" = "yes" ] && /etc/rc.d/init.d/netfs start
|
|
|
|
# Restart services if necessary
|
|
if [ -x /var/run/apm-resume-post ]; then
|
|
/var/run/apm-resume-post &>/dev/null
|
|
rm -f /var/run/apm-resume-post
|
|
fi
|
|
|
|
|
|
sync
|
|
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue "$@"
|
|
|
|
# Finally, run anacron to catch up cron stuff we missed...
|
|
# If anacron is installed and we're on AC power or we want
|
|
# to run it even in battery mode.
|
|
if [ -x /usr/sbin/anacron ]; then
|
|
CROND=`cat /var/run/apm-resume-anacron | awk '{ print $1 }'`
|
|
ANACRON=`cat /var/run/apm-resume-anacron | awk '{ print $2 }'`
|
|
if [ "x$CROND" = "xon" -o "x$ANACRON" = "xon" ]; then
|
|
if apm | LC_ALL=C grep -q on-line &>/dev/null; then
|
|
/usr/sbin/anacron -s
|
|
elif test "x$ANACRON_ON_BATTERY" = "xyes"; then
|
|
/usr/sbin/anacron -s
|
|
fi
|
|
fi
|
|
if [ -f /var/run/apm-resume-anacron ]; then
|
|
rm -f /var/run/apm-resume-anacron
|
|
fi
|
|
fi
|
|
|
|
if test "x$HDPARM_AT_RESUME" != "x"; then
|
|
for i in /proc/ide/hd*; do
|
|
DRIVE=/dev/`echo $i |sed -e "s,.*/,,g"`
|
|
if test "x`cat $i/media`" = "xdisk"; then
|
|
hdparm $HDPARM_AT_RESUME $DRIVE
|
|
fi
|
|
done
|
|
fi
|
|
|
|
rm -f "$LOCKFILE"
|
|
;;
|
|
change)
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue-pre ] && /etc/sysconfig/apm-scripts/apmcontinue-pre "$@"
|
|
case $2 in
|
|
power)
|
|
|
|
# Change from battery power to AC power or vice versa.
|
|
if apm | LC_ALL=C grep -q on-line &>/dev/null; then
|
|
if [ "x$LAPTOPMODE" = "xyes" ]; then
|
|
/etc/sysconfig/apm-scripts/laptopmode stop
|
|
fi
|
|
what="start"
|
|
if [ -n "$LOWPOWER_SERVICES" -a -e /var/run/apmd/LOW_POWER ]; then
|
|
rm -f /var/run/apmd/LOW_POWER
|
|
for i in $LOWPOWER_SERVICES; do
|
|
/sbin/service $i start
|
|
done
|
|
fi
|
|
else
|
|
what="stop"
|
|
if [ "x$LAPTOPMODE" = "xyes" ]; then
|
|
/etc/sysconfig/apm-scripts/laptopmode start
|
|
fi
|
|
fi
|
|
if [ -n "$POWER_SERVICES" ]; then
|
|
for i in $POWER_SERVICES; do
|
|
/sbin/service $i $what
|
|
done
|
|
fi
|
|
;;
|
|
battery)
|
|
# Battery low. If you want to be on the safe side, maybe put
|
|
# the harddisk into extreme powersaving, or "apm -s" here.
|
|
if [ -n "$LOWPOWER_SERVICES" ]; then
|
|
touch /var/run/apmd/LOW_POWER
|
|
for i in $LOWPOWER_SERVICES; do
|
|
/sbin/service $i stop
|
|
done
|
|
fi
|
|
;;
|
|
esac
|
|
if [ -f /etc/sysconfig/apm-scripts/apmcontinue ]; then
|
|
. /etc/sysconfig/apm-scripts/apmcontinue $@
|
|
fi
|
|
;;
|
|
start)
|
|
# This occurs at system startup - you usually don't need to do
|
|
# anything here.
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue-pre ] && /etc/sysconfig/apm-scripts/apmcontinue-pre "$@"
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue $@
|
|
;;
|
|
stop)
|
|
# This occurs at system shutdown - you usually don't need to do
|
|
# anything here.
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue-pre ] && /etc/sysconfig/apm-scripts/apmcontinue-pre "$@"
|
|
[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue $@
|
|
;;
|
|
*)
|
|
if [ -f /etc/sysconfig/apm-scripts/apmcontinue ]; then
|
|
. /etc/sysconfig/apm-scripts/apmcontinue "$@"
|
|
else
|
|
logger "FAIL: Wrong parameter \"$PROG\" in apmscript!"
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
exit 0
|