Hibernate from suspend if battery gets low

How can I make the laptop wake up from suspend once in a while to check battery level, and if it’s low; hibernate?

Last night I suspended the laptop with AC connected, then we got a power outage. When I woke up the battery was 0%, and all my work in progress was gone. If the suspend mode included some kind of battery level monitor, the system would have hibernated rather than running out of battery. (This has been default behavior in windows since 98.)

This should actually be default behaviour (maybe set for 4 hours if I remember).

Linux != Windows

Always save your work before leaving the system unattended.

Hibernating AKA suspend-to-disk may overly wear yout ssd’s and is often something you need to configure manually - if your system supports it at all.

You could look into your power configuration.

Suffice your system supports this (do note the possible extra wear on your ssd)

  • Find the On battery section
  • On suspend - choose Hybrid Sleep
1 Like

Which I knew how to save… All documents were saved, but I had 30ish pdf’s open, scrolled down to whatever section I needed to look at, 20ish documents documents/spreadsheets/presentations open with various information selected to show how far I’d got in gathering the information, 9 instances of firefox open, logged in as different users, in progress of filling in various forms based on the information gathered from the documents mentioned above.

And at this subject windows works out of the box, while I have not been able to make manjaro work, even though I’ve tried several times over the 5 years I’ve been using it.

Don’t compare apples and oranges.

Look for the mentioned sleep option - that implies that adequate swap is available and the system is configured for hibernation.

I booted my XFCE laptop

  • Search for Power Manager
  • On the General tab
    • When battery button is pressed → Hybrid Sleep
  • On System tab
    • configure critical power to hibernate

//Note:
Manjaro is not a consumer system - in the sense of configuring everything to everybody’s liking - which of course is an impossible task.

All my years with Linux - hibernation has always been a hit or miss - that is how it is :man_shrugging: - I have learned to live with it :slight_smile:

Perhaps this helps:

Clearly it’s not. I suspect the functionality might be a part of the suspend-then-hibernate function. But I can’t figure out how the set that up. It’s not an option in xfce power manager. The guides I find are either old or for other distros. Some suggest enable suspend-then-hibernate.service, but no such service exists. (I do find suspend-then-hibernate.target.) Some suggest creating symlink in /etc to suspend-then-hibernate.service manually, but I can’t find the service file in my system.
Is there a guide available the applies for manjaro?

(I do have hibernate working. If laptop runs out of battery when powered on (not suspended) it goes to hibernate, and resumes without any issue.)

And if I get the suspend-then-hibernate to work, does it do what I’m looking for? I’m not looking for a timer to hibernate after X minutes of suspend. I’m only looking for hibernate if battery goes low.

Perhaps

  • hybrid sleep is defined as save state to memory and disk
    • if not simultanously, at least in the same process
  • suspend then hibernate is a little different
    • it suspends to ram
    • if not restored within a short period
      • it writes to disk
      • power off

But you also need to consider the threshold for Critical battery - as it was the lack of battery power that caused your system to fully shutdown without saving state.

2 Likes

Is “check battery level while suspended” a part of suspend-then-hibernate?
If not, is there any other path to look at to find this functionality?

See this from my comment above

Check the grub config - to verify if the system is configured for hibernation - look for the resume=UUID= as this will tell if it configured

grep -e "GRUB_CMDLINE_LINUX" /etc/default/grub

I don’t have “hybrid sleep” as an option in power manager. My options are “do nothing”, “suspend”, “hibernate”, “shutdown”, “ask”.

As I said, hibernate works perfectly while laptop is powered on (not suspended). I have working suspend, working hibernate, working shutdown. But not working suspend-then-hibernate.
I cannot locate any suspend-then-hibernate.service file anywhere on my system. I do find suspend-then-hibernate.target

If suspend-then-hibernate does not run battery level check, it shouldn’t be impossible to modify it’s behavior a bit. If all suspend-then-hibernate does is to set a wake up timer to run a script that hibernates, there must be something to that script that, before it hibernates performs a check if the wake-up was caused by timer or user interaction. It shouldn’t be impossible to modify that script to do something like this:

if wakeup caused by user interaction
   then resume to normal operation
   else
      if battery level < threshold && AC not connected
         then hibernate
         else suspend-then-hibernate
     fi
fi

Basically this logic should wake up the pc and check if battery level still is above a threshold. If there is still plenty of battery, reset the suspend-then-hibernate timer and put the laptop back into suspend. If it’s not plenty of battery, run hibernate. If the hibernate delay timer is set shorter than the time expected for battery to drain from threshold to 0% during suspend, this should ensure battery not running out while suspended.

Is it not in

/usr/lib/systemd/system/

Because:

$ cat /usr/lib/systemd/system/systemd-suspend-then-hibernate.service
#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  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=System Suspend then Hibernate
Documentation=man:systemd-suspend-then-hibernate.service(8)
DefaultDependencies=no
Requires=sleep.target
After=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/systemd-sleep suspend-then-hibernate

If the options is not available to you - it is possible your system does not support it.

In powermanager on the system tab → can you set critical - default to 10% if I recall correct - to hibernate?

1 Like

Is it worth checking the swap?

