Firewall zones (profiles) in Linux, and how to switch them automatically if you use UFW

Firstly, a note on terminology: UFW (Uncomplicated Firewall) and its two GUI front-ends Gufw and UFW Frontends use the term ‘application profile’ to refer to a pre-configured set of rules specified in a file. Files containing UFW application profiles are placed in the directory /etc/ufw/applications.d/. An application profile for SMB, for example, enables the root user to use the UFW command ‘ufw allow Samba‘ (‘ufw allow CIFS‘ in Gentoo Linux) rather than having to enter UFW commands specifying the precise ports and network protocols that SMB uses. However, this blog post is not about UFW’s application profiles; it is about what Gufw calls ‘profiles’ and firewalld calls ‘zones’.

In essence a profile/zone is a collection of firewall policies and rules. Both Gufw and firewalld include the concept of a ‘zone’, although Gufw uses the term ‘profile’ rather than ‘zone’. UFW Frontends does not have the concept of a ‘zone’; rules entered via UFW Frontends apply to any network to which you connect your laptop. The ability to define different zones for different networks is handy. For example, you can have certain policies and rules when your laptop is connected to your home network, and different policies and rules when your laptop is connected to the network in a café, hotel, airport or other public place.

An attractive feature of firewalld when used in conjunction with NetworkManager and KDE Plasma is that it is possible to use the desktop environment’s network management module (‘System Settings’ > ‘Connections’) to specify a particular firewalld zone for a particular network connection. For example, let’s say you used firewalld to specify certain policies and rules for a zone you named ‘office’, and you then specified in the System Settings – Connections GUI that a connection named ‘ACM’ should use the zone ‘office’. Thereafter, whenever you connect your laptop to the network named ‘ACM’, firewalld will use the policies and rules you previously configured for the zone ‘office’.

Unlike firewalld, Gufw does not have the ability to switch profiles automatically according to which network the laptop is connected. You have to select manually the profile you wish to use. You would launch Gufw prior to connecting to, for example, your office’s network, select the profile ‘Office’ (or whatever you have named it), then connect your laptop to that network.

I think many people would be satisfied with the functionality currently provided by Gufw. I could use the Gufw GUI to create Gufw profiles with names such as ‘Home’, ‘HomeDave’, ‘Public’, ‘HQoffice’, ‘USoffice’, ‘PestanaRio’ and so on, and specify the different policies and rules I want for each profile. At home I would launch Gufw on my laptop and select the Home profile then connect to my home network; in the office at work I would launch Gufw on my laptop and select the HQoffice profile then connect to the office network; at my friend Dave’s house I would launch Gufw on my laptop and select the HomeDave profile then connect to the house network; and so on. Nevertheless I do see the attraction of automated zone switching, as provided by firewalld in conjunction with NetworkManager and KDE. It would be handy if my laptop could switch automatically to the Home profile when my laptop connected to the network at my home with the name ‘BTHub5-8EUQ’, automatically switch to the HQoffice profile when my laptop connected to the network named ‘HQ-Office2’ in the office, and so on.

I use UFW on my two laptops running Gentoo Linux. The package ufw-frontends is also installed but normally I use UFW directly via the command line. However I wanted to learn about zones/profiles while using UFW, and I also wanted to see if I could automate the switching of zones without resorting to installing firewalld. NetworkManager has the ability to launch ‘hook’ scripts when certain things happen — when a network connection changes, for example — and this seemed to me to be a way of switching profiles automatically.

I had not used Gufw before, so I decided to install it. A package is available in many Linux distributions but there is no ebuild for Gufw in Gentoo’s main Portage tree and I could not find an up-to-date ebuild for it in any Portage overlays. Therefore I created the ebuild for net-firewall/gufw-19.10.0 shown below. It probably needs improving, but it does install a working Gufw in Gentoo Linux.

# Copyright 1999-2019 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

EAPI=7
PYTHON_COMPAT=( python3_{5,6,7} )
DISTUTILS_IN_SOURCE_BUILD=1

inherit distutils-r1

MY_PN="gui-ufw"
MY_PV="$(ver_cut 1-2)"

DESCRIPTION="GUI frontend for managing ufw."
HOMEPAGE="https://gufw.org/"
SRC_URI="https://launchpad.net/${MY_PN}/trunk/${MY_PV}/+download/${MY_PN}-${PV}.tar.gz"

LICENSE="GPL-3"
SLOT="0"
KEYWORDS="~amd64"
IUSE=""

DEPEND="dev-python/python-distutils-extra"
RDEPEND="net-firewall/ufw
	dev-python/netifaces
	dev-python/pygobject:3
	net-libs/webkit-gtk[introspection]
	sys-auth/elogind
	sys-auth/polkit
	x11-libs/gtk+:3[introspection]
	x11-themes/gnome-icon-theme-symbolic
"
S=${WORKDIR}/${MY_PN}-${PV}

pkg_postinst() {
	sed '/dist-packages/d' -i /usr/bin/gufw-pkexec
	sed -E '/\/share\//d' -i /usr/bin/gufw-pkexec
	local PYTHONVERSION="$(python -c 'import sys; print("{}.{}".format(sys.version_info.major, sys.version_info.minor))')"
	sed -E "s|python3\.[0-9]|python${PYTHONVERSION}|g" -i /usr/bin/gufw-pkexec
	sed -E 's|\/lib\/|\/lib64\/|g' -i /usr/bin/gufw-pkexec
}

How To Set Up a Firewall with GUFW on Linux‘ is a good tutorial on Gufw.

As I had not used Gufw previously, I had to play around with it to understand better its functional design. I found that if I configure rules directly via UFW on the command line without using Gufw, Gufw does not allow me to edit those rules (but does allow me to delete them) and those rules exist whichever Gufw profile is selected in the Gufw GUI. Gufw profiles are stored in files named ‘/etc/gufw/*.profile‘ (e.g. /etc/gufw/Home.profile) and these files will not include UFW rules entered via the command line. On the other hand, UFW rules created via the Gufw GUI apply solely to the currently-selected Gufw profile, which is what I would have expected. In other words, I can create a different set of policies and rules in each Gufw profile. Therefore I believe Gufw profiles (as distinct from UFW application profiles) are basically analogous to firewalld’s zones. It also appears to me that Gufw maintains configuration files specifying policies and rules independently of UFW, which Gufw then applies to UFW. In other words, if you are a Gufw user you should not use UFW directly to configure policies and rules, otherwise Gufw’s configuration files will not include what you did directly using UFW. To reiterate, use only Gufw or only UFW, not both.

The current Gufw profile’s name is listed in the file /etc/gufw/gufw.cfg. For example, I currently have the Home profile selected in the Gufw GUI, and the file gufw.cfg contains the following:

[GufwConfiguration]
profile = Home
windowwidth = 542
windowheight = 530
confirmdetelerule = yes

If I examine the contents of the file /etc/gufw/Home.profle I see that it contains the UFW policies and rules I specified for the Gufw Home profile:

[fwBasic]
status = enabled
incoming = deny
outgoing = allow
routed = disabled

[Rule0]
ufw_rule = 137,138/udp ALLOW IN 192.168.1.0/24
description = Samba
command = /usr/sbin/ufw allow in proto udp from 192.168.1.0/24 to any port 137,138
policy = allow
direction = in
protocol = 
from_ip = 192.168.1.0/24
from_port = 
to_ip = 
to_port = 137,138/udp
iface = 
routed = 
logging = 

[Rule1]
ufw_rule = 139,445/tcp ALLOW IN 192.168.1.0/24
description = Samba
command = /usr/sbin/ufw allow in proto tcp from 192.168.1.0/24 to any port 139,445
policy = allow
direction = in
protocol = 
from_ip = 192.168.1.0/24
from_port = 
to_ip = 
to_port = 139,445/tcp
iface = 
routed = 
logging =

I also notice that the other Gufw profiles can differ. For example, my Office.profile file contains the following:

[fwBasic]
status = enabled
incoming = deny
outgoing = allow
routed = allow

The profile name listed in gufw.cfg gets changed when the user changes the profile using the Gufw GUI. It appears to me that only at the point in time when the user selects a certain Gufw profile in the Gufw GUI does Gufw parse the applicable *.profile file and issue commands to UFW to implement the policies and rules specified in the *.profile file.

Initially I tried to automate the process of changing the Gufw profile by doing the following:

  1. I created a NetworkManager Dispatcher hook script to:

    1. detect when the laptop connects to a network;

    2. determine whether the network is at my home, at my workplace or in a public place (café, airport or wherever) by looking at the connection name;

    3. edit gufw.cfg to change the name of the Gufw profile according to the network connected.
  2. I configured KDE to launch Gufw automatically at login, hoping that would implement the Gufw profile specified in gufw.cfg.

When I connected the laptop to various networks, Gufw did indeed show the name of the profile selected by the NetworkManager Dispatcher hook script, but the associated Gufw profile’s rules had not been applied. They were only applied if I clicked on the ‘Profile’ pull-down menu in Gufw, selected a different Gufw profile, then re-selected the desired Gufw profile. Therefore driving Gufw from a NetworkManager Dispatcher hook script is not possible. This is a pity, as Gufw is an easy way to manage UFW from a GUI; it allows the user to create, delete and edit zones (Gufw profiles) and to select them manually. What Gufw doesn’t do is enable the user to associate those zones with connection names, nor trigger specific zone automatically based on the selected network connection. firewalld, on the other hand, does enable the user to do both those things.

As my attempt at automating the switching of zones in Gufw had failed, I decided to create a NetworkManager Dispatcher hook script to switch zones automatically by using UFW commands. Initially I though about creating a bespoke UFW application profile for each zone and allowing/denying those in the script, but it is actually easier to use the fundamental UFW commands in the script, especially as UFW commands are relatively easy to understand. Also, this approach means everything is in a single file, which facilitates configuration. I can simply edit the script in order to: a) add or delete a zone; b) change a zone’s name; c) change policies and rules for a zone; d) add or delete a connection; e) change the name of a connection; f) change the zone a connection uses. Granted, editing a script is not as user-friendly as using the firewalld GUI to configure a zone and then using KDE Plasma’s system settings module Connections to specify that zone for a specific connection, but my script is not particularly difficult to understand and edit. And by using such a script I can continue to use UFW rather than installing firewalld and having to learn how to use it.

My NetworkManager Dispatcher hook script /etc/NetworkManager/dispatcher.d/20_ufw-zones is listed below. In the main body of the script I define the zone I wish to use for each connection, and in the function select_zone I define the policies and rules I want each zone to use.

#!/bin/bash
INTERFACE=$1
STATUS=$2
WIRED=enp4s0f1
WIFI=wlp3s0

CT_helper_rule() {
    echo "# The following is needed to enable Samba commands to" >> /etc/ufw/before.rules
    echo "# work properly for broadcast NetBIOS name resolution" >> /etc/ufw/before.rules
    echo "#"  >> /etc/ufw/before.rules
    echo "# raw table rules" >> /etc/ufw/before.rules
    echo "*raw" >> /etc/ufw/before.rules
    echo ":OUTPUT ACCEPT [0:0]" >> /etc/ufw/before.rules
    echo "-F OUTPUT" >> /etc/ufw/before.rules
    echo "-A OUTPUT -p udp -m udp --dport 137 -j CT --helper netbios-ns" >> /etc/ufw/before.rules
    echo "COMMIT" >> /etc/ufw/before.rules
}
 
select_zone() {
    ufw --force reset
    ufw --force enable
    ZONE=$1
    case "$ZONE" in
    'Home')
        ufw default deny incoming
        ufw default allow outgoing
        #
        # Rules for SMB
        ufw allow from 192.168.1.0/24 to any port 137,138 proto udp
        ufw allow from 192.168.1.0/24 to any port 139,445 proto tcp
        CT_helper_rule
        #
        # Rules for KDEConnect
        ufw allow from 192.168.1.0/24 to any port 1714:1764 proto udp
        ufw allow from 192.168.1.0/24 to any port 1714:1764 proto tcp
    ;;
    'Office')
        ufw default deny incoming
        ufw default allow outgoing
    ;;
    'Public')
        ufw default reject incoming
        ufw default allow outgoing
    ;;
    'JohnsHouse')
        ufw default deny incoming
        ufw default allow outgoing
        #
        # Rules for SMB
        ufw allow from 192.168.42.0/24 to any port 137,138 proto udp
        ufw allow from 192.168.42.0/24 to any port 139,445 proto tcp
        CT_helper_rule
        #
        # Rules for KDEConnect
        ufw allow from 192.168.42.0/24 to any port 1714:1764 proto udp
        ufw allow from 192.168.42.0/24 to any port 1714:1764 proto tcp
    ;;
    esac
    ufw --force reload
    rm /etc/ufw/*.rules.20* # Delete backups of *.rules files ufw makes every time it is reset
    echo -n `date +"[%F %T %Z]"` >> /var/log/ufw-zones.log
    echo " Zone $ZONE selected for connection $ACTIVE on interface $INTERFACE." >> /var/log/ufw-zones.log
}
 
# Check if either the wired or wireless interface is up
if [ "$INTERFACE" = "$WIRED" -o "$INTERFACE" = "$WIFI" ] && [ "$STATUS" = "up" ]; then
 
    # Check if a single connection is active
    if [ `nmcli c | grep -v "\-\-" | grep -v "NAME.*UUID.*TYPE.*DEVICE" | wc -l` -eq 1 ]; then
 
        # Ascertain the name of the active connection
        ACTIVE=`nmcli c | grep -v "\-\-" | grep -v "NAME.*UUID.*TYPE.*DEVICE" | awk -F' ' '{print $1}'`
 
        case "$ACTIVE" in
 
        'eth0')
            ZONE="Home"
        ;;
        'POR1-wired')
            ZONE="Office"
        ;;
        'BTHub5-8EUQ')
            ZONE="Home"
        ;;
        'BTHub5-8EUQ-5GHz')
            ZONE="Home"
        ;;
        'John1')
            ZONE="JohnsHouse"
        ;;
        'GRAND MERCURE')
            ZONE="Public"
        ;;
        *)
            # If connection name is not in above list
            ZONE="Public"
        ;;

        esac

        select_zone $ZONE
        exit $?

    fi
fi

The log file that the script uses contains a chronological record of the connections made and the zones selected:

$ cat /var/log/ufw-zones.log 
[2019-09-30 20:13:52 BST] Zone Home selected for connection eth0 on interface enp4s0f1.
[2019-10-01 22:59:18 BST] Zone Home selected for connection BTHub5-8EUQ-5GHz on interface wlp3s0.
[2019-10-02 17:59:23 EDT] Zone Public selected for connection loganwifi on interface wlp3s0.
[2019-10-03 10:12:46 EDT] Zone Office selected for connection POR1-wired on interface enp4s0f1.
Advertisements

Paul Gideon Dann’s patchset for Poppler to enable Okular (Qt5) to use Cairo rather than Splash to render PDF files

If you view the same PDF file in Okular (KDE) and Evince (GNOME), you may notice that fonts and lines are rendered better in Evince. Both applications use Poppler to render text and graphics in PDF files, but Poppler uses a different rendering backend in the two applications. For Evince Poppler uses the Cairo library, whereas for Okular Poppler uses Splash, a backend inherited from Poppler’s predecessor Xpdf (still in development). Unfortunately for KDE users, Cairo often does a better job than Splash. However, independent software engineer Paul Gideon Dann came to the rescue by producing the patchset poppler-cairo-backend to modify Poppler in order to make it use the Cairo library instead of Splash when Poppler is used by Okular. To quote the README file for Paul’s patchset:

Purpose of this Patchset

Currently, the default backend for the Qt5 wrapper (used by Okular) is Splash. Unfortunately, Splash does not support subpixel rendering of fonts, so those of us using KDE are stuck with somewhat ugly-looking fonts. This patchset adds support for the Cairo backend to the Qt5 wrapper. It also forces subpixel rendering in the Cairo backend. The upshot of this is that we get beautiful fonts in Okular.

The README focuses on fonts, but in fact the rendering of lines in graphics in PDF files can also be improved by the application of the patchset.

Apparently the Poppler maintainer feels that the introduction of a dependency on Cairo to the Qt5 wrapper (even an optional dependency) in Poppler would be controversial, and he is not willing to merge the patchset. For Okular users who already have Cairo installed (e.g. for Firefox, Inkscape, Scribus and so on), and who are noticing inadequate rendering of some PDF files, Paul’s patchset is worth trying.

In Gentoo Linux, which is a source code-based distribution, it is very easy to apply the patchset. For example, I did the following to apply the patchset for Poppler 0.80.0 in a ~amd64 (Testing Branch) installation:

1. Created a package-specific and version-specific directory to hold the patchset:

root # mkdir -p /etc/portage/patches/app-text/poppler-0.80.0

2. Downloaded the patchset for Poppler 0.80.0 from the following Web page:

https://github.com/giddie/poppler-cairo-backend/tree/76e607bcf010d6d9b8df5cb0f851ef9c91d4caf2

3. Copied the patchset to the directory created in Step 1:

root # cp /home/fitzcarraldo/Downloads/*.patch /etc/portage/patches/app-text/poppler-0.80.0/
root # ls -1 /etc/portage/patches/app-text/poppler-0.80.0
0001-Cairo-backend-added-to-Qt5-wrapper.patch
0002-Setting-default-Qt5-backend-to-Cairo.patch
0003-Apply-subpixel-rendering-in-Cairo-Backend.patch

4. Checked first that the patchset could be applied successfully before actually using it:

root # cd /usr/portage/app-text/poppler
root # ebuild poppler-0.80.0.ebuild clean prepare
 * poppler-0.80.0.tar.xz BLAKE2B SHA512 size ;-) ...                                     [ ok ]
 * checking ebuild checksums ;-) ...                                                     [ ok ]
 * checking auxfile checksums ;-) ...                                                    [ ok ]
 * checking miscfile checksums ;-) ...                                                   [ ok ]
>>> Unpacking source...
>>> Unpacking poppler-0.80.0.tar.xz to /var/tmp/portage/app-text/poppler-0.80.0/work
>>> Source unpacked in /var/tmp/portage/app-text/poppler-0.80.0/work
>>> Preparing source in /var/tmp/portage/app-text/poppler-0.80.0/work/poppler-0.80.0 ...
 * Applying poppler-0.60.1-qt5-dependencies.patch ...                                    [ ok ]
 * Applying poppler-0.28.1-fix-multilib-configuration.patch ...                          [ ok ]
 * Applying poppler-0.78.0-respect-cflags.patch ...                                      [ ok ]
 * Applying poppler-0.61.0-respect-cflags.patch ...                                      [ ok ]
 * Applying poppler-0.57.0-disable-internal-jpx.patch ...                                [ ok ]
 * Applying 0001-Cairo-backend-added-to-Qt5-wrapper.patch ...                            [ ok ]
 * Applying 0002-Setting-default-Qt5-backend-to-Cairo.patch ...                          [ ok ]
 * Applying 0003-Apply-subpixel-rendering-in-Cairo-Backend.patch ...                     [ ok ]
 * User patches applied.
>>> Source prepared.

5. Re-merged Poppler to apply the patchset to the Poppler source code and rebuild the patched package:

root # emerge -1v poppler

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] app-text/poppler-0.80.0:0/90::gentoo  USE="cairo cjk cxx introspection jpeg jpeg2k lcms png qt5 tiff utils -curl -debug -doc -nss" 0 KiB

Total: 1 package (1 reinstall), Size of downloads: 0 KiB

>>> Verifying ebuild manifests
>>> Emerging (1 of 1) app-text/poppler-0.80.0::gentoo
>>> Installing (1 of 1) app-text/poppler-0.80.0::gentoo
>>> Jobs: 1 of 1 complete                           Load avg: 1.06, 1.11, 0.95
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

 * GNU info directory index is up-to-date.

6. Re-merged Okular so that it uses the patched Poppler dependency:

root # emerge -1v okular

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] kde-apps/okular-19.08.1:5::gentoo  USE="chm crypt djvu image-backend pdf postscript tiff -debug -epub -handbook -markdown -mobi -mobile -plucker -share -speech -test" 0 KiB

Total: 1 package (1 reinstall), Size of downloads: 0 KiB

>>> Verifying ebuild manifests
>>> Emerging (1 of 1) kde-apps/okular-19.08.1::gentoo
>>> Installing (1 of 1) kde-apps/okular-19.08.1::gentoo
>>> Jobs: 1 of 1 complete                           Load avg: 1.17, 1.13, 1.04
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

 * GNU info directory index is up-to-date.

My thanks go to Paul for taking the time to produce the patchset.

Preventing Lubuntu 18.04 from leaving a user process running after the user logs out

My family’s desktop machine has Lubuntu 18.04 installed, which uses systemd and the LXDE desktop environment. Each family member has their own user account, thus the installation is a single-seat, multi-user installation. For each user’s account I set up the virus-checking scheme described in an earlier post, suitably modified to take into account the differences between Lubuntu 18.04 and Gentoo Linux running KDE. For example, the monitorDownloadsGUI script in Lubuntu 18.04 uses zenity rather than kdialog, and, as Lubuntu 18.04 uses systemd, the ClamAV daemon’s service file in Lubuntu 18.04 is /lib/systemd/system/clamav-daemon.service rather than the OpenRC init file /etc/init.d/clamd used in my Gentoo Linux installations.

The virus-checking script ~/.monitorDownloadGUI in each user’s home directory is launched automatically by LXDE at login because I created a Desktop Configuration File ~/.config/autostart/monitorDownloadsGUI.desktop in each user’s account. For example, the contents of the file in my account are as follows:

[Desktop Entry]
Type=Application
Exec=/home/fitzcarraldo/.monitorDownloadsGUI

However, I recently noticed that Lubuntu 18.04 does not terminate the monitorDownloadsGUI process when the user logs out. I do not see this behaviour on my laptops running Gentoo Linux with OpenRC and KDE, so I am not sure why this is happening in Lubuntu 18.04 with systemd and LXDE. The output of the ‘ps -ef‘ command after each of the three example steps shown below illustrates the behaviour.

Step 1. george is the only user who is logged-in.

$ ps -ef | grep bash | grep -v grep
george    1410     1  0 02:05 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
george    1597  1358  0 02:05 pts/0    00:00:00 /bin/bash

Step 2. ringo uses ‘Logout’ > ‘Switch User’ to login to his account.

$ ps -ef | grep bash | grep -v grep
george    1410     1  0 02:05 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
george    1597  1358  0 02:05 pts/0    00:00:00 /bin/bash
ringo     2382     1  0 02:06 ?        00:00:00 /bin/bash /home/ringo/.monitorDownloadsGUI

Step 3. ringo logs out of his account.

$ ps -ef | grep bash | grep -v grep
george    1410     1  0 02:05 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
george    1597  1358  0 02:05 pts/0    00:00:00 /bin/bash
ringo     2382     1  0 02:06 ?        00:00:00 /bin/bash /home/ringo/.monitorDownloadsGUI

Notice that the process with PID 2382 is still running, even though user ringo is no longer logged in.

If a user logs out and logs in again, or if users switch between sessions using ‘Logout’ > ‘Switch User’, it is also possible for multiple instances of the script per user to be running. For example:

$ ps -ef | grep bash | grep -v grep
george    1564     1  0 11:14 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
ringo     2522     1  0 11:16 ?        00:00:00 /bin/bash /home/ringo/.monitorDownloadsGUI
george    3803     1  0 11:17 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
george    5997     1  0 11:19 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
george    6054  5881  0 11:19 pts/0    00:00:00 /bin/bash

Notice that several instances of the script are running for user george. There should only be one instance.

In order to prevent these multiple instances, I added the shell script lines below to the existing LightDM session-cleanup-script that I had created previously to solve a different problem in the Lubuntu 18.04 installation (see an earlier blog post).

# Get rid of duplicate instances (if any) per user of the virus-checker script's process
who -u | grep -v "\." > /tmp/logged-in_users
while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
# $f1 is username
# $f2 is password ('x')
# $f3 is UID
# $f4 is GID
# $f5 is UID info
# $f6 is home directory
# $f7 is command/shell
do
    match=0
    while read a b c d e f g h # Use this if this script is launched by LightDM in Lubuntu 18.04
#    while read a b c d e f g # Use this if you launch this script from a terminal in Lubuntu 18.04
    #
    # If this script is launched by a user, 'who -u' returns the following fields:
    # "john     tty7         2019-08-31 17:08 00:01        1624 (:0)"
    # If this script is launched by LightDM, 'who -u' returns the following fields:
    # "john     tty7        Aug 31 17:08 00:01        1624 (:0)"
    #
    do
        if [[ $f6 == *"/home/"* ]] && [[ $f7 == "/bin/bash" ]] && [[ $a == $f1 ]]; then
            match=1
            user=$f1
            tty=$b
        fi
    done < /tmp/logged-in_users
    if [[ $match -eq 1 ]] && [[ $(echo $tty | sed 's/[^0-9]*//g') -gt 6 ]]; then
        if [[ `ps -ef | grep bash | grep "$user" | grep monitorDownloadsGUI | awk -F' ' '{print $2}' | wc -l` -gt 1 ]]; then
            kill `ps -ef | grep bash | grep "$user" | grep monitorDownloadsGUI | awk -F' ' '{print $2}' | tail -n +2`
        fi
    elif [[ $match -ne 1 ]]; then
        if [[ $f6 == *"/home/"* ]] && [[ $f7 == "/bin/bash" ]] && [[ `ps -ef | grep bash | grep "$f1" | grep monitorDownloadsGUI | awk -F' ' '{print $2}' | wc -l` -gt 1 ]]; then
            kill `ps -ef | grep bash | grep "$f1" | grep monitorDownloadsGUI | awk -F' ' '{print $2}' | tail -n +2`
        elif [[ $f6 == *"/home/"* ]] && [[ $f7 == "/bin/bash" ]] && [[ `ps -ef | grep bash | grep "$f1" | grep monitorDownloadsGUI | awk -F' ' '{print $2}' | wc -l` -eq 1 ]]; then
            kill `ps -ef | grep bash | grep "$f1" | grep monitorDownloadsGUI | awk -F' ' '{print $2}'`
        fi
    fi
done < /etc/passwd
rm /tmp/logged-in_users

The above lines of Bash script kill additional instances of monitorDownloadGUI on a per-user basis when a user session ends. If LightDM’s session-cleanup-script does this, there will be no more than one instance of a monitorDownloadsGUI process per logged-in user, and no instances of a monitorDownloadGUI process for users who have logged out:

$ ps -ef | grep bash | grep -v grep
george    1473     1  0 12:32 ?        00:00:00 /bin/bash /home/george/.monitorDownloadsGUI
george    1693  1412  0 12:32 pts/0    00:00:00 /bin/bash

Problem solved. Well, worked around. I would like to know what causes the problem to happen in the first place. I assume it is either systemd or LXDE.

How to run KDE Dolphin, Kate and KWrite as root user

When using KDE I occasionally wish to launch KWrite or Kate as root user in order to edit system files more easily than using a TUI editor in a terminal window (either launched as root user or by using the sudoedit command). Being able to browse using Dolphin as the root user occasionally is also useful. These all used to be possible by launching the application with the kdesu command, but in 2017 KDE developer Martin Gräßlin removed this option on security grounds (see his blog post ‘Editing files as root‘). Attempting to launch e.g. Kate using the sudo command results in the following message:

$ sudo kate
Executing Kate with sudo is not possible due to unfixable security vulnerabilities.

