2

Currently I have settings in GNOME Power Management to setup timeout after which my system will suspend.

I want to add an additional timeout for the system to shutdown after some period of inactivity during its suspend.

So it will looks like that:

  1. Suspend after 15 minutes of inactivity.
  2. Shutdown after 12 hours of inactivity during suspend.
anlar
  • 4,165
  • I am new to Linux and if there is a way, I don't know. Sorry. But you can create a Python (or whatever) script to enter the proper command in the terminal. So it will automatically do what you want. – Mani Apr 21 '21 at 10:26
  • AFAIK Gnome uses systemd for the actual handling of all sleep states. If Gnome's own UI does not provide a setting for what you wish, you might need to setup a configuration at the systemd level. Would you be willing to? And in any case, what you want to achieve requires a hardware clock able (and enabled) to wake up the system from suspend. Does your system have a /sys/class/rtc/rtc0/wakealarm file? – LL3 Apr 25 '21 at 13:16
  • @LL3 I'm fine with any non-UI methods. Yes, my system have /sys/class/rtc/rtc0/wakealarm file. – anlar Apr 26 '21 at 11:55

3 Answers3

2

If hibernation is fine, use systemd's suspend-then-hibernate which will hibernate a suspended system after a timeout. In sleep.conf set HibernateDelaySec= to your desired value.

Source official systemd manual.


EDIT:

For using hibernation, Fedora needs to be reconfigured in order to enable it.

  1. First of all you'll need a swap partition at least the size of your RAM - hibernation means saving the contents of RAM to the swap partition and thus the size is self-explaining. Usually this would mean shrinking your current partition and creating a new swap partition.

Guides for this are around here:

Do not forget to add the swap partition it in /etc/fstab and activate the usage via swapon -a. Example fstab-entry:

# swap:
UUID=abc123-this-is-a-uuid none swap sw 0 0
  1. Add the resume option to the initramfs. Fedora uses dracut for this, and I'll follow this guide.
  • create a file /etc/dracut.conf.d/resume.conf with the line add_dracutmodules+=" resume " (make sure not to forget the spaces)
  • run dracut -f
  1. Add the swap partition to grub, so it knows from where to resume:
  • in /etc/default/grub search for the line GRUB_CMDLINE_LINUX=
  • add resume=UUID=abc123-this-is-a-uuid (i.e. the swap UUID)
  • update grub: grub2-mkconfig -o /boot/grub2/grub.cfg or grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
  1. I don't think this is necessary, but can't hurt. Activate hibernation in /etc/systemd/sleep.conf:

    [Sleep]
    AllowHibernation=yes
    HibernateMode=shutdown
    
  2. Reboot and test hibernation: open some windows, run systemctl hibernate. It should shut down and the windows resume after you reboot.

FelixJN
  • 13,566
  • 1
    I don't think Fedora supports hibernation. :( https://pagure.io/fedora-workstation/blob/master/f/hibernationstatus.md – rickhg12hs Apr 17 '21 at 21:45
  • @rickhg12hs not by default, but you may enable it. Prerequisite is a swap partition of at least the size of the RAM. – FelixJN Apr 25 '21 at 16:53
2

Fedora uses systemd as the system's overall manager, and Gnome by default relays Sleep/Standby/Suspend operations to systemd.

Assuming that by "Suspend" we mean "Suspend-to-RAM" (as opposed to "-to-Disk") and that by "Shutdown" we mean literally "powering off the machine", and also assuming a machine fitted with a hardware clock that supports system wakeup and thus enabled in the BIOS/EFI as an accepted wakeup device, it is possible to configure systemd via some carefully crafted "Units" (as in systemd parlance) so as to implement a self-poweroff after some specified time spent in "Suspend" state, while also not involving hibernation (nor any dedicated swap/partitions) at all during the transitions.

These custom systemd Units essentially arm a wakeup [Timer] immediately before entering the "Suspend" state, and once the alarm triggers the system is woken up to execute the custom [Service] associated with the [Timer]. Such [Service] of course performs the power-off operation. Should the machine be woken up through some other means instead, hence the timer had not elapsed yet, the self-poweroff is not performed and gets cancelled altogether.

The systemd Units I have come up with to implement such logic are quite a few, so here is a shell script that installs all of them. The script needs to be run only once, as "root" (via sudo is ok), in order to set things up in the system-wide (not the user-wide) configuration of systemd:

#!/bin/sh --

sysd=/etc/systemd/system

set -e

mkdir -p "$sysd/systemd-suspend.service.d"

cat > "$sysd/systemd-suspend.service.d/99-trigger-system-back-after-suspend.conf" <<'EOF' [Service] ExecStopPost=-/bin/systemctl --no-block start system-is-back-after-suspend.target EOF

cat > "$sysd/cancel-self-poweroff.service" <<'EOF' [Unit] Description=Cancel self-poweroff after suspend After=system-is-back-after-suspend.target Conflicts=self-poweroff.timer

[Service] Type=oneshot ExecStart=/bin/rm -f /run/systemd/system/self-poweroff.timer

[Install] WantedBy=system-is-back-after-suspend.target EOF

cat > "$sysd/self-poweroff.service" <<'EOF' [Unit] Description=Actual self-poweroff after suspend After=suspend.target Before=system-is-back-after-suspend.target RefuseManualStart=true

[Service] Type=oneshot ExecStart=/bin/systemctl --no-block poweroff

Uncomment the following line while commenting out the above line for testing.

#ExecStart=/bin/echo poweroff

Note the echoed string goes to systemd journal log.

Do a systemctl daemon-reload after modifying this file.

EOF

cat > "$sysd/schedule-self-poweroff.service" <<'EOF' [Unit] Description=Schedulation of self-poweroff after some time spent in suspend state Before=systemd-suspend.service Requisite=suspend.target

[Service] Type=oneshot EnvironmentFile=/etc/self-poweroff.conf ExecStartPre=/bin/sh -c 'printf -- %%s\\n "[Timer]" "Persistent=yes" "OnCalendar=$(date -d "now + ${MY_SUSPEND_TIMEOUT}" "+%%Y-%%m-%%d %%H:%%M:%%S")" "AccuracySec=1s" "WakeSystem=yes" >| /run/systemd/system/self-poweroff.timer' ExecStart=/bin/systemctl start self-poweroff.timer

On systemd 237 onwards (Fedora 28 onwards) you may uncomment the line below while commenting out the above ExecStart and ExecStartPre lines

#ExecStart=/bin/sh -c 'systemd-run --on-calendar="$(date -d "now + ${MY_SUSPEND_TIMEOUT}" "+%%Y-%%m-%%d %%H:%%M:%%S")" --timer-property=AccuracySec=1s --timer-property=WakeSystem=yes --timer-property=Persistent=yes --unit=self-poweroff.service'

Do a systemctl daemon-reload after modifying this file.

[Install] WantedBy=suspend.target EOF

cat > "$sysd/system-is-back-after-suspend.target" <<'EOF' [Unit] Description=Synchronization point for self-poweroff after suspend DefaultDependencies=no After=suspend.target StopWhenUnneeded=yes EOF

cat > /etc/self-poweroff.conf <<'EOF' MY_SUSPEND_TIMEOUT=12 hours EOF

systemctl enable schedule-self-poweroff.service cancel-self-poweroff.service systemctl daemon-reload

Once the script has been run to install the Units, you can alter the timeout in the dedicated /etc/self-poweroff.conf file, which is also created by the script. There you set the MY_SUSPEND_TIMEOUT variable to whatever amount of time you wish, and you can express time in hours and/or minutes (mins) and/or seconds (secs) as per date -d command's date-parsing abilities.

LL3
  • 5,418
1

Without knowing the full answer but might help you on your search is to edit /etc/systemd/logind.conf and add the following lines.

IdleAction=poweroff
IdleActionSec=720min

This would poweroff poweroff the system after 12 hours of "idle" time. But I am not sure if the session is reported as idle if it is suspended.

Saft
  • 36