The LCFG Sleep Component
Introduction
The sleep component does two basic things:
- It arranges for the machine to wake up in time to run important cron jobs.
- It sends the machine to sleep (switches it to an ACPI S3 suspend state) when idle.
Both of these tasks are fairly Linux-specific so the component has been designed with only Linux in mind.
The purpose is to save electricity, but at the same time to carry on with essential housekeeping tasks such as running updaterpms.
The component is configurable in various ways - for example you can specify maximum and minimum sleep periods, a minimum period between sleeps, extra tests for idleness, and extra commands to run at sleep or resume time.
For more details see the lcfg-sleep man page or
lcfg-sleep at svn.lcfg.org
. Report bugs at
bugs.lcfg.org
. The component was written by
Chris Cooke
. Feedback would be welcome.
How to Install
#include <lcfg/options/sleep.h>
Then run
updaterpms
and start the sleep component (reboot or
om sleep start
).
A sensible sleep policy is set up out of the box, so the machine will start sleeping when idle and waking for more important cron jobs.
Points to Note
Verbose mode
If
sleep.ng_verbose
is set to true, the component will log enough messages to explain its reasoning to you. This may be a help if you find the machine sleeping less or more than you expected.
Cron jobs
The component ignores cron jobs which are listed in the
cronignores
resource. All remaining cron jobs are considered important, so the component will ensure that the machine is awake to run them. If you find that a machine is waking unnecessarily often, take a look at which cron jobs are and aren't listed in that resource, and set the logging to verbose (mentioned above).
Here's an example. Suppose you wanted the sleep component to ignore the following cron job:
*/5 * * * /bin/blobby /var/log/blobby.log
This could be done by adding a
sleep.cronignores
entry for it.
As the man page explains,
sleep.cronignores
is a list of tags, each of which corresponds to a
sleep.cronignore_tag
resource.
This should be set to some text which matches only the cron job to be ignored. Like so:
/* add a new tag to the list */
!sleep.cronignores mADD(blobby)
/* ignore every cron job containing '/var/log/blobby.log' */
sleep.cronignore_blobby /var/log/blobby.log
X Windows
The sleep component communicates with the GNOME session manager to find out whether and for how long the computer's keyboard and mouse have been idle. By default sleep will not be permitted until the keyboard and mouse have been idle for at least three hours. This setting can be changed using the
xidletime
resource.
If the X session uses a different session manager or none instead of GNOME, the sleep component will not be able to tell whether or not the keyboard and mouse are idle, so will not initiate sleep while an X session is in progress.
Hardware Peculiarities
Sleep can be quite hardware-specific: different models can behave differently. The component can be configured to allow for hardware differences between models, and sometimes this is necessary to get the machine to suspend and resume reliably. If you're having difficulty with unreliable sleep on one particular model,
file a bug
or get in touch.
Extra Config Ideas
You may want to change the default behaviour slightly for your site, or add to the configuration. Here are some examples of extra configuration which you can add if you like.
Keep a log of sleep and resume times
/* Keep a log of when we sleep and wake up */
/* Run this extra command at suspend time */
!sleep.suspendcommands mPREPEND(log)
sleep.suspend_log /bin/echo "`/bin/date` : Suspend" >> /var/lcfg/log/sleep.activity
/* Run this extra command at resume time */
!sleep.resumecommands mEXTRA(log)
sleep.resume_log /bin/echo "`/bin/date` : Resume" >> /var/lcfg/log/sleep.activity
/* Add the new log file to the logrotate list */
sleep.ng_extralogs activity
Send mail on sleep and resume
/* Mail me when you fall asleep and wake up. */
!sleep.suspendcommands mADD(mailme sleep)
sleep.suspend_mailme /bin/grep `/bin/date +%d/%m/%y` /var/lcfg/log/sleep | /bin/grep `/bin/date +%H:%M` | /bin/mail -s "Falling asleep" my@mail.address
/* Add a short delay before sleep to give the mail time to be sent */
sleep.suspend_sleep sleep 5
!sleep.resumecommands mADD(mailme)
sleep.resume_mailme /bin/mail -s "Waking up" my@mail.address < /dev/null
Don't sleep at all
From the profile
To disable the sleep component, just give the
sleep.active
resource a false value:
!sleep.active mSET(false)
From the command line
The command
om sleep disable
is another way of disabling sleep.
om sleep enable
will enable it again.
On one particular model
To disable sleep on one model of machine, add that model's name to the
sleep.blacklist
resource. The model name should be the value of
sysinfo.model
on that machine but with spaces replaced by underscores (e.g.
HP_dc7900
or
Dell_Optiplex_780
).
Don't sleep during working hours
You might want the machine to sleep only outside working hours. Here are a few ideas for ways to do this.
Use the disable and enable methods
/* Wake at 9am Mon-Fri and disable sleep */
!cron.additions mEXTRA(disablesleep)
cron.add_disablesleep 0 9 * * 1-5 usr/bin/om sleep disable
/* Enable sleep at 5pm Mon-Fri */
!cron.additions mEXTRA(enablesleep)
cron.add_enablesleep 0 17 * * 1-5 /usr/bin/om sleep enable
However, remember that the
om sleep disable
command is intended for use by the machine's users, and that automated use of it via LCFG may interfere with this.
Use a file
Create and destroy a file at appropriate times and disable sleep while the file doesn't exist.
/* Sleep if the tmp file exists */
!sleep.extratests mEXTRA(OKtoSleep)
sleep.test_OKtoSleep ( [ -e /var/tmp/OKtoSleep ] )
/* Create tmp file at 6pm Mon-Fri */
!cron.additions mEXTRA(dosleep)
cron.add_dosleep 0 18 * * 1-5 /bin/touch /var/tmp/OKtoSleep
/* Wake at 8am Mon-Fri and remove tmp file */
!cron.additions mEXTRA(OKtoSleep)
cron.add_OKtoSleep 0 8 * * 1-5 /bin/rm -f /var/tmp/OKtoSleep
This method can safely be used in multiple overlapping ways on the same machine: just pick a different filename for each instance.
Use a context
Define a context in which
sleep.active
is false, then run a cron job which switches contexts at the start and end of the working day.
!sleep.active[sleepy=no] mSET(no)
/* Wake at 8.30am */
!cron.additions mADD(notsleepy)
cron.add_notsleepy 30 8 * * 1-5 /usr/bin/context sleepy=no
/* Sleepy at 5.30pm */
!cron.additions mADD(sleepy)
cron.add_sleepy 30 17 * * 1-5 /usr/bin/context sleepy=
This would make
sleep.active
false during the working day (so the sleep component wouldn't do anything) and
true at all other times.
When using contexts be careful not to use them in more than one place - for instance the
sleepy context is already used on Informatics DICE machines.