New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to interrupt suspend? #72

Closed
metafarion opened this Issue Aug 7, 2018 · 16 comments

Comments

Projects
None yet
3 participants
@metafarion
Copy link

metafarion commented Aug 7, 2018

I'm trying to make use of the sleep hooks placed in /lib/elogind/system-sleep to prevent the system from suspending under certain conditions, but unlike pm-utils, elogind doesn't seem to care if a pre-suspend script exits with code 1. What is the proper way to conditionally interrupt automatic suspend?

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Aug 10, 2018

elogind doesn't seem to care if a pre-suspend script exits with code 1

But it should. I have to investigate this.

@Yamakuzure Yamakuzure self-assigned this Aug 10, 2018

@metafarion

This comment has been minimized.

Copy link
Author

metafarion commented Aug 10, 2018

I am by no means a master coder, but I've placed a simple script in the system-sleep directory to test this functionality.

#!/bin/bash
echo 'Yes, I ran.' > /tmp/nosleep.txt
exit 1

The text DOES get written, but the system sleeps anyway. I also get the following item in dmesg:

/lib64/elogind/system-sleep/nosleep4u.sh failed with error code 1.

I'm working with elogind-235.2 on a Gentoo system

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Aug 14, 2018

So everything is working just fine except the suspension isn't cancelled. That gives me a good hint about where to start looking, thank you very much!

I have to ask for a bit of patience, though, I am currently migrating towards v239.

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Sep 26, 2018

This is the last issue open before v239 can be released. As some other issues have been fixed, too, this means new service releases for 236 and 238, too.

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Sep 28, 2018

@metafarion : It seems we were both mistaken. I looked up all places where stuff from SYSTEM_SLEEP_PATH and SYSTEM_POWEROFF_PATH gets executed in systemd, and the whole thing is in no way designed to even be able to react on the outcome of what it started.

Or in other words: Both folders are not meant to hold anything that can interrupt a pending suspension or shutdown.

However, I found out in that process, that elogind does not use /lib/elogind/system-shutdown at all.
Strictly speaking it doesn't need to, because the user will have a system that has means to execute something on poweroff. However, I am currently implementing that anyway, for cases where the underlying system does not provide the user with such means.

BUT before you now think that this issue is closed, let me tell you that it is not. I will simply change the type from "Bug" to "Feature Request".
As I am sure that there are settings out there that rely on elogind commencing a suspension even if such a program/script from /lib/elogind/system-sleep fails, this can not be added automatically.

What would be the most elegant way to do so? A configuration option maybe?

@metafarion

This comment has been minimized.

Copy link
Author

metafarion commented Sep 28, 2018

The details of "how" are definitely out of my league. I'm no coder, just a sysadmin looking to be able to configure intelligent automatic suspend on my workstations. Virtually all window managers rely on mouse/keyboard input to keep them awake, and therefore have no respect for other conditions that might constitute "activity". I had previously been putting scripts in /etc/pm/sleep.d provided by pm-utils, which allowed me to define such conditions, but pm-utils is no longer used by many window managers. I don't even remember where I read that /lib/.../system-sleep/ could be used in the same way.

If that's not the right way to do it, I can accept that; it just seemed like the sort of thing that systemd/elogind should be able to do.

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Sep 28, 2018

The details of "how" are definitely out of my league. I'm no coder, just a sysadmin looking to be able to configure intelligent automatic suspend on my workstations.

On the contrary, you are perfect! This feature must clearly be an "opt-in", so how does an actual sysadmin would like to perform such an "opt-in"?
Would an entry in /etc/elogind/logind.conf be alright? What would be a sound name for such an option?

First I thought of an option to loginctl.
But I am on Plasma, and Powerdevil can not (have to look that up tonight) be configured to a specific command, it uses dbus calls. So something other than a configuration option would be useless for Plasma users.

@metafarion

This comment has been minimized.

Copy link
Author

metafarion commented Sep 28, 2018

