1

Configure suspend-then-hibernate to use uswsusp

I'm using uswsusp for suspend to RAM and suspend to disk (hibernate) via systemd. Therefore I've adjusted /etc/systemd/system/systemd-suspend.service.d/override.conf and /etc/systemd/system/systemd-hibernate.service.d/override.conf.

Suspend and hibernate works find using uswsusp. My problem is that systemd still uses the kernel's swsusp for suspend-then-hibernate. This, of course, results in a failure while restoring from hibernate because of the wrong mkinitcpio hook.

I assume that it is necessary to adjust the systemd configuration for suspend-then-hibernate (/etc/systemd/system/systemd-suspend-then-hibernate.service.d/override.conf) as well. But I've no idea what it must look like. Is it even possible or would it require uswsusp to support suspend-then-hibernate?

I'm on arch linux. This question is somehow related to this one.

/etc/systemd/system/systemd-suspend.service.d/override.conf:

[Service]
ExecStart=
ExecStartPre=-/usr/bin/run-parts -v -a pre /usr/lib/systemd/system-sleep
ExecStart=/usr/bin/s2ram
ExecStartPost=-/usr/bin/run-parts -v --reverse -a post /usr/lib/systemd/system-sleep

/etc/systemd/system/systemd-hibernate.service.d/override.conf:

[Service]
ExecStart=
ExecStartPre=-/usr/bin/run-parts -v -a pre /usr/lib/systemd/system-sleep
ExecStart=/usr/bin/s2disk
ExecStartPost=-/usr/bin/run-parts -v --reverse -a post /usr/lib/systemd/system-sleep
2

I was looking to do the same thing and got stuck at the same point as you and didn't know how to configure it. In the end I found a work-around which worked for me in the answer here: https://superuser.com/a/1153147

It doesn't use the actual systemd configuration for suspend-then-hibernate but instead uses a normal suspend but then runs a script after your chosen delay which wakes the system and puts it into hibernation

(Note that for me on Ubuntu 18.04 the correct path was /lib/systemd/system-sleep/ rather than /usr/lib/systemd/system-sleep/)

  • Placing a script in /usr/lib/systemd/system-sleep/ will effect all systemd-sleep modes. This would hack the suspend-then-hibernate feature into the normal suspend mode. But I wanted to use the modes independently from each other. Inspired by your answer and the linked one I created a solution that better fits my needs. – jojoob Jan 7 at 9:38
  • Indeed, I personally had no use for the normal suspend mode so I took the lazy route but yours is a better general solution and perhaps I'll change over to it for more flexibility in the future – Adam Lett Jan 7 at 12:30
1

Inspired by @AdamLett's answer I implemented to following solution/workaround.

I edited the systemd-suspend-then-hibernate service to use a custom script I have created at /usr/local/bin/s2ram-then-s2disk.sh

#!/bin/bash
# Custom suspend-then-hibernate script using uswsusp.

# Edit the "HibernateDelaySec" variable below to set the number
# of seconds to remain in suspend before hibernate.
HibernateDelaySec=1200

curtime=$(date +%s)
lock=/tmp/rtchibernate.lock

# Suspending... Record current time and set a wake up timer.
echo "$curtime" > $lock
rtcwake -m no -s $HibernateDelaySec
s2ram

# The systen is now suspended.

# Coming out of sleep...
curtime=$(date +%s)
sustime=`cat $lock`
rm $lock

# Did we wake up due to the rtc timer above?
if [ $(($curtime - $sustime)) -ge $HibernateDelaySec ]; then
    # Hibernate (suspend to disk)...
    s2disk
else
    # Cancel the rtc timer and wake up normally.
    rtcwake -m disable
fi

/etc/systemd/system/systemd-suspend-then-hibernate.service.d/override.conf

[Service]
ExecStart=
ExecStartPre=-/usr/bin/run-parts -v -a pre /usr/lib/systemd/system-sleep
ExecStart=/usr/local/bin/s2ram-then-s2disk.sh
ExecStartPost=-/usr/bin/run-parts -v --reverse -a post /usr/lib/systemd/system-sleep
1

I ran into the answer for this, but don't have the URL (working on home system at the time). You need to add "-a hibernate" after the "-a pre" and "-a post" ExecStart lines. I also had to change the path for system-sleep since I am using Ubuntu as the previous post mentions.

Example:

[Service] 
ExecStart=
ExecStartPre=-/usr/bin/run-parts -v -a pre -a hibernate /lib/systemd/system-sleep
ExecStart=/usr/bin/s2disk
ExecStartPost=-/usr/bin/run-parts -v --reverse -a post -a hibernate /lib/systemd/system-sleep
0

Create the following systemd service for hybrid-sleep (suspend then hibernate).

File name: systemd-hybrid-sleep.service

[Service] ExecStart= ExecStartPre=-/usr/bin/run-parts -v -a pre -a hybrid-sleep /lib/systemd/system-sleep ExecStart=/usr/bin/s2both ExecStartPost=-/usr/bin/run-parts -v --reverse -a post -a hybrid-sleep /lib/systemd/system-sleep

I added this on my system last night and left my machine in this state as a test. A short test proved that suspend worked, but I wanted to let my battery drain to test the restore from hibernate tonight.

  • hybrid-sleep (or s2both as it is called by uswsusp) is not the same as suspend-then-hibernate. hybrid-sleep writes the state to disk and to ram at the same tim. This is useful for quick resume (from suspend) but if the system runs out of battery a resume from hibernate is still possible. suspend-then-hibernate instead suspends the system and if it is not resumed by the user after a specified time it will hibernate. I use this to have quick suspend/resume but to make sure the system is encrypted (I use full disk encryption) if I did not use it for a certain time. – jojoob Feb 1 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.