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.
3
  • 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, 2021 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, 2021 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, 2021 at 11:55

3 Answers 3

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.

2
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.

1
+50

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.

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.