The following guide lets you suspend to both memory and disk, so you never lose your work if your battery is depleted while suspended. The workflow looks like this:
- Suspend to RAM and create a hibernate image (for example, when you shut your lid)
- If you resume with battery power – you resume from memory
- If you run out of battery while suspended, use the hibernate image to resume
This allows you to never lose your work due to your battery going out.
Here’s how you set it up (example: Fedora 22+)
1) Tell Your Desktop Environment to let systemd handle Power Management
(run as normal user)
Use the xconf-query command below to tell systemd to handle power management.
xfconf-query -c xfce4-power-manager -p \ /xfce4-power-manager/logind-handle-lid-switch -s true
This should work as-is with logind.conf settings below. I don’t run GNOME so this is untested – please comment if this doesn’t work and I’ll update the guide.
You need to tell powerdevil to perform no action when the lid is closed.
After that you need to follow the instructions on comment #5 of this KDE bug report.
Other Windows Managers (Awesome, i3, etc)
This should work out of the box.
2) Make Systemd (logind) Handle Close Lid Events with Hybrid Suspend
(run as root)
Uncomment/Edit the following lines in /etc/systemd/logind.conf
(you need both due to BZ#1039364)
3) Install Systemd target to Lock Screen on Resume
(run as root)
Since systemd is now handling pm-suspend events, it has no way of telling your respective screensaver to lock. We need to utilize a systemd unit file to invoke screensaver on resume. I am going to focus on xscreensaver here as that’s the default for XFCE but see the below notes on other desktop environments.
** GNOME USERS ** Skip this step and see the stack exchange thread on gnome-screensaver via dbus
** KDE USERS ** You can skip this step.
** NOTE ** Change to your non-root username below before pasting the second part.
cat > /etc/systemd/system/screenlock.service << EOF [Unit] Description=Lock the screen on resume from suspend [Service] User=$myuser Environment=DISPLAY=:0 ExecStart=/usr/bin/xscreensaver-command -lock [Install] WantedBy=hybrid-sleep.target EOF
4) Start / Enable Systemd Lockscreen Service
(run as root)
systemctl restart systemd-logind systemctl enable screenlock.service systemctl start screenlock.service
Start the screenlock service, your screen will lock – unlock it once and off you go.
systemctl enable screenlock.service
5) Setup Kernel to use Swap Partition for Hibernate
(run as root)
5A) Obtain the UUID of your swap partition
** NOTE ** You need to take the output of
blkid like below for the next step.
blkid | grep swap
Note your output:
/dev/mapper/fedora-swap: UUID="cc4ed223-58db-43b9-9dd4-34bfabd0043a" TYPE="swap"
5B) Now set a temporary variable for swap UUID
swapuuid="cc4ed223-58db-43b9-9dd4-34bfabd0043a" && echo $swapuuid
5C) Add Resume line into Grub
This next command does a sed in-line edit on the GRUB_CMDLINE_LINUX_DEFAULT portion of grub.conf, use with care. We choose to append after “quiet” because everyone probably has that set.
cp /etc/default/grub /root/grub-backup && sed -i \ "s/quiet/quiet resume=\/dev\/disk\/by-uuid\/$swapuuid/" \ /etc/default/grub
5D) Regenerate your initrd so it contains resume= option
grub2-mkconfig -o /boot/grub2/grub.cfg
At this point you need to reboot to take effect, but everything should work.
Suspend when closing lid will take a few seconds longer than normal since you’re also copying a hibernate image but I think it’s well worth the price.
Is it Working?
If things are working correctly you should see both the lid sleep trigger via Systemd and PM utils saving your hibernated image. On Fedora 22+ a simple journalctl -xr showed this activity.
I have not found a way to quickly test hybrid suspend resume from hibernation without depleting the battery to 1-2% and closing the lid. Google Hangouts or similar activities always kills my battery quickly. It does work for me and others however and saved my work a few times.
example.com systemd-logind: Hibernating and suspending... example.com systemd-logind: Lid closed.
example.com kernel: PM: Wrote 2751856 kbytes in 4.02 seconds (684.54 MB/s) example.com kernel: PM: Image saving done. example.com kernel: PM: Image saving progress: 100% example.com kernel: PM: Image saving progress: 90% example.com kernel: PM: Image saving progress: 80% example.com kernel: PM: Image saving progress: 70% example.com kernel: PM: Image saving progress: 60% example.com kernel: PM: Image saving progress: 50% example.com kernel: PM: Image saving progress: 40% example.com kernel: PM: Image saving progress: 30% example.com kernel: PM: Image saving progress: 20% example.com kernel: PM: Image saving progress: 10% example.com kernel: PM: Image saving progress: 0% example.com kernel: PM: Using 3 thread(s) for compression. : Compressing and saving image data (687964 pages)...
Black Screen on Hibernate Resume
Sometimes you’ll get what appears to be a black screen when your battery is depleted and you resume from an hibernate image. Simply increase your screen brightness. This might just be a bug and you can also use the following entry in /etc/default/grub for a permanent fix:
Using Lots of Memory prior to Hybrid Suspend
One limitation to hibernate is that you cannot be using more physical memory than the size allotted to your swap partition. While this is rare (Swap is usually the amount of your memory or around 8GB) it can happen.
Note, this does not mean that you need a swap partition equal to your total memory, only that your active memory usage shouldn’t exceed your swap partition size. This is usually rare in modern Linux operating systems. Below you can find some instructions to work around this if you run into this issue.
Resizing Swap Partition
Here’s some generic steps to expand your swap partition, stealing storage from your /home. Note: this will NOT work on XFS as there’s no way to shrink partitions, only grow them.
- Reboot into runlevel 1
- Unmount /home
- Resize your /home partition
lvresize --resizefs --size SIZE /dev/fedora/home
Note: SIZE should probably be the current size minus 8GB or whatever you’d need to make swap match your system memory.
- Extend your swap partition
swapoff -a ; lvextend /dev/fedora/swap -l +100%FREE ; swapon -a