[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#735093: flash-kernel: does not correctly handle removal of the highest-versioned installed kernel package



Package: flash-kernel
Version: 3.11
Severity: normal
Tags: patch

Flash-Kernel 3.11 does not properly handle a removal of the
highest-versioned kernel package.  The same applies to current
git as of 2014-01-12 which will probably be released as 3.12.

When called from the kernel postinst in this case, it just aborts
instead of flashing the remaining then-highest-versioned kernel,
which in specific cases could lead to an unbootable system.

Attached is a patch against current mainline flash-kernel git
(as of 7f52719ab0a607b89555baffd1cc8c14207c0f8f).

It is available for merging in the "rpi-support-rebased" branch at
http://anonscm.debian.org/gitweb/?p=users/merker/flash-kernel.git;a=shortlog;h=refs/heads/rpi-support-rebased

Regards,
Karsten

-- 
Gem. Par. 28 Abs. 4 Bundesdatenschutzgesetz widerspreche ich der Nutzung
sowie der Weitergabe meiner personenbezogenen Daten für Zwecke der
Werbung sowie der Markt- oder Meinungsforschung.
>From 989312441af9bdec76ba571eb3c6ae3d65f93d4e Mon Sep 17 00:00:00 2001
From: "K. Merker" <merker@debian.org>
Date: Thu, 2 Jan 2014 14:34:32 +0100
Subject: [PATCH] Add extended kernel package removal handling

Until now, flash-kernel has not properly handled a removal of the
highest-versioned kernel package.  When called from the kernel
postinst in this case, it just aborted instead of flashing the
remaining then-highest-versioned kernel, which could lead to an
unbootable system.

This patch adds extended removal handling which takes care
of the issue.
---
 debian/copyright            |    1 +
 flash-kernel.8              |   18 ++++++++++---
 functions                   |   63 +++++++++++++++++++++++++++++++++++--------
 kernel-hook/zz-flash-kernel |    6 +++--
 4 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/debian/copyright b/debian/copyright
index af21da0..e9fb23c 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -6,6 +6,7 @@ Copyright:
 Copyright (C) 2006  Joey Hess  <joeyh@debian.org>
 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011  Martin Michlmayr <tbm@cyrius.com>
 Copyright (C) 2011  Loïc Minier <lool@dooz.org>
+Copyright (C) 2014  Karsten Merker <merker@debian.org>
 
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
diff --git a/flash-kernel.8 b/flash-kernel.8
index 7b5bad5..8165372 100644
--- a/flash-kernel.8
+++ b/flash-kernel.8
@@ -3,7 +3,7 @@
 .SH NAME
 flash-kernel \- put kernel and initramfs in boot location
 .SH SYNOPSIS
-.B flash-kernel [--supported] [kvers]
+.B flash-kernel [--machine machine-type] [--context calling-context] [--supported] [kvers]
 .SH DESCRIPTION
 flash-kernel is a script which will put the kernel and initramfs in
 the boot location of embedded devices that don't load the kernel and
@@ -11,7 +11,7 @@ initramfs directly from /boot.  flash-kernel supports devices that
 boot from flash memory (hence the name) as well as some devices that
 require a special boot image on the disk.
 .P
-Optionally, it can be passed a version of the kernel to flash; only
+Optionally, it can be passed a version of the kernel to process; only
 the highest version will be flashed and other versions will be
 ignored.  Kernel and initrd are read from /boot.
 .P
@@ -20,7 +20,17 @@ the subarchitectures of the machine and the image to be flashed
 match. Valid filenames for images to flash are suffixed with the
 subarchitecture.
 .P
-If the \-\-supported option is used, flash\-kernel will test to see if
+If the \-\-supported option is used, flash\-kernel will test whether
 the hardware is supported, and return a true or false value.
+.P
+The \-\-machine option allows to manually override the auto-detected
+machine type string.
+.P
+The \-\-context option is used internally by the kernel
+postinst/postrm scripts which call flash-kernel upon kernel package
+installations and removals.  It provides flash-kernel with the
+information that it is running in the kernel packages
+postinst/postrm context. Valid values are postinst.d* and
+postrm.d*.
 .SH AUTHOR
-Martin Michlmayr <tbm@cyrius.com>
+Martin Michlmayr <tbm@cyrius.com>, Karsten Merker <merker@debian.org>
\ No newline at end of file
diff --git a/functions b/functions
index 26a16ed..4b1745e 100644
--- a/functions
+++ b/functions
@@ -351,28 +351,69 @@ android_flash() {
 }
 
 main() {
-if [ "x$1" = "x--machine" ]; then
-	machine="$2"
-	shift 2
-else
+
+while [ $# -gt 0 ]
+do
+        if [ "x$1" = "x--machine" ]; then
+                machine="$2"
+                shift 1
+        elif [ "x$1" = "x--context" ]; then
+                context="$2"
+                shift 1
+        elif [ "x$1" = "x--supported" ]; then
+                do_check_supported="true"
+        elif [ $# -eq 1 ]; then
+                kvers="$1"
+        fi
+        shift 1
+done
+
+if [ -z "$machine" ]; then
 	get_machine
 fi
 
-if [ "x$1" = "x--supported" ]; then
+if [ -n "$do_check_supported" ]; then
 	if check_supported "$machine"; then
 		exit 0
+	else
+		exit 1
 	fi
-	exit 1
 fi
 
-# kernel + initrd installation/upgrade mode, with optional version
-
-kvers="$1"
 latest_version=$(linux-version list | linux-version sort | tail -1)
-if [ -n "$kvers" ] && [ "$kvers" != "$latest_version" ]; then
-	echo "Ignoring old or unknown version $kvers (latest is $latest_version)" >&2
+
+# context parameter is passed when main() is called from
+# /etc/kernel/* to be able to differentiate between being called
+# upon kernel installation or kernel removal
+
+case "$context" in
+	postrm.d*)	mode="remove" ;;
+	*)		mode="install" ;;
+esac
+
+if [ -n "$kvers" ] && [ "$kvers" != "$latest_version" ] && [ "$mode" = "install" ]; then
+	echo "flash-kernel: Ignoring old or unknown version $kvers (latest is $latest_version)" >&2
 	exit 0
 fi
+
+if [ -n "$kvers" ] && [ "$mode" = "remove" ]; then
+	if $(linux-version compare "$kvers" lt "$latest_version"); then
+		echo "flash-kernel: Removal of kernel version ${kvers}." >&2
+		echo "flash-kernel: A higher version (${latest_version}) is still installed, no reflashing required." >&2
+		exit 0
+	else
+		echo "flash-kernel: Kernel ${kvers} has been removed." >&2
+		if [ -n "${latest_version}" ]; then
+			echo "flash-kernel: Flashing the remaining highest-versioned kernel (${latest_version})." >&2
+		else
+			echo "flash-kernel: WARNING: No other kernel packages found!" >&2
+			echo "flash-kernel: The system might be unbootable." >&2
+			echo "flash-kernel: Please install a kernel package before rebooting the system." >&2
+			exit 0
+		fi
+	fi
+fi
+
 kvers="$latest_version"
 
 # accumulate multiple calls in a trigger to only run flash-kernel once; the
diff --git a/kernel-hook/zz-flash-kernel b/kernel-hook/zz-flash-kernel
index 336134a..c228d4f 100755
--- a/kernel-hook/zz-flash-kernel
+++ b/kernel-hook/zz-flash-kernel
@@ -29,9 +29,11 @@ _version="${version%\'}"
 # only call flash-kernel once on install, upgrade, removal or purge
 # XXX apparently kernel postinst doesn't always pass maintainer scripts
 # arguments
-case "$(basename "$(dirname "$self")")/$action" in
+
+context="$(basename "$(dirname "$self")")/$action"
+case "$context" in
   postinst.d/configure|postinst.d/|postrm.d/remove|postrm.d/)
-    exec flash-kernel "$abi"
+    exec flash-kernel --context "$context" "$abi"
   ;;
 esac
 
-- 
1.7.10.4


Reply to: