2

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

4 Answers 4

4

Inspired by @AdamLett's answer I implemented the 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
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/)

2
  • 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, 2019 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, 2019 at 12:30
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
1
  • This works for immediate hibernation but not for suspend-then-hibernate.
    – Alex Ball
    Nov 29, 2019 at 22:09
0

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

File name: /etc/systemd/system/systemd-hybrid-sleep.service.d/override.conf

[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

[Edit: Note use of -a hybrid-sleep and s2both.]

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.

1
  • 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, 2019 at 22:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .