mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-12 09:17:44 +03:00
d12e9bdc76
If mkosi.kernel/ exists, the mkosi script will try to build a kernel image from it. We use the architecture defconfig as a base and add our own extra configuration on top. We also add some extra tooling to the build image required to build the kernel and include some documentation in HACKING.md on how to use this new feature. To avoid the kernel sources from being copied into the build or final image (which we don't want because it takes a while), we put the mkosi.kernel/ directory in .gitignore and use "SourceFileTransfer=mount" so that the sources are still accessible in the build image.
299 lines
11 KiB
Bash
Executable File
299 lines
11 KiB
Bash
Executable File
#!/bin/sh
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
set -e
|
|
|
|
# This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
|
|
# Simply invoke "mkosi" in the project directory to build an OS image.
|
|
|
|
ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1
|
|
UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
|
|
|
|
# On Fedora "ld" is (unfortunately — if you ask me) managed via
|
|
# "alternatives". Since we'd like to support building images in environments
|
|
# with only /usr/ around (e.g. mkosi's UsrOnly=1 option), we have the problem
|
|
# that /usr/bin/ld is a symlink that points to a non-existing file in
|
|
# /etc/alternative/ in this mode. Let's work around this for now by manually
|
|
# redirect "ld" to "ld.bfd", i.e. circumventing the /usr/bin/ld symlink.
|
|
if [ ! -x /usr/bin/ld ] && [ -x /usr/bin/ld.bfd ]; then
|
|
mkdir -p "$HOME"/bin
|
|
ln -s /usr/bin/ld.bfd "$HOME"/bin/ld
|
|
PATH="$HOME/bin:$PATH"
|
|
fi
|
|
|
|
# If mkosi.builddir/ exists mkosi will set $BUILDDIR to it, let's then use it
|
|
# as out-of-tree build dir. Otherwise, let's make up our own builddir.
|
|
[ -z "$BUILDDIR" ] && BUILDDIR=build
|
|
|
|
# Meson uses Python 3 and requires a locale with an UTF-8 character map.
|
|
# Not running under UTF-8 makes the `ninja test` step break with a CodecError.
|
|
# So let's ensure we're running under UTF-8.
|
|
#
|
|
# If our current locale already is UTF-8, then we don't need to do anything:
|
|
if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ] ; then
|
|
# Try using C.UTF-8 locale, if available. This locale is not shipped
|
|
# by upstream glibc, so it's not available in all distros.
|
|
# (In particular, it's not available in Arch Linux.)
|
|
if locale -a | grep -q -E "C.UTF-8|C.utf8"; then
|
|
export LC_CTYPE=C.UTF-8
|
|
# Finally, try something like en_US.UTF-8, which should be
|
|
# available in Arch Linux, but is not present in Debian's
|
|
# minimal image in our mkosi config.
|
|
elif locale -a | grep -q en_US.utf8; then
|
|
export LC_CTYPE=en_US.UTF-8
|
|
else
|
|
# If nothing works, fail early.
|
|
echo "*** Could not find a valid locale that supports UTF-8. ***" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# The bpftool script shipped by Ubuntu tries to find the actual program to run via querying `uname -r` and
|
|
# using the current kernel version. This obviously doesn't work in containers. As a workaround, we override
|
|
# the ubuntu script with a symlink to the first bpftool program we can find.
|
|
for bpftool in /usr/lib/linux-tools/*/bpftool; do
|
|
[ -x "$bpftool" ] || continue
|
|
ln -sf "$bpftool" /usr/sbin/bpftool
|
|
break
|
|
done
|
|
|
|
if [ ! -f "$BUILDDIR"/build.ninja ] ; then
|
|
sysvinit_path=$(realpath /etc/init.d)
|
|
|
|
init_path=$(realpath /sbin/init 2>/dev/null)
|
|
if [ -z "$init_path" ] ; then
|
|
rootprefix=""
|
|
else
|
|
rootprefix=${init_path%/lib/systemd/systemd}
|
|
rootprefix=/${rootprefix#/}
|
|
fi
|
|
|
|
meson "$BUILDDIR" \
|
|
-D "sysvinit-path=$sysvinit_path" \
|
|
-D "rootprefix=$rootprefix" \
|
|
-D man=false \
|
|
-D translations=false \
|
|
-D version-tag="${VERSION_TAG}" \
|
|
-D mode=developer \
|
|
-D b_sanitize="${SANITIZERS:-none}" \
|
|
-D install-tests=true \
|
|
-D tests=unsafe \
|
|
-D slow-tests=true \
|
|
-D utmp=true \
|
|
-D hibernate=true \
|
|
-D ldconfig=true \
|
|
-D resolve=true \
|
|
-D efi=true \
|
|
-D tpm=true \
|
|
-D environment-d=true \
|
|
-D binfmt=true \
|
|
-D repart=true \
|
|
-D sysupdate=true \
|
|
-D coredump=true \
|
|
-D pstore=true \
|
|
-D oomd=true \
|
|
-D logind=true \
|
|
-D hostnamed=true \
|
|
-D localed=true \
|
|
-D machined=true \
|
|
-D portabled=true \
|
|
-D sysext=true \
|
|
-D userdb=true \
|
|
-D homed=true \
|
|
-D networkd=true \
|
|
-D timedated=true \
|
|
-D timesyncd=true \
|
|
-D remote=true \
|
|
-D nss-myhostname=true \
|
|
-D nss-mymachines=true \
|
|
-D nss-resolve=true \
|
|
-D nss-systemd=true \
|
|
-D firstboot=true \
|
|
-D randomseed=true \
|
|
-D backlight=true \
|
|
-D vconsole=true \
|
|
-D quotacheck=true \
|
|
-D sysusers=true \
|
|
-D tmpfiles=true \
|
|
-D importd=true \
|
|
-D hwdb=true \
|
|
-D rfkill=true \
|
|
-D xdg-autostart=true \
|
|
-D translations=true \
|
|
-D polkit=true \
|
|
-D acl=true \
|
|
-D audit=true \
|
|
-D blkid=true \
|
|
-D fdisk=true \
|
|
-D kmod=true \
|
|
-D pam=true \
|
|
-D pwquality=true \
|
|
-D microhttpd=true \
|
|
-D libcryptsetup=true \
|
|
-D libcurl=true \
|
|
-D idn=true \
|
|
-D libidn2=true \
|
|
-D qrencode=true \
|
|
-D gcrypt=true \
|
|
-D gnutls=true \
|
|
-D openssl=true \
|
|
-D cryptolib=openssl \
|
|
-D p11kit=true \
|
|
-D libfido2=true \
|
|
-D tpm2=true \
|
|
-D elfutils=true \
|
|
-D zstd=true \
|
|
-D xkbcommon=true \
|
|
-D pcre2=true \
|
|
-D glib=true \
|
|
-D dbus=true \
|
|
-D gnu-efi=true \
|
|
-D kernel-install=true \
|
|
-D analyze=true \
|
|
-D bpf-framework=true
|
|
fi
|
|
|
|
cd "$BUILDDIR"
|
|
ninja "$@"
|
|
if [ "$WITH_TESTS" = 1 ] ; then
|
|
for id in 1 2 3; do
|
|
getent group $id >/dev/null || echo "g testgroup$id $id -" | ./systemd-sysusers -
|
|
done
|
|
|
|
if [ -n "$SANITIZERS" ]; then
|
|
export ASAN_OPTIONS="$ASAN_OPTIONS"
|
|
export UBSAN_OPTIONS="$UBSAN_OPTIONS"
|
|
TIMEOUT_MULTIPLIER=3
|
|
else
|
|
TIMEOUT_MULTIPLIER=1
|
|
fi
|
|
|
|
meson test --print-errorlogs --timeout-multiplier=$TIMEOUT_MULTIPLIER
|
|
fi
|
|
cd "$SRCDIR"
|
|
|
|
# Ubuntu Focal is stuck with meson 0.53.0.
|
|
if [ "$(meson -v | cut -d . -f 2)" -gt 53 ] ; then
|
|
meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed
|
|
else
|
|
meson install -C "$BUILDDIR" --no-rebuild --only-changed
|
|
fi
|
|
|
|
mkdir -p "$DESTDIR"/etc
|
|
|
|
cat >"$DESTDIR"/etc/issue <<EOF
|
|
\S (built from systemd tree)
|
|
Kernel \r on an \m (\l)
|
|
|
|
EOF
|
|
|
|
if [ -n "$IMAGE_ID" ] ; then
|
|
mkdir -p "$DESTDIR"/usr/lib
|
|
sed -n \
|
|
-e '/^IMAGE_ID=/!p' \
|
|
-e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release"
|
|
|
|
OSRELEASEFILE="$DESTDIR"/usr/lib/os-release
|
|
else
|
|
OSRELEASEFILE=/usr/lib/os-release
|
|
fi
|
|
|
|
|
|
if [ -n "$IMAGE_VERSION" ] ; then
|
|
mkdir -p "$DESTDIR"/usr/lib
|
|
sed -n \
|
|
-e '/^IMAGE_VERSION=/!p' \
|
|
-e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp"
|
|
|
|
cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release
|
|
rm /tmp/os-release.tmp
|
|
fi
|
|
|
|
# If $CI_BUILD is set, copy over the CI service which executes a service check
|
|
# after boot and then shuts down the machine
|
|
if [ -n "$CI_BUILD" ]; then
|
|
mkdir -p "$DESTDIR/usr/lib/systemd/system"
|
|
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service"
|
|
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
|
chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
|
fi
|
|
|
|
if [ -n "$SANITIZERS" ]; then
|
|
LD_PRELOAD=$(ldd $BUILDDIR/systemd | grep libasan.so | awk '{print $3}')
|
|
|
|
mkdir -p "$DESTDIR/etc/systemd/system.conf.d"
|
|
|
|
cat > "$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF
|
|
[Manager]
|
|
ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
|
|
UBSAN_OPTIONS=$UBSAN_OPTIONS\\
|
|
LD_PRELOAD=$LD_PRELOAD
|
|
DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
|
|
UBSAN_OPTIONS=$UBSAN_OPTIONS\\
|
|
LD_PRELOAD=$LD_PRELOAD
|
|
EOF
|
|
|
|
# ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose
|
|
# all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any
|
|
# sanitizer failures appear directly on the user's console.
|
|
mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d"
|
|
|
|
cat > "$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF
|
|
[Service]
|
|
StandardOutput=tty
|
|
EOF
|
|
|
|
# Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users.
|
|
# This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As
|
|
# a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login
|
|
# from calling vhangup() so that journald's ASAN logs correctly end up in the console.
|
|
|
|
mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d"
|
|
|
|
cat > "$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF
|
|
[Service]
|
|
TTYVHangup=no
|
|
CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
|
|
EOF
|
|
fi
|
|
|
|
# Make sure services aren't enabled by default on Debian/Ubuntu.
|
|
mkdir -p "$DESTDIR/etc/systemd/system-preset"
|
|
echo "disable *" > "$DESTDIR/etc/systemd/system-preset/99-mkosi.preset"
|
|
|
|
if [ -d mkosi.kernel/ ]; then
|
|
cd "$SRCDIR/mkosi.kernel"
|
|
mkdir -p "$BUILDDIR/mkosi.kernel"
|
|
|
|
make O="$BUILDDIR/mkosi.kernel" defconfig
|
|
|
|
scripts/config \
|
|
--file $BUILDDIR/mkosi.kernel/.config \
|
|
--enable BPF_SYSCALL \
|
|
--enable BPF_JIT \
|
|
--enable BPF_JIT_ALWAYS_ON \
|
|
--enable BPF_JIT_DEFAULT_ON \
|
|
--enable BPF_UNPRIV_DEFAULT_OFF \
|
|
--enable USERMODE_DRIVER \
|
|
--enable BPF_PRELOAD \
|
|
--enable BPF_PRELOAD_UMD \
|
|
--enable BPF_LSM \
|
|
--enable BTRFS_FS \
|
|
--enable BTRFS_FS_POSIX_ACL \
|
|
--enable PSI \
|
|
--enable CGROUPS \
|
|
--enable CGROUP_BPF \
|
|
--enable MEMCG \
|
|
--enable MEMCG_SWAP \
|
|
--enable MEMCG_KMEM
|
|
|
|
# Make sure all unset options are set to their default value.
|
|
make O="$BUILDDIR/mkosi.kernel" olddefconfig
|
|
|
|
make O="$BUILDDIR/mkosi.kernel" -j "$(nproc)"
|
|
|
|
KERNEL_RELEASE="$(make O=$BUILDDIR/mkosi.kernel -s kernelrelease)"
|
|
mkdir -p "$DESTDIR/usr/lib/modules/$KERNEL_RELEASE"
|
|
make O="$BUILDDIR/mkosi.kernel" INSTALL_MOD_PATH="$DESTDIR/usr" modules_install
|
|
make O="$BUILDDIR/mkosi.kernel" INSTALL_PATH="$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" install
|
|
fi
|