From 939ac94134fafc7fc6211bdf73b0447e41d0561e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 27 Jun 2010 01:02:45 +0000 Subject: [PATCH] linux-base: If the disk ID update process fails, give the user a chance to retry or change their answers (Closes: #585609) svn path=/dists/sid/linux-2.6/; revision=15912 --- debian/changelog | 2 + debian/linux-base.postinst | 121 ++++++++++++++++++++++-------------- debian/linux-base.templates | 11 ++++ 3 files changed, 87 insertions(+), 47 deletions(-) diff --git a/debian/changelog b/debian/changelog index deefcafa7..01c0d56a6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -36,6 +36,8 @@ linux-2.6 (2.6.32-16) UNRELEASED; urgency=low * Enable IPv6 support for IPVS (IP_VS_IPV6) (Closes: #584549) * Revert "tpm: autoload tpm_tis based on system PnP IDs", included in stable 2.6.32.12 (Closes: #584273) + * linux-base: If the disk ID update process fails, give the user a + chance to retry or change their answers (Closes: #585609) [ Aurelien Jarno ] * [sh4] fix sh_tmu clocksource following recent nohz changes. diff --git a/debian/linux-base.postinst b/debian/linux-base.postinst index 085631876..00a4ddb18 100644 --- a/debian/linux-base.postinst +++ b/debian/linux-base.postinst @@ -24,38 +24,10 @@ use FileHandle; use POSIX (); use UUID; -# Since debconf clients get their standard input and output redirected -# to the debconf front-end, we need to redirect them again before -# running any other program. -sub _system { - my $pid = fork(); - die "$!" unless defined($pid); - if ($pid == 0) { - # &2 - POSIX::dup2(2, 1) or die "$!"; - exec(@_); - exit(255); # usual exit code for failed exec - } else { - waitpid($pid, 0); - # The built-in system() function does this substitution - if (POSIX::WIFEXITED($?) && POSIX::WEXITSTATUS($?) == 255) { - return -1; - } else { - return $?; - } - } -} - package DebianKernel::DiskId; ### utility -# Import _system() function -*_system = \&main::_system; - sub id_to_path { my ($id) = @_; $id =~ m|^/| @@ -347,7 +319,7 @@ sub grub1_update { } sub grub1_post { - _system('update-grub'); + system('update-grub'); } ### GRUB 2 config @@ -384,7 +356,7 @@ sub grub2_update { } sub grub2_post { - _system('grub-mkconfig', '-o', '/boot/grub/grub.cfg'); + system('grub-mkconfig', '-o', '/boot/grub/grub.cfg'); } ### LILO @@ -553,13 +525,13 @@ sub lilo_update { } sub lilo_post { - _system('lilo'); + system('lilo'); } ### SILO sub silo_post { - _system('silo'); + system('silo'); } ### ELILO @@ -576,7 +548,7 @@ sub elilo_update { } sub elilo_post { - _system('elilo'); + system('elilo'); } ### extlinux @@ -639,7 +611,7 @@ sub extlinux_new_update { } sub extlinux_post { - _system('update-extlinux'); + system('update-extlinux'); } # udev persistent-cd @@ -1038,40 +1010,40 @@ my @config_files = ({packages => 'mount', sub ext2_set_label { my ($bdev, $label) = @_; - _system('tune2fs', '-L', $label, $bdev) == 0 or die "tune2fs failed: $?"; + system('tune2fs', '-L', $label, $bdev) == 0 or die "tune2fs failed: $?"; } sub ext2_set_uuid { my ($bdev, $uuid) = @_; - _system('tune2fs', '-U', $uuid, $bdev) == 0 or die "tune2fs failed: $?"; + system('tune2fs', '-U', $uuid, $bdev) == 0 or die "tune2fs failed: $?"; } sub jfs_set_label { my ($bdev, $label) = @_; - _system('jfs_tune', '-L', $label, $bdev) == 0 or die "jfs_tune failed: $?"; + system('jfs_tune', '-L', $label, $bdev) == 0 or die "jfs_tune failed: $?"; } sub jfs_set_uuid { my ($bdev, $uuid) = @_; - _system('jfs_tune', '-U', $uuid, $bdev) == 0 or die "jfs_tune failed: $?"; + system('jfs_tune', '-U', $uuid, $bdev) == 0 or die "jfs_tune failed: $?"; } sub fat_set_label { my ($bdev, $label) = @_; - _system('dosfslabel', $bdev, $label) == 0 or die "dosfslabel failed: $?"; + system('dosfslabel', $bdev, $label) == 0 or die "dosfslabel failed: $?"; } sub ntfs_set_label { my ($bdev, $label) = @_; - _system('ntfslabel', $bdev, $label) == 0 or die "ntfslabel failed: $?"; + system('ntfslabel', $bdev, $label) == 0 or die "ntfslabel failed: $?"; } sub reiserfs_set_label { my ($bdev, $label) = @_; - _system('reiserfstune', '--label', $label, $bdev) + system('reiserfstune', '--label', $label, $bdev) or die "reiserfstune failed: $?"; } sub reiserfs_set_uuid { my ($bdev, $uuid) = @_; - _system('reiserfstune', '--uuid', $uuid, $bdev) + system('reiserfstune', '--uuid', $uuid, $bdev) or die "reiserfstune failed: $?"; } @@ -1135,16 +1107,16 @@ sub swap_set_uuid { sub ufs_set_label { my ($bdev, $label) = @_; - _system('tunefs.ufs', '-L', $label, $bdev) or die "tunefs.ufs failed: $?"; + system('tunefs.ufs', '-L', $label, $bdev) or die "tunefs.ufs failed: $?"; } sub xfs_set_label { my ($bdev, $label) = @_; - _system('xfs_admin', '-L', $label, $bdev) or die "xfs_admin failed: $?"; + system('xfs_admin', '-L', $label, $bdev) or die "xfs_admin failed: $?"; } sub xfs_set_uuid { my ($bdev, $uuid) = @_; - _system('xfs_admin', '-U', $uuid, $bdev) or die "xfs_admin failed: $?"; + system('xfs_admin', '-U', $uuid, $bdev) or die "xfs_admin failed: $?"; } my %filesystem_types = ( @@ -1431,9 +1403,42 @@ sub update_config { } } +sub update_all { + # The update process may be aborted if a command fails, but we now + # want to recover and ask the user what to do. We can use 'do' to + # prevent 'die' from exiting the process, but we also need to + # capture and present error messages using debconf as they may + # otherwise be hidden. Therefore, we fork and capture stdout and + # stderr from the update process in the main process. + my $pid = open(PIPE, '-|'); + return (-1, '') unless defined $pid; + + if ($pid == 0) { + # Complete redirection + # &1 + POSIX::dup2(1, 2) or die "$!"; + + # Do the update + set_new_ids(); + update_config(@_); + exit; + } else { + my @output = (); + while () { + push @output, $_; + } + close(PIPE); + return ($?, join('', @output)); + } +} + sub transition { use Debconf::Client::ConfModule ':all'; +retry: %bdev_map = (); %id_map = (); @@ -1520,8 +1525,30 @@ sub transition { die "Error retrieving answer for $question: $answer" if $ret; if ($answer eq 'true') { - set_new_ids(); - update_config(\%update_map, @auto_configs); + my ($rc, $output) = update_all(\%update_map, @auto_configs); + if ($rc != 0) { + # Display output of update commands + $question = 'linux-base/disk-id-update-failed'; + $output =~ s/\n/\\n/g; + ($ret, $seen) = subst($question, 'output', $output); + die "Error setting debconf substitutions in $question: $seen" + if $ret; + ($ret, $seen) = input('high', $question); + if ($ret && $ret != 30) { + die "Error setting debconf question $question: $seen"; + } + ($ret, $seen) = go(); + if ($ret && $ret != 30) { + die "Error asking debconf question $question: $seen"; + } + + # Mark previous questions as unseen + fset('linux-base/disk-id-convert-auto', 'seen', 'false'); + fset('linux-base/disk-id-convert-plan', 'seen', 'false'); + fset('linux-base/disk-id-convert-plan-no-relabel', 'seen', + 'false'); + goto retry; + } } } diff --git a/debian/linux-base.templates b/debian/linux-base.templates index 7d46c9808..1eabf49bb 100644 --- a/debian/linux-base.templates +++ b/debian/linux-base.templates @@ -74,3 +74,14 @@ _Description: Boot loader configuration check needed You should generally identify these devices by UUID or label. However, on MIPS systems the root device must be identified by name. + +Template: linux-base/disk-id-update-failed +Type: error +# Not yet translated +Description: Failed to update disk device IDs + An error occurred while attempting to update the system configuration: + . + ${output} + . + You can either correct this error and retry the automatic update, + or choose to update the system configuration yourself.