If I'm understanding you, that would mean you'd have to set "allowsuspendinterrupts = 1" or something in logind.conf and then it would respect your exception scripts. That sounds like a reasonable approach to me.

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Sep 28, 2018

👍

@metafarion

This comment has been minimized.

Copy link
Author

metafarion commented Nov 13, 2018

239.1 just arrived in Portage; I'm gonna try it out as soon as I get a little free time.

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Nov 13, 2018

@metafarion : I have not yet implemented this feature. It is, however, planned for 239.2 which is almost ready.
If everything goes as I hope, the new release will be out by the end of this week.

Yamakuzure added a commit that referenced this issue Nov 20, 2018

Prep v239.2: Add options to make suspend/poweroff interruptable.
/etc/elogind/logind.conf:
The new options AllowPowerOffInterrupts and AllowSuspendInterrupts
were added for users to control whether scripts run at system suspend
or poweroff shall be able to interrupt the ongoing process.

This is achieved by adding callback functions to the calls to
execute_directories() to react on sleep/shutdown script failures.

The infrastructure is not meant to react on failing executables in
the system-sleep or system-shutdown directories, so the only possible
way of doing this was to have the callback to react on the scripts
outputs to STDOUT.

Currently the callback function reacts on lines beginning with either
of the keywords CANCELLED, CRITICAL, ERROR and FAILED. To make it a
bit more convenient, the case of the keywords is ignored.

This feature is considered to be experimental.

Bug: #72
Closes: #72
Signed-Off-By: Sven Eden <sven.eden@prydeworx.com>
@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Nov 20, 2018

@metafarion : I have eventually succeeded in implementing an opt-in feature to interrupt sleep/poweroff.

Unfortunately the infrastructure in systemd is not written to react on exit codes from called executables. Further more everything is executed in parallel. So if you needed to have scripts be called in the exact given order, it wouldn't have worked anyway. At least not as expected.

So I have added a callback function that forces the execution to become sequential, and that reacts on lines printed to STDOUT.
If you need a message to cancel the ongoing suspension/poweroff, just let it print something that begins(!) with either "CANCELLED", "CRITICAL", "ERROR" or "FAILED".

I consider this to be an experimental feature. And I am certain it needs to be refined in the future.#

Hopefully it can do what you need it to do.

@novazur972

This comment has been minimized.

Copy link

novazur972 commented Nov 27, 2018

Sorry but I don't understand how to use this new feature.
I use Gentoo. I have sys-auth/elogind-239.2 installed.
I create a executable file in /lib/elogind/system-sleep with ::
#!/bin/sh
echo "CANCELLED not permitted now"
I got in syslog
Nov 27 01:25:18 medion kernel: <35>[37863.350849] (sd-executor)[22657]: Script failed at line 1: CANCELLED not permitted now
Nov 27 01:25:18 medion kernel: <38>[37863.362775] elogind-daemon[22122]: Suspending system...
and suspend continues.

Where do I make a mistake ?

@Yamakuzure

This comment has been minimized.

Copy link
Collaborator

Yamakuzure commented Nov 27, 2018

To make this work, you have to change /etc/elogind/logind.conf to contain:

[Sleep]
#AllowPowerOffInterrupts=no
AllowSuspendInterrupts=yes

The feature is strictly opt-in, as it is a) experimental and b) shall not change the behavior of already used scripts/executables without the user meaning to do so.
(That's also the reason why I have "hidden" the documentation a bit. It is in the loginctl man page under "Hook directories")

Once this features isn't that experimental any more, I'll spread the documentation out to be more consistent with what's where.

@novazur972

This comment has been minimized.

Copy link

novazur972 commented Nov 27, 2018

@novazur972

This comment has been minimized.

Copy link

novazur972 commented Nov 27, 2018

Works nicely for me.
I just had to add in /lib/elogind/system-sleep a script 000pre_suspend containing :

#!/bin/sh
case "${1}" in
        pre)
                /usr/local/perso/pre_suspend.sh
                [ $? = 1 ] && echo "CANCELLED by inhibit"
                ;;
esac

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment