I was having trouble using suspend, hibernate and hybrid sleep functionality on Ubuntu 17.04 using Gnome 3.24. The troubles started immediately after installing the uswsusp package:
$ apt-get install uswsusp
I was hopeful and typed systemctl hibernate
, but the system got stuck on
“Snapshotting system”.
After a hard shutdown, the system was no longer bootable. It would only boot in
recovery after waiting for 5 minutes on /scripts/local-premount
.
These issues were caused by having an encrypted swap file, but soon other issues surfaced, rooted in shaky support for hibernation in both Ubuntu and Gnome.
So, here’s a guide to how I set up hibernation.
Set up a non-encrypted swap
First, set up a non-encrypted swap file dedicated to system hibernation.
$ fallocate -l 8g /swapfile
$ chmod 0600 /swapfile
$ mkswap /swapfile
This creates a swap file of 8 gigabytes. Create a swap file that has enough size to hold the hibernated system snapshot (the safest bet is to create a swap file with the same size as the amount of available memory). We will only enable the swap when we want to hibernate.
Note that this wastes some hard drive space when not hibernating; an alternative is to give the encrypted swap a passphrase — but that would require you to enter the passphrase each boot.
Install uswsusp
$ apt-get install uswsusp
After installing, the package configuration should start. If it doesn’t, type:
$ dpkg-reconfigure -pmedium uswsusp
Select the swap file we just created as the location it should store the system snapshot. The configuration will ask you whether you want to encrypt the system snapshot; I recommend you do.
At this point the following should hibernate your system and turn it off. Once you turn it back on, it should restore the state from the system snapshot:
$ swapon /swapfile
$ s2disk
If it works, great! What remains is the integration of this with your system and Gnome.
Create wrapper scripts
We only want to enable the swap for hibernation and hybrid sleep, and disable the swap afterwards. We create scripts that enable the swap, hibernate/suspend the system, and disable the swap when we resume.
Create the following two scripts in a new directory /opt/sleepscripts
.
# /opt/sleepscripts/s2disk.sh:
$ swapon /swapfile
$ s2disk
$ swapoff /swapfile
# /opt/sleepscripts/s2both.sh:
$ swapon /swapfile
$ s2both
$ swapoff /swapfile
Note that s2disk
will create a snapshot and hibernate the system, whereas
s2both
will create a snapshot and suspend the system — only if the system
powers off (e.g. because the battery runs out) will the snapshot be used to
resume, i.e. it’s a hybrid sleep.
Configure systemd
Copy the default systemd hibernate and hybrid sleep service configurations:
$ cp /lib/systemd/system/systemd-hibernate.service /etc/systemd/system/
$ cp /lib/systemd/system/systemd-hybrid-sleep.service /etc/systemd/system/
Edit /etc/systemd/system/systemd-hibernate.service
, change the service section to:
[Service]
Type=oneshot
ExecStart=/bin/bash /opt/sleepscripts/s2disk.sh
Similarly, edit /etc/systemd/system/systemd-hybrid-sleep.service:
[Service]
Type=oneshot
ExecStart=/bin/bash /opt/sleepscripts/s2both.sh
Reload systemd
. Hibernating through systemd should now work:
systemctl daemon-reload
systemctl hibernate
Support laptop lid events
Open the Gnome tweak tool. Go to the power setting, and set the laptop to suspend when the laptop lid is closed. For some reason, this automatically performs a hybrid sleep. The other options (hibernate, shutdown, etc.) don’t work at all for me.
Add a hibernate icon to the Gnome status menu
Install the Hibernate Status Button Gnome extension. Enable it in the Gnome tweak tool. Next, create the following file:
/var/lib/polkit-1/localauthority/50-local.d/com.ubuntu.enable-hibernate.pkla
and save the following in it:
[Re-enable hibernate by default in upower]
Identity=unix-user:*
Action=org.freedesktop.upower.hibernate
ResultActive=yes
[Re-enable hibernate by default in logind]
Identity=unix-user:*
Action=org.freedesktop.login1.hibernate;org.freedesktop.login1.handle-hibernate-key;org.freedesktop.login1;org.freedesktop.login1.hibernate-multiple-sessions;org.freedesktop.login1.hibernate-ignore-inhibit
ResultActive=yes
After rebooting, your status menu should look as in the image. Clicking on the hibernate button will now hibernate your system.
"posts/2017-hibernation-and-hybrid-sleep-on-ubuntu-17-04-gnome-3-24/image.png"