Execute systemd unit before hibernating

2

I am in a situation that is similar to what is described in Hibernation without swap enabled : I would like my swap to be disabled everytime, except for hibernation.

Thus, the idea I had was to create systemd units to be executed right before and after hibernate.target. What I have right now for swapon is:

#swapon.service
[Unit]
Description=Enable swap before hibernate
Before=systemd-hibernate.service

[Service]
User=root
Type=simple
ExecStart=/usr/bin/swapon -a 

[Install]
RequiredBy=hibernate.target

and for swapoff :

#swapoff.service
[Unit]
Description=User resume actions [swapoff]
After=systemd-hibernate.service

[Service]
User=root
Type=simple
ExecStart=/usr/bin/swapoff -a

[Install]
WantedBy=hibernate.target

Thus, if my swap is disabled, running systemctl start hibernate.target has the expected behavior: my computer hibernates and right after hibernation, swap is disabled again as expected.

Nevertheless, running systemctl hibernate or sending an hibernation signal fails: it turns out that swapon.service is not executed before hibernation starts, and I get an error message :

Failed to hibernate system via logind: Sleep verb not supported

What is interesting is that if I manually turn swap on before launching systemctl hibernate, then hibernation successes and swapoff.unit is ran at resume: I can infer that hibernation.target has been executed.

Can anyone help me understand how to force swapon.service to be executed before any hibernation operation begins? Note that I tried to add hibernate.target sleep.target to the After= line of swapon.service, with no effect.

Thanks in advance. :)


EDIT : according to man 8 systemd-hibernate.service, all files that are located in /lib/systemd/system-sleep are executed with specific parameters before and after hibernation, suspend and hybreed-sleep. Thus, I tried to put this script:

#!/bin/sh
#/lib/systemd/system-sleep/manage_swap

if [ $2 = "hibernate" ] || [ $2 = "hybrid-sleep" ]; then
    if [ $1 = "pre" ]; then
            swapon -a
    elif [ $1 = "post" ]; then
            swapoff -a
    else
            exit 1
    fi
elif [ $2 = "suspend" ]; then
    exit 0
else
    exit 1
fi
exit 0

But systemctl hibernate still results in a Sleep verb not supported error… :|


EDIT 2 : I was wondering whether setting swappiness to 0 and enabling swap would be enough to do what I want. If I set swappiness to 0, then I can hibernate, but does this ensure that swap will never be used, even if a program tries to allocate more memory than my quantity of free RAM?

Ie: with swappiness 0, if 15 GB out of 16 are allocated and a program asks for 2 GB, does the kernel allocate 2 GB to the program and swap 1 GB of memory, or does it refuse to satisfy the allocation request?

Valentin Melot

Posted 2018-04-22T20:36:59.650

Reputation: 21

No answers