Implementing a scheme for system-wide automatic Suspend to RAM in Lubuntu 20.10

Lubuntu 20.10 is installed on my family’s desktop PC (single-seat, multi-user). This version of the distribution uses the SDDM display manager and the LXQt desktop environment. Previously the machine had Lubuntu 18.04 installed, which used the LightDM display manager and the LXDE desktop environment.

In Lubuntu 18.04 each user could configure the power manager in their LXDE session to make the machine suspend to RAM if that user was logged-in but had not used the keyboard and mouse for a user-specified number of minutes. The problem with that approach was that, if two or more users happened to be logged-in simultaneously because a user did not log out and another user used ‘Switch User’ in LXDE to log-in, the power manager in a logged-in but unused session would eventually suspend the machine even though another user was still active in a different session. Very annoying. Secondly, if nobody was logged-in and the LightDM greeter screen was displayed, the machine would not suspend to RAM automatically after a period of inactivity; the only way to get the machine to suspend to RAM if nobody was logged-in was to suspend it manually from the greeter screen. I implemented my own fix for both problems in Lubuntu 18.04 (see my previous blog posts How to make LightDM suspend to RAM automatically from the login screen and lock screen in Lubuntu 18.04 and How to stop inactive user sessions triggering Suspend to RAM in a single-seat, multi-user installation of Lubuntu 18.04) but I had to use a different approach in Lubuntu 20.10 because it uses SDDM and LXQt.

The new scheme I implemented in Lubuntu 20.10 is partly an academic exercise because LXQt in Lubuntu 20.10 does not have a ‘Switch User’ option that would enable more than one user to be logged in simultaneously. LXQt Issue 14 and SDDM Issue 991 appear to be about this limitation. Furthermore, I think systemd may also be a factor (Lubuntu uses Version 246, which no longer includes seat_can_multi_session() that the version of SDDM in Lubuntu 20.10 may depend on for the ‘Switch User’ option). The disappearance of a ‘Switch User’ option has been reported previously for various Linux distributions using KDE and systemd 246, such as Arch Linux, Gentoo Linux and Kubuntu. Therefore it may be that all three packages would need to be altered in order for Lubuntu to provide a ‘Switch User’ option. Anyway, the scheme I have implemented in Lubuntu 20.10 could handle more than one user logged-in simultaneously if that were possible, as I catered for that possibility in case future updates to LXQt and SDDM have a ‘Switch User’ option. Even without a ‘Switch User’ option in LXQt, my scheme enables Lubuntu 20.10 to suspend to RAM automatically when no one is logged in and the SDDM greeter screen is displayed, which is also useful. Furthermore, my scheme also provides system-wide Suspend to RAM control, removing the need for users to touch the LXQt power manager settings in their individual user accounts.

Note that, as was the case in Lubuntu 18.04, Lubuntu 20.10 does not terminate all the user’s processes when the user logs out. This can be seen if you use the ‘ps -ef‘ command when logged in as a different user. Also, the user’s session is not closed; its state is always shown as ‘closing’ if you use the ‘loginctl list-sessions‘ and ‘loginctl session-status <ID>‘ commands. I suspect this behaviour is a ‘feature’ of systemd rather than Lubuntu itself, but I could be wrong. Anyway, in order to cater for this behaviour my scheme is more complex than it would be otherwise.

By the way, I believe this scheme would probably work in other Linux distributions that use systemd and have a desktop environment that can be configured to launch scripts automatically at login. In fact, the scheme could also be adapted for use in a distribution that does not use systemd. For example, in an installation that uses OpenRC the suspend.sh script (see further down) could be launched at boot from a script in the /etc/local.d/ directory. In distributions without systemd the logger command could be used to log messages in the system log file.

My scheme to provide system-wide automatic Suspend to RAM in Lubuntu 20.10 is detailed below. If new versions of LXQt, SDDM and systemd (whichever of those is required for a ‘Switch User’ option) are added to the Lubuntu repositories in future, hopefully the scheme detailed below already caters for that option.

1. Select ‘Preferences’ > ‘LXQt settings’ > ‘Power Management’ in each user’s LXQt account, click on ‘Idle’ and untick ‘Enable Idleness Watcher’ to prevent LXQt Power Manager in each user’s LXQt session from suspending to RAM independently.

Note: It is possible for the system administrator to configure this for all users via the command line instead. For example:

$ nano ~/.config/lxqt/lxqt-powermanagement.conf

Change ‘enableIdlenessWatcher=true‘ to ‘enableIdlenessWatcher=false‘:

[General]
__userfile__=true
backlightIdleness=0
backlightIdlenessOnBatteryDischarging=true
enableBatteryWatcher=false
enableIdlenessBacklightWatcher=false
enableIdlenessWatcher=false
enableLidWatcher=false
idlenessAction=-1
idlenessTime=@Variant(\0\0\0\xf\0\0\x3\xe8)
idlenessTimeSecs=900
runCheckLevel=1
$ $ ls -la ~/.config/lxqt/lxqt-powermanagement.conf
-rw-rw-r-- 1 fitzcarraldo fitzcarraldo 304 Feb  8 22:10 /home/bill/.config/lxqt/lxqt-powermanagement.conf
$ sudo cp ~/.config/lxqt/lxqt-powermanagement.conf /home/aquilino/.config/lxqt/lxqt-powermanagement.conf
$ sudo chown aquilino.aquilino /home/aquilino/.config/lxqt/lxqt-powermanagement.conf
$ sudo chmod 664 /home/aquilino/.config/lxqt/lxqt-powermanagement.conf

and so on for every user. For example, if the installation has accounts for five users with usernames aquilino, cholo, fitzcarraldo, molly and paul:

$ sudo updatedb; sudo locate lxqt-powermanagement.conf | grep .config                                      
/home/aquilino/.config/lxqt/lxqt-powermanagement.conf
/home/cholo/.config/lxqt/lxqt-powermanagement.conf
/home/fitzcarraldo/.config/lxqt/lxqt-powermanagement.conf
/home/molly/.config/lxqt/lxqt-powermanagement.conf
/home/paul/.config/lxqt/lxqt-powermanagement.conf

2. Install the X Windows utility xprintidle so it can be used in a Bash script to determine when a user is idle or active:

$ sudo apt install xprintidle

3. Create the script /usr/local/bin/check_if_idle.sh

An instance of this script will be launched when each user logs in to the desktop environment (see Step 4). Each instance of the script will run continuously and its purpose is to create periodically a file with a specific name, or periodically delete files with specific names, in the RAM-based /tmp/ directory. These zero-length files are used to inform the suspend.sh script (see Step 5) whether or not the applicable user has been using the keyboard or mouse within a specified timeout period (specified as 15 minutes in the script). From now on I will use the term ‘flag-files’ when referring to such files, as they are effectively Boolean flags to pass binary information from a Bash script in each user’s session to a Bash script that actually initiates suspending to RAM. If the active user’s session has been idle for the specified timeout period, the script deletes all that user’s flag-files in order to indicate to the suspend.sh script that the specific user is no longer an impediment to suspending to RAM. Similarly, when the user logs out, the applicable flag-file is deleted in order to indicate to the suspend.sh script that the user is no longer an impediment to suspending. The flag-file is not deleted if the user is logged in but not the active user, in order to indicate to the suspend.sh script that it must not suspend to RAM unless the active user has been idle for the specified timeout period (notice that the script check_if_idle.sh deletes all the user’s non-VT (Virtual Terminal, a.k.a. ‘TTY console’) flag-files when the active user has been idle for the specified timeout period).

$ sudo nano /usr/local/bin/check_if_idle.sh
#!/bin/bash
CurrentUser=$(whoami)
touch /tmp/not_idle_$CurrentUser$BASHPID
IdleAfter=900000 # consider idle after 900000 ms (15 min) of inactivity
while true; do
  State=$( loginctl session-status | grep -m 1 State | awk -F " " '{ print $2 }' )
  if [[ "$State" == "active" ]]; then
  IdleTimeMillisecs=$(xprintidle 2>/dev/null)
    if [[ $IdleTimeMillisecs -ge $IdleAfter ]]; then
      rm /tmp/not_idle_$CurrentUser* 2>/dev/null
    fi
    if [[ $IdleTimeMillisecs -lt $IdleAfter ]]; then
      touch /tmp/not_idle_$CurrentUser$BASHPID
    fi
  elif [[ "$State" == "online" ]]; then
    touch /tmp/not_idle_$CurrentUser$BASHPID
  elif [[ "$State" == "closing" ]]; then
    rm /tmp/not_idle_$CurrentUser$BASHPID 2>/dev/null
  fi
  sleep 1
done
$ chmod 755 /usr/local/bin/check_if_idle.sh

As far as I have been able to ascertain from systemd documentation, currently the following three session states are possible: “online” (session logged in, but session not active, i.e. not in the foreground), “active” (session logged in and active, i.e. in the foreground), “closing” (session nominally logged out, but some processes belonging to it are still around).

Note: I could have created a separate configuration file and made the Bash script read $IdleAfter from it, but I decided to keep things simple and specify the time-out period in the script itself.

4. Add the following command to LXQt Application Menu > Preferences > LXQt settings > Session Settings > Autostart > LXQt Autostart for each user (give it the name ‘Check_if_idle’) so that an instance of check_if_idle.sh is launched automatically when a user logs in:

/usr/local/bin/check_if_idle.sh

Note: It is possible for the system administrator to configure this for all users via the command line instead. For example:

$ nano ~/.config/autostart/Check_if_idle.desktop
[Desktop Entry]
Exec=/usr/local/bin/check_if_idle.sh
Name=Check_if_idle
OnlyShowIn=LXQt;
Type=Application
Version=1.0
$ ls -la ~/.config/autostart/Check_if_idle.desktop
-rw-rw-r-- 1 fitzcarraldo fitzcarraldo 118 Feb  9 13:27 /home/fitzcarraldo/.config/autostart/Check_if_idle.desktop
$ sudo cp ~/.config/autostart/Check_if_idle.desktop /home/aquilino/.config/autostart/Check_if_idle.desktop
$ sudo chown aquilino.aquilino /home/aquilino/.config/autostart/Check_if_idle.desktop
$ sudo chmod 664 /home/aquilino/.config/autostart/Check_if_idle.desktop

and so on for every user. For example, if the installation has accounts for five users with usernames aquilino, cholo, fitzcarraldo, molly and paul:

$ sudo updatedb; sudo locate Check_if_idle.desktop
/home/aquilino/.config/autostart/Check_if_idle.desktop
/home/cholo/.config/autostart/Check_if_idle.desktop
/home/fitzcarraldo/.config/autostart/Check_if_idle.desktop
/home/molly/.config/autostart/Check_if_idle.desktop
/home/paul/.config/autostart/Check_if_idle.desktop

5. Create the script /usr/local/bin/suspend.sh

This script will be a service launched at boot via a systemd unit file. Its purpose is twofold:

  • to check periodically if there has been keyboard and mouse activity while the SDDM greeter screen is displayed and to suspend to RAM if there has not been any activity within a specificed timeout period (which I have also specified as 15 minutes);
  • to check periodically for flag-files in the /tmp/ directory to ascertain if there has been any activity by logged-in LXQt users within a specified timeout period, and to ascertain if any user is logged in to a VT, and to suspend to RAM if neither of those are the case.
