You are not logged in.

#1 2019-02-20 06:52:09

MilanKnizek
Member
Registered: 2005-12-13
Posts: 88

[SOLVED] How to interrupt a running systemd suspend?

Hi,

I would like to utilise the GDM auto suspend functionality, however only if I am able to add some futher checks - e.g. to prevent suspend when there is an active SSH login.

Back when pm-utils were used, I could have added a script to /etc/pm/sleep.d/ directory, which - when exiting with error - would have stopped the suspend process.

PM utils are not used anymore and systemd suspend seems to be in place. I read the Arch Wiki on Power Management, and it does not mention how to interrupt the already running suspend process - the 'hooks' seem to lack such a functionality.

Is there a workaround how to interrupt a suspend process?

Or is the only way to disable GDM suspend on 'idle' and write my own cron scripts to do various checks (no local logins, no SSH logins, etc.) and trigger systemd suspend?

Thanks for any hints,

Milan

Last edited by MilanKnizek (2019-02-20 19:47:05)


--
Milan Knizek
http://knizek.net

Offline

#2 2019-02-20 09:29:48

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: [SOLVED] How to interrupt a running systemd suspend?

This article here is mentioned in the man-page named "systemd-sleep":

https://www.freedesktop.org/wiki/Softwa … d/inhibit/

Doing "apropos inhibit" I could also find an interesting tool named "systemd-inhibit" that comes with systemd:

systemd-inhibit may be used to execute a program with a shutdown, sleep, or idle inhibitor lock taken. The lock will be acquired before the specified command line is executed and released afterwards.

That 'systemd-sleep' man-page also mentions a location for scripts "/usr/lib/systemd/system-sleep/", but it can't be used for this problem here. I tried putting a simple script there that just does "exit 1", and this does not stop the suspend. It only causes a message to be logged in the journal:

systemd[1]: Reached target Sleep.
systemd[1]: Starting Suspend...
[15110]: /usr/lib/systemd/system-sleep/test.sh failed with exit status 1.
systemd-sleep[15109]: Suspending system...

Offline

#3 2019-02-20 16:16:24

MilanKnizek
Member
Registered: 2005-12-13
Posts: 88

Re: [SOLVED] How to interrupt a running systemd suspend?

Hm, so the logic with systemd-login is different - if an app wants to block suspend, it has to set the block beforehand even that there is no "suspend" action taking place. I would prefer the easier pre-suspend check.

Anyway, at the moment I plan to check only for an active SSH logon (not really a mere connection, but an active terminal), so I assume I could use SSHRC to create a suspend inhibit block. (systemd-login supposedly releases stale blocks, let's see if it really does once the SSH connections terminate.)

I'll do some tests and report back, if I succeed.


--
Milan Knizek
http://knizek.net

Offline

#4 2019-02-20 19:42:26

MilanKnizek
Member
Registered: 2005-12-13
Posts: 88

Re: [SOLVED] How to interrupt a running systemd suspend?

I got it working, although it still seems to me a bit clumsy. On SSH login, systemd-inhibit runs a loop checking the SSH_TTY existence. Once systemd-inhibit finishes, the "delay" block for suspend is removed.

$ cat /etc/ssh/sshrc
#!/bin/bash

# MK: As per 'man sshd 8'
#     This file is run only when $HOME/.ssh/rc does not exists
#     or when it is forbidden by 'PermitUserRc no' sshd_config option
#     If xauth is needed, it must be added here, too.

export tmp_f="/tmp/mk_systemd-inhibit-suspend.log" # The file will be cleaned on reboot

echo "New SSH logon at $SSH_TTY on $(date)" >> "$tmp_f"

# MK: systemd-inhibit must be detached otherwise SSH does not continue the logon process
#     unprivileged user may use only "delay" lock, "block" is not possible.
#     Set InhibitDelayMaxSec=XXX in /etc/systemd/logind.conf and restart the daemon:
#       $ sudo systemctl restart systemd-logind.service

if [ ! -z ${SSH_TTY} ]; then
  nohup \
    systemd-inhibit --what="sleep" --who="sshd" --why="No sleep due to $SSH_TTY" --mode="delay" \
    /usr/local/bin/mk_systemd-inhibit-sleep-ssh.sh \
    & >> "$tmp_f"
fi
$ cat /usr/local/bin/mk_systemd-inhibit-sleep-ssh.sh
#!/bin/bash

# MK: A helper for /etc/ssh/sshrc

export LANG=C

while who | grep --quiet " $(echo ${SSH_TTY} | cut -d "/" -f 3- ) "; do
  echo "$(date): ${SSH_TTY} is active" >> "$tmp_f"
  sleep 60
done

# SSH logon ended, exiting...

It is not the greatest solution - when I am logged in remotely in GUI session (xrdp -> XVnc), the suspend action by GDM triggers a screen lock in my remote session every 20 minutes :-) However, the suspend is not really completed, so far so good.

Last edited by MilanKnizek (2019-02-22 08:55:56)


--
Milan Knizek
http://knizek.net

Offline

#5 2020-03-10 17:30:11

knovoselic
Member
Registered: 2018-12-13
Posts: 16

Re: [SOLVED] How to interrupt a running systemd suspend?

Here's my solution, hope it helps someone:

Edit SSH config file, add the following line:

$ vim /etc/ssh/sshd_config
...
ForceCommand /usr/bin/inhibit-sleep-for-ssh
...

You can add it for all connections or use Match keyword to apply it to specific user(s)/group(s).

The script looks like this:

$ vim /usr/bin/inhibit-sleep-for-ssh
#!/bin/bash
sudo systemd-inhibit --what sleep --why "Do not sleep while $SSH_TTY session is active" sleep infinity &
INHIBIT_PID=$!

if [ -z "$SSH_ORIGINAL_COMMAND" ]; then
  $SHELL
else
  $SSH_ORIGINAL_COMMAND
fi
sudo kill $INHIBIT_PID

The only drawback is that your user needs to be able to run systemd-inhibit as a super user, for my use-case that was acceptable. The last "sudo kill" command is not needed - looks like the sleep and lock are automatically terminated when the SSH session terminates, but I've added it just in case.

Offline

Board footer

Powered by FluxBB