rtcidle
rtcidle is a Linux daemon that monitors the user activity
and suspend the computer after a period of inactivity.
Features:
- program the real time clock (RTC) to wake the computer
up two minutes before the next scheduled job in the at or
cron spool;
- do not sleep if certain programs are running; this includes
for example cdrecord (wodim), as cd-writing should not be
interrupted by suspension.
Requires:
- the evdev kernel module, for monitoring USB input devices;
- either APM or ACPI, to suspend;
- either the rtc or the rtc-cmos kernel modules, to program
the wakeup time.
Installation
- get the sources from the
download page;
- download the sources of either vixie cron or
cronie
- change Makefile.local to point to the vixie cron or
cronie source directory, and to the correct at spool directory
- make
- copy rtcidle.conf to /etc; add every
program you don't want to be interrupted by suspension
there;
- if something is to be done before suspension or after
wakeup, add to /etc/rtcidle.before and
/etc/rtcidle.after (this is something you will
probably find out after the first test run, see below)
- update the crontables: if a scheduled program is
expected to take more than a few seconds, launch it using
the enclosed program waiting; that is, convert:
* * * * * /path/to/program arguments
into:
* * * * * /path/to/waiting /path/to/program arguments
or, to enforce a timeout in seconds:
* * * * * /path/to/waiting -t timeout /path/to/program arguments
rtcidle does not program a wakup for programs containing the
string rtcidle-nowakeup anywhere in the command line
- remember to do the same for at jobs
- run rtcidle
The directories cron and at contain
standalone programs to check if the at and cron queues are
checked correctly. Change to these directory and run
make to compile these programs. They are only
needed for testing, not for normal operation.
Customization
Some customization of the /etc files may be
required to make everything run fine through a suspension.
For testing, you can use rtcidle -i, which makes
the system going into suspended mode immediately, without
waiting for user inactivity. This way, you can then
immediately wake the computer up to check whether it is
fully operational after the sleep. Note that the -i
flag only changes the behaviour at the beginning: when the
system wakes up, it again waits for user inactivity before
sleeping again.
rtcidle reads /etc/rtcidle.conf before suspending.
This is a list of program names. If any of these programs is
running, suspension is not entered. At a minimum,
waiting and CD-writing programs should be there.
Other programs you may not want to be interrupted are
backup scripts, etc.
Some kernel modules and/or userspace daemons do not behave
correctly through a suspension. You may want to stop them in
/etc/rtcidle.before and restart them in
/etc/rtcidle.after. If the problem only occur
occasionally (or after a long suspension), you may
alternatively check whether these services still work in
/etc/rtcidle.after and restart them otherwise. For
example, my computer sometimes looses control of the network
interface during a sleep, ending up with a "Disabling IRQ
#12" message. I solved the problem by adding the following
to /etc/rtcidle.after:
ping -c 3 another_local_computer
if [ "$?" != 0 ];
then
echo "Restarting network"
/etc/init.d/network stop
# remove and reload modules on irq 12
rmmod ...
sleep 1
modprobe ...
/etc/init.d/network start
fi
Finding out what to stop and restart (or check and restart)
may require some tries.
If rtcidle.before returns a value different from 0, suspension
is canceled. This return value is the passed to /etc/rtcidle.after,
which is still executed.
Options
The first options are mainly intended for testing. The first two do not run the
rtcidle.before and rtcidle.after scripts, unless the third is given. The first
script is passed the timestamp of the wakeup time, and if it returns a value
different from zero then suspension is canceled. The second script is passed
the return value of the first.
- -a
- test the alarm only: the program should wait ten seconds, then terminate
- -s
- test suspend: the computer should go in suspension, waking up in ten
seconds
- -e
- include execution of /etc/rtcidle.before and /etc/rtcidle.after in the test
- -t seconds
- use this number of seconds instead of ten
- -w time
- wake up at this time, specified as number of seconds since the Epoch
- -i
- immediate: do not wait for user inactivity upon launch; at wakeup, run as
usual
- -d
- do not run as a daemon;
without -i, just show the time of next cron or at job
- -y
- standby instead of suspend
- -Y
- first standby, then suspend (may be useful if the system wakes up
immediately at the first attempt but not at the second)
- -n
- do not check /dev/input/event* for user activity (which requires
kernel module evdev), only the interrupts
Note: rtcidle only tests activity of the input devices (keyboard, mouse,
etc.) on the local machine. As a result, the activity of a user working from a
remote host (e.g., with ssh) will be missed. Run "waiting -i" in background to
avoid suspension, kill it before logging out.
Kernel
A power management module (either apm or acpi) is required, as well as a
real-time clock module (either the old rtc module or the new rtc-cmos). In
order to compile the old rtc module, a patch to drivers/char/Kconfig is
required:
- if RTC_LIB
+ if RTC_CLASS
If the system appears to enter suspension but comes out of it immediately, the
problem may be some component that wakes it up. This can be found out by:
Notes
- not all computers support suspension; not all that do
are able to wake up at a programmed time; before running
rtcidle I suggest to check whether your computer supports
both features: use apmsleep (if you use APM with
the old RTC framework; it is part of the apmd
package) or rtcwake (ACPI with the new RTC
framework, included in util-linux-ng)
to check this.
- If your computer enters the sleep state but then does
not wake up at the programmed time, a last resort is to
program the bios wakeup time using nvram-wakeup;
this is probably the least likely to work, as the wake-up
feature is designed for a different aim; if it works, it has
to be explicitely called in /etc/rtcidle.before;
this script is passed as argument the wakeup time, expressed
as number of seconds since 1/1/1970.
- rtcidle uses the system time, but the program you use
for sleeping may use the hardware clock instead; keep these
two synchronized
- Some kernel versions allow both acpi and apm to be
active at the same time (this is disabled in recent
versions); this configuration didn't work for me: computer
entered suspension but then did not wake up no matter what I
did (pressing a key, pressing the power-on button, etc.)
- If a suspended computer does not wake up upon key press, try
with the power-on button; generally, which events cause
suspension to end are specified in the BIOS configuration.
- The rtc module and the rtc-core/rtc-cmos ones conflict with
each other: if they are both present, the computer may enter
sleep state but not wake up at the right time; note that the rtc
module may be compiled in the kernel instead of as a module, in
which case it does not show up in the result of lsmod;
the old rtc module is disabled in newer kernel, and requires a
kernel patch to be compiled for the x86 architecture
- Some computers may enter sleep state but then come out
immediately; this may be due to a keyboard interrupt (try
sleep 1; apm -s or similar) or to some other event
waking up the computer, such as a network packet (check with
tcpdump -p); which events wake the computer can
usually be configured in the BIOS; the serial port could be
the cause as well: disable in /etc/rtcidle.before and enable
it again in /etc/rtcidle.after
- Some configurations require two calls to enter suspension.
This can be done by passing -Y to rtcidle. It is probably due
to some interrupt waking the system after the first call
- Currently, rtcidle wakes up for every cron or at job,
but do not wait for its completion unless the program is
launched via waiting. This may or may not the
expected behaviour
- The kernel warning in timekeeping.c, function ktime_get,
seems harmless
- Sometimes, the "rtc wakeup" feature has to be disabled
in the BIOS for the rtc alarm to work
- Some versions of cron refuse to read a crontab having
permissions different from 600. However, other versions of
crontab write files with permission 644. The solutions:
- compile rtcidle with the sources of the same version of
the running cron
- in database.c of cron, remove the goto
right after the line that contains the string "BAD FILE
MODE"
sourceforge page