File 0001-Add-support-for-mkosi-initrd.patch of Package suse-module-tools
From ddb21966321c89dea01242cd2460e9089e5f2380 Mon Sep 17 00:00:00 2001
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
Date: Mon, 2 Sep 2024 16:58:39 +0200
Subject: [PATCH] Add support for mkosi-initrd
`mkosi` provides the `mkosi-initrd` script [1], which allows to generate initrds
locally on the system. Although it is not equivalent in features to `dracut`,
it's a valid alternative with its own benefits in some use cases:
- Clear ownership of bugs: no 3rd party binary (e.g. dracut) deciding what is
installed from each package or even modifying them.
- Any change on a package configured to be included would automatically apply to
the initrd (if the package triggers initrd rebuild).
- It attempts to shift the maintenance effort from the initrd generator to the
responsible package.
To choose which initrd generator will be used, use a new `INITRD_GENERATOR`
option in `/etc/sysconfig/bootloader`. If not defined, the default will still be
dracut.
[1] https://github.com/systemd/mkosi/commit/99ca14cffb13309a0e6865b2724cc199916c753b
---
README.md | 114 ++++++++++++++++++-----------------
dracut-posttrans | 26 ++++++++
kernel-scriptlets/rpm-script | 2 +-
mkosi-initrd-posttrans | 55 +++++++++++++++++
regenerate-initrd-posttrans | 50 +++++++++------
suse-module-tools.spec | 4 ++
weak-modules2 | 71 ++++++++++++++++++++--
7 files changed, 243 insertions(+), 79 deletions(-)
create mode 100644 dracut-posttrans
create mode 100644 mkosi-initrd-posttrans
diff --git a/README.md b/README.md
index 184beb5..68a857f 100644
--- a/README.md
+++ b/README.md
@@ -120,8 +120,8 @@ kernel package.
# Boot Loader Specification (BLS) and EFI System Partition (ESP)
There are scripts generating boot entries (via perl-Bootloader), new
-initrds (via dracut) and updating the kernel module dependency lists
-(via depmod). If we are in a system using the boot entries defined in
+initrds (via dracut or mkosi-initrd) and updating the kernel module dependency
+lists (via depmod). If we are in a system using the boot entries defined in
the bootloader specification (BLS), then we need to take special
considerations.
@@ -141,76 +141,80 @@ coordination, reordering certain actions depending on the kind of
system. The following table summarizes those interactions:
-| Model | Operation | Element | Done |
-|------------------|-----------|------------|--------------------------------|
-| Traditional | Kernel | depmod | wm2 (rpm-script/post[un]) |
-| | | initrd | wm2 (rpm-script/post[un]) |
-| | | boot entry | rpm-script/post[un] |
-| | | | |
-| | KMP | depmod | wm2 (inkmp-script/post[un]) |
-| | | initrd | wm2 (inkmp-script/post[un]) |
-| | | | |
-| | Dracut | initrd | regenerate-initrd-posttrans[1] |
-|------------------|-----------|------------|--------------------------------|
-| MicroOS[2] | Kernel | depmod | wm2 (rpm-script/post[un]) |
-| | | initrd | wm2 (rpm-script/post[un]) |
-| | | boot entry | rpm-script/post[un] |
-| | | | |
-| | KMP | depmod | wm2 (inkmp-script/post[un]) |
-| | | initrd | wm2 (inkmp-script/post[un]) |
-| | | | |
-| | Dracut | initrd | regenerate-initrd-posttrans |
-|------------------|-----------|------------|--------------------------------|
-| Tumbleweed + BLS | Kernel | depmod | wm2 (rpm-script/post[un])[3] |
-| | | initrd | wm2 (rpm-script/post[un]) |
-| | | boot entry | rpm-script/post[un] |
-| | | | |
-| | KMP | depmod | wm2 (inkmp-script/post[un]) |
-| | | initrd | wm2 (inkmp-script/post[un]) |
-| | | | |
-| | Dracut | initrd | regenerate-initrd-posttrans |
-|------------------|-----------|------------|--------------------------------|
-| MicroOS + BLS | Kernel | depmod | wm2 (rpm-script/post[un]) |
-| | | initrd | snapper plugin[4] |
-| | | boot entry | snapper plugin |
-| | | | |
-| | KMP | depmod | snapper plugin[5] |
-| | | initrd | wm2 (rpm-script/post[un]) |
-| | | | |
-| | Dracut | initrd | snapper plugin |
-|------------------|-----------|------------|--------------------------------|
-| Tumbleweed + BLS | Kernel | depmod | wm2 (rpm-script/post[un])[6] |
-| (no btrfs) | | initrd | wm2 (rpm-script/post[un]) |
-| | | boot entry | rpm-script/post[un] |
-| | | | |
-| | KMP | depmod | wm2 (inkmp-script/post[un]) |
-| | | initrd | wm2 (inkmp-script/post[un]) |
-| | | | |
-| | Dracut | initrd | regenerate-initrd-posttrans |
-|------------------|-----------|------------|--------------------------------|
+| Model | Operation | Element | Done |
+|------------------|-----------------|------------|--------------------------------|
+| Traditional | Kernel | depmod | wm2 (rpm-script/post[un]) |
+| | | initrd | wm2 (rpm-script/post[un]) |
+| | | boot entry | rpm-script/post[un] |
+| | | | |
+| | KMP | depmod | wm2 (inkmp-script/post[un]) |
+| | | initrd | wm2 (inkmp-script/post[un]) |
+| | | | |
+| | dracut / | initrd | regenerate-initrd-posttrans[2] |
+| | mkosi-initrd[1] | | |
+|------------------|-----------------|------------|--------------------------------|
+| MicroOS[3] | Kernel | depmod | wm2 (rpm-script/post[un]) |
+| | | initrd | wm2 (rpm-script/post[un]) |
+| | | boot entry | rpm-script/post[un] |
+| | | | |
+| | KMP | depmod | wm2 (inkmp-script/post[un]) |
+| | | initrd | wm2 (inkmp-script/post[un]) |
+| | | | |
+| | dracut | initrd | regenerate-initrd-posttrans |
+|------------------|-----------------|------------|--------------------------------|
+| Tumbleweed + BLS | Kernel | depmod | wm2 (rpm-script/post[un])[4] |
+| | | initrd | wm2 (rpm-script/post[un]) |
+| | | boot entry | rpm-script/post[un] |
+| | | | |
+| | KMP | depmod | wm2 (inkmp-script/post[un]) |
+| | | initrd | wm2 (inkmp-script/post[un]) |
+| | | | |
+| | dracut | initrd | regenerate-initrd-posttrans |
+|------------------|-----------------|------------|--------------------------------|
+| MicroOS + BLS | Kernel | depmod | wm2 (rpm-script/post[un]) |
+| | | initrd | snapper plugin[5] |
+| | | boot entry | snapper plugin |
+| | | | |
+| | KMP | depmod | snapper plugin[6] |
+| | | initrd | wm2 (rpm-script/post[un]) |
+| | | | |
+| | dracut | initrd | snapper plugin |
+|------------------|-----------------|------------|--------------------------------|
+| Tumbleweed + BLS | Kernel | depmod | wm2 (rpm-script/post[un])[7] |
+| (no btrfs) | | initrd | wm2 (rpm-script/post[un]) |
+| | | boot entry | rpm-script/post[un] |
+| | | | |
+| | KMP | depmod | wm2 (inkmp-script/post[un]) |
+| | | initrd | wm2 (inkmp-script/post[un]) |
+| | | | |
+| | dracut | initrd | regenerate-initrd-posttrans |
+|------------------|-----------------|------------|--------------------------------|
Notes:
-[1] Triggered by the `%regenerate_initrd_post[trans]` macros
+[1] The `mkosi-initrd` integration is in its initial phase and is intended for
+ traditional systems only.
-[2] In MicroOS (or any system that use transactional-update) the
+[2] Triggered by the `%regenerate_initrd_post[trans]` macros
+
+[3] In MicroOS (or any system that use transactional-update) the
kernel in /boot is inside the transaction, so gets discarded if
the snapshot is dropped.
-[3] Could be done in the snapper plugin, but it is done in
+[4] Could be done in the snapper plugin, but it is done in
weak-modules2 as in the traditional case, by calling `sdbootutil
--no-reuse-initrd`, which also creates the boot entry. The initrd
name is selected from the current default boot entry
-[4] When adding or removing a kernel, the `sdbootutil
+[5] When adding or removing a kernel, the `sdbootutil
set_default_snapshot` will regenerate boot entries for all the
remaining kernels in the snapshot. This will synchronize also the
initrds (but can leave old initrds in the ESP). Also, wm2 will
create a mark in `/run/regenerate-initrd`.
-[5] A direct call to `regenerate-initrd-posttrans` inside the
+[6] A direct call to `regenerate-initrd-posttrans` inside the
transaction will drop the call and keep the
`/run/regenerate-initrd` directory. A second call (from the
snapper plugin) will complete it.
-[6] `sdbootutil` partially understand BLS systems without snapshots.
+[7] `sdbootutil` partially understand BLS systems without snapshots.
diff --git a/dracut-posttrans b/dracut-posttrans
new file mode 100644
index 0000000..07a08a5
--- /dev/null
+++ b/dracut-posttrans
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+: "${DRACUT:=/usr/bin/dracut}"
+
+if [ ! -x "$DRACUT" ]; then
+ echo "${0##*/}: dracut is not installed, not rebuilding the initrd." >&2
+ exit 0
+fi
+
+initrd_warn_chroot_build() {
+ echo "Please run \"$DRACUT -f --regenerate-all\" as soon as your system is complete." >&2
+}
+
+initrd_regenerate() {
+ local kver="$1"
+ "$DRACUT" -f --kver "$kver"
+ return $?
+}
+
+initrd_regenerate_all() {
+ "$DRACUT" -f --regenerate-all
+}
+
+initrd_cleanup() {
+ :
+}
diff --git a/kernel-scriptlets/rpm-script b/kernel-scriptlets/rpm-script
index c8353c2..ce48b1a 100644
--- a/kernel-scriptlets/rpm-script
+++ b/kernel-scriptlets/rpm-script
@@ -265,7 +265,7 @@ case $op in
if [ -x $wm2 ]; then
run_wm2 --add-kernel "$kernelrelease"-"$flavor" || script_rc=$?
else
- echo "$wm2 does not exist, please run depmod and dracut manually" >&2
+ echo "$wm2 does not exist, please run depmod and dracut/mkosi-initrd manually" >&2
script_rc=1
fi
diff --git a/mkosi-initrd-posttrans b/mkosi-initrd-posttrans
new file mode 100644
index 0000000..7570415
--- /dev/null
+++ b/mkosi-initrd-posttrans
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+: "${MKOSI_INITRD:=/usr/bin/mkosi-initrd}"
+
+if [ ! -x "$MKOSI_INITRD" ]; then
+ echo "${0##*/}: mkosi-initrd is not installed, not rebuilding the initrd." >&2
+ exit 0
+fi
+
+# FIXME: mkosi-initrd fails to cp files directly to /boot
+MKOSI_INITRD_STAGING_DIR="$(mktemp -p /var/tmp/ -d -t mkosi-initrd-stagingXXXXXXXX)"
+if [ ! -d "$MKOSI_INITRD_STAGING_DIR" ]; then
+ echo "${0##*/}: failed to create mkosi-initrd staging directory." >&2
+ exit 1
+fi
+
+initrd_warn_chroot_build() {
+ # FIXME: mkosi-initrd does not provide anything like --regenerate-all yet
+ echo "Please regenerate all the initrds with \"$MKOSI_INITRD\" as soon as your system is complete." >&2
+}
+
+initrd_regenerate() {
+ local kver="$1"
+ local res
+
+ "$MKOSI_INITRD" --kernel-version "$kver" -O "$MKOSI_INITRD_STAGING_DIR" -o "initrd-$kver"
+ res=$?
+ [ $res -ne 0 ] && return $res
+
+ chmod 600 "$MKOSI_INITRD_STAGING_DIR/initrd-$kver"
+ res=$?
+ [ $res -ne 0 ] && return $res
+
+ cp --reflink=auto "$MKOSI_INITRD_STAGING_DIR/initrd-$kver" "/boot/initrd-$kver"
+ return $?
+}
+
+initrd_regenerate_all() {
+ # FIXME: mkosi-initrd does not provide anything like --regenerate-all yet
+ for d in /lib/modules/*; do
+ [ -d "$d" ] || continue
+ kver=${d##*/}
+ if "$MKOSI_INITRD" --kernel-version "$kver" -O "$MKOSI_INITRD_STAGING_DIR" -o "initrd-$kver" \
+ && chmod 600 "$MKOSI_INITRD_STAGING_DIR/initrd-$kver"; then
+ # The staging dir will contain: initrd-<kver> -> initrd-<kver>.cpio.zst
+ cp --reflink=auto "$MKOSI_INITRD_STAGING_DIR/initrd-$kver" "/boot/initrd-$kver"
+ rm -f "$MKOSI_INITRD_STAGING_DIR/initrd-$kver"*
+ fi
+ done
+}
+
+initrd_cleanup() {
+ rm -rf "$MKOSI_INITRD_STAGING_DIR"
+}
+
diff --git a/regenerate-initrd-posttrans b/regenerate-initrd-posttrans
index 8763739..89826e5 100644
--- a/regenerate-initrd-posttrans
+++ b/regenerate-initrd-posttrans
@@ -15,14 +15,29 @@
# to have all initrds generated. This script is called from posttrans
# and takes care of generating the initrds
-: ${DRACUT:=/usr/bin/dracut}
-if [ ! -x "$DRACUT" ]; then
- echo "${0##*/}: dracut is not installed, not rebuilding the initrd" >&2
- exit 0
-fi
+# get the configured INITRD_GENERATOR from /etc/sysconfig/bootloader
+INITRD_GENERATOR="$(. /etc/sysconfig/bootloader 2>/dev/null && echo "$INITRD_GENERATOR")"
+[ "$INITRD_GENERATOR" = "mkosi" ] && INITRD_GENERATOR="mkosi-initrd"
+
+# dracut is the default initrd generator
+: "${INITRD_GENERATOR:=dracut}"
+
+# check if the configured initrd generator is supported
+[ "$INITRD_GENERATOR" = "dracut" ] || [ "$INITRD_GENERATOR" = "mkosi-initrd" ] || {
+ echo "${0##*/}: the initrd generator \"$INITRD_GENERATOR\" configured in /etc/sysconfig/bootloader is not supported." >&2
+ echo "${0##*/}: valid options are \"dracut\" or \"mkosi-initrd\"." >&2
+ exit 1
+}
+
+# check if the specific posttrans script is available
+[ -x "/usr/lib/module-init-tools/${INITRD_GENERATOR}-posttrans" ] || {
+ echo "${0##*/}: missing required /usr/lib/module-init-tools/${INITRD_GENERATOR}-posttrans." >&2
+ exit 1
+}
+. /usr/lib/module-init-tools/"${INITRD_GENERATOR}"-posttrans
if [ -e "/usr/bin/sdbootutil" ] && /usr/bin/sdbootutil is-installed; then
- is_sdbootutil=1
+ is_sdbootutil=1
fi
dir=/run/regenerate-initrd
@@ -45,12 +60,12 @@ fi
for f in "$dir"/*; do
case $f in
- "$dir/*")
+ "$dir/*")
[ -e "$f" ] || break;;
esac
# check if we are in a build chroot
- if ! [ -f /etc/fstab -a ! -e /.buildenv -a -x "$DRACUT" ] ; then
- echo "Please run \"$DRACUT -f --regenerate-all\" as soon as your system is complete." >&2
+ if [ ! -f /etc/fstab ] || [ -e /.buildenv ]; then
+ initrd_warn_chroot_build
rm "$dir"/*
exit 0
fi
@@ -66,7 +81,7 @@ if test -e "$dir/all"; then
if [ -n "$is_sdbootutil" ]; then
/usr/bin/sdbootutil --no-reuse-initrd --default-snapshot add-all-kernels
else
- "$DRACUT" -f --regenerate-all
+ initrd_regenerate_all
fi
work_done=yes
}
@@ -88,19 +103,20 @@ else
continue
}
if [ -n "$is_sdbootutil" ]; then
- if ! /usr/bin/sdbootutil --no-reuse-initrd --default-snapshot add-kernel "$kver"; then
- err=$?
- else
- work_done=yes
- fi
- elif ! "$DRACUT" -f --kver "$kver"; then
+ /usr/bin/sdbootutil --no-reuse-initrd --default-snapshot add-kernel "$kver"
err=$?
+ [ $err -eq 0 ] && work_done=yes
else
- work_done=yes
+ initrd_regenerate "$kver"
+ err=$?
+ [ $err -eq 0 ] && work_done=yes
fi
done
fi
+# Clean-up before exit
+trap 'initrd_cleanup' EXIT
+
# For XEN/grub2 configurations, make sure the updated initrds are copied
# to the EFI system partition. See /etc/grub.d/20_linux_xen.
# The test for xen*.gz is simplistic but should be correct here.
diff --git a/suse-module-tools.spec b/suse-module-tools.spec
index deaeb57..144d54a 100644
--- a/suse-module-tools.spec
+++ b/suse-module-tools.spec
@@ -120,6 +120,8 @@ install -pm 644 "depmod-00-system.conf" "%{buildroot}%{depmod_dir}/00-system.con
install -d -m 755 "%{buildroot}/usr/lib/module-init-tools"
install -pm 755 -t "%{buildroot}/usr/lib/module-init-tools/" \
weak-modules2 driver-check.sh unblacklist lsinitrd-quick get_dracut_drivers
+install -pm 755 "dracut-posttrans" "%{buildroot}/usr/lib/module-init-tools/"
+install -pm 755 "mkosi-initrd-posttrans" "%{buildroot}/usr/lib/module-init-tools/"
install -pm 755 "regenerate-initrd-posttrans" "%{buildroot}/usr/lib/module-init-tools/"
install -d -m 755 "%{buildroot}/usr/lib/module-init-tools/kernel-scriptlets"
install -pm 755 "kernel-scriptlets/cert-script" "%{buildroot}/usr/lib/module-init-tools/kernel-scriptlets"
@@ -249,6 +251,8 @@ exit 0
#
%files scriptlets
/usr/lib/module-init-tools/kernel-scriptlets
+/usr/lib/module-init-tools/dracut-posttrans
+/usr/lib/module-init-tools/mkosi-initrd-posttrans
/usr/lib/module-init-tools/regenerate-initrd-posttrans
%changelog
diff --git a/weak-modules2 b/weak-modules2
index 897a465..064ca08 100644
--- a/weak-modules2
+++ b/weak-modules2
@@ -56,7 +56,9 @@
# kmps: list of kmps, newest first
#
-: ${DRACUT:=/usr/bin/dracut}
+: "${DRACUT:=/usr/bin/dracut}"
+: "${MKOSI_INITRD:=/usr/bin/mkosi-initrd}"
+
find_lsinitrd() {
local lsi
LSINITRD=
@@ -100,6 +102,24 @@ find_sdbootutil() {
dlog "SDBOOTUTIL=$SDBOOTUTIL"
}
+find_initrd_generator() {
+ INITRD_GENERATOR="$(. /etc/sysconfig/bootloader 2>/dev/null && echo "$INITRD_GENERATOR")"
+
+ # dracut is the default initrd generator
+ if [ -z "$INITRD_GENERATOR" ]; then
+ INITRD_GENERATOR="dracut"
+ elif [ "$INITRD_GENERATOR" = "mkosi" ]; then
+ INITRD_GENERATOR="mkosi-initrd"
+ fi
+
+ [ "$INITRD_GENERATOR" = "dracut" ] || [ "$INITRD_GENERATOR" = "mkosi-initrd" ] || {
+ echo "ERROR: the initrd generator \"$INITRD_GENERATOR\" configured in /etc/sysconfig/bootloader is not supported." >&2
+ exit 1
+ }
+
+ dlog "INITRD_GENERATOR=$INITRD_GENERATOR"
+}
+
find_usrmerge_boot() {
local filename=$1
local kver=$2
@@ -453,7 +473,7 @@ DRACUT_CONFDIR=/etc/dracut.conf.d
DRACUT_BUILTIN_CONFDIR=/usr/lib/dracut/dracut.conf.d
GET_DRACUT_DRIVERS=/usr/lib/module-init-tools/get_dracut_drivers
-get_initrd_basenames() {
+get_dracut_basenames() {
local setpriv=$(command -v setpriv)
local conf= cf
@@ -479,6 +499,24 @@ $(cat "$cf")"
"$GET_DRACUT_DRIVERS" "$conf"
}
+get_mkosi_initrd_basenames() {
+ # TODO: get drivers from mkosi-initrd conf (KernelModulesInclude=, KernelModulesExclude=)
+ get_current_basenames "$1"
+}
+
+get_initrd_basenames() {
+ local krel=$1
+
+ case "$INITRD_GENERATOR" in
+ "dracut")
+ get_dracut_basenames "$krel"
+ ;;
+ "mkosi-initrd")
+ get_mkosi_initrd_basenames "$krel"
+ ;;
+ esac
+}
+
# test if rebuilding initrd is needed for $krel.
# stdin - list of changed modules ("_kernel_" for the whole kernel)
needs_initrd() {
@@ -487,12 +525,21 @@ needs_initrd() {
# Don't generate an initrd for kdump here. It's done automatically with mkdumprd when
# /etc/init.d/boot.kdump is called to load the kdump kernel. See mkdumprd(8) why
# it is done this way.
- if [[ "$krel" == *kdump* ]] ; then
+ if [[ "$krel" == *kdump* ]]; then
return 1
fi
- if ! [ -f /etc/fstab -a ! -e /.buildenv -a -x "$DRACUT" ] ; then
- echo "Please run \"$DRACUT -f /boot/initrd-$krel $krel\" as soon as your system is complete." >&2
+ if ! [ -f /etc/fstab -a ! -e /.buildenv ]; then
+ case "$INITRD_GENERATOR" in
+ "dracut")
+ echo "Please run \"$DRACUT -f /boot/initrd-$krel $krel\" as soon as your system is complete." >&2
+ ;;
+ "mkosi-initrd")
+ # FIXME: mkosi-initrd fails to cp files directly to /boot
+ echo "Please run \"$MKOSI_INITRD --kernel-version $krel -o initrd-$krel && \
+chmod 600 initrd-$krel && cp initrd-$krel /boot\" as soon as your system is complete." >&2
+ ;;
+ esac
return 1
fi
# KMPs can force initrd rebuild with %kernel_module_package -b that sets
@@ -556,7 +603,18 @@ run_depmod_build_initrd() {
doit "$SDBOOTUTIL" --no-reuse-initrd add-kernel "$krel"
elif [ -z "$SDBOOTUTIL" ]; then
local initrd="$(get_current_initrd $krel)"
- doit "$DRACUT" -f "$initrd" $krel
+ case "$INITRD_GENERATOR" in
+ "dracut")
+ doit "$DRACUT" -f "$initrd" $krel
+ ;;
+ "mkosi-initrd")
+ # FIXME: mkosi-initrd fails to cp files directly to /boot
+ doit "$MKOSI_INITRD" --kernel-version "$krel" -O "$tmpdir" -o "initrd-$krel" && \
+ doit chmod 600 "$tmpdir/initrd-$krel" && \
+ doit cp --reflink=auto "$tmpdir/initrd-$krel" "$initrd" && \
+ doit rm -f "$tmpdir/initrd-$krel"*
+ ;;
+ esac
fi
status=$?
fi
@@ -929,6 +987,7 @@ fi
find_depmod
find_lsinitrd
find_sdbootutil
+find_initrd_generator
tmpdir=$(mktemp -d /var/tmp/${0##*/}.XXXXXX)
trap "rm -rf $tmpdir" EXIT
--
2.43.0