Files
c630/overlay/etc/kernel/install.d/95-c630-devicetree.install.in
rob thijssen fc4d7d7ceb
All checks were successful
build image / build (push) Successful in 39m19s
Stop kernel upgrades writing entries that cannot boot
Simulating an upgrade — running kernel-core's %posttrans command by hand —
turned up two faults that had nothing to do with the full /boot, and would
have broken every future kernel install on their own.

95-c630-devicetree trusted $KERNEL_INSTALL_BOOT_ROOT. `kernel-install inspect`
reports "Layout: other, Boot Root: /boot/efi" here, because the ESP is all it
recognises, while Fedora's 20-grub.install writes BLS entries to
/boot/loader/entries regardless. So the hook looked for the device tree on the
ESP, did not find it, and skipped the patch — leaving an entry with no
devicetree line, which on this machine cannot boot. Paths in a BLS entry are
relative to the filesystem holding the entry, so the only correct boot root is
the one carrying both loader/entries and dtb-<kver>. Search for that instead.

dracut-config-rescue sets dracut_rescue_image=yes, so each install also built
a second ~210 MiB initramfs, which is what refilled /boot straight after it
was cleared. That image cannot boot this machine either: the rescue entry is
<machine-id>-0-rescue.conf, carrying no kernel version, so the devicetree hook
never matches it. Turned off.

Verified by rerunning the simulation: both kernels now have a devicetree line
and a present initrd, no rescue image is generated, snd-soc-wsa881x is rebuilt
automatically, and /boot holds at 72%.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
2026-08-14 16:54:41 +03:00

78 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/bash
#
# Teach kernel-install about the C630's device tree.
#
# The C630's UEFI hands Linux no device tree, so GRUB has to load one. Fedora's
# BLS snippets have a `devicetree` key for exactly this, but nothing in the
# stock toolchain populates it — which means a plain `dnf update kernel` would
# otherwise produce an unbootable entry. This hook runs after 20-grub.install
# and 90-loaderentry.install, both of which write the entry, and patches it.
set -eu
COMMAND="${1:?}"
KERNEL_VERSION="${2:?}"
DTB_REL="@DEVICE_DTB@"
# Do NOT trust $KERNEL_INSTALL_BOOT_ROOT. On this machine kernel-install
# decides the boot root is /boot/efi — `kernel-install inspect` reports
# "Layout: other, Boot Root: /boot/efi" — because the ESP is the only thing it
# recognises. Fedora's 20-grub.install ignores that and writes BLS entries to
# /boot/loader/entries anyway. Believing kernel-install meant looking for the
# device tree on the ESP, not finding it, and skipping the patch, so every
# kernel upgrade produced an entry with no devicetree line: installed, listed
# in the menu, and unable to boot.
#
# The paths inside a BLS entry are relative to the filesystem the entry itself
# lives on, so the only correct boot root is the one holding both the entries
# directory and the device tree. Look for that rather than being told.
find_boot_root() {
local cand
for cand in "${KERNEL_INSTALL_BOOT_ROOT:-}" /boot /efi /boot/efi; do
[ -n "$cand" ] || continue
[ -d "${cand}/loader/entries" ] || continue
[ -e "${cand}/dtb-${KERNEL_VERSION}/${DTB_REL}" ] || continue
printf '%s\n' "$cand"
return 0
done
return 1
}
case "$COMMAND" in
add)
if ! BOOT_ROOT=$(find_boot_root); then
echo "95-c630-devicetree: found no boot root holding both loader/entries" \
"and dtb-${KERNEL_VERSION}/${DTB_REL}; leaving boot entries alone" \
"rather than writing a bad one. The resulting entry will NOT boot" \
"— see docs/install.md" >&2
exit 0
fi
dtb_path="/dtb-${KERNEL_VERSION}/${DTB_REL}"
shopt -s nullglob
for entry in "${BOOT_ROOT}/loader/entries"/*-"${KERNEL_VERSION}".conf; do
# Drop any stale devicetree line, then append the current one. Doing it
# in that order makes the hook idempotent across re-installs.
tmp="${entry}.c630.$$"
grep -v '^devicetree[[:space:]]' "$entry" > "$tmp"
printf 'devicetree %s\n' "$dtb_path" >> "$tmp"
mv -f "$tmp" "$entry"
echo "95-c630-devicetree: set devicetree ${dtb_path} in ${entry}"
done
;;
remove)
# The build writes its own bootstrap entry under a fixed name, which
# kernel-install would not otherwise clean up when the kernel goes away.
# The device tree is likely already gone here, so the add-time search does
# not apply; just look wherever entries live.
for cand in "${KERNEL_INSTALL_BOOT_ROOT:-}" /boot /efi /boot/efi; do
[ -n "$cand" ] || continue
rm -f "${cand}/loader/entries/c630-${KERNEL_VERSION}.conf"
done
;;
esac
exit 0