Attempting to launch e.g. Kate using the kdesu command results in a pop-up window prompting me to enter the root user’s password, but then does not launch Kate:

$ kdesu kate
$

I am willing to accept a small risk despite the ‘unfixable security vulnerabilities’ , and a 2018 Kubuntu Forums post by KDE user Rog131 provided me with a solution. It is possible to launch Dolphin, Kate and KWrite as root from your user account by using the pkexec command. For example, to launch Dolphin you can enter:

$ pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true dolphin

Dolphin first displays an orange-coloured box with the warning message ‘Running Dolphin as root can be dangerous. Please be careful.’ and you can then browse and open root-owned directories and files.

You can also launch Kate and KWrite as root from your user account in the same way:

$ pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true kate
$ pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true kwrite

To make it easy to launch them as root user from e.g. Konsole or Yakuake you could set aliases for the three commands in your ~/.bashrc file:

$ tail -n 3 ~/.bashrc
alias dolroot="pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true dolphin"
alias kateroot="pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true kate"
alias kwriteroot="pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true kwrite"

Then all you would need to type in a terminal window would be:

$ dolroot
$ kateroot
$ kwriteroot

which are no more difficult than having to type:

$ kdesu dolphin
$ kdesu kate
$ kdesu kwrite

If an alias is used, rooted-Dolphin/Kate/KWrite can be launched from the command line but cannot be launched via KDE’s Application Launcher menu or KRunner. On the other hand, if a wrapper script is used, rooted-Dolphin/Kate?KWrite can be launched from the user’s command line and via KDE’s Application Launcher menu (and therefore via KRunner too). For example, I created three tiny Bash scripts dolroot, kateroot and kwriteroot. The scripts simply contain the aforementioned pkexec command. For example, dolroot contains:

#!/bin/bash
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY KDE_SESSION_VERSION=5 KDE_FULL_SESSION=true dolphin

Don’t forget to make them executable:

$ chmod 700 dolroot
$ chmod 700 kateroot
$ chmod 700 kwriteroot
$ ls -la *root
-rwx------ 1 fitzcarraldo fitzcarraldo 115 Jul 30 15:33 dolroot
-rwx------ 1 fitzcarraldo fitzcarraldo 112 Jul 30 15:34 kateroot
-rwx------ 1 fitzcarraldo fitzcarraldo 114 Jul 30 15:34 kwriteroot	

After adding entries for dolroot, kateroot and kwriteroot to the KDE Application Launcher’s menu, you can press Alt+F2 as usual to display the KRunner launcher then enter ‘dolroot’, ‘kateroot’ or ‘kwriteroot’ (without the quotes, obviously) in the KRunner window to launch Dolphin/Kate/KWrite as root user. A window will pop-up for you to enter the root user’s password. Once you have entered the root user’s password, the application will be launched.

Thankfully KDE’s Nathaniel Graham is pragmatic:

D12795 – Re-allow running Dolphin as the root user (but still not using sudo)
D12732 – Show a warning when running as the root user

How to change the height of the Kickoff Application Launcher menu in KDE Plasma

The height of the KDE Plasma Kickoff Application Launcher menu is not user-configurable, which is odd in a Desktop Environment with a reputation for being highly user-configurable.

It turns out that the height and width of the pop-up menu are hard-coded in the ASCII file /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml:

root # grep -E "Layout.minimumHeight.*units.gridUnit" /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml
    Layout.minimumHeight: units.gridUnit * 34
root # grep -E "Layout.minimumWidth.*units.gridUnit" /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml
    Layout.minimumWidth: units.gridUnit * 26

Now, I was a bit fed up having to scroll up and down the launcher menu to see all fourteen entries in my Favourites list, so I decided to increase the height of the menu, which I did by editing /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml as root user:

root # nano /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml
root # grep -E "Layout.minimumHeight.*units.gridUnit" /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml
    Layout.minimumHeight: units.gridUnit * 44

The only downside to this is that the file will be overwritten when the package kde-plasma/plasma-desktop is upgraded.

The following command would allow me to make sure the file contains the height value of ’44’ that I want:

root # sed -i '/Layout.minimumHeight: units.gridUnit/ c\    Layout.minimumHeight: units.gridUnit * 44' /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml

Therefore, to automate the editing of the file in my Gentoo installations that use OpenRC I created a shell script /etc/local.d/50-set_Kickoff_height.start with the following contents:

#!/bin/bash
if [ -e /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml ]; then
    sed -i '/Layout.minimumHeight: units.gridUnit/ c\    Layout.minimumHeight: units.gridUnit * 44' /usr/share/plasma/plasmoids/org.kde.plasma.kickoff/contents/ui/FullRepresentation.qml
fi

The FullRepresentation.qml file will then be edited every time the machine boots, which is a tad inefficient but not a big overhead.

This is not a perfect solution because the menu will revert to its default height following an upgrade to the package kde-plasma/plasma-desktop until I reboot the machine, but it is good enough for me.

How to stop inactive user sessions triggering Suspend to RAM in a single-seat, multi-user installation of Lubuntu 18.04

In my previous post I mentioned a problem that I had still not been able to fix in a single-seat, multi-user installation of Lubuntu 18.04: Xfce Power Manager in each user’s account can cause the installation to suspend to RAM if a user has not logged out of his/her session and another user is using a different session. Each user account in Lubuntu 18.04 has its own XfcePower Manager settings, stored in the file ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml. If the property /xfce4-power-manager/inactivity-on-ac has a value of 15 (minutes) or higher, that session can cause the machine to suspend to RAM even if the session is not active while someone else’s session is active. The example below illustrates the effect.

Consider five users mick, christine, john, stevie and lindsey with the following settings for the number of minutes of inactivity that will trigger suspension to RAM:

mick@aspirexc600:~$ xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/inactivity-on-ac
30
christine@aspirexc600:~$ xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/inactivity-on-ac
25
john@aspirexc600:~$ xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/inactivity-on-ac
45
stevie@aspirexc600:~$ xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/inactivity-on-ac
15
lindsey@aspirexc600:~$ xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/inactivity-on-ac
30

Now, suppose that john boots the machine, logs in to his account to check his e-mail, leaves the e-mail client open and goes off to grab lunch without logging out. Then stevie comes along and clicks on ‘Logout’ > ‘Switch User’ to display the LightDM greeter screen (or the greeter screen is already displayed because john‘s session has already been locked), logs in to her account and begins to use, say, LibreOffice Writer. Even though stevie is busy typing, the machine will suspend to RAM after 45 minutes of inactivity by john. This can be very annoying.

In addition to the individual users’ Xfce Power Manager configuration files in Lubuntu 18.04, I found the following Xfce Power Manager configuration files which appear to be system-wide:

/etc/xdg/xdg-Lubuntu/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml
/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml

First attempt at fixing the problem

I asked all the users to configure their accounts to never cause the machine to suspend, by using the Xfce Power Manager settings GUI in their session and selecting ‘Never’. I noticed this caused each user’s /xfce4-power-manager/inactivity-on-ac property to become ‘14‘:

user $ xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/inactivity-on-ac
14

Note that users must not edit their file ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml; if they do, the settings shown in the Xfce Power Manager settings GUI will not be updated. Users must either use the Xfce Power Manager settings GUI or xfconf-query commands as explained on the askubuntu Web page ‘Change xfce4-power-manager option from terminal‘.

Then I edited the file /etc/xdg/xdg-Lubuntu/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml to make its contents the same as the previous contents of the individual users’ settings when Suspend to RAM was enabled individually):

<?xml version="1.0" encoding="UTF-8"?>

<channel name="xfce4-power-manager" version="1.0">
  <property name="xfce4-power-manager" type="empty">
    <property name="power-button-action" type="uint" value="3"/>
    <property name="show-tray-icon" type="bool" value="true"/>
    <property name="brightness-switch-restore-on-exit" type="int" value="1"/>
    <property name="brightness-switch" type="int" value="0"/>
    <property name="presentation-mode" type="bool" value="false"/>
    <property name="inactivity-on-ac" type="uint" value="30"/>
    <property name="blank-on-ac" type="int" value="10"/>
    <property name="dpms-on-ac-sleep" type="uint" value="0"/>
    <property name="dpms-on-ac-off" type="uint" value="0"/>
    <property name="brightness-on-ac" type="uint" value="9"/>
    <property name="lock-screen-suspend-hibernate" type="bool" value="true"/>
    <property name="logind-handle-lid-switch" type="bool" value="false"/>
    <property name="dpms-enabled" type="bool" value="false"/>
    <property name="general-notification" type="bool" value="true"/>
    <property name="sleep-button-action" type="uint" value="0"/>
    <property name="hibernate-button-action" type="uint" value="0"/>
  </property>
</channel>

After rebooting, leaving one or more users logged in without any activity did not cause the installation to suspend to RAM after 30 minutes of no activity in any session.

So I then edited the file /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml to make its contents the same as the above. After rebooting, leaving one or more users logged in without any activity did not cause the installation to suspend to RAM after 30 minutes of no activity in any session.

I therefore assume that the above two files are ignored by Xfce Power Manager during normal operation.

Second attempt at fixing the problem

I used the procedure given in the Xfce4-power-manager FAQs to check if Xfce Power Manager in Lubuntu 18.04 uses systemd-logind to suspend the installation, and indeed it does:

TRACE[xfpm-polkit.c:366] xfpm_polkit_check_auth_intern(): Action=org.freedesktop.login1.suspend is authorized=TRUE

Therefore I edited /etc/systemd/logind.conf to add IdleAction=suspend and IdleActionSec=30min, and rebooted. However, this had no discernable effect either. Leaving one or more users logged in without any activity did not cause the installation to suspend to RAM after 30 minutes of no activity in any session.

Third attempt (successful) at fixing the problem

So, what to do?! In my previous post I explained how I had fixed the problem of not being able to suspend to RAM automatically from the LightDM greeter screen. I decided to keep the scripts from that post and add a new script sessions_sleep.sh to the root crontab. The contents of all the files and the crontab are shown below.

user $ cd /etc/lightdm/lightdm.conf.d/
user $ cat 10_lubuntu.conf 
[Seat:*]
greeter-setup-script=/etc/lightdm/lightdm.conf.d/lightdm_sleep.sh
session-setup-script=/etc/lightdm/lightdm.conf.d/lightdm_kill_sleep.sh
session-cleanup-script=/etc/lightdm/lightdm.conf.d/unmount_FREECOM_HDD.sh
user $ ls
05_lubuntu.conf  lightdm_kill_sleep.sh       sessions_sleep.sh
10_lubuntu.conf  lightdm_sleep.sh            unmount_FREECOM_HDD.sh
user $ cat lightdm_sleep.sh 
#!/bin/bash
# This forms part of the scheme to provide automatic suspension while the greeter screen is displayed
file="/tmp/unique_identifier"
(while true; do sleep 30m; systemctl suspend; done) &
echo $! > $file
user $ cat lightdm_kill_sleep.sh
#!/bin/bash
# This forms part of the scheme to provide automatic suspension while the greeter screen is displayed
file="/tmp/unique_identifier"
if [ -f "$file" ]; then
    kill `cat $file`
    rm $file
fi
user $ tail -n 11 unmount_FREECOM_HDD.sh
#----------------------------------------------------------------------------------------------------
#
# This forms part of the scheme to provide automatic suspension while the greeter screen is displayed
file="/tmp/unique_identifier"
if [ -f "$file" ]; then
    kill `cat $file`
    rm $file
fi
#
#----------------------------------------------------------------------------------------------------
exit 0

If the machine did not already have a permanently-connected external USB HDD (LABEL=”FREECOM HDD”) then it would have sufficed to specify a script named, for example, lightdm_kill_sleep2.sh instead of unmount_FREECOM_HDD.sh:

user $ cat 10_lubuntu.conf 
[Seat:*]
greeter-setup-script=/etc/lightdm/lightdm.conf.d/lightdm_sleep.sh
session-setup-script=/etc/lightdm/lightdm.conf.d/lightdm_kill_sleep.sh
session-cleanup-script=/etc/lightdm/lightdm.conf.d/lightdm_kill_sleep2.sh
user $ cat lightdm_kill_sleep2.sh
#!/bin/bash
# This forms part of the scheme to provide automatic suspension while the greeter screen is displayed
file="/tmp/unique_identifier"
if [ -f "$file" ]; then
    kill `cat $file`
    rm $file
fi
user $ sudo nano sessions_sleep.sh
user $ sudo chmod +x sessions_sleep.sh
user $ cat sessions_sleep.sh 
#!/bin/bash
while true
do
    # Only monitor idle time and suspend after specified inactivity if lightdm_sleep.sh is not taking care of those
    if [[ `ps -ef | grep bash | grep lightdm_sleep.sh | wc -l` -eq 0 ]]; then
        #-------------------------------STAGE 1: FIND OUT WHO IS THE ACTIVE USER--------------------------------------
        #
        while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
        # $f1 is username
        # $f2 is password ('x')
        # $f3 is UID
        # $f4 is GID
        # $f5 is UID info
        # $f6 is home directory
        # $f7 is command/shell
        do
            if [[ $f6 == *"/home/"* ]] && [[ $f7 == "/bin/bash" ]]; then
                if `loginctl list-users | grep -ve '^$\|USER\|listed' | awk -F' ' '{print $2}' | grep -q $f1`; then
                    state=`loginctl show-user $f3 | grep State | awk -F'=' '{print $2}'`
                    if [[ $state != "active" ]]; then
                        inactive_user=$f1
                    elif [[ $state == "active" ]]; then
                        active_user=$f1
                    fi
                fi
            fi
        done < /etc/passwd
        #
        #-------------------------------STAGE 2: ASCERTAIN USER SESSIONS---------------------------------------------
        #
        # Find idle time for each X Windows session and suspend to RAM if the active user has been idle for >=30min.
        #
        who -u | grep -v "\." > /tmp/logged-in_users
        #
        while read a b c d e f g
        # $a is username
        # $b is the tty (tty1 to tty12)
        # $c is the date (yyyy-mm-dd)
        # $d is the time (hh:mm)
        # $e is the idle time (hh:mm) which does not reflect reality in this installation, for some reason
        # $f is the PID
        # $g is the display e.g. "(:1)"
        # Example: "john     tty7         2019-08-31 17:08 00:01        1624 (:0)"
        do
            if [[ $(echo $b | sed 's/[^0-9]*//g') -gt 6 ]]; then
                display=$(echo $g | sed 's/[^0-9]*//g')
                idle_millisecs=$(env DISPLAY=:$display sudo -u $a xprintidle)
                let idle_minutes=$idle_millisecs/60000
                if [[ $idle_minutes -ge 30 ]] && [[ $a == "$active_user" ]]; then
                    systemctl suspend
                fi
            fi
        done < /tmp/logged-in_users
        rm /tmp/logged-in_users
        #
        #------------------------------------------------------------------------------------------------------------
        sleep 10 # Frequency to repeat check
   fi
done

I installed the utility xprintidle via the Linux distribution’s package manager. As the name of the utility suggests, it returns the time (in milliseconds) that an X Windows session has been idle. Nice utility, by the way.

user $ sudo crontab -e
user $ sudo crontab -l | grep -v ^#
@reboot sudo /etc/lightdm/lightdm.conf.d/sessions_sleep.sh

Note that, despite its name, ‘@reboot‘ in the cron job will run the script after a cold boot as well as after a warm boot (reboot). Also note that the use of ‘sudo‘ in the root cron job is not an error; it makes the root cron job use the root user’s environment variables.

Remember that the property /xfce4-power-manager/inactivity-on-ac has to be configured to have a value of 14 (which corresponds to ‘Never’ in the Xfce Power Manager settings GUI) for every user. This should be done by each user using the Xfce Power Manager settings GUI in their own session.

Basically, the scheme works as follows: At boot, Lubuntu 18.04 launches the looping Bash script sessions_sleep.sh, which remains running but does nothing because no X Windows users are logged in. When LightDM runs the greeter-setup-script (lightdm_sleep.sh) and displays the greeter screen, sessions_sleep.sh still does nothing while lightdm_sleep.sh is running and taking care of managing suspension. When an X Windows user logs in and LightDM’s session-setup-script (lightdm_kill_sleep.sh) kills the running script lightdm_sleep.sh, the script sessions_sleep.sh then takes over monitoring users’ activity in X Windows and triggers suspension if the active user has not used his/her session for 30 minutes. If an X Windows user logs out, LightDM’s session-cleanup-script (unmount_FREECOM_HDD.sh) also kills lightdm_sleep.sh if it is running. When LightDM again runs its greeter-setup-script (lightdm_sleep.sh) and displays the greeter screen, that again inhibits sessions_sleep.sh from taking any action if no X Windows user is logged in. This all sounds convoluted, but it seems to work fine so far.

Because Xfce Power Manager is no longer used to monitor idle time and trigger suspension, ‘Presentation mode’ in Xfce Power Manager can no longer prevent the system from suspending after 30 minutes of inactivity while someone is watching a long video or playing music, for example. However this is not a problem; to temporarily inhibit suspension the user can use the method given in my earlier post ‘How to move a mouse pointer automatically in Linux to simulate user activity‘.

The Lubuntu 18.04 architecture

I suspect most Lubuntu 18.04 installations are on laptops or desktop machines with a single user, i.e. single-seat, single-user installations. In such a case, unless the user has created multiple user accounts that he/she logs into concurrently (by using ‘Switch User’, for example), the machine will never suspend unexpectedly while the user is logged in and using the session. I think the way LightDM, light-locker, systemd-logind and Xfce Power Manager have been bundled in Lubuntu 18.04 to manage suspending to RAM is a dog’s breakfast. The design apparently does not take into consideration that different people could be logged in concurrently in a single-seat installation. Try forcing people to log off so that only one person is ever logged in — it won’t happen! To be interrupted by Suspend to RAM triggered by Xfce Power Manager due to inactivity in a different session is illogical; the system should not suspend when someone is actively using the system. Therefore, in my opinion, management of suspension (and hibernation) ought to be configured and managed system-wide, not on a per-user basis, and a design should not require users to hack the installation to the extent I have described above. I was ‘scratching an itch’, but users should not have to jump through hoops to get an installation to function in a sensible manner. For all I know there may be a simpler way of achieving the functionality in Lubuntu 18.04 that I have described in this post and my previous post, but, if there is, it is not obvious. LightDM, light-locker, systemd and Xfce Power Manager are developed by different people, and functionality such as suspension and hibernation does not seem to have been considered using ‘helicopter vision’. Designing disparate applications developed separately to work together holistically is not a trivial task.

Anyway, hopefully I have fixed the problem and also ‘scratched my itch’. No more unexpected suspensions while I am using the family desktop machine!

How to make LightDM suspend to RAM automatically from the login screen and lock screen in Lubuntu 18.04

My family’s desktop machine has Lubuntu 18.04 installed, which generally works well. Each family member has their own account, therefore the installation is a single-seat, multi-user system. Lubuntu 18.04 uses LightDM for the display manager, light-locker (which uses LightDM) for the screen locker, and Xfce Power Manager for power management. Xfce Power Manager enables each user to specify for their session that the machine will suspend to RAM, and to configure the duration of inactivity in their session that will trigger suspension.

However, a couple of things about this arrangement are annoying. Firstly, if two or more users happen to be logged-in simultaneously because a family member does not bother to log out, Xfce Power Manager in an inactive session will eventually suspend the machine even when another user is actively using a different session. Secondly, if nobody is logged-in and the LightDM greeter screen is displayed, the machine will not suspend to RAM automatically after a period of inactivity. The only way to get the machine to suspend to RAM if nobody is logged-in is to click on the power indicator in the greeter’s system tray and select ‘Suspend’ from the drop-down menu.

I still have not figured out how to fix the first of the above-mentioned problems, but a Web search finally turned up a fix for the second problem: a post by Linux user boyi in Arch Linux Forums thread ‘need lightdm to suspend system‘. Below I explain how I implemented this in my family’s Lubuntu 18.04 installation. Basically, when the LightDM greeter screen is displayed LightDM runs a looping shell script (lightdm_sleep.sh) that will suspend the machine after a specified time has elapsed, and either logging in or unlocking the screen will run another shell script (lightdm_kill_sleep.sh) that kills the first script. Once a user has either logged in or unlocked the screen, Xfce Power Manager in that user’s session takes over monitoring activity.

1. Pre-existing situation
When I originally installed Lubuntu 18.04 I made sure each user used the Xfce Power Manager GUI to configure suspension to RAM. Each user’s own settings are shown below:

user $ cat ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml
<?xml version="1.0" encoding="UTF-8"?>

<channel name="xfce4-power-manager" version="1.0">
  <property name="xfce4-power-manager" type="empty">
    <property name="power-button-action" type="uint" value="3"/>
    <property name="show-tray-icon" type="bool" value="true"/>
    <property name="brightness-switch-restore-on-exit" type="int" value="1"/>
    <property name="brightness-switch" type="int" value="0"/>
    <property name="presentation-mode" type="bool" value="false"/>
    <property name="inactivity-on-ac" type="uint" value="30"/>
    <property name="blank-on-ac" type="int" value="10"/>
    <property name="dpms-on-ac-sleep" type="uint" value="0"/>
    <property name="dpms-on-ac-off" type="uint" value="0"/>
    <property name="brightness-on-ac" type="uint" value="9"/>
    <property name="lock-screen-suspend-hibernate" type="bool" value="true"/>
    <property name="logind-handle-lid-switch" type="bool" value="false"/>
    <property name="dpms-enabled" type="bool" value="false"/>
    <property name="general-notification" type="bool" value="true"/>
    <property name="sleep-button-action" type="uint" value="3"/>
    <property name="hibernate-button-action" type="uint" value="3"/>
  </property>
</channel>

Note that each user must not edit their file ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml directly, as the properties in the Xfce Power Manager settings GUI will not be updated if they do. Users must either use the Xfce Power Manager settings GUI or use xfconf-query commands on the command line as explained on the askubuntu Web page ‘Change xfce4-power-manager option from terminal‘.

The LightDM configuration files in /etc/lightdm/lightdm.conf.d/ were as follows:

user $ ls /etc/lightdm/lightdm.conf.d/
05_lubuntu.conf  10_lubuntu.conf  unmount_FREECOM_HDD.sh

The file 05_lubuntu.conf was installed when I installed Lubuntu 18.04. The two files 10_lubuntu.conf and unmount_FREECOM_HDD.sh were previously created by me in order to unmount a permanently-connected external USB HDD when a user logs out, to avoid an access problem when another user logs in (see an earlier blog post).

user $ cat /etc/lightdm/lightdm.conf.d/10_lubuntu.conf
[Seat:*]
session-cleanup-script=/etc/lightdm/lightdm.conf.d/unmount_FREECOM_HDD.sh

2. Modifications to enable installation to suspend when no user is logged in

2.1 Specify the scripts

user $ cd /etc/lightdm/lightdm.conf.d/
user $ sudo nano 10_lubuntu.conf
user $ cat 10_lubuntu.conf 
[Seat:*]
greeter-setup-script =/etc/lightdm/lightdm.conf.d/lightdm_sleep.sh
session-setup-script=/etc/lightdm/lightdm.conf.d/lightdm_kill_sleep.sh
session-cleanup-script=/etc/lightdm/lightdm.conf.d/unmount_FREECOM_HDD.sh

2.2 Create the two scripts

user $ sudo nano lightdm_sleep.sh
user $ sudo chmod +x lightdm_sleep.sh
user $ cat lightdm_sleep.sh 
#!/bin/sh
file="/tmp/unique_identifier"
(while true; do sleep 30m; systemctl suspend; done) &
echo $! > $file
user $ sudo nano lightdm_kill_sleep.sh
user $ sudo chmod +x lightdm_kill_sleep.sh
user $ cat lightdm_kill_sleep.sh 
#!/bin/sh
file="/tmp/unique_identifier"
if [ -f "$file" ]
then
    kill `cat $file`
    rm $file
fi

2.3 Modify the existing session cleanup script to include the lightdm_kill_sleep.sh code

user $ tail -n 11 unmount_FREECOM_HDD.sh
################################################
# Code below copied from lightdm_kill_sleep.sh
file="/tmp/unique_identifier"
if [ -f "$file" ]
then
    kill `cat $file`
    rm $file
fi
# End of code copied from lightdm_kill_sleep.sh
################################################
exit 0

Of course, specifying lightdm_kill_sleep.sh would have sufficed if the installation did not already have a session cleanup script:

user $ cat 10_lubuntu.conf
[Seat:*]
greeter-setup-script =/etc/lightdm/lightdm.conf.d/lightdm_sleep.sh
session-setup-script=/etc/lightdm/lightdm.conf.d/lightdm_kill_sleep.sh
session-cleanup-script=/etc/lightdm/lightdm.conf.d/lightdm_kill_sleep.sh

3. Summary
Thus the file situation is now as follows:

user $ ls /etc/lightdm/lightdm.conf.d/
05_lubuntu.conf  10_lubuntu.conf  lightdm_kill_sleep.sh  lightdm_sleep.sh  unmount_FREECOM_HDD.sh
  • If nobody logs in after booting the machine, the machine will suspend to RAM after 30 minutes* due to greeter-setup-script.
  • If a user logs in, session-setup-script ensures only Xfce Power Manager controls suspension to RAM while the LightDM greeter screen is not displayed.
  • If a user logs out and no other user is logged in, the machine will suspend to RAM after 30 minutes* due to greeter-setup-script.
  • If a user locks the screen, the machine will suspend to RAM after 30 minutes* due to greeter-setup-script.

*Obviously the period of inactivity to trigger suspension to RAM can be configured by changing the time specified in the lightdm_sleep.sh script.

50th anniversary of Apollo 11

I recall watching on live TV in 1969 Neil Armstrong stepping onto the Moon for the first time. I still think the Apollo programme is mankind’s greatest technological achievement to date, especially taking into account the state of the art in the 1960s, albeit massive funding, around 400,000 professionals and some 5,000 companies working on the project helped immensely.

If you have a technical background and are interested in learning a bit about the technical aspects of the equipment and the mission, I can recommend W. David Woods’ book ‘How Apollo Flew to the Moon’. I found the sections on guidance particularly interesting. The book even addresses eating, ablution, urinating, defecating and waste disposal on the journey.

On the 40th anniversary of Apollo 11 I wrote a short post in the Sabayon Linux forums on using Audacity to analyse the recording of Neil Armstrong’s famous “One small step”, which I refreshed in this blog for the 42nd anniversary (see One small step for [a] man… revisited using Audacity).

To mark the 50th anniversary of the launch of Apollo 11, on 16 July this year I went to the cinema to watch the Todd Douglas Millar’s documentary ‘Apollo 11’ (see Apollo 11 [Official Trailer]), which has received good reviews due to its use of 65mm and 70mm footage. Actually, although I very much enjoyed it, quite a lot of the footage used is not 65mm or 70mm, and I found the soundtrack too loud, often making it difficult for me to make out what the controllers and astronauts said. Anyway, if you have not been to see it, I can still recommend it.

This week the UK TV channel BBC Four showed the US PBS (Public Broadcasting Service) excellent multi-part documentary ‘Chasing the Moon‘, which I found riveting. In fact, I much preferred it to Todd Douglas Millar’s ‘Apollo 11’, although the two documentaries are different animals and not really directly comparable. Anyway, if you are interested in the US-USSR space race, the internal politics behind the Apollo programme, and the Mercury, Gemini and Apollo programmes, I can thoroughly recommend ‘Chasing the Moon’, which is to be released shortly on DVD if you do not have the chance to catch it on TV or to stream it. I found the comments by Sergei Krushchev (the son of Nikita Khrushchev) particularly interesting, especially his mention about the hushed-up death of a Soviet cosmonaut in a fire during a test with a pure-oxygen environment prior to the Apollo 1 accident. If the Americans had known about this, it might have prevented the equally gruesome deaths of Grissom, White, and Chaffee in 1967.

YouTube is a gold mine if you are interested in old and newer films, documentaries and vlogs on the Apollo programme. There are hundreds of videos about it. If you are a computer buff, the videos on the AGC (Apollo Guidance Computer) are fascinating. The recent series of videos on the restoration to working condition of a privately-owned scrapped AGC are fascinating. Below are a few of the documentaries and videos I have watched this week to celebrate the 50th anniversary of Apollo 11. I have included links to a couple of the videos in the above-mentioned series on restoration of an AGC; you will be able to find the others in the series if you are interested.

  1. Chasing the Moon
  2. Spacecraft Films The Mighty Saturns Part I The Early Saturns
  3. Spacecraft Films The Mighty Saturns Part II The Saturn V
  4. Moon Machines: Command Module (2/6)
  5. Moon Machines: Navigation Computer (3/6)
  6. Moon Machines: Lunar Module (4/6)
  7. MIT Science Reporter – Computer for Apollo (1965)
  8. MIT Science Reporter – Landing on the Moon (1966)
  9. MIT Science Reporter – Returning from the Moon (1966)
  10. MIT Science Reporter – Food For Space Travelers (1966)
  11. The Real Story Behind the Apollo 11 Computer Error | WSJ
  12. The Journeys of Apollo
  13. The Apollo 4 Mission (1967)
  14. The Flight Of Apollo 7 (1968)
  15. Apollo 8 – Go For TLI (1969)
  16. Apollo 10 – To Sort Out The Unknowns (1969)
  17. Apollo 11 Saturn V Launch Camera E-8
  18. Restored Apollo 11 Moonwalk – Original NASA EVA Mission Video – Walking on the Moon
  19. Moon in Google Earth – Apollo 11 Landing
  20. Hear Buzz Aldrin tell the story of the first moon landing
  21. NASA: Moon Landing – Apollo 11 Descent Film and LRO [Lunar Reconnaissance Orbiter] Imagery
  22. Apollo 11: The Complete Descent
  23. Why were there missing rungs on the Lunar Lander’s Ladder?
  24. Apollo AGC Part 1: Restoring the computer that put man on the Moon
  25. Apollo AGC Part 23: Flying realistic Apollo 11 moon landings with the Apollo Guidance Computer
  26. An Audience with Neil Armstrong (2011 interview)
  27. Apollo 11 crew member [Buzz Aldrin]
  28. WATCH: Astronaut Michael Collins discusses the Apollo 11 launch 50 years later
  29. Apollo’s Most Important Discovery (Inside NASA’s Moon Rock Vault!)
  30. Where does NASA keep the Moon Rocks? – Smarter Every Day 220
  31. APOLLO MOON SUIT: demonstration of functioning, and manufacturing (1969)
  32. Moon Machines: Space Suit (5/6)
  33. The Space Suit Special

Conspiracy theories and their debunking

  1. NASA: Moon Landing – Apollo 11 Descent Film and LRO [Lunar Reconnaissance Orbiter] Imagery
  2. Moon-Landing Hoax Still Lives On, 50 Years After Apollo 11. But Why?
  3. Apollo and the moon-landing hoax
  4. Moon landing conspiracy theories – Hoax claims and rebuttals
  5. A Brief History of Moon Hoaxes – Why do people still believe in them?
  6. Why Faking the Moon Landing Was Impossible
  7. Debunking the Myth that the Moon Landing Was a Hoax
  8. Nvidia Debunks Conspiracy Theories About Moon Landing
  9. Moon Hoax: Debunked!
  10. The Space Suit Special

The USSR

And, finally, these videos about the USSR’s failed attempt to put a man on the Moon are worth watching:

  1. Why Russia Did Not Put a Man on the Moon – The Secret Soviet Moon Rocket
  2. Soviet N1 Moon Rocket Documentary

Amazing that the NK-33 closed-cycle engines originally developed for the N1 were purchased by a US company, modified and finally used in a new launcher in 2013. The later and larger RD-180, also a Russian closed-cycle engine, is – if I understand correctly – still used to power US Atlas rockets until US-designed replacements are available.

Why I switched from WhatsApp to Signal

I had avoided WhatsApp until late 2017 when one of my family installed it on my phone with the promise I would find it useful to keep in touch during a two-month work trip. Actually, it turned out to be more useful for work, as WhatsApp is the preferred method of communication at the company I visited on that trip.

Now, I was aware that Facebook acquired WhatsApp in 2014 for US$19 billion. I do not have a Facebook account and have no intention of getting one, and the fact Facebook owns WhatsApp was one of the reasons I had been reluctant to install WhatsApp in the first place. However, it didn’t take me long to like WhatsApp. The UI is very well designed, the functionality excellent and WhatsApp Web is easy and convenient to use. WhatsApp is a polished product, no doubt about that. The end-to-end encryption of WhatsApp messages is comforting, although that was not my main reason for using it. Offhand I can only think of one function I find annoying in the WhatsApp UI: when you forward a message containing an image, there is no automatic way to include the text accompanying the original message.

Recently I have read several articles stating that Facebook intends to display advertising in WhatsApp from 2020 onwards. I am sick and tired of ‘surveillance capitalism‘ tracking me and bombarding me with advertising on the Web, and this news prompted me to search for a replacement for WhatsApp. A newspaper article mentioned Signal, which I learned happens to be the source of the encryption protocol used by WhatsApp. I also learned that WhatsApp co-founder Brian Acton, who left Facebook in 2017, is Executive Chairman of the Signal Foundation, which he co-founded with the creator of Signal in 2018. So I decided to give Signal a try, and was pleasantly surprised as the UI is very similar to WhatsApp. OK, it’s not quite as polished aesthetically, but it was easy to use from the get-go.

I initially found Signal’s security-related functionality confusing. I was not sure what the so-called ‘Safety Number‘ per contact does. It turns out that you can ensure your connection with a given contact is secure by ‘verifying the Safety Number’ with that contact. From then onwards ‘Verified‘ will appear next to the contact’s name and phone number at the top of the conversation window. Verifying the Safety Number is optional, which was not clear to me initially. Each contact’s Safety Number is actually a 3 x 4 table of 5-digit numbers. You should compare the Safety Number in your app with the Safety Number in your contact’s app in a way that prevents someone intercepting you both; you can either scan a QR Code or make a visual or audible comparison of the Safety Number in your app with the Safety Number in your contact’s app. If both Safety Number tables match, you can both click on ‘Mark as verified’ in your app. The app will then warn you if a safety number has been changed because someone is intercepting your conversation (a so-called ‘man-in-the-middle’ attack).

The other security-related function I found confusing initially is resetting a session (‘Settings’ > ‘Reset session’). It is normally not necessary for you to touch this, but, if for some reason the encryption keys between two contacts no longer match (the Signal app would notify you if that occurs), either party can reset their session and force Signal to negotiate a new session.

Unlike WhatsApp, Signal does not have a Web browser UI to use on desktop machines. It used to have such an interface (using Google’s Chrome browser) but now there is a Signal desktop app instead, with versions available for Windows, Mac OS and Linux. I have Gentoo Linux on my laptops and Lubuntu Linux on the family desktop, so I have installed the Linux desktop Signal app on those machines.

Unlike WhatsApp, the phone app and the desktop app do not sync earlier messages. By this I mean that, if you install the desktop app and launch it, you will not see any earlier messages that are visible in the phone app. Similarly, if you delete a message in the phone app it will not be deleted in the desktop app, and vice versa. This is a bit of a nuisance, but is OK once you get used to it. Perhaps this has been done with security as well as storage capacity in mind; Signal stores as little of your data as possible on its servers.

Below are a few aspects of Signal functionality that I prefer over WhatsApp:

  • In the phone app it is possible to set the colour of the background (‘wallpaper’) for contacts, not just the top-level page. Thus I have made the background black for contacts to help a little to conserve the phone’s battery charge.
  • When I forward a message that includes an image, Signal includes the original text as well as the image. Further more, it gives me the opportunity to edit the message text before actually forwarding the message.
  • When I forward a message containing an image, the whole image is displayed. For example, recently someone sent me a WhatsApp message containing a cartoon which I did not understand; I did not realise there was a caption until I tapped on the image to expand it. When I forwarded the message to a Signal contact (by selecting the message in WhatsApp and tapping the Share icon), the caption at the bottom of the cartoon was visible in the resulting Signal message without needing to tap on the image.
  • The Signal phone app lets you disable link previews (a.k.a. ‘URL previews’) easily in Settings, whereas you cannot disable link previews in WhatsApp (see Should WhatsApp let you disable URL previews?).
  • Signal allows you to specify a message lifetime (‘Disappearing messages’). You can specify that messages will never be deleted automatically, or will be deleted after a certain time has elapsed (user-selectable from 5 seconds up to 1 week).
  • Although WhatsApp uses Signal’s encryption technology, unlike Signal it does not encrypt backups.
  • Unlike WhatsApp, Signal does not store message metadata.
  • Signal is fully open-source (and free of charge, with a promise of no advertising). WhatsApp is closed-source.
  • The icons of contacts are obtained from your phone’s contact list, not specified within the app itself. Some of my WhatsApp contacts have not bothered to create an icon in WhatsApp, but I had set up an icon for them in my phone’s contact list, and that icon is used in Signal.

