From 1e1b047b8488587564eb07b739139c305f17f20f Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sun, 20 Sep 2026 10:06:02 +0200 Subject: [PATCH] kernel-debs: run header_postinst.d from linux-headers postinst (DKMS order-safety) DKMS modules only ever got built from the linux-image postinst, via run-parts /etc/kernel/postinst.d (which includes dkms's autoinstall hook). The linux-headers postinst compiled the header tree but did NOT run /etc/kernel/header_postinst.d -- unlike stock Debian, whose linux-headers postinst runs that directory, and where dkms ships /etc/kernel/header_postinst.d/dkms to (re)build modules when headers install. Consequence: the linux-image / linux-headers configure ORDER mattered. In a single apt transaction (kernel install or an armbian-config branch switch) apt is free to configure linux-image before linux-headers; the image postinst then runs its DKMS autoinstall with no headers present and fails, and nothing rebuilds the module when the headers are configured moments later. The module is left unbuilt, and pre-#10766 the failed image postinst aborted before the boot-symlink relink, which could leave the board unbootable. Observed on a Radxa Cubie A5E: current->edge switch failed because aic8800-sdio DKMS built with no edge headers. Fix: after compiling the header tree, run the same header hooks Debian runs -- run-parts /etc/kernel/header_postinst.d with the kernel version as the argument. Now whichever of linux-image / linux-headers is configured LAST builds the DKMS modules, so install order no longer matters and the module is ready on the first pass. Non-fatal (|| true): a broken out-of-tree module must not stop the headers package from installing. Verified live on the Cubie A5E: with aic8800-sdio registered in the dkms tree but not built for the running kernel (the exact post-image-install state), running `run-parts --arg= /etc/kernel/header_postinst.d` rebuilt and installed the module ("Autoinstall ... succeeded"). Complements #10766 (relink boot symlinks even if a postinst.d hook fails): that keeps the board bootable if a build genuinely fails; this makes the build succeed regardless of package configure order. Signed-off-by: Igor Pecovnik --- lib/functions/compilation/kernel-debs.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/functions/compilation/kernel-debs.sh b/lib/functions/compilation/kernel-debs.sh index 5856478ed3f4..6abea6aea127 100644 --- a/lib/functions/compilation/kernel-debs.sh +++ b/lib/functions/compilation/kernel-debs.sh @@ -651,6 +651,24 @@ function kernel_package_callback_linux_headers() { rm -f include/generated/.armbian-build.tar.gz fi EOT_POSTINST_FINISH + + # Now that the header tree is compiled, run the same header hooks Debian runs + # from its linux-headers postinst. dkms ships /etc/kernel/header_postinst.d/dkms, + # which (re)builds DKMS modules for this kernel version. This is the safety net + # that makes the linux-image / linux-headers configure ORDER irrelevant: if the + # image is configured first (e.g. in a single apt transaction), its DKMS + # autoinstall runs with no headers present and fails; building here, when the + # headers land, completes the module on the first pass. Without this hook Armbian + # only ever built DKMS from the linux-image postinst, so a transaction that + # configured the image before its headers left the module unbuilt -- and, + # pre-#10766, could abort the image postinst before the boot-symlink relink and + # leave the board unbootable. Non-fatal: a broken out-of-tree module must not + # stop the headers package from installing. + cat <<- EOT_POSTINST_HEADER_HOOKS + if [ -d /etc/kernel/header_postinst.d ]; then + DEB_MAINT_PARAMS="\$*" run-parts --arg="${kernel_version_family}" /etc/kernel/header_postinst.d || true + fi + EOT_POSTINST_HEADER_HOOKS ) }