#!/bin/bash
rm /tmp/not_idle_* 2>/dev/null
rm /tmp/triggered_suspend_greeter 2>/dev/null
rm /tmp/triggered_suspend 2>/dev/null
IdleAfter=900000 # Consider SDDM Greeter idle after 900000 ms (15 min) of inactivity
while true; do
  sleep 30 # Do not delete this line or reduce the time
  NumLoggedInUsers=$(who -qs | grep -o '[0-9]\+')
  if [[ $NumLoggedInUsers -eq 0 ]]; then
    rm /tmp/not_idle_* 2>/dev/null
    AuthFile=$(find /var/run/sddm/ -type f)
    if IdleTimeMillisecs=$(DISPLAY=:0 XAUTHORITY=$AuthFile xprintidle 2>/dev/null) ; then
      Running_in_X_Windows=true
    else
      echo "Cannot calc Idle time for Greeter screen." # Log the problem in systemd journal.
      IdleTimeMillisecs=0
      Running_in_X_Windows=false
    fi
    if [[ $IdleTimeMillisecs -gt $IdleAfter ]] ; then
      touch /tmp/triggered_suspend_greeter
      systemctl suspend -i # Comment out when debugging
    fi
  else
    # Only suspend if all users have been idle for the time specified in /usr/local/bin/check_if_idle.sh
    if [[ `ls -1 /tmp/not_idle_* 2>/dev/null | wc -l` -eq 0 ]]; then
      touch /tmp/triggered_suspend
      systemctl suspend -i
    fi
  fi
done
$ sudo chmod 755 /usr/local/bin/suspend.sh

Note: I could have created a separate configuration file and made the Bash script read $IdleAfter from it, but I decided to keep things simple and specify the timeout period in the script itself.

6. Create the systemd unit file /etc/systemd/system/suspend.service so that systemd can launch the suspend.sh script at boot. Note that this service is different to, and independent from, systemd’s service for suspending to RAM (systemd-suspend.service).

[Unit]
Description=Suspend to RAM if idle for specified time

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/suspend.sh
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
$ sudo chmod 640 /etc/systemd/system/suspend.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable suspend.service

7. Add the following lines to the end of each user’s ~/.profile file:

# Stop /usr/local/bin/suspend.sh suspending to RAM if this user logs in to a VT
CurrentUser=$(whoami)
CurrentVT=$(tty | grep -o '[0-9]\+') # Will be zero if not run on a VT
rm /tmp/not_idle_$CurrentUser* 2>/dev/null
if [[ $CurrentVT -ne 0 ]]; then
  touch /tmp/not_idle_VT"$CurrentVT"_"$CurrentUser"
fi

This addition only creates a flag-file if the applicable user logs in to a VT, and the flag-file is created using a different naming convention to flag-files for LXQt processes in order to be able to distinguish between specific VT console use and pseudo-terminal use, to prevent the suspend.sh script from suspending to RAM while a user is logged in to a VT.

8. Add the following lines to the end of each user’s ~/.bash_logout file:

# Allow /usr/local/bin/suspend.sh to suspend to RAM after this user logs out from a VT session
CurrentUser=$(whoami)
CurrentVT=$(tty | grep -o '[0-9]\+')
if [[ $CurrentVT -ne 0 ]]; then
  rm /tmp/not_idle_VT"$CurrentVT"_"$CurrentUser" 2>/dev/null
fi

The flag-file uses a different naming convention to flag-files used for LXQt processes, in order to be able to indicate to the suspend.sh script that the specific VT user has logged out and therefore is no longer an impediment to suspending to RAM.

9. Create the file /usr/lib/systemd/system-sleep/automatic-suspend-scheme to log when the scheme causes the system to suspend to RAM and also when the system wakes from that suspension.