swapon --show
  1. I use a swapfile, so to work this out I would first disable that…
  2. Set for 16 GiB RAM, 1G count 16 (be patient, takes a couple of minutes).
sudo swapoff -a
sudo dd if=/dev/zero of=/swapfile bs=1G count=16
sudo mkswap /swapfile
sudo swapon /swapfile
grep SwapTotal /proc/meminfo
systemctl hybrid-sleep

How does this work for you?

At least then you’d have manual control if you’re worried about battery to do hybrid sleep.

There it was! Thanks!

2 Likes

I can. And hibernate works perfectly.
I can also run

# systemctl suspend-then-hibernate

Then it does suspend.

But I cannot get service status:

# systemctl status suspend-then-hibernate 
Unit suspend-then-hibernate.service could not be found.
1 Like

I think swap is not the issue, as hibernate works.

The reason I use suspend rather than hibernate when the charger is connected is to reduce write operations to the ssd. Hybrid sleep does not seem useful to my needs.

Hybrid sleep is available is available in the shutdown / restart / suspend /… dialog box. But it is not available in the power manager settings dialog.

Suspend-then-hibernate is not available any other place than command line.

This should help:

https://docs.xfce.org/xfce/xfce4-power-manager/faq

Maybe, but I don’t understand how.

I did this:

$ xfce4-power-manager -q
$ xfce4-power-manager --no-daemon --debug > debug-power-manager.log

$ grep hiber debug-power-manager.log 
TRACE[xfpm-xfconf.c:169] xfpm_xfconf_load(): Using default configuration for lock-screen-suspend-hibernate
TRACE[xfpm-xfconf.c:169] xfpm_xfconf_load(): Using default configuration for hibernate-button-action
TRACE[xfpm-xfconf.c:169] xfpm_xfconf_load(): Using default configuration for logind-handle-hibernate-key
TRACE[xfpm-polkit.c:345] xfpm_polkit_check_auth_intern(): polkit request: (('unix-process', {'pid': <uint32 5703>, 'start-time': <uint64 1262114>}), 'org.freedesktop.login1.hibernate', @a{ss} {}, uint32 0, '')
TRACE[xfpm-polkit.c:366] xfpm_polkit_check_auth_intern(): Action=org.freedesktop.login1.hibernate is authorized=TRUE
TRACE[xfpm-polkit.c:345] xfpm_polkit_check_auth_intern(): polkit request: (('unix-process', {'pid': <uint32 5703>, 'start-time': <uint64 1262114>}), 'org.freedesktop.login1.hibernate', @a{ss} {}, uint32 0, '')
TRACE[xfpm-polkit.c:366] xfpm_polkit_check_auth_intern(): Action=org.freedesktop.login1.hibernate is authorized=TRUE
TRACE[xfpm-manager.c:647] xfpm_manager_inhibit_sleep_systemd(): Inhibiting systemd sleep: handle-power-key:handle-suspend-key:handle-hibernate-key:handle-lid-switch

Doesn’t look like useful information to me. The most useful is probably that suspend-then-hibernate is not mentioned anywhere

Note:

I have never done this before. It is based on information I’ve learned from the internet the last less than 24 hours.

I take no responsibility if something goes wrong or doesn’t work as expected.

It seems you’ll have to first have logind handle the lid open/close event:

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

Then you’ll have to allow hibernate-then-suspend in systemd. Edit '/etc/systemd/sleep.conf` and uncomment the necessary values:

sudo nano /etc/systemd/sleep.conf
#  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.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file (or a copy of it placed in
# /etc/ if the original file is shipped in /usr/), or by creating "drop-ins" in
# the /etc/systemd/sleep.conf.d/ directory. The latter is generally
# recommended. Defaults can be restored by simply deleting the main
# configuration file and all drop-ins located in /etc/.
#
# Use 'systemd-analyze cat-config systemd/sleep.conf' to display the full config.
#
# See systemd-sleep.conf(5) for details.

[Sleep]
#AllowSuspend=yes
#AllowHibernation=yes
AllowSuspendThenHibernate=yes
#AllowHybridSleep=yes
#SuspendState=mem standby freeze
#HibernateMode=platform shutdown
#MemorySleepMode=
#HibernateDelaySec=
#SuspendEstimationSec=60min

From How to configure suspend-then-hibernate properly? - #3 by kagetora13 - Newbie - EndeavourOS :

(D) Configure Suspend-Then-Hibernate

Once it’s possible to enter & wake from the hibernation state, we can then transition to the suspend-then-hibernate step. For this, we have to configure systemd to handle entering hibernation from the suspend state after a given period.

(D1) Set a delay in the sleep.conf, which will inform systemd how long to stay in the suspend state before hibernating.

(a) Add the following to the “/etc/systemd/sleep.conf” file.

[Sleep]
AllowSuspendThenHibernate=yes
HibernateState=disk
#Suspend then Hibernate after 15 min
HibernateDelaySec=15min

(D2) Inform systemd the behavior of the power switch, lid closing, and suspend state.

(a) Add the following to “/etc/systemd/logind.conf”

[Login]
HandlePowerKey=suspend-then-hibernate
HandleLidSwitch=suspend-then-hibernate

I don’t know if that will help, but perhaps it does.

1 Like