28 Feb 2017
Setting up suspend to hibernate in Fedora
Important Note: When you upgrade to the current version Fedora 26 (which right now - July 2017 - ships with systemd 233), you might run into a regression which prevents any units depending on the suspend one not to be executed. The same applies to any scripts and programs in /usr/lib/systemd/system-sleep/ which are supposed to be executed before and after one of the power save states is activates. As a consequence, suspend-to-hibernate is not working on Fedora as long as this issue is not fixed in upstream systemd and rolled out to Fedora :-(
Computers usually support two major energy saving modes: Suspend and Hibernate. Suspend basically shuts down all hardware components except your RAM (because it will preserve your current state there). Hibernate instead will write the current RAM contents to disk and then turn off everything. Both modes have their pro’s and con’s: Suspend is much faster, i.e. when you close your laptop lid you usually want the session to be back as soon as you open the lid again. So during the day you probably want to use this mode mostly. Hibernate on the other side has a greater potential for saving energy, as the system is basically shut down completely and restored to exactly this point later when you turn it on again. Hence, this mode is ideal when you seldom use your device (e.g. when you have to prepare for some events in your professional life and hence don’t have too much free time to spend with your private hardware ;-) ). Besides the energy and time components, there is another point that kicks in when using full disk encryption: Using suspend is less secure, because sensitive data is stored unencrypted in the still powered on RAM. Especially when you often take your laptop with you or in case of a laptop you use for your company, you surely don’t want someone else to gain access to your data. The good news is: You actually don’t have to decide for one or the other ;-) While it is not available out of the box, you can easily enable a mode where your laptop goes into suspend mode when you close your lid and later - say after one or two hours of not being used - it goes to hibernate, increasing energy saving and protecting your data in case you use full disk encryption. So, here is how to enable this “suspend-to-hibernate” mode in Fedora:
Enable Hibernate
You read right. If you have not already done so, you first have to enable Hibernate on your freshly installed Fedora box. This is due to the installer does not add the required parameters to the kernel boot arguments. Fortunately, this is a well documented task to do.
Enable Suspend-to-Hibernate
This as well is quite easy, even though not documented for the case of Fedora. However, our friends over at Arch Linux have summed up everything nicely in their Wiki and Forums: First, you need to create a new file /etc/systemd/system/suspend-to-hibernate.service
with the following contents:
[Unit]
Description=Delayed hibernation trigger
Documentation=https://bbs.archlinux.org/viewtopic.php?pid=1420279#p1420279
Documentation=https://wiki.archlinux.org/index.php/Power_management
Before=suspend.target
Conflicts=hibernate.target hybrid-suspend.target
StopWhenUnneeded=true
[Service]
Type=oneshot
RemainAfterExit=yes
Environment="WAKEALARM=/sys/class/rtc/rtc0/wakealarm"
# Important: Here you can set the delay after when we go to hibernate:
Environment="SLEEPLENGTH=+2hour"
ExecStart=-/usr/bin/sh -c 'echo -n "alarm set for "; date +%%s -d$SLEEPLENGTH | tee $WAKEALARM'
ExecStop=-/usr/bin/sh -c '\
alarm=$(cat $WAKEALARM); \
now=$(date +%%s); \
if \[ -z "$alarm" \] || \[ "$now" -ge "$alarm" \]; then \
echo "hibernate triggered"; \
systemctl hibernate; \
else \
echo "normal wakeup"; \
fi; \
echo 0 > $WAKEALARM; \
'
[Install]
WantedBy=sleep.target
Basically, you can ignore most stuff if you don’t care. The most interesting part is the line after the Important: comment: It determines the time the computer shall remain in suspend before going to hibernate. The default two hours are a decent choice for most use cases. In theory, you could try to enable this new service by running
sudo systemctl enable suspend-to-hibernate
However, some updates in systemd obviously changed something that prevents the service from working flawlessly with the suspend service delivered with systemd itself. The good thing is, that this is easily fixed. Run the following
sudo cp /usr/lib/systemd/system/suspend.target /etc/systemd/system/
To create a local copy of the suspend target definition and edit it to include the part after the line marked with Important: below (keep everything else as it is to be as near at the default definition as possible):
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Suspend
Documentation=man:systemd.special(7)
DefaultDependencies=no
Requires=systemd-suspend.service
After=systemd-suspend.service
StopWhenUnneeded=yes
# Important: Add a dependency to our suspend-to-hibernate service:
Requires=suspend-to-hibernate.service
That’s it. If you’ve not already done so enable the suspend-to-hibernate service as shown above using systemctl enable
.
Thank You For Reading
I am a software/firmware developer, working in Dresden, Germany. In my free time, I spent some time on developing apps, presenting some interesting findings here in my blog.
Comments