Is it possible to make Ubuntu go into Hibernate state from Suspend, aka "Suspend Sedation"?
What I am looking for is this:
When I close the lid, the laptop is put into Suspend. Then, after a pre-determined time (even if the battery is going strong) if I still don't use it, it should put itself into a Hibernate to save battery power.
For example, my laptop is set up to go into a Suspend once I close the lid. If then I don't use it for entire day, the battery goes flat, because even in suspend mode the hardware still consumes a small amount of power, and the battery eventually discharges. What I want is to be able to tell Ubuntu that even if it is suspended, it still needs to go into Hibernate after some hours of inactivity.
Windows can do that. Ubuntu can be programmed to go into Standby or Hibernate on timer, but not both.
In Ubuntu 18.04 and newer it much more easier. In systemd is available a new mode suspend-then-hibernate. To start using this function you need to create a file /etc/systemd/sleep.conf with the next content:
Then you can test it by command:
you can edit
HibernateDelaySec
to reduce delay to hibernate.If all works fine you can change Lid Close Action, to do it you need to edit the file /etc/systemd/logind.conf
You need to find option
HandleLidSwitch=
, uncomment it and change toHandleLidSwitch=suspend-then-hibernate
. Then you need to restart systemd-logind service (warning! you user session will be restarted) by the next command:That's all! Now you can use this nice function.
The solution to this is simple. First, upon suspend and resume, the pm-suspend program executes a series of scripts in
/etc/pm/sleep.d
and/usr/lib/pm-utils/sleep.d
. So my solution is to add a script that does the following:Here is a script that does this. Name it
0000rtchibernate
and place it in the/etc/pm/sleep.d
directory (the 0000 is important, so that the script executes first on suspend, and last on resume).Hopefully this code comes through on this message board (this is my first post here).
Edit the timeout value
autohibernate=7200
at the top, to however many seconds you which to sleep before going into hibernation. The current value above is 2 hours. Note, that you laptop WILL wake up at that time for a few seconds, while it is executing the hibernate function.So if you plan on putting your laptop in a case, don't suspend, but hibernate instead. Otherwise your laptop could overheat in esp. if it is in a tight fitting slip case (although it will only be on for a few seconds to a minute).
I've been using this method for the past couple of days, so far it has been successful (and saved me from a dead battery this afternoon). Enjoy.
For other Linux distributions that use
systemd
and newer Ubuntu versions this should still work if you place the script in/usr/lib/systemd/system-sleep
instead of/etc/pm/sleep.d
. Also, replace the/usr/sbin/pm-hibernate
command withsystemctl hibernate
.To explain how this works (this is similar to Windows) in simple words: the machine doesn't wake up from standby when battery gets low to be able to save the machine state to the swap partition, it saves everything to the swap partition immediately on standby, and when the battery runs out, it will recover from that by loading the state from the swap partition (as it would do in case you hibernated).
AFAIK linux will/should use hybrid standby/hibernate instead of "normal" standby if it knows that it works for your hardware. It's also possible that this is disabled currently because of too many bugs or something... ;)
If you like experimenting, maybe you can see if you can get any good results with pm-suspend-hybrid.
If the following says you're lucky, then in theory hybrid suspend is supported on your system:
You may be interested in s2both. It is provided by the package
uswsusp
in Ubuntu 10.10. It suspends to disk, but instead of shutting down the system instead puts it in S3, which is the power mode usually associated with the "Suspend" option in Ubuntu. pm-suspend-hybrid is another tool that purports to do the same thing.To make this automated on lid close, take a look at the following guide which allows you to run an arbitrary script when a lid event is caught:
http://ubuntuforums.org/showthread.php?t=1076486
If you happen to have a ThinkPad, the manpage for
tpctl
makes reference to an argument,--pm-sedation-hibernate-from-suspend-timer
, which seems to provide the feature you're looking for. I would caution you against trying this on non-ThinkPad hardware.For reference, I looked through the manpage for hibernate.conf; it didn't seem to have any relevant options but might be worth a second reading.
Ubuntu 16.04 - from suspend/sleep into hibernate after a pre-determined time
It seems that on Ubuntu 16.04 things are a little different, so steps I took to make it work were:
Make sure hibernate is working as expected when running
Copy the original
suspend.target
file:Then edit the file
/etc/systemd/system/suspend.target
and add the line:to the
[Unit]
section of that file.Create the file
/etc/systemd/system/delayed-hibernation.service
with the following content:/etc/delayed-hibernation.conf
for the script with the following content:Create the script which will actually does the hard work.
Create file
/usr/local/bin/delayed-hibernation.sh
with the content:It took me quite a lot until writing this script based on other replies in this thread, things I found on the internet like https://bbs.archlinux.org/viewtopic.php?pid=1554259
My version of the script tries to deal with many problems like go into suspend again if hibernate was not successful but do not wake again after the pre-determined time over and over.
Final step I assume would be to just execute
to make sure new service/configurations are being used.
To check the service log, you can use:
or for a complete log of the service use:
A normal log I get from the running service is:
So This would be it, I hope it really helps someone since I spent days trying to figure out the right combination of configurations and script versions to make this handy feature work.
Just in case something goes wrong during
pm-hibernate
i'd rather put the computer to suspend than let it run. So you can use:Here's an updated version of Derek Pressnall's answer that works with systemd and includes Eliah Kagan's suggestion, just drop it in /usr/lib/systemd/system-sleep/delayed_hibernation.sh and make it executable:
Here is my recipe (tested it on two notebooks Ubuntu 16.04):
Put this script whereever you like (I put it to root,
/syspend.sh
) and make it executable (chmod +x /suspend.sh
)Then create systemd target:
# touch /etc/systemd/system/suspend-to-sleep.target
Paste this content:Then enable it
# systemctl enable suspend-to-sleep.target
.I've faced an issue on the one of notebooks: closing lid didn't trigger this target. This was due to xfce4-power-manager. There are two ways to workaround this problem. The first one is to edit
/etc/systemd/logind.conf
file and replaceHandleLidSwitch=ignore
withHandleLidSwitch=suspend
. But it will be systemwide, so I just added symlink to my script# ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate
Another more common workaround you can use
hybrid-sleep
(like the Mac OS does). If your computer supports hibernation, you can use this feature:That command should suspend and send to disk (hibernate) the computer. After some time the computer will turn off (when turning on, it will use the hibernation files to wake up).
p.s.: I know it's not exactly what the OP posted, but it's fairly close
Don't forget to chmod +x that file, make it executable.
There's another solution without rtcwake, using wakealarm in /sys/class/rtc/rtc0. Make use obsolete code in pm-functions (/usr/lib/pm-utils) after the comments #since the kernel does not directly support ... , ('cos the current kernel (after 3.6 something) does directly support). Revert that code and put in do_suspend() part instead of do_suspend_hybrid().
Obsolete code (suspend then hibernate when suspend_hybrid is called):
Recommended. Even easier to use uswsusp while the same time maximize the benefit of s2both i.e. s2both when suspend. Put the reverted code in do_suspend() part of uswsusp module (/usr/lib/pm-utils/module.d).
Reverted code (suspend_hybrid when suspend is called):
With uswsusp, we can see the progress of suspend/hibernate and the reverse process displayed in text, even we can abort it by pressing backspace. Without uswsusp, suspend/hibernate just appear-disappear annoyingly, especially when wakealarm is triggered and execute hibernate (s2disk in uswsusp). Set the period of sleep before hibernate in the usual place on pm-functions file.
Here's the uswsusp mod: (remember, this module is called from pm-functions so the inserted variables are the same)