Power Saving for the Workstation, Part 2

By: A. Lizard
Tuesday, July 31, 2007 08:42:48 PM EST
URL: http://www.linuxplanet.com/linuxplanet/tutorials/6408/1/

Automatically Suspending to RAM

In part 1, you were shown how to set up hibernate and modify the configuration scripts to make it possible to suspend your desktop to RAM. In part 2, you'll step through how to implement your changes.

In the KDE Control Center, drill down through Peripherals, Display, to the Power Saving tab. Check the Enable Power Saving checkbox and set time for "Switch Off Monitor." In a non-KDE environment, find "Display Power Management." That's what automatically turns off DPMS when the system is idling.

When your monitor is shut off via DPMS by whatever method, your computer will go into suspend if you install this script:

sleep-detector-1.sh

#!/bin/bash
# put this in /usr/local/bin/sleep-detector-1.sh
# put sh /usr/local/bin/sleep-detector.sh
# default display on current host
# moved xset +dpms to icon
# try to make sure that monitor sessions don't multiply indefinitely
# note: the echo statements are for debugging when running in a terminal.
# the touch statements are also for debug. 
until [ "$STATUS" == "DPMS is Disabled" ]; do
DISPLAY=:0.0

STATUS=`xset -display $DISPLAY -q | grep -o 'DPMS is Disabled'`
if [ "$STATUS" == "DPMS is Disabled" ]
then 
echo "end suspend monitor loop - DPMS Disabled"
touch /home/username/suspend/dpms-disabled
exit 
fi

STATUS=`xset -display $DISPLAY -q | grep -o 'DPMS is Enabled'`
if [ "$STATUS" == "DPMS is Enabled" ]
then echo "SUSPEND script - DPMS working - continue monitoring" 
touch /home/username/suspend/dpms-enabled
fi

STATUS=`xset -display $DISPLAY -q | grep -o 'Monitor is On'`
if [ "$STATUS" == "Monitor is On" ]
then echo "Monitor is On - script"
touch /home/username/suspend/monitor-is-on
fi

STATUS=`xset -display $DISPLAY -q | grep -o 'Monitor is Off'`
if [ "$STATUS" == "Monitor is Off" ]
then touch /home/username/suspend/monitor-is-off
echo "Monitor is Off - script"
hibernate-ram --force
echo "hibernate-ram terminated"
fi

STATUS=`xset -display $DISPLAY -q | grep -o 'Monitor is in Suspend'`
if [ "$STATUS" == "Monitor is in Suspend" ]
then echo "Monitor is in Suspend - script"
touch /home/username/suspend/monitor-is-suspend
hibernate-ram --force
fi

STATUS=`xset -display $DISPLAY -q | grep -o 'Monitor is in Standby'`
if [ "$STATUS" == "Monitor is in Standby" ]
then echo "Monitor is in Standby-script"
touch /home/username/suspend/monitor-is-standby
hibernate-ram --force
fi
sleep 30
done
exit

The touch statements are there for diagnostic purposes, they aren't necessary to the normal operation of the script, but the touch statements will tell you where the script crashed by simply checking to see what is in /home/username/suspend. Clear the directory before running the script if you're debugging.

Turning Suspend On, Off From the Desktop

Turning Suspend On, Off From the Desktop

What if you're doing a long download or any other lengthy unattended process which you do NOT want interrupted via suspend? Since the suspend sleep-detector.sh script for monitoring checks for DPMS being enabled, turning off DPMS will abort the script.

Figures 1 and 2 provide some icons for you to use. Right-click each of the icon images (48x48) and save them somewhere you can find them later.

For KDE users, right-click your desktop screen and Create New > Link to Application. On the General tab, click the icon displayed to open the Select Icon dialog box. Select the Other icons option and then Browse. Locate where you saved Figure 2 (suspend-off.png), and then click Open. Back in the General tab, enter Suspend Off in the Link to Application text box. In the Application tab, set the Command value to xset -dpms.

Repeat the process for the Suspend On icon, only this time enter this line in the Application tab's Command field:

xset +dpms;sh /usr/local/bin/sleep-detector-1.sh

Also in the Application tab, click the Advanced Features button and enter the User value as root.

To start suspend-to-RAM, click the Suspend On icon. This only works from root because the actual hibernate script does a "is the user root?" check, which I haven't figured out how to bypass, and the script doesn't run stably out of rc.local. You can run it manually from a script, if you do, you can tell if it's on by:

$ ps -A

Look for sleep, sh, you might see xset.

To shut it down, click the Suspend Off icon. Root access is not required, because while sleep-detector-1.sh runs as root, xset does not. If you want to revert to normal operation, you have to restart DPMS before restarting the script.

On my box and configuration, suspend takes about 30 seconds, returning from suspend takes about 20 seconds.

There was an intermittent problem with this, as the desktop didn't go into screensaver sometimes and then didn't go into suspend mode. It seems to have been fixed by removing the sh sleep-detector-1.sh command from rc.local, which is why the suspend monitor has to be started manually.

The workaround below may help you with problems that you might have that I didn't. Xterm is used here because the display might not be visible from the usual console window, and xterm works directly with X Windows.

Open an X Terminal via menu, with the Start > System > Xterm menu command. Or, from a regular terminal enter:

# xterm

From within Xterm

# xset -dpms
# xset +dpms
# /usr/local/bin/sleep-detector-1.sh

Do You Have a UPS?

Use hibernate instead of /sbin/shutdown in the regular UPS shutdown script from Network UPS Tools. Instead of just shutting down your applications and OS in an orderly fashion, take up exactly where you left off when the power went down. Just start the shutdown in plenty of time before your UPS runs out of power.

Open /etc/hibernate/upsmon.conf with text editor as root (original command commented out via #):

# SHUTDOWNCMD "/sbin/shutdown -h +0"
SHUTDOWNCMD "/usr/sbin/hibernate –force"

Try it without –force first. If you didn't need it for hibernate-ram, you probably won't need it here.

"If you have a UPS that did not come with working Linux software, visit this HOWTO.

Alternate Suspend Methods

If the preceeding method doesn't work for you, and you have the right kernel functions built in, installing the programs (uswsusp/swsusp) via Debian aptitude might work, but watch carefully what aptitude or apt-get might tell you about packages it wants to remove.

If the method described here fails, Tux-on-Ice (formerly called suspend2, name changeover still in progress) provides a special kernel module to facilitate suspend/hibernate. You'll have to rebuild the kernel to make it work. For more information, go to the site, they have extensive documentation and a mailing list. There will also be a replacement suspend (PM_SUSPEND) built into kernel versions 2.6.21+, this may work better for you.

Note that there are two competing developer groups and suspend/hibernate implementations at this point. The biggest difference for the user is that the suspend software from the Tux-on-ice has to be separately downloaded and compiled by the user into a custom kernel. SOFTWARE_SUSPEND and soon, PM_SUSPEND are built-in.

Unsolved Problems

I'd still like to know why other than the hibernate I installed from the Debian etch/lenny repositories, my attempt to install anything that has to do with ACPI, seems to want to gut my current system, as can be seen below. Aptitude seems to want to satisfy dependencies by ripping out approximately the same set of programs every time I tried installing an ACPI-related program.

All the ACPI-related programs I've tried except the Debian repository version of hibernate, including a more current copy of hibernate, swsusp (suspends without requiring APM or ACPI support), uswsusp (userspace software suspend), athcool (power-off for Attlon CPUs), kpowersave, or even sleepd (a non-hibernate method for putting the computer into a sleep state) have the following results:

terrarium:/var/log# aptitude install sleepd
[snip]
The following packages are unused and will be REMOVED:
  arj comerr-dev gtkhtml3.8 hspell libacl1-dev 
libart-2.0-dev libarts1-dev libasound2-dev libaspell-dev 
libattr1-dev libaudio-dev libaudiofile-dev 
libavahi-client-dev libavahi-common-dev libavahi-core4 
libavahi-qt3-dev libavcodec0d libavformat0d libbrlapi1 
libbz2-dev libcamel1.2-8 libcupsys2-dev libdbus-1-dev 
libebook1.2-5 libecal1.2-6 libedata-cal1.2-5 
libedataserver1.2-7 libedataserverui1.2-6 
libegroupwise1.2-10 libesd0-dev  libexchange-storage1.2-1 
libfam-dev libflac++5 libflac7  libgail-gnome-module 
libgcrypt11-dev libgksu1.2-0 libgksuui1.0-1  libgl1-mesa-dev
 libglu1-mesa-dev libgnutls-dev libgpg-error-dev libgpod0 
 libgtkhtml3.8-15 libgucharmap4 libidn11-dev 
libjack0.100.0-dev  libjasper-1.701-dev libjpeg62-dev 
libkadm55 libkexif1 libkrb5-dev liblcms1-dev libloudmouth1-0
 liblua50-dev liblualib50-dev libmad0-dev libmng-dev 
libnautilus-burn3 libogg-dev liboggflac3 libopencdk8-dev 
libopenexr-dev libpcre3-dev libpcrecpp0 libpoppler0c2 
libpoppler0c2-glib   libpoppler0c2-qt libpopt-dev 
libpostproc0d libqt3-compat-headers   libqt3-headers 
libqt3-mt-dev libsasl2-dev libssl-dev libtasn1-3-dev  
 libtiff4-dev libtiffxx0c2 libtunepimp-bin libtunepimp3 libvorbis-dev  
 libxklavier10 libxml2-dev libxmu-dev 
libxmu-headers libxslt1-dev    libxt-dev lua50 
mesa-common-dev mkisofs qt3-dev-tools tetex-base   
tetex-bin

The following NEW packages will be installed:
  sleepd
0 packages upgraded, 1 newly installed, 93 to remove and 0 not upgraded.
Need to get 18.3kB of archives. After unpacking 73.1MB will be freed.
Do you want to continue? [Y/n/?] n
Abort.
terrarium:/var/log#

Since I didn't want my OS gutted, deciding that I didn't want to continue wasn't difficult. However, this may not be a problem for you, I've got a lot of things installed here starting with KDE that you might not. So if what I recommend here doesn't work, check into the alternatives I mentioned. The hibernate configuration files will probably have to be restored to defaults or otherwise modified to make them work.

Copyright Jupitermedia Corp. All Rights Reserved.