Introduction to systemd for SysV
Systemd is an all-in-one package
providing init (PID
1) and various services such as managing daemons, sessions, locale,
etc. It can do that for the whole system (“system” mode, supposed
to run as PID 1) or for users (“user” mode). For SysV, the system mode should
not be needed, except that more and more packages require the user
mode and the user mode relies on the system mode daemon running to
start. Systemd must therefore be
modified so that the system mode can run as a normal daemon (not
PID 1), and does not perform all the initializations it would
perform as an init system.
Note
Development versions of BLFS may not build or run some packages
properly if LFS or dependencies have been updated since the most
recent stable versions of the books.
Package Information
systemd Dependencies
Required
dbus-1.16.2 (runtime)
Recommended
Note
Linux-PAM-1.7.2 is not strictly required to
build systemd, but the main
reason to build systemd is for
the systemd-logind
daemon and the pam_systemd.so PAM
module. Linux-PAM-1.7.2 is required for them. All
packages in BLFS book with a dependency on systemd expect that it has been built with
Linux-PAM-1.7.2.
Linux-PAM-1.7.2 and Polkit-127
(runtime)
Optional
btrfs-progs-6.17.1, cURL-8.18.0,
cryptsetup-2.8.4, git-2.53.0, iptables-1.8.11, libarchive-3.8.5,
libidn2-2.3.8, libpwquality-1.4.5, libseccomp-2.6.0,
libxkbcommon-1.13.1, make-ca-1.16.1, p11-kit-0.26.2, qemu-10.2.0,
libqrencode-4.1.1, rsync-3.4.1,
sphinx-9.1.0, Valgrind-3.26.0,
zsh-5.9 (for the zsh completions), AppArmor, audit-userspace,
bash-completion,
jekyll, kexec-tools,
libbpf, libdw, libfido2,
libmicrohttpd,
pefile, pyelftools,
quota-tools,
rpm, SELinux,
systemtap, tpm2-tss and
Xen
Optional (to rebuild the manual pages)
docbook-xml-4.5, docbook-xsl-nons-1.79.2, libxslt-1.1.45, and lxml-6.0.2 (to
build the index of systemd manual pages)
Editor Notes: https://wiki.linuxfromscratch.org/blfs/wiki/Logind
Kernel
Configuration
Enable the following options in the kernel configuration and
recompile the kernel if necessary:
General setup --->
[*] Control Group support ---> [CGROUPS]
[ /*] CPU controller ---> [CGROUP_SCHED]
File systems --->
[*] Inotify support for userspace [INOTIFY_USER]
Pseudo filesystems --->
[*] Tmpfs virtual memory file system support (former shm fs) [TMPFS]
[*] Tmpfs POSIX Access Control Lists [TMPFS_POSIX_ACL]
Installation of systemd
Warning
If a previous version of systemd has been installed, remove a
service that will generate errors on following boots. As the
root user:
rm -fv /usr/lib/systemd/system/systemd-update-utmp-runlevel.service
Remove some tests in the program ensuring it can only be run as PID
1 in system mode:
sed -e '/^ if (arg_action == ACTION_RUN &&$/,+4s|^|//|' \
-i src/core/main.c &&
sed -e '/private bus only/,+2s|^|//|' \
-i src/core/dbus.c
Remove two unneeded groups, render
and sgx, from the default udev
rules:
sed -i -e 's/GROUP="render"/GROUP="video"/' \
-e 's/GROUP="sgx", //' rules.d/50-udev-default.rules.in
Build systemd by running the following commands:
mkdir build &&
cd build &&
meson setup .. \
--prefix=/usr \
--buildtype=release \
-D default-dnssec=no \
-D firstboot=false \
-D install-tests=false \
-D ldconfig=false \
-D man=auto \
-D sysusers=false \
-D rpmmacrosdir=no \
-D homed=disabled \
-D mode=release \
-D pam=enabled \
-D pamconfdir=/etc/pam.d \
-D dev-kvm-mode=0660 \
-D nobody-group=nogroup \
-D sysupdate=disabled \
-D ukify=disabled \
-D docdir=/usr/share/doc/systemd-259.1 &&
ninja
This package can only be tested on a system booted with systemd.
Installation should not overwrite already installed files from
Udev in LFS. So first do a DESTDIR
install:
DESTDIR=$(pwd)/dest ninja install
Then, as the root user:
pushd dest &&
find . | while read -r p; do
p=${p#.}
if [ -z "$p" ]; then continue; fi
q=${p/systemd/udev}
if [ -e "$p" ]; then continue; fi
if [ -e "$q" ] &&
! [ -e ."$q" ] &&
! [ -d ."$p" ]; then continue; fi
if ! [ -h ."$p" ] &&
[ -d ."$p" ]; then
m=$(stat -c %a ."$p")
mkdir -m $m "$p"
else
cp -P --preserve=mode,xattr ."$p" "$p";
fi
done
popd
Command Explanations
--buildtype=release:
Specify a buildtype suitable for stable releases of the package, as
the default may produce unoptimized binaries.
-D pamconfdir=/etc/pam.d:
Forces the PAM files to be installed in /etc/pam.d rather than
/usr/lib/pam.d.
-D homed=disabled: Removes
a daemon that does not offer any use under a traditional BLFS
configuration, especially using accounts created with useradd. To
enable systemd-homed, first ensure that you have cryptsetup-2.8.4 and libpwquality-1.4.5 installed, and then
change “disabled” to “enabled” in the above
meson setup command.
-D ukify=disabled: Removes
a script for combining a kernel, an initramfs, and a kernel command
line etc. into an UEFI application which can be loaded by the UEFI
firmware to start the embedded Linux kernel. It's not needed for
booting a BLFS system with UEFI if following Using GRUB to Set
Up the Boot Process with UEFI. And, it requires the
pefile Python module at runtime,
so if it's enabled but pefile is
not installed, one test for it will fail in the test suite. To
enable systemd-ukify,
install the pefile module and then
change “disabled” to “enabled” in the above
meson setup command.
Configuring systemd
The /etc/pam.d/system-session file
needs to be modified and a new file needs to be created in order
for systemd-logind to
work correctly. Run the following commands as the root user:
grep 'pam_systemd' /etc/pam.d/system-session ||
cat >> /etc/pam.d/system-session << "EOF"
# Begin Systemd addition
session required pam_loginuid.so
session optional pam_systemd.so
# End Systemd addition
EOF
cat > /etc/pam.d/systemd-user << "EOF"
# Begin /etc/pam.d/systemd-user
account required pam_access.so
account include system-account
session required pam_env.so
session required pam_limits.so
session required pam_loginuid.so
session optional pam_keyinit.so force revoke
session optional pam_systemd.so
auth required pam_deny.so
password required pam_deny.so
# End /etc/pam.d/systemd-user
EOF
The “system”
mode of systemd should now be restricted to only start a minimum
set of daemons. As the root user:
rm -v /usr/lib/systemd/system-generators/* &&
grep -l systemctl /usr/lib/udev/rules.d/* | \
xargs sed -i '/systemctl/s/^/#/' &&
grep -l systemd-sysctl /usr/lib/udev/rules.d/* | \
xargs sed -i '/systemd-sysctl/s/^/#/' &&
for t in sysinit.target basic.target; do
sed -E '/^(Wants|After|Conflicts|Requires|Before)/s/^/#/' \
/usr/lib/systemd/system/$t > /etc/systemd/system/$t
done &&
rm -rfv /usr/lib/systemd/system/sysinit.target.wants.ignore &&
mv /usr/lib/systemd/system/sysinit.target.wants{,.ignore} &&
ln -sfv sysinit.target /etc/systemd/system/default.target &&
mkdir -pv /etc/systemd/system/sysinit.target.wants &&
for u in systemd-journal-catalog-update.service \
systemd-journal-flush.service \
systemd-journald.service \
systemd-logind.service; do
cp -v /usr/lib/systemd/system/$u /etc/systemd/system &&
ln -sfv ../$u /etc/systemd/system/sysinit.target.wants
done &&
ln -sfv /dev/null /etc/systemd/system/tmp.mount
Now the shutdown process of systemd has to be modified to interact nicely
with SysV. This is done by
introducing a unit that triggers a switch to runlevel 1 at the
beginning of the systemd shutdown process and by replacing the
systemd-shutdown
executable with a small script. As the root user:
cat > /etc/systemd/system/telinit1.service << EOF &&
[Unit]
Description=trigger single user mode at shutdown
# Must trigger before shutting down dbus
After=dbus.service
[Service]
Type=oneshot
ExecStop=/usr/sbin/telinit 1
ExecStop=/usr/bin/sleep 1
RemainAfterExit=yes
EOF
ln -s ../telinit1.service /etc/systemd/system/sysinit.target.wants &&
mv /usr/lib/systemd/systemd-shutdown{,.orig} &&
cat > /usr/lib/systemd/systemd-shutdown <<"EOF" &&
#!/usr/bin/bash
while [ -n "$1" ]; do
case "$1" in
--*) shift; continue ;;
reboot|poweroff|halt|kexec|exit) cmd="$1"; break ;;
*) echo Unrecognized option: $1; exit 1 ;;
esac
done
if [ -z "$cmd" ]; then echo No command given; exit 1; fi
if [ reboot = "$cmd" ]; then telinit 6
else telinit 0
fi
EOF
chmod a+x /usr/lib/systemd/systemd-shutdown
Boot Script
A desktop environment often runs as a group of systemd user
services. Those services are spawned by the systemd per-user
instance, instead of the login shell. To ensure those services
get the environment variables we've set via /etc/profile.d, as the root user, install a systemd environment
generator to dump all the relevant exported environment variables
into the systemd per-user instance when the instance starts to
run:
install -vdm755 /etc/systemd/user-environment-generators &&
cat > /etc/systemd/user-environment-generators/50-profile.sh << "EOF" &&
#!/usr/bin/env -S -i /usr/bin/bash
# SPDX-License-Identifier: MIT
. /etc/profile
# Systemd should have already set a better value for them.
unset XDG_RUNTIME_DIR
for i in $(locale); do
unset ${i%=*}
done
# Some shell magic that we don't want to expose.
unset SHLVL
# Systemd does not want to pass functions to the environment
for i in $(declare -pF | awk '{print $3}'); do
unset -f $i
done
python3 << _EOF
import os
for var in os.environ:
# Simply unsetting them in shell does not work.
if var in ['LC_CTYPE', '_']:
continue
print(var + '=' + os.environ[var])
_EOF
EOF
chmod -v 755 /etc/systemd/user-environment-generators/50-profile.sh
Read systemd.environment-generator(7)
for details about the systemd environment generators. Note that
if you've edited the content of /etc/profile.d when a desktop environment is
running, you need to run the systemctl --user daemon-reload
command to sync the change into the systemd per-user instance,
and then log out and log in again to sync the change into the
desktop environment.
To automatically start the systemd daemon when the system
is rebooted, install the /etc/rc.d/init.d/systemd bootscript from the
blfs-bootscripts-20260204-sysdonv package
as the root user:
make install-systemd
Contents
A list of the installed files, along with their short descriptions
can be found at
../../../../lfs/view/development/chapter08/systemd.html#contents-systemd.
Listed below are the newly installed programs along with short
descriptions.
Short Descriptions
|
homectl
|
is a tool to create, remove, change, or inspect a home
directory managed by systemd-homed; note
that it's useless for the classic UNIX users and home
directories which we are using in LFS/BLFS book
|
|
systemd-cryptenroll
|
Is used to enroll or remove a system from full disk
encryption, as well as set and query private keys and
recovery keys
|
|
systemd-cryptsetup
|
Attaches or removes an encrypted block device
|
|
pam_systemd.so
|
is a PAM module used to register user sessions with the
systemd login manager,
systemd-logind
|