Below are a few aspects of WhatsApp functionality that I prefer over Signal:

  • Signal has the ability to show link previews for a few Web sites (currently for Imgur, Instagram, Reddit, and YouTube only), whereas WhatsApp shows them for all sites. (From a security perspective some people might regard this as a disadvantage of WhatsApp.)
  • I prefer the white/green ticks in WhatsApp to the unfilled/filled circles with ticks in Signal, but that is purely an aesthetic opinion.
  • WhatsApp syncs all messages between the phone app and the Web UI, not just new messages, whereas Signal just syncs the messages sent and received since you installed the desktop app. (From a Security perspective some people might regard this as an advantage of Signal over WhatsApp.)

Conclusion

In general I find Signal as good as WhatsApp, if not better. I had been worried I would not find an alternative to WhatsApp that is as easy to use and as intuitive. In fact Signal is very good, and, once you understand the security features I mentioned above, it is essentially the same as WhatsApp, which was a relief to me as I like the general concept of the WhatsApp UI.

At the moment I am having to use both WhatsApp and Signal because some of my contacts only use WhatsApp, but I have already persuaded some contacts to switch to Signal and I anticipate more will migrate to Signal once WhatsApp begins displaying adverts next year.

How to chroot in Sabayon Linux

Example 1: Sabayon Linux was installed in conventional partitions

Let’s say, for example, that the installation has three partitions: /dev/sda1 (EFI System Partition formatted with FAT32); /dev/sda2 (root partition formatted with ext4); /dev/sda3 (linuxswap). Modify the mount command below accordingly if the root directory is on a different partition. In this example, /boot is on the same partition as root (/) and therefore does not need to be mounted separately.

Boot a Sabayon Linux LiveDVD or LivePenDrive, open a terminal window and enter the following commands:

sabayonuser@sabayon ~ $ su
sabayon sabayonuser # fdisk -l # Ascertain the partitioning scheme.
sabayon sabayonuser # mkdir /mnt/mychroot
sabayon sabayonuser # mount /dev/sda2 /mnt/mychroot
sabayon sabayonuser # mount --rbind /dev /mnt/mychroot/dev
sabayon sabayonuser # mount --make-rslave /mnt/mychroot/dev
sabayon sabayonuser # mount -t proc /proc /mnt/mychroot/proc
sabayon sabayonuser # mount --rbind /sys /mnt/mychroot/sys
sabayon sabayonuser # mount --make-rslave /mnt/mychroot/sys
sabayon sabayonuser # mount --rbind /tmp /mnt/mychroot/tmp
sabayon sabayonuser # chroot /mnt/mychroot /bin/bash
sabayon / # source /etc/profile
sabayon / # env-update
>>> Regenerating /etc/ld.so.cache...
sabayon / # export PS1="(chroot) $PS1"
(chroot) sabayon / # 

Now you can enter whatever commands you want in the chrooted environment. When you have finished, exit the chroot as follows:

(chroot) sabayon / # exit
exit
sabayon sabayonuser # umount -R /mnt/mychroot/tmp /mnt/mychroot/sys /mnt/mychroot/proc /mnt/mychroot/dev /mnt/mychroot
sabayon sabayonuser # shutdown -h now

Example 2: Sabayon Linux was installed in a logical volume

Let’s say, for example, that the installation has three partitions: /dev/sda1 (EFI System Partition formatted with FAT32); /dev/sda2 (/boot partition formatted with ext4); /dev/sda3 as the LVM Physical Volume with Volume Group sabayon_sabayon containing Logical Volumes root (formatted as ext4) and swap (linuxswap). Modify the mount commands accordingly if the structure is different in your case. In this example, /boot is not on the same partition as root (/) and therefore needs to be mounted separately.

Boot a Sabayon Linux LiveDVD or LivePenDrive, open a terminal window and enter the following commands:

sabayonuser@sabayon ~ $ su
sabayon sabayonuser # fdisk -l # Ascertain the partitioning scheme.
sabayon sabayonuser # pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda3
  VG Name               sabayon_sabayon
  PV Size               39.31 GiB / not usable 2.00 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              10064
  Free PE               1
  Allocated PE          10063
  PV UUID               489QRE-rvgD-JUXz-ZYad-1DM7-XNwr-lDFVNw

sabayon sabayonuser # vgdisplay
  --- Volume group ---
  VG Name               sabayon_sabayon
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               39.31 GiB
  PE Size               4.00 MiB
  Total PE              10064
  Alloc PE / Size       10063 / 39.31 GiB
  Free  PE / Size       1 / 4.00 MiB
  VG UUID               oZ2s2c-fm35-VBCT-ef3i-n8OJ-79a2-IOJ5iW

sabayon sabayonuser # lvdisplay
  --- Logical volume ---
  LV Path                /dev/sabayon_sabayon/swap
  LV Name                swap
  VG Name                sabayon_sabayon
  LV UUID                dNoMjX-yv7i-3UVR-vG2s-jsJG-PHfX-BvCYs9
  LV Write Access        read/write
  LV Creation host, time sabayon, 2018-01-05 22:55:16 +0000
  LV Status              available
  # open                 0
  LV Size                2.00 GiB
  Current LE             512
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           251:0
   
  --- Logical volume ---
  LV Path                /dev/sabayon_sabayon/root
  LV Name                root
  VG Name                sabayon_sabayon
  LV UUID                Lf81Ni-LfMu-Pifu-UUzl-ypKK-xSUc-pPfawz
  LV Write Access        read/write
  LV Creation host, time sabayon, 2018-01-05 22:55:17 +0000
  LV Status              available
  # open                 0
  LV Size                37.31 GiB
  Current LE             9551
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           251:1

sabayon sabayonuser # pvscan
File descriptor 16 (socket:[30370]) leaked on pvscan invocation. Parent PID 2635: bash
  PV /dev/sda3   VG sabayon_sabayon   lvm2 [39.31 GiB / 4.00 MiB free]
  Total: 1 [39.31 GiB] / in use: 1 [39.31 GiB] / in no VG: 0 [0   ]
sabayon sabayonuser # vgscan
File descriptor 16 (socket:[30370]) leaked on vgscan invocation. Parent PID 2635: bash
  Reading volume groups from cache.
  Found volume group "sabayon_sabayon" using metadata type lvm2
sabayon sabayonuser # vgchange -ay
File descriptor 16 (socket:[30370]) leaked on vgchange invocation. Parent PID 2635: bash
  2 logical volume(s) in volume group "sabayon_sabayon" now active
sabayon sabayonuser # lvscan
File descriptor 16 (socket:[30370]) leaked on lvscan invocation. Parent PID 2635: bash
  ACTIVE            '/dev/sabayon_sabayon/swap' [2.00 GiB] inherit
  ACTIVE            '/dev/sabayon_sabayon/root' [37.31 GiB] inherit
sabayon sabayonuser # mkdir /mnt/mychroot
sabayon sabayonuser # mount /dev/sabayon_sabayon/root /mnt/mychroot
sabayon sabayonuser # mount /dev/sda2 /mnt/mychroot/boot
sabayon sabayonuser # mount --rbind /dev /mnt/mychroot/dev
sabayon sabayonuser # mount --make-rslave /mnt/mychroot/dev
sabayon sabayonuser # mount -t proc /proc /mnt/mychroot/proc
sabayon sabayonuser # mount --rbind /sys /mnt/mychroot/sys
sabayon sabayonuser # mount --make-rslave /mnt/mychroot/sys
sabayon sabayonuser # mount --rbind /tmp /mnt/mychroot/tmp
sabayon sabayonuser # chroot /mnt/mychroot /bin/bash
sabayon / # source /etc/profile
sabayon / # env-update
>>> Regenerating /etc/ld.so.cache...
sabayon / # export PS1="(chroot) $PS1"
(chroot) sabayon / # 

Now you can enter whatever commands you want in the chrooted environment. For example:

(chroot) sabayon / # equo version
319

When you have finished, exit the chroot as follows:

(chroot) sabayon / # exit
exit
sabayon sabayonuser # umount -R /mnt/mychroot/tmp /mnt/mychroot/sys /mnt/mychroot/proc /mnt/mychroot/dev /mnt/mychroot/boot /mnt/mychroot
sabayon sabayonuser # equo version
310
sabayon sabayonuser # shutdown -h now

In the example above I have used the ‘equo version‘ command in the chroot environment and in the LiveDVD environment, simply to illustrate that the two environments are not the same. As you can see, the LiveDVD I used has the package equo-310 installed, whereas the installation on the HDD has equo-319 installed.

By the way, if using the Sabayon Linux KDE LiveDVD/LivePenDrive, I discovered that the LVM command ‘vgchange -ay‘ can be omitted if I launch the KDE Partition Manager:

sabayon sabayonuser # partitionmanager

I just look at the partitions in the KDE Partition Manager’s GUI and quit the application (‘File’ > ‘Quit’).