12

I am trying to save power by switching desktops to suspend mode when they are inactive. But many desktops are also accessed via SSH by their owners. There is a wakeonlan solution deployed to enable owners to switch on the machine, but the problem is that machines will auto-suspend again in 10 minutes, even though the SSH connection is on.

What I am trying to do is to include the active SSH sessions in the "activity" definitions.

The question is can it be done via setting a polkit rule? Can it be done via putting a script that runs before the actual suspend, and aborts it if SSH sessions are found? I need a clean legit way of doing this. If not that, then hacky ways are also welcome.

Current naive hacky solution: edit /usr/sbin/pm-suspend:

#check for SSH sessions, and prevent suspending:
if [ "$(who | grep -cv "(:")" -gt 0 ]; then
    echo "SSH session(s) are on. Not suspending."
    exit 1
fi

This serves the purpose. But I don't know when an update will overwrite the file /usr/sbin/pm-suspend. I also don't know how this will work with other suspend implementations like tuxonice.

  • 2
    May I suggest using grep -cv :0 instead of passing through wc? – terdon Sep 8 '14 at 18:49
  • 1
    Another idea for more elegance: You can drop the invocation of [ if you write if who | grep -qv :0; then (assuming you have a POSIX conforming grep like GNU grep). – David Foerster Sep 30 '14 at 23:53
19

Until Ubuntu 14.10 (Upstart-based)

Have a look at pm-action(8) and search for /etc/pm/sleep.d in section “FILES”. If one of these scripts returns with a non-zero exit status, suspension is prevented.

Updated instructions for clarity:

  1. So create a file /etc/pm/sleep.d/05_ssh_keepawake.

  2. Put a shebang (#!/bin/sh) and the code mentioned in the question in this file.

  3. Set execute permissions on it:

    chmod +x /etc/pm/sleep.d/05_ssh_keepawake
    

Since Ubuntu 15.04 (systemd-based)

systemd doesn’t use pm-utils to manage its power state hooks but has its own infrastructure to the same end. Sleep inhibitor checkers are no longer executed on sleep but must be set by the action that inhibits sleep (see 1).

As such you’d have to add commands to the SSH session log-in and log-out that registers a sleep inhibitor with systemd (e. g. via systemd-inhibit(1)) and later releases the inhibitor. If somebody knows how to hook into SSH log-in and log-out, I’d welcome a comment or edit so that we could work out the relevant steps and commands.

The following section is work in progress – Only use it when you know what you’re doing!

You might be able to write a systemd unit /etc/systemd/system/ssh-inhibt-sleep.service that makes itself a dependency of sleep.target using the RequiredBy option. If your new unit fails (with a non-zero exit status from its invoked process), it will make sleep.target and thus the subsequent sleep action.

[Unit]
Description=Check for running SSH sessions and, if any, inhibit sleep
Before=sleep.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c '! who | grep -qv :0'`

[Install]
RequiredBy=sleep.target

As always you need to activate systemd units for them to take effect:

sudo systemctl enable ssh-inhibt-sleep.service

For more info see systemd.unit(5) and systemd.service(5).

  • this doesn't seem to work in 18.04. Is this no longer the solution? – Michael Jarret Sep 13 at 23:43
  • 1
    @MichaelJarret: Indeed. I updated my question with some info on the situation with systemd. – David Foerster Sep 15 at 13:23
  • I found the following while trying to sort this out yesterday, but couldn't modify the previous script to do the job here – Michael Jarret Sep 15 at 15:00
  • I can't edit my comment, but also this seems relevant – Michael Jarret Sep 15 at 15:07
  • 1
    @MichaelJarret: I had another idea that you could try. See the update to my answer. – David Foerster Sep 17 at 2:25

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.