diff --git a/debian/changelog b/debian/changelog index d770508fa..de06e0337 100644 --- a/debian/changelog +++ b/debian/changelog @@ -53,6 +53,8 @@ linux-2.6 (2.6.31~rc6-1~experimental.1) UNRELEASED; urgency=low * ib_ipath: remove firmware for QLogic IBA7220 and use request_firmware() to load it * dvb-usb-af9005: remove firmware and disable + * Add warning on upgrade to a new upstream version where the system + appears to be missing necessary firmware files (closes: #541702) [ Martin Michlmayr ] * [armel/orion5x, armel/kirkwood] Set GPIO_SYSFS=y since these diff --git a/debian/templates/temp.image.plain/postinst b/debian/templates/temp.image.plain/postinst index d796a8dff..40cbf8c0a 100755 --- a/debian/templates/temp.image.plain/postinst +++ b/debian/templates/temp.image.plain/postinst @@ -19,6 +19,7 @@ #use strict; #for debugging use Cwd 'abs_path'; use Debconf::Client::ConfModule qw(:all); +use POSIX (); version('2.0'); my $capb=capb("backup"); @@ -760,6 +761,94 @@ if ( -d "$modules_base/$version" ) { } } } + + # If we are installing (not upgrading) a package for a newer + # upstream version than that of the running kernel, check whether + # the user might be missing necessary firmware, perhaps because + # it has now been removed from the kernel. + # + # We base this check on the modules used in the running kernel and + # the corresponding (by name) modules in the new kernel. This is + # not entirely accurate because: + # 1. A device may now be handled by a module with a different name, + # leading us to miss the dependency + # 2. A device may be handled by a module that needs firmware only + # for some other device, leading us to claim a dependency wrongly + + if (!defined($ARGV[1]) || $ARGV[1] eq '') { + (undef, undef, my $running_version) = POSIX::uname(); + my $running_patchlevel = $running_version; + $running_patchlevel =~ s/^2\.6\.(\d+).*/$1/; + my $new_patchlevel = $version; + $new_patchlevel =~ s/^2\.6\.(\d+).*/$1/; + + FIRMWARE_CHECK: + if ($new_patchlevel > $running_patchlevel) { + my $missing = ''; + my %module_paths; + open(DEP, "<$modules_base/$version/modules.dep") or last FIRMWARE_CHECK; + while () { + if (m|(.*/([^/]*)\.ko):|) { + my ($path, $module) = ($1, $2); + $module =~ s/-/_/g; + $module_paths{$module} = $path; + } + } + close(DEP); + open(MODULES, ') { + s/ .*//s; + my $module = $_; + my $module_path = $module_paths{$module}; + if (defined($module_path)) { + my $first = 1; + open(MODINFO, + "modinfo -F firmware '$modules_base/$version/$module_path' |"); + while () { + chomp; + my $firmware = $_; + unless (-e "/lib/firmware/$firmware" || + -e "/lib/firmware/$version/$firmware") { + if ($first) { + $missing .= "\\n" if $missing ne ''; + $missing .= "$module: "; + $first = 0; + } else { + $missing .= ', '; + } + $missing .= $firmware; + } + } + close(MODINFO); + } + } + close(MODULES); + + if ($missing ne '') { + my ($ret, $seen); + my $text = "${package_name}/postinst/missing-firmware-${version}"; + + ($ret, $seen) = subst($text, 'runningversion', $running_version); + die "Error setting debconf substitutions in $text: $seen" if $ret; + + ($ret, $seen) = subst($text, 'version', $version); + die "Error setting debconf substitutions in $text: $seen" if $ret; + + ($ret, $seen) = subst($text, 'missing', $missing); + die "Error setting debconf substitutions in $text: $seen" if $ret; + + ($ret, $seen) = input('high', $text); + if ($ret && $ret != 30) { + die "Error setting debconf question $text: $seen"; + } + + ($ret, $seen) = go(); + if ($ret && $ret != 30) { + die "Error asking debconf question $text: $seen"; + } + } + } + } } diff --git a/debian/templates/temp.image.plain/templates b/debian/templates/temp.image.plain/templates index 99149f229..4c26916e7 100644 --- a/debian/templates/temp.image.plain/templates +++ b/debian/templates/temp.image.plain/templates @@ -91,3 +91,17 @@ Description: Abort kernel removal? . It is highly recommended to abort the kernel removal unless you are prepared to fix the system after removal. + +Template: =ST-image-=V/postinst/missing-firmware-=V +Type: note +Description: Required firmware files may be missing + This system is currently running Linux ${runningversion} and you are + installing Linux ${version}. In the new version some of the drivers + used on this system may require additional firmware files: + . + ${missing} + . + Most firmware files are not included in the Debian system because + no source code is available for them. You may need to reconfigure + the package manager to include the non-free section of the Debian + archive before you can install these firmware files.