$ sudo nano /usr/lib/systemd/system-sleep/automatic_suspend_scheme
#!/bin/bash
# This hook script will run when suspending/hibernating and when resuming/thawing.
# Check $1 ('pre' or 'post') and $2 ('suspend', 'hibernate', or 'hybrid-sleep') to ascertain
# which is happening.
case $1/$2 in
  pre/*)
    # Put here any commands you want to be run when suspending or hibernating.
    if [[ -f /tmp/triggered_suspend_greeter ]]; then
      echo "Automatic Suspend Scheme - Suspend to RAM (No users logged in)." # Log the event in the systemd journal
    fi
    if [[ -f /tmp/triggered_suspend ]]; then
      echo "Automatic Suspend Scheme - Suspend to RAM." # Log the event in the systemd journal
    fi
    ;;
  post/*)
    # Put here any commands you want to be run when resuming from suspension or thawing from hibernation.
    if [[ -f /tmp/triggered_suspend_greeter ]]; then
      echo "Automatic Suspend Scheme - Resuming from Suspend to RAM (No users logged in)." # Log the event in the systemd journal
      rm /tmp/triggered_suspend_greeter
    fi
    if [[ -f /tmp/triggered_suspend ]]; then
      echo "Automatic Suspend Scheme - Resuming from Suspend to RAM." # Log the event in the systemd journal
      rm /tmp/triggered_suspend
    fi
    ;;
esac
$ sudo chmod 755 /usr/lib/systemd/system-sleep/automatic_suspend_scheme

10. Reboot and test

From now on, the installation should suspend to RAM if all logged-in LXQt users have been inactive for 15 minutes or more. This does not preclude any user selecting Leave > Suspend from the LXQt Application Menu to suspend to RAM manually. If no users are logged in — i.e. the SDDM greeter screen is displayed on the monitor — the installation will suspend to RAM if there is no keyboard and mouse activity for 15 minutes. This does not preclude any user clicking on the icon on the SDDM greeter screen to suspend the machine to RAM manually. The Bash scripts suspend.sh and check_if_idle.sh can be edited to alter the timeout period if a different timeout is desired. The scheme will not trigger suspending to RAM while someone is logged in via a VT (a.k.a. TTY console). I am the only person in my family who knows how to use a VT; all the other family members use only the LXQt desktop environment.

Caveat: The suspend.sh script can initiate suspending to RAM if no /tmp/not_idle_* files exist, so do not delete manually any of the not_idle_* files in the /tmp/ directory.

If you want to check what is happing to the sessions, processes and flag-files, the following commands are useful:

$ systemctl status suspend
$ ps -ef | grep check
$ ps -ef | grep suspend
$ ls /tmp/not_idle*
$ loginctl list-sessions
$ loginctl session-status <session number> | grep State

For example, below is some output from those commands when users paul and aquilino were using the machine. User paul booted the machine and logged-in on the SDDM greeter screen, then logged out to let user aquilino login on the SDDM greeter screen. Then user aquilino logged out and user paul logged in again on the SDDM greeter screen and entered the following commands in a pseudo-terminal (e.g. QTerminal) window:

$ systemctl status suspend
● suspend.service - Suspend to RAM if idle for specified time
     Loaded: loaded (/etc/systemd/system/suspend.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2021-02-11 16:25:53 GMT; 35min ago
   Main PID: 966 (suspend.sh)
      Tasks: 2 (limit: 4476)
     Memory: 1.5M
     CGroup: /system.slice/suspend.service
             ├─  966 /bin/bash /usr/local/bin/suspend.sh
             └─36254 sleep 30

Feb 11 16:25:53 aspirexc600 systemd[1]: Started Suspend to RAM if idle for specified time.
$ ps -ef | grep check
paul        1337       1  0 16:27 ?        00:00:01 /bin/bash /usr/local/bin/check_if_idle.sh
aquilino    4904       1  0 16:34 ?        00:00:01 /bin/bash /usr/local/bin/check_if_idle.sh
paul        9187       1  0 16:38 ?        00:00:01 /bin/bash /usr/local/bin/check_if_idle.sh
paul       37124    9236  0 17:01 pts/0    00:00:00 grep --color=auto check
$ ps -ef | grep suspend
root         966       1  0 16:25 ?        00:00:00 /bin/bash /usr/local/bin/suspend.sh
paul       38515    9236  0 17:02 pts/0    00:00:00 grep --color=auto suspend
$ ls /tmp/not_idle*
/tmp/not_idle_paul9187
$ loginctl list-sessions
SESSION  UID USER     SEAT  TTY
     12 1000 paul     seat0    
      3 1000 paul     seat0    
      8 1001 aquilino seat0    

3 sessions listed.
$ loginctl session-status 12 | grep State
           State: active
                  └─41171 grep --color=auto State
$ loginctl session-status 3 | grep State
           State: closing
$ loginctl session-status 8 | grep State
           State: closing

Then user paul pressed Ctrl+Alt+F2 to switch to VT2 (tty2), logged in as user paul and entered the commands:

$ ps -ef | grep check
paul        1337       1  0 16:27 ?        00:00:01 /bin/bash /usr/local/bin/check_if_idle.sh
aquilino    4904       1  0 16:34 ?        00:00:01 /bin/bash /usr/local/bin/check_if_idle.sh
paul        9187       1  0 16:38 ?        00:00:01 /bin/bash /usr/local/bin/check_if_idle.sh
paul       50191   48181  0 17:12 tty2     00:00:00 grep --color=auto check
$ ps -ef | grep suspend
root         966       1  0 16:25 ?        00:00:00 /bin/bash /usr/local/bin/suspend.sh
paul       50295   48181  0 17:12 tty2     00:00:00 grep --color=auto suspend
$ ls /tmp/not_idle*
/tmp/not_idle_paul9187  /tmp/not_idle_VT2_paul
$ loginctl list-sessions
SESSION  UID USER     SEAT  TTY
     12 1000 paul     seat0    
     15 1000 paul     seat0 tty2
      3 1000 paul     seat0    
      8 1001 aquilino seat0    

4 sessions listed.
$ loginctl session-status 12 | grep State
           State: online
$ loginctl session-status 15 | grep State
           State: active
                  └─50741 grep --color=auto State
$ loginctl session-status 3 | grep State
           State: closing
$ loginctl session-status 8 | grep State
           State: closing

Then user paul pressed Ctrl+Alt+F1 to switch back to his LXQt session and entered the following commands in the already open pseudo-terminal window:

$ ps -ef | grep check
paul        1337       1  0 16:27 ?        00:00:02 /bin/bash /usr/local/bin/check_if_idle.sh
aquilino    4904       1  0 16:34 ?        00:00:02 /bin/bash /usr/local/bin/check_if_idle.sh
paul        9187       1  0 16:38 ?        00:00:02 /bin/bash /usr/local/bin/check_if_idle.sh
paul       61359    9236  0 17:22 pts/0    00:00:00 grep --color=auto check
$ ps -ef | grep suspend
root         966       1  0 16:25 ?        00:00:00 /bin/bash /usr/local/bin/suspend.sh
paul       61473    9236  0 17:22 pts/0    00:00:00 grep --color=auto suspend
$ ls /tmp/not_idle*
/tmp/not_idle_paul9187  /tmp/not_idle_VT2_paul
$ loginctl list-sessions
SESSION  UID USER     SEAT  TTY 
     12 1000 paul     seat0     
     15 1000 paul     seat0 tty2
      3 1000 paul     seat0     
      8 1001 aquilino seat0     

4 sessions listed.
$ loginctl session-status 12 | grep State
           State: active
                  └─62165 grep --color=auto State
$ loginctl session-status 15 | grep State
           State: online
$ loginctl session-status 3 | grep State
           State: closing
$ loginctl session-status 8 | grep State
           State: closing

Then user paul pressed Ctrl+Alt+F2 to switch back to tty2, entered ‘exit‘ to log out of his VT session, then pressed Ctrl+Alt+F1 to switch back to his LXQt session and entered the following commands:

$ ps -ef | grep check
paul        1337       1  0 16:27 ?        00:00:03 /bin/bash /usr/local/bin/check_if_idle.sh
aquilino    4904       1  0 16:34 ?        00:00:03 /bin/bash /usr/local/bin/check_if_idle.sh
paul        9187       1  0 16:38 ?        00:00:03 /bin/bash /usr/local/bin/check_if_idle.sh
paul       92759    9236  0 17:48 pts/0    00:00:00 grep --color=auto check
$ ps -ef | grep suspend
root         966       1  0 16:25 ?        00:00:00 /bin/bash /usr/local/bin/suspend.sh
paul       92922    9236  0 17:48 pts/0    00:00:00 grep --color=auto suspend
$ ls /tmp/not_idle*
/tmp/not_idle_paul9187
$ loginctl list-sessions
SESSION  UID USER     SEAT  TTY
     12 1000 paul     seat0    
      3 1000 paul     seat0    
      8 1001 aquilino seat0    

3 sessions listed.
$ loginctl session-status 12 | grep State
           State: active
                  └─93554 grep --color=auto State
$ loginctl session-status 3 | grep State
           State: closing
$ loginctl session-status 8 | grep State
           State: closing

As you can see in the output above, even though user paul logged out of his first LXQt session (Session 3), and user aquilino logged out of his only LXQt session (Session 8), those two sessions did not end, remaining in the state ‘closing’. You can also see that user paul‘s VT session (Session 15) did close when he logged out on VT2 (tty2). Addiionally, you can see in the output above the flag-files that were created and deleted during that period.

The following command shows the entries in the systemd journal for the scheme’s service (suspend.service) since the system last booted:

$ journalctl -b -u suspend.service
-- Logs begin at Sat 2021-01-02 01:52:36 GMT, end at Sat 2021-02-13 01:16:09 GMT. --
Feb 13 00:24:18 aspirexc600 systemd[1]: Started Suspend to RAM if idle for specified time.

The above output shows no error messages since the service started at 00:24:18 when the system was last booted.

If you want to check the systemd journal to see when the scheme suspended the system to RAM automatically and was manually woken up from that sleep:

$ journalctl | grep "Automatic Suspend Scheme"

Add ‘-b‘ if you want to check only since the system last booted:

$ journalctl -b | grep "Automatic Suspend Scheme"
Feb 13 00:39:49 aspirexc600 systemd-sleep[1611]: Automatic Suspend Scheme - Suspend to RAM (No users logged in).
Feb 13 00:44:32 aspirexc600 systemd-sleep[1691]: Automatic Suspend Scheme - Resuming from Suspend to RAM (No users logged in).
Feb 13 01:01:59 aspirexc600 systemd-sleep[10470]: Automatic Suspend Scheme - Suspend to RAM.
Feb 13 01:04:52 aspirexc600 systemd-sleep[10556]: Automatic Suspend Scheme - Resuming from Suspend to RAM.

The following command shows entries in the systemd journal by the systemd suspend service (systemd-suspend.service) and systemd-sleep command since the system last booted, so it is possible to check both the times at which the automated scheme suspended and the times at which the system was manually suspended, and also the times at which the system was woken manually:

$ journalctl -b -u systemd-suspend.service
-- Logs begin at Sat 2021-01-02 01:52:36 GMT, end at Sat 2021-02-13 01:16:09 GMT. --
Feb 13 00:39:49 aspirexc600 systemd[1]: Starting Suspend...
Feb 13 00:39:49 aspirexc600 systemd-sleep[1611]: Automatic Suspend Scheme - Suspend to RAM (No users logged in).
Feb 13 00:39:49 aspirexc600 systemd-sleep[1609]: Suspending system...
Feb 13 00:44:32 aspirexc600 systemd-sleep[1609]: System resumed.
Feb 13 00:44:32 aspirexc600 systemd-sleep[1691]: Automatic Suspend Scheme - Resuming from Suspend to RAM (No users logged in).
Feb 13 00:44:32 aspirexc600 systemd[1]: systemd-suspend.service: Succeeded.
Feb 13 00:44:32 aspirexc600 systemd[1]: Finished Suspend.
Feb 13 01:01:59 aspirexc600 systemd[1]: Starting Suspend...
Feb 13 01:01:59 aspirexc600 systemd-sleep[10470]: Automatic Suspend Scheme - Suspend to RAM.
Feb 13 01:01:59 aspirexc600 systemd-sleep[10468]: Suspending system...
Feb 13 01:04:51 aspirexc600 systemd-sleep[10468]: System resumed.
Feb 13 01:04:52 aspirexc600 systemd-sleep[10556]: Automatic Suspend Scheme - Resuming from Suspend to RAM.
Feb 13 01:04:51 aspirexc600 systemd[1]: systemd-suspend.service: Succeeded.
Feb 13 01:04:51 aspirexc600 systemd[1]: Finished Suspend.
Feb 13 01:12:51 aspirexc600 systemd[1]: Starting Suspend...
Feb 13 01:12:51 aspirexc600 systemd-sleep[14964]: Suspending system...
Feb 13 01:15:50 aspirexc600 systemd-sleep[14964]: System resumed.
Feb 13 01:15:53 aspirexc600 systemd[1]: systemd-suspend.service: Succeeded.
Feb 13 01:15:53 aspirexc600 systemd[1]: Finished Suspend.

You can see above that the system automatically suspended to RAM at 00:39:49 after 15 minutes of inactivity on the SDDM greeter screen. Someone then pressed the space bar on the keyboard to wake the system at 00:44:32, and logged in to the LXQt desktop. The system suspended to RAM automatically again at 01:01:59 after that user had not touched the keyboard and mouse for 15 minutes in the active LXQt session. That user then woke the system manually again at 01:04:52, then manually suspended the system at 01:12:51 using the LXQt Application Menu (Leave > Suspend). Finally, at 01:15:50 the same user woke the system manually again.

11. Make /tmp/ RAM-based (optional)

By default, the Lubuntu 20.10 Installer creates the directory /tmp/ on the same disk partition as the root directory:

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       916G  139G  731G  16% /

If your machine has plenty of RAM, if you want you could configure the system to mount a tmpfs filesystem on /tmp/ instead, as show below.

I decided to specify a tmpfs maximum size of 200MB for /tmp/ (tmpfs doesn’t reserve this memory, it allocates only the memory actually needed):

$ echo "tmpfs /tmp tmpfs rw,nosuid,nodev,size=200M" | sudo tee -a /etc/fstab
$ grep tmp /etc/fstab
tmpfs /tmp tmpfs rw,nosuid,nodev,size=200M

Note: If I had not included ‘,size=200M‘ in /etc/fstab, the maximum size for the tmpfs filesystem mounted on /tmp/ would have defaulted to half the available RAM in the machine.

Then I rebooted to check that /tmp/ is now in RAM:

$ df -h /tmp/
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           200M  4.0K  200M   1% /tmp
$ findmnt /tmp/
TARGET SOURCE FSTYPE OPTIONS
/tmp   tmpfs  tmpfs  rw,nosuid,nodev,relatime,size=204800k

The space used in /tmp/ will vary depending on what is running. For example, editing a large LibreOffice document will require space in /tmp/, so keep an eye on the amount of space used in /tmp/ and adjust the maximum size of the tmpfs partition if necessary.

About Fitzcarraldo
A Linux user with an interest in all things technical.

One Response to Implementing a scheme for system-wide automatic Suspend to RAM in Lubuntu 20.10

  1. Fitzcarraldo says:

    When resuming after Suspend to RAM, the LXQt desktop is momentarily revealed before the xscreensaver lockscreen appears. The user might not want the contents of the desktop to be visible, even briefly, in case someone else has woken the machine from sleep. To stop this happening, from the LXQt Application Menu:

    1. Select ‘Preferences’ > ‘Screensaver’.

    2. Click on the ‘Advanced’ tab.

    3. Untick ‘Fade to Black when Blanking’.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: