Linux sleep: how to wake with a key press or mouse click

Several years ago we started sending the Linux machines in our student labs to sleep when idle, to save power. We configured them to check carefully before deciding whether or not they were idle enough to sleep, and also to wake themselves up in time to run important cron jobs. Machines could also be woken manually when needed.
This was fine, except for one problem: the only way to wake the machine manually was to press its power button. That’s not how most people try to wake a sleeping machine: it’s far more natural to press a key on its keyboard, or click one of its mouse buttons.
We’ve had a user education campaign which seems to have successfully taught most users of the labs how to wake a machine up, but there’s still a persistent minority of people who don’t understand, or maybe get impatient, and who sometimes end up doing something rash such as forcing a sleeping machine to reboot; so we get a steady flow of broken machines.
To solve this problem I’ve been trying for a long time to find out how to enable wake from sleep with a key press or mouse click. I’ve even been trying to find out if it was actually possible with Linux.
I have finally succeeded! It is possible, I’ve done it, and the solution will shortly be rolled out to our student lab machines. Here’s how:
The key file to manipulate is called /proc/acpi/wakeup. This file is a list of devices which can be used to wake the machine from sleep – and whether or not they’re currently allowed to. A status of “disabled” against a device means that it won’t wake the machine, while “enabled” means that it will. Here are the default contents of /proc/acpi/wakeup on my desktop HP dc7900 running Fedora 13:
Device S-state Status Sysfs node PCI0 S4 *disabled no-bus:pci0000:00 COM1 S4 *disabled pnp:00:07 PEG1 S4 *disabled pci:0000:00:01.0 PEG2 S4 *disabled IGBE S4 *disabled pci:0000:00:19.0 PCX1 S4 *disabled pci:0000:00:1c.0 PCX2 S4 *disabled PCX5 S4 *disabled pci:0000:00:1c.4 PCX6 S4 *disabled HUB S4 *disabled pci:0000:00:1e.0 USB1 S3 *disabled pci:0000:00:1d.0 USB2 S3 *disabled pci:0000:00:1d.1 USB3 S3 *disabled pci:0000:00:1d.2 USB4 S3 *disabled pci:0000:00:1a.0 USB5 S3 *disabled pci:0000:00:1a.1 USB6 S3 *disabled pci:0000:00:1a.2 EUS1 S3 *disabled pci:0000:00:1d.7 EUS2 S3 *disabled pci:0000:00:1a.7 PBTN S4 *enabled
The only device that’s allowed to wake the machine is PBTN – the power button.
To enable a device, just echo its device code to the file, like this:
# echo USB3 > /proc/acpi/wakeup
A quick look at /proc/acpi/wakeup confirms that USB3 is now enabled for wakeup:
USB1 S3 *disabled pci:0000:00:1d.0 USB2 S3 *disabled pci:0000:00:1d.1 USB3 S3 *enabled pci:0000:00:1d.2 USB4 S3 *disabled pci:0000:00:1a.0 USB5 S3 *disabled pci:0000:00:1a.1
I wanted to make it possible for the keyboard and the mouse to wake the machine, so I used this method to “enable” all of the USB devices.
Note that echoing the device code to the file toggles the device’s status: a disabled device is enabled, and an enabled one is disabled.
Note also that if writing a Perl script to do this, you’ll have to open /proc/acpi/wakeup for writing, echo a device code, then close the file, separately for each device you want to enable.
Here’s a bit of Perl which will enable wakeup on all USB devices, if you run it from an account which has permission to write to /proc/acpi/wakeup:
#!/usr/bin/perl
my $wakeup = "/proc/acpi/wakeup";
my @disabled;
my $device;
# Let's take a look at the wakeup file
open(INPUT, "< $wakeup")
or die "Couldn't open $wakeup for reading: $!\n";
# Remember the names of each disabled USB device
while () {
if (/^(USB\d+).*disabled/) {
push(@disabled, $1);
print "Added $1 to disabled list\n";
}
}
# We've finished reading from the file
close(INPUT);
# Enable each device on our list
foreach $device (@disabled) {
print "$device is disabled! Enabling it now.\n";
open(OUTPUT, "> $wakeup")
or die "Couldn't open $wakeup for writing: $!\n";
print OUTPUT $device;_
or die "Couldn't echo $device to $wakeup: $!\n";
close(OUTPUT);
}
One Response
Leave a Reply
You must be logged in to post a comment.
[...] How to wake up SuSe 12.1 64bit from sleep by clicking mouse orvia keyboard This might help: http://blog.inf.ed.ac.uk/chris/2011/…r-mouse-click/ Reply With Quote « Previous Thread | Next Thread [...]
How to wake up SuSe 12.1 64bit from sleep by clicking mouse or via keyboard
August 1, 2012 at 1:32 am