GNU bug report logs - #57490
UPower ignores ‘critical-power-action’

Previous Next

Package: guix;

Reported by: Ludovic Courtès <ludo <at> gnu.org>

Date: Tue, 30 Aug 2022 16:00:02 UTC

Severity: important

Tags: notabug

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Ludovic Courtès <ludo <at> gnu.org>
To: 57490 <at> debbugs.gnu.org
Subject: bug#57490: UPower ignores ‘critical-power-action’
Date: Wed, 31 Aug 2022 16:46:04 +0200
Ludovic Courtès <ludo <at> gnu.org> skribis:

> Setting ‘hybrid-sleep-state’ to '("mem") doesn’t help though:
> “CanHybridSleep” still returns “na”.  I’m looking at ‘can_sleep_state’
> in elogind without seeing why it doesn’t return true.

Having changed elogind’s “LogLevel” to “debug” with a 1km-long
‘dbus-send’ command I’ll spare you, I got this in /var/log/debug for my
“CanHybridSleep” method call (in QEMU):

--8<---------------cut here---------------start------------->8---
Aug 31 16:01:07 localhost elogind[183]: Got message type=method_call sender=:1.78 destination=org.freedesktop.login1 path=/org/freedesktop/login1 interface=org.freedesktop.login1.Manager member=CanHybridSleep cookie=2 reply_cookie=0 signature=n/a error-name=n/a error-message=n/a
Aug 31 16:01:07 localhost elogind[183]: Sleep mode "mem" is supported by the kernel.
Aug 31 16:01:07 localhost elogind[183]: No possible swap partitions or files suitable for hibernation were found in /proc/swaps.
Aug 31 16:01:07 localhost elogind[183]: Sent message type=method_return sender=n/a destination=:1.78 path=n/a interface=n/a member=n/a cookie=190 reply_cookie=2 signature=s error-name=n/a error-message=n/a
--8<---------------cut here---------------end--------------->8---

Closer inspection of the code confirms what we can guess from the above:
if swap space is missing, ‘can_sleep’ returns false, even if the chosen
sleep state is “mem”:

--8<---------------cut here---------------start------------->8---
static int can_sleep_internal(const char *verb, bool check_allowed, const SleepConfig *sleep_config) {
        bool allow;
        char **modes = NULL, **states = NULL;
        int r;

        assert(STR_IN_SET(verb, "suspend", "hibernate", "hybrid-sleep", "suspend-then-hibernate"));

[...]

#if 0 /// elogind supports setting a suspend mode
        if (!can_sleep_state(states) || !can_sleep_disk(modes))
                return false;
#else // 0
        if (!can_sleep_state(states) ||
            !((strcmp("suspend", verb) && can_sleep_disk(modes)) ||
              (streq("suspend", verb) && can_sleep_mem(modes))))
                return false;
#endif // 0

        if (streq(verb, "suspend"))
                return true;

        if (!enough_swap_for_hibernation())
                return -ENOSPC;

        return true;
}
--8<---------------cut here---------------end--------------->8---

(Specifically, ‘enough_swap_for_hibernation’ returns false when there’s
no space space.)

The caller:

--8<---------------cut here---------------start------------->8---
static int method_can_shutdown_or_sleep(
                Manager *m,
                sd_bus_message *message,
                InhibitWhat w,
                const char *action,
                const char *action_multiple_sessions,
                const char *action_ignore_inhibit,
                const char *sleep_verb,
                sd_bus_error *error) {

[...]

        if (sleep_verb) {
#if 0 /// elogind needs to have the manager being passed
                r = can_sleep(sleep_verb);
#else // 0
                r = can_sleep(m, sleep_verb);
#endif // 0
                if (IN_SET(r,  0, -ENOSPC))
                        return sd_bus_reply_method_return(message, "s", "na");
                if (r < 0)
                        return r;
        }
--8<---------------cut here---------------end--------------->8---

I find it a bit ridiculous: if we’re choosing “mem”, then we shouldn’t
need to check for swap space.

However, given how ‘hybrid-sleep’ is documented¹, it’s not meant to be
implemented by suspend-to-RAM:

  A low-power state where execution of the OS is paused, which might be
  slow to enter, and on complete power loss does not result in lost data
  but might be slower to exit in that case. This mode is called
  suspend-to-both by the kernel.

So, as a conclusion, it would seem that everything here is working as
advertised: no swap, no hybrid-sleep.  (We should probably document that
in the manual.)


One issue remains: UPower should have called elogind’s “PowerOff” method
for ordered shutdown before total power outage, but either that didn’t
happen or elogind didn’t do it right (which is weird, because ‘loginctl
poweroff’ DTRT.)

Thoughts?

Ludo’.

¹ https://man.voidlinux.org/logind.conf.5




This bug report was last modified 2 years and 249 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.