Hey I've read through the bug, but still didn't setup a test environment, but "triggered" by Hector and Clint's activity on the bug I thought I'd rather share patches and proposals early.
First, quick problem statement: a) flash-kernel isn't called when installing a new kernel ABI b) flash-kernel might be called more times than strictly needed c) flash-kernel doesn't have a clear contract on what to do when multiple kernels are installed on the system or when kernels are removed == triggers == In the middle of this bug's thread, there is a proposal to add triggers; it wasn't entirely obvious to me what part of the problem triggers would solve. I think triggers are good to avoid running things multiple time, so they would mostly help with the problem b). This would be helpful if for instance linux-2.6's postinst would call flash-kernel, and initramfs-tools' postinst would also call flash-kernel. However in practice that's not what happens; instead, pretty much all packages arrange to call update-initramfs -u which is implemented as a trigger -- and hence only runs once -- which calls flash-kernel. Some packages like linux-2.6 will also call the update-initramfs -c or -d, but that doesn't call flash-kernel. One area where triggers would be helpful is to avoid multiple calls when doing installation or upgrades of multiple kernels. Unfortunately, you can't pass arguments to triggers, so only one flash-kernel call type can be implemented as a trigger, for instance the "flash-kernel --supported" and "flash-kernel 2.6.38-2" calls wouldn't be implemented as triggers, but "flash-kernel" would be. I'm attaching a sample patch doing this (untested, but it's just to support the discussion). The current implementation of "flash-kernel" without a kernel ABI is to use /vmlinuz and /initrd.img or /boot/vmlinuz and /boot/initrd.img, but I don't think we can rely on these symlinks being up-to-date on all Debian installs; does anybody think so? == getting flash-kernel called on new kernels ABIs == I think this one is relatively simple, flash-kernel always requires an initrd (and it depends on initramfs-tools), and if a kernel is updated, its initrd will be updated as well; once update-initramfs is done, it will call /etc/initramfs/post-update.d/* per: http://kernel-handbook.alioth.debian.org/ch-update-hooks.html#s-initramfs-hooks We should probably change update-initramfs-tools to not hardcode the call to flash-kernel anymore and rely on /etc/initramfs/post-update.d for this as well. == multiple kernels and removals == The hard part is dealing with multiple kernels being installed, or kernels being removed. The good news is that for most boards, when a kernel is removed the system should remain mostly bootable (at least up to mounting the root) since flash-kernel copies the kernel and initrd data in NAND or generates an uImage, except the GTA02 initrd. The best thing I could think of is having all /etc/initramfs/post-update.d and /etc/kernel/postinst.d calls keep a note of which kernel initrd are being touched, and update /var/lib/flash-kernel/known-kernels with the data. flash-kernel would install the highest version according to dpkg --compare-versions and we could implement a config file to force a specific kernel later (e.g. /etc/flash-kernel.conf) or perhaps even support for chosing between kernels in future versions (debconf? boot menu?). The reason the state file is needed is that if you have upgrades for linux-2.6.37 and linux-2.6.38, and the linux-2.6.37 one is installed after linux-2.6.38, you still want the linux-2.6.38 update to be the flashed one. The reason we need to track all versions in the state file is for removals where we want to select the next highest available version of the kernel. The main problem is that flash-kernel wont know about all versions at the time where we introduce this. I'm attaching a naive implementation which doesn't deal with removals and only keeps track of the latest initrd ABI (not of the kernel one). (again, untested, sorry!) NB: debian/initramfs/post-update.d/flash-kernel needs to be +x in the native package. So to sum up, on top of the trigger support, I would propose that we add an initramfs hook to track available versions in a /var/lib/flash-kernel/ file and use that in the trigger to select the highest still installed version we should flash. Does this make sense? Any issue with this proposal? Cheers, -- Loïc Minier
diff -Nru flash-kernel-2.39/debian/changelog flash-kernel-2.40/debian/changelog --- flash-kernel-2.39/debian/changelog 2011-03-02 18:59:05.000000000 +0100 +++ flash-kernel-2.40/debian/changelog 2011-03-09 02:15:03.000000000 +0100 @@ -1,3 +1,9 @@ +flash-kernel (2.40) UNRELEASED; urgency=low + + * Add support for triggers. + + -- Loïc Minier <l...@debian.org> Wed, 09 Mar 2011 02:14:19 +0100 + flash-kernel (2.39) unstable; urgency=low * Add support for Buffalo Linkstation LiveV3 (LS-CHL). Closes: #612167 diff -Nru flash-kernel-2.39/debian/flash-kernel.postinst flash-kernel-2.40/debian/flash-kernel.postinst --- flash-kernel-2.39/debian/flash-kernel.postinst 1970-01-01 01:00:00.000000000 +0100 +++ flash-kernel-2.40/debian/flash-kernel.postinst 2011-03-09 02:19:34.000000000 +0100 @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ "$1" = "triggered" ]; then + FLASH_KERNEL_NOTRIGGER=y flash-kernel +fi + +#DEBHELPER# diff -Nru flash-kernel-2.39/debian/triggers flash-kernel-2.40/debian/triggers --- flash-kernel-2.39/debian/triggers 1970-01-01 01:00:00.000000000 +0100 +++ flash-kernel-2.40/debian/triggers 2011-03-09 02:28:23.000000000 +0100 @@ -0,0 +1 @@ +interest flash-kernel diff -Nru flash-kernel-2.39/flash-kernel flash-kernel-2.40/flash-kernel --- flash-kernel-2.39/flash-kernel 2011-03-02 18:59:05.000000000 +0100 +++ flash-kernel-2.40/flash-kernel 2011-03-09 02:13:30.000000000 +0100 @@ -111,6 +111,9 @@ esac fi +# kernel + initrd installation/upgrade mode, with optional version + +# if an explicit version was given, just try installing that if [ -n "$1" ]; then kvers="$1" kfile="/boot/vmlinuz-$kvers" @@ -118,6 +121,21 @@ desc="Debian kernel $1" idesc="Debian ramdisk $1" else + # no version was given, just accumulate multiple calls in a trigger to + # only run flash-kernel once; the trigger will just call flash-kernel + # again with FLASH_KERNEL_NOTRIGGER set to force a real + if [ -z "$FLASH_KERNEL_NOTRIGGER" ] && [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] && dpkg-trigger --check-supported 2>/dev/null; then + # flash-kernel trigger isn't disabled, and we're called from + # some package maintainer script (e.g. some postinst calls + # flash-kernel), and dpkg-trigger is installed and confirms + # that the running dpkg support triggers: we can use the + # flash-kernel trigger (asynchronously) + if dpkg-trigger --no-await flash-kernel; then + exit 0 + fi + # dpkg-trigger failed for some reason, proceed to a normal run + fi + if [ -e /vmlinuz ]; then kfile=/vmlinuz ifile=/initrd.img
diff -Nru flash-kernel-2.39/debian/changelog flash-kernel-2.40/debian/changelog --- flash-kernel-2.39/debian/changelog 2011-03-02 18:59:05.000000000 +0100 +++ flash-kernel-2.40/debian/changelog 2011-03-09 04:07:47.000000000 +0100 @@ -1,3 +1,15 @@ +flash-kernel (2.40) UNRELEASED; urgency=low + + * Add support for triggers. + * Add support for tracking and installing only the highest kernel ABI. + - Add /etc/initramfs/post-update.d/flash-kernel: write kernel ABI to + /var/lib/flash-kernel/highest-abi only if it's the highest we've seen. + - Change flash-kernel to call itself with + /var/lib/flash-kernel/highest-abi as the explicit ABI to install if it's + present. + + -- Loïc Minier <l...@debian.org> Wed, 09 Mar 2011 02:14:19 +0100 + flash-kernel (2.39) unstable; urgency=low * Add support for Buffalo Linkstation LiveV3 (LS-CHL). Closes: #612167 diff -Nru flash-kernel-2.39/debian/dirs flash-kernel-2.40/debian/dirs --- flash-kernel-2.39/debian/dirs 2011-03-02 18:59:05.000000000 +0100 +++ flash-kernel-2.40/debian/dirs 2011-03-09 04:04:15.000000000 +0100 @@ -1 +1,2 @@ usr/sbin +var/lib/flash-kernel diff -Nru flash-kernel-2.39/debian/flash-kernel.postinst flash-kernel-2.40/debian/flash-kernel.postinst --- flash-kernel-2.39/debian/flash-kernel.postinst 1970-01-01 01:00:00.000000000 +0100 +++ flash-kernel-2.40/debian/flash-kernel.postinst 2011-03-09 02:19:34.000000000 +0100 @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ "$1" = "triggered" ]; then + FLASH_KERNEL_NOTRIGGER=y flash-kernel +fi + +#DEBHELPER# diff -Nru flash-kernel-2.39/debian/initramfs/post-update.d/flash-kernel flash-kernel-2.40/debian/initramfs/post-update.d/flash-kernel --- flash-kernel-2.39/debian/initramfs/post-update.d/flash-kernel 1970-01-01 01:00:00.000000000 +0100 +++ flash-kernel-2.40/debian/initramfs/post-update.d/flash-kernel 2011-03-09 04:07:08.000000000 +0100 @@ -0,0 +1,29 @@ +#!/bin/sh + +set -e + +if [ $# != 2 ]; then + echo "$0 called without expected arguments (ABI and initrd)" >&2 + exit 1 +fi + +abi="$1" +# ignored for now +_initrd="$2" + +ABI_FILE="/var/lib/flash-kernel/highest-abi" + +current="" +if [ -r "$ABI_FILE" ]; then + current="$(cat "$ABI_FILE")" +fi + +if dpkg --compare-version "$current" ge "$abi"; then + echo "$1: Current ABI $current is already as high or higher" >&2 + exit 0 +fi + +echo "$1: Updating to new ABI $abi" >&2 +echo "$abi" >"$ABI_FILE.tmp" +mv -f "$ABI_FILE.tmp" "$ABI_FILE" + diff -Nru flash-kernel-2.39/debian/install flash-kernel-2.40/debian/install --- flash-kernel-2.39/debian/install 1970-01-01 01:00:00.000000000 +0100 +++ flash-kernel-2.40/debian/install 2011-03-09 04:04:33.000000000 +0100 @@ -0,0 +1 @@ +debian/initramfs/post-update.d/flash-kernel etc/initramfs/post-update.d/ diff -Nru flash-kernel-2.39/debian/triggers flash-kernel-2.40/debian/triggers --- flash-kernel-2.39/debian/triggers 1970-01-01 01:00:00.000000000 +0100 +++ flash-kernel-2.40/debian/triggers 2011-03-09 02:28:23.000000000 +0100 @@ -0,0 +1 @@ +interest flash-kernel diff -Nru flash-kernel-2.39/flash-kernel flash-kernel-2.40/flash-kernel --- flash-kernel-2.39/flash-kernel 2011-03-02 18:59:05.000000000 +0100 +++ flash-kernel-2.40/flash-kernel 2011-03-09 04:04:02.000000000 +0100 @@ -111,6 +111,9 @@ esac fi +# kernel + initrd installation/upgrade mode, with optional version + +# if an explicit version was given, just try installing that if [ -n "$1" ]; then kvers="$1" kfile="/boot/vmlinuz-$kvers" @@ -118,6 +121,31 @@ desc="Debian kernel $1" idesc="Debian ramdisk $1" else + # no version was given, just accumulate multiple calls in a trigger to + # only run flash-kernel once; the trigger will just call flash-kernel + # again with FLASH_KERNEL_NOTRIGGER set to force a real + if [ -z "$FLASH_KERNEL_NOTRIGGER" ] && [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] && dpkg-trigger --check-supported 2>/dev/null; then + # flash-kernel trigger isn't disabled, and we're called from + # some package maintainer script (e.g. some postinst calls + # flash-kernel), and dpkg-trigger is installed and confirms + # that the running dpkg support triggers: we can use the + # flash-kernel trigger (asynchronously) + if dpkg-trigger --no-await flash-kernel; then + exit 0 + fi + # dpkg-trigger failed for some reason, proceed to a normal run + fi + + # if the highest ABI file information is present, call ourselves again + # in "install kernel and initrd for this ABI" mode + ABI_FILE="/var/lib/flash-kernel/highest-abi" + if [ -r "$ABI_FILE" ]; then + abi="$(cat "$ABI_FILE")" + if [ -n "$abi" ]; then + exec flash-kernel "$abi" + fi + fi + if [ -e /vmlinuz ]; then kfile=/vmlinuz ifile=/initrd.img