One feature desktop Linux has been lacking out of the box is hybrid-suspend, supported as of Kernel versions 3.6+.

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+).

NOTE: You don’t need to have your swap partition space match your physical memory, you only need enough swap space to suspend your current memory usage footprint (usually a lot less).

1) Tell Your Desktop Environment to let systemd handle Power Management

(run as normal user)

XFCE

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

Note: In later versions of XFCE (4.13 or 4.14+) this xconf-query setting may not exist, in this case you’ll want to create it first.

xfconf-query -c xfce4-power-manager -p /logind-handle-lid-switch -n -t bool -s true

Now you can re-run the original command to set it.

You can query what the value is at any time by removing the -s true

xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/logind-handle-lid-switch true

GNOME

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.

KDE/Plasma

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.

Update 2017-10: KDE now has an option to set lid close event to hybrid suspend in later versions.

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)



HandleLidSwitch=hybrid-sleep HandleLidSwitchDocked=hybrid-sleep

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.

myuser=username

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[1078]: Hibernating and suspending... example.com systemd-logind[1078]: 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:

video.use_native_backlight=0

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