completely switch to erofs also for upgrades

our generator now always runs to generate the relevant units for erofs
use

tar build has been removed, instead we spend some extra time on zstd
compression of the erofs
This commit is contained in:
Harald Sitter
2025-08-19 04:46:20 +02:00
parent f845045c53
commit 7e6223e467
8 changed files with 18 additions and 170 deletions

View File

@@ -26,6 +26,7 @@ make_debug_archive () {
# Finally compress /tmp/debugroot/usr into a zstd tarball at $DEBUG_TAR.
# We actually only need usr because that's where all the relevant stuff lays anyways.
# TODO: needs really moving to erofs instead of tar
tar --directory=/tmp/debugroot --create --file="$DEBUG_TAR" usr
zstd --threads=0 --rm "$DEBUG_TAR" # --threads=0 automatically uses the optimal number
}
@@ -42,7 +43,6 @@ MAIN_UKI=${OUTPUT}.efi # Output main UKI path
LIVE_UKI=${OUTPUT}_live.efi # Output live UKI path
EROFS_UKI=${OUTPUT}_erofs.addon.efi # Output live UKI path
DEBUG_TAR=${OUTPUT}_debug-x86-64.tar # Output debug archive path (.zst will be added)
ROOTFS_TAR=${OUTPUT}_root-x86-64.tar # Output rootfs tarball path (.zst will be added)
ROOTFS_EROFS=${OUTPUT}_root-x86-64.erofs # Output erofs image path
IMG=${OUTPUT}.raw # Output raw image path
@@ -119,11 +119,6 @@ mount esp.raw esp.raw.mnt
# Copy everything from /usr/share/factory/boot into esp.raw.mnt.
cp --archive --recursive "${OUTPUT}/usr/share/factory/boot/." esp.raw.mnt
# FIXME a hack to remove the rootflags= from the live boot because they are not applicable
# Can be dropped once erofs is default and we don't need the addon anymore.
ukify build \
--cmdline "kde-linux.erofs=1" \
--output esp.raw.mnt/EFI/Linux/$EFI_BASE.efi.extra.d/erofs.addon.efi
# We're done, unmount esp.raw.mnt.
umount esp.raw.mnt
@@ -135,15 +130,10 @@ cp "$MAIN_UKI" "${OUTPUT}/usr/share/factory/boot/EFI/Linux/$EFI"
cd .. # and back to root
# Create rootfs tarball for consumption by systemd-sysext (doesn't currently support consuming raw images :()
rm -rf "$ROOTFS_TAR" ./*.tar
time tar -C "${OUTPUT}"/ --xattrs --xattrs-include=*.* -cf "$ROOTFS_TAR" .
time zstd -T0 --rm "$ROOTFS_TAR"
# Drop flatpak data from erofs. They are in the usr/share/factory and deployed from there.
rm -rf "$OUTPUT/var/lib/flatpak"
mkdir "$OUTPUT/var/lib/flatpak" # but keep a mountpoint around for the live session
time mkfs.erofs -d0 -zzstd -Efragments,ztailpacking "$ROOTFS_EROFS" "$OUTPUT" > /dev/null 2>&1
time mkfs.erofs -d0 -zzstd:$ZSTD_LEVEL -Efragments,ztailpacking "$ROOTFS_EROFS" "$OUTPUT" > /dev/null 2>&1
cp --reflink=auto "$ROOTFS_EROFS" kde-linux.cache/root.raw
# Now assemble the two generated images using systemd-repart and the definitions in mkosi.repart into $IMG.

View File

@@ -31,43 +31,20 @@ rm -rfv ./*
btrfs subvolume sync . || true
btrfs quota enable --simple .
if grep "kde-linux.erofs=1" /proc/cmdline; then
btrfs subvolume create @system
mkdir @system/boot @system/proc @system/sys @system/dev @system/run @system/usr
cp /dev/gpt-auto-root kde-linux_$IMAGE_VERSION.erofs
btrfs subvolume create @system
mkdir @system/boot @system/proc @system/sys @system/dev @system/run @system/usr
cp /dev/gpt-auto-root kde-linux_$IMAGE_VERSION.erofs
# Overmount calamares' mount with the subvol mount
mount -o "subvol=@system" "$device" "$ROOT"
mount -t proc proc "$ROOT/proc"
mount -t sysfs sys "$ROOT/sys"
mount -o bind /dev "$ROOT/dev"
mount -t tmpfs tmpfs "$ROOT/run"
mkdir "$ROOT/run/udev" # This is not part of @system but rather the $ROOT (do not move this to the mkdir list of @system!)
mount -o bind /run/udev "$ROOT/run/udev"
mount -t efivarfs efivarfs "$ROOT/sys/firmware/efi/efivars"
mount -o ro,X-mount.subdir=usr /dev/gpt-auto-root "$ROOT/usr"
else
btrfs subvolume create @kde-linux_$IMAGE_VERSION
cp -ra /system/. @kde-linux_$IMAGE_VERSION
btrfs subvolume create @home
btrfs subvolume create @root
btrfs subvolume create @locale
btrfs subvolume create @snap
btrfs subvolume create @var-overlay
btrfs subvolume create @etc-overlay
mkdir @var-overlay/upper @var-overlay/work @etc-overlay/upper @etc-overlay/work
# Overmount calamares' mount with the subvol mount
mount -o "subvol=@kde-linux_$IMAGE_VERSION" "$device" "$ROOT"
mount -t proc proc "$ROOT/proc"
mount -t sysfs sys "$ROOT/sys"
mount -o bind /dev "$ROOT/dev"
mount -t tmpfs tmpfs "$ROOT/run"
mkdir "$ROOT/run/udev" # This is not part of @system but rather the $ROOT (do not move this to the mkdir list of @system!)
mount -o bind /run/udev "$ROOT/run/udev"
mount -t efivarfs efivarfs "$ROOT/sys/firmware/efi/efivars"
_kde-linux-overlay "$device" "$ROOT"
fi
# Overmount calamares' mount with the subvol mount
mount -o "subvol=@system" "$device" "$ROOT"
mount -t proc proc "$ROOT/proc"
mount -t sysfs sys "$ROOT/sys"
mount -o bind /dev "$ROOT/dev"
mount -t tmpfs tmpfs "$ROOT/run"
mkdir "$ROOT/run/udev" # This is not part of @system but rather the $ROOT (do not move this to the mkdir list of @system!)
mount -o bind /run/udev "$ROOT/run/udev"
mount -t efivarfs efivarfs "$ROOT/sys/firmware/efi/efivars"
mount -o ro,X-mount.subdir=usr /dev/gpt-auto-root "$ROOT/usr"
# ESP is a bit tricky. Find the block device of the root partition and then we'll ask systemd for an ESP on that device.
# ... and luks devices are even more tricky because we need to get the real device first
@@ -95,19 +72,3 @@ systemd-tmpfiles --root="$ROOT" --exclude-prefix=/usr --create
systemctl --root="$ROOT" preset-all
systemctl --root="$ROOT" preset-all --global
if grep "kde-linux.erofs=1" /proc/cmdline; then
# Enable the erofs feature. This file will eventually need removing by a service file or something when erofs is full default.
mkdir --parents $ROOT/etc/sysupdate.d/erofs.feature.d/
cat <<- EOF >> $ROOT/etc/sysupdate.d/erofs.feature.d/enable.conf
# Auto generated by KDE Linux installer. Enables EROFS rootfs.
[Feature]
Enabled=true
EOF
mkdir --parents $ROOT/etc/sysupdate.d/tar.feature.d/
cat <<- EOF >> $ROOT/etc/sysupdate.d/tar.feature.d/enable.conf
# Auto generated by KDE Linux installer. Disables tar rootfs.
[Feature]
Enabled=false
EOF
fi

View File

@@ -1,71 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
# SPDX-FileCopyrightText: 2023-2024 Harald Sitter <sitter@kde.org>
set -ex
rootdisk=/dev/disk/by-partlabel/KDELinux
if [ -b /dev/gpt-auto-root ]; then
# When the partition was auto detected we can just use the auto-root device
rootdisk=/dev/gpt-auto-root
elif [ -b /dev/disk/by-partlabel/KDEOS ]; then
rootdisk=/dev/disk/by-partlabel/KDEOS # Fallback for older images
fi
rootdisk=${1:-$rootdisk}
sysroot=${2:-/sysroot}
# TODO should probably transition to .mount units or a generator instead
# NOTE: this is also called by calamares, so maybe mount units are a bad idea
if [ -d "${sysroot}/system/@etc-overlay" ]; then
# already mounted
exit 0
fi
mount -v \
-o rw,subvol=/ \
"$rootdisk" "${sysroot}/system"
# Make sure our subvolumes exist! In particular if we introduce subvolumes after installation.
# FIXME This is a bit garbage. It'd be much tidier if we could tell repart to do this for us. But in some sort of
# safe mode so it doesn't twiddle the partition table.
[ -d "${sysroot}/system/@root" ] || btrfs subvolume create "${sysroot}/system/@root"
# container storage benefits from not being inside a overlay filesystem
[ -d "${sysroot}/system/@containers" ] || btrfs subvolume create "${sysroot}/system/@containers"
[ -d "${sysroot}/system/@docker" ] || btrfs subvolume create "${sysroot}/system/@docker"
# Clean up legacy volumes
# @locale is no longer used because we now generate all locales into the image
[ -d "${sysroot}/system/@locale" ] && btrfs subvolume delete "${sysroot}/system/@locale"
mount -v \
-o rw,subvol=@home \
"$rootdisk" "${sysroot}/home"
mount -v \
-o rw,subvol=@root \
"$rootdisk" "${sysroot}/root"
mount -v \
-o rw,subvol=@snap \
"$rootdisk" "${sysroot}/snap"
mount -v \
-t overlay \
-o "rw,lowerdir=${sysroot}/etc,upperdir=${sysroot}/system/@etc-overlay/upper,workdir=${sysroot}/system/@etc-overlay/work,index=off,metacopy=off" \
overlay "${sysroot}/etc"
mount -v \
-t overlay \
-o "rw,lowerdir=${sysroot}/var,upperdir=${sysroot}/system/@var-overlay/upper,workdir=${sysroot}/system/@var-overlay/work,index=off,metacopy=off" \
overlay "${sysroot}/var"
mkdir -p "${sysroot}/var/lib/containers"
mount -v \
-o rw,subvol=@containers \
"$rootdisk" "${sysroot}/var/lib/containers"
mkdir -p "${sysroot}/var/lib/docker"
mount -v \
-o rw,subvol=@docker \
"$rootdisk" "${sysroot}/var/lib/docker"
# TODO: should we maybe also mount /etc into the initrd /etc so we have early access to fstab and the like

View File

@@ -32,7 +32,7 @@ ukify build \
--output live.efi
# lsm= defaulting to apparmor from https://wiki.archlinux.org/title/AppArmor
echo "rw rootflags=subvol=@kde-linux_$IMAGE_VERSION,compress=zstd:1 \
echo "rw rootflags=subvol=@system,compress=zstd:1 \
lsm=landlock,lockdown,yama,integrity,apparmor,bpf \
vt.global_cursor_default=0 quiet splash loglevel=3" > cmdline
mkinitcpio --config mkinitcpio.conf --generate initrd --kernel "$kernel_version"
@@ -41,7 +41,3 @@ ukify build \
--initrd initrd \
--cmdline @cmdline \
--output kde-linux.efi
ukify build \
--cmdline "rootflags=subvol=@system,compress=zstd:1 kde-linux.erofs=1" \
--output erofs.addon.efi

View File

@@ -19,11 +19,6 @@ if grep "kde-linux.live=1" /proc/cmdline; then
exit 0
fi
if ! grep "kde-linux.erofs=1" /proc/cmdline; then
echo "kde-linux.erofs=1 not in cmdline. Not generating mount units."
exit 0
fi
if [ "$SYSTEMD_IN_INITRD" = "1" ]; then
# The transition service in case the system needs transitioning still

View File

@@ -1,24 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
# SPDX-FileCopyrightText: 2024 Harald Sitter <sitter@kde.org>
[Unit]
Description=Overlay Root File System
DefaultDependencies=no
Requires=sysroot.mount
Conflicts=shutdown.target
After=sysroot.mount systemd-repart.service
Before=initrd-root-fs.target initrd-parse-etc.service shutdown.target
AssertPathExists=/etc/initrd-release
# On the live system we let systemd.volatile handle the overlay since we want to discard changes
ConditionKernelCommandLine=!kde-linux.live=1
# The erofs system works by virtue of a systemd generator
ConditionKernelCommandLine=!kde-linux.erofs=1
# Make sure the module is loaded
Wants=modprobe@overlay.service
After=modprobe@overlay.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/_kde-linux-overlay
Restart=no

View File

@@ -3,4 +3,4 @@
[Feature]
Description=EROFS-based RootFS
Enabled=false
Enabled=true

View File

@@ -3,4 +3,5 @@
[Feature]
Description=Tar-based RootFS
# This continues to be enabled so the artifacts get vacuumed.
Enabled=true