{ config, pkgs, lib, ... }: # Relevant references: # How to prevent systemd suspend from stopping any service with a dont-sleep.service. https://askubuntu.com/q/830442/1002706 # systemctl show test-block-suspend.service -p TimeoutStopUSec #=> TimeoutStopUSec=infinity # systemctl cat test-block-suspend.service # systemctl list-dependencies --before test-block-suspend.service #=> test-block-suspend.service #=> ├─shutdown.target #=> ├─sleep.target #=> │ ├─systemd-hibernate.service #=> │ ├─systemd-hybrid-sleep.service #=> │ ├─systemd-suspend-then-hibernate.service #=> │ └─systemd-suspend.service #=> └─suspend.target #=> └─post-resume.service { # Alternative approach to adding `conflicts`, `before` and `ExecStop`. # # Immediately before entering system suspend, all executables in /usr/lib/systemd/system-sleep/ are run. # Execution of the sleep action is not continued until all have finished. # TODO: This happens after my screen got blank, wifi disabled, screen locker activated, etc. # environment.etc."systemd/system-sleep/test-block-suspend".source = # pkgs.writeShellScript "test-block-suspend" '' # set -eu -o pipefail # if [ "$1" == "pre" ]; then # while :; do # systemctl is-active --quiet test-block-suspend.service || exit 0 # ${pkgs.coreutils}/bin/echo 'Waiting until service has finished ...' # ${pkgs.coreutils}/bin/sleep 1s # done # fi # ''; systemd.services."test-block-suspend" = { description = "Inhibit suspend"; # If suspend is initiated, this service is stopped. conflicts = [ "sleep.target" ]; # Start-up of `sleep.target` # is delayed until this service has finished starting up. before = [ "sleep.target" ]; serviceConfig = { # `simple`: # As soon as the main process (defined in the `ExecStart`) is started (forked), # start-up is considered as finished. # `notify`: # The service sends a "READY=1" notification message via `sd_notify` when it has finished starting up. # Requires `NotifyAccess`. # See https://www.freedesktop.org/software/systemd/man/latest/systemd-notify.html Type = "notify"; NotifyAccess = "main"; # To stop this service `ExecStop` is run instead of sending SIGTERM to the main process of the service. # The command specified by `ExecStop` does never end, # thus stopping this service takes forever. # TODO: However, the sleep action continues while `ExecStop` is running. As a reslut, the system suspends. ExecStop = "${pkgs.coreutils}/bin/sleep infinity"; TimeoutStopSec = "infinity"; # This service executes a shell script as main process. ExecStart = pkgs.writeShellScript "test-block-suspend-execstart" '' set -eu -o pipefail #handle_sigterm(){ # #while :; do # printf '%s\n' 'Ignoring SIGTERM ...' >&2 # # ${pkgs.coreutils}/bin/sleep 5s # #done #} #trap 'handle_sigterm' TERM #printf '%s\n' 'Start-up 30s ...' #${pkgs.coreutils}/bin/sleep 30s systemd-notify READY=1 while :; do printf '%s\n' 'Still alive' ${pkgs.coreutils}/bin/sleep 5s done ''; }; }; }