linux/debian/templates/temp.image.plain/postinst

1029 lines
34 KiB
Perl
Executable File

#! /usr/bin/perl
#
#use strict; #for debugging
use Cwd 'abs_path';
use Debconf::Client::ConfModule qw(:all);
use POSIX ();
version('2.0');
my $capb = capb('backup', 'escape');
$|=1;
# Predefined values:
my $version = "=V";
my $link_in_boot = "=IB"; # Should be empty, mostly
my $no_symlink = "=S"; # Should be empty, mostly
my $do_symlink = "Yes"; # target machine defined
my $do_boot_enable = "Yes"; # target machine defined
my $do_bootloader = "Yes"; # target machine defined
my $kimage = "=K"; # Should be empty, mostly
my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom, arcboot or delo
my $image_dir = "=D"; # where the image is located
my $initrd = "=I"; # initrd kernel
my $mkimage = "=M"; # command to generate the initrd image
my $use_hard_links = ''; # hardlinks do not work across fs boundaries
my $postinst_hook = ''; #Normally we do not
my $minimal_swap = ''; # Do not swap symlinks
my $ignore_depmod_err = ''; # normally we do not
my $relink_src_link = 'YES'; # There is no harm in checking the link
my $relink_build_link = 'YES'; # There is no harm in checking the link
my $force_build_link = ''; # There is no harm in checking the link
my $arch = "=A"; # should be same as dpkg --print-architecture
my $kernel_arch = "=B";
my $ramdisk = "=MK"; # List of tools to create initial ram fs.
my $package_name = "=ST-image-$version";
my $explicit_do_loader = '';
my $Loader = "NoLOADER"; #
$Loader = "LILO" if $loader =~ /^lilo/io;
$Loader = "SILO" if $loader =~ /^silo/io;
$Loader = "QUIK" if $loader =~ /^quik/io;
$Loader = "yaboot" if $loader =~ /^yaboot/io;
$Loader = "PALO" if $loader =~ /^palo/io;
$Loader = "NETTROM" if $loader =~ /^nettrom/io;
$Loader = "VMELILO" if $loader =~ /^vmelilo/io;
$Loader = "ZIPL" if $loader =~ /^zipl/io;
$Loader = "ELILO" if $loader =~ /^elilo/io;
$Loader = "ARCBOOT" if $loader =~ /^arcboot/io;
$Loader = "DELO" if $loader =~ /^delo/io;
# This should not point to /tmp, because of security risks.
my $temp_file_name = "/var/log/$loader" . "_log.$$";
#known variables
my $image_dest = "/";
my $realimageloc = "/$image_dir/";
my $have_conffile = "";
my $modules_base = '/lib/modules';
my $CONF_LOC = '/etc/kernel-img.conf';
# Ignore all invocations except when called on to configure.
exit 0 unless $ARGV[0] =~ /configure/;
my $DEBUG = 0;
# Do some preliminary sanity checks here to ensure we actually have an
# valid image dir
chdir('/') or die "could not chdir to /:$!\n";
die "Internal Error: ($image_dir) is not a directory!\n"
unless -d $image_dir;
# remove multiple leading slashes; make sure there is at least one.
$realimageloc =~ s|^/*|/|o;
$realimageloc =~ s|/+|/|o;
die "Internal Error: ($realimageloc) is not a directory!\n"
unless -d $realimageloc;
if (-r "$CONF_LOC" && -f "$CONF_LOC" ) {
if (open(CONF, "$CONF_LOC")) {
while (<CONF>) {
chomp;
s/\#.*$//g;
next if /^\s*$/;
$do_symlink = "" if /do_symlinks\s*=\s*(no|false|0)\s*$/i;
$no_symlink = "" if /no_symlinks\s*=\s*(no|false|0)\s*$/i;
$link_in_boot = "" if /link_in_boot\s*=\s*(no|false|0)\s*$/i;
$do_boot_enable = '' if /do_boot_enable\s*=\s*(no|false|0)\s*$/i;
$do_bootloader = '' if /do_bootloader\s*=\s*(no|false|0)\s*$/i;
$use_hard_links = '' if /use_hard_links\s*=\s*(no|false|0)\s*$/i;
$minimal_swap = '' if /minimal_swap\s*=\s*(no|false|0)\s*$/i;
$ignore_depmod_err = '' if /ignore_depmod_err\s*=\s*(no|false|0)\s*$/i;
$relink_src_link = '' if /relink_src_link\s*=\s*(no|false|0)\s*$/i;
$relink_build_link = '' if /relink_build_link\s*=\s*(no|false|0)\s*$/i;
$force_build_link = '' if /force_build_link\s*=\s*(no|false|0)\s*$/i;
$do_symlink = "Yes" if /do_symlinks\s*=\s*(yes|true|1)\s*$/i;
$no_symlink = "Yes" if /no_symlinks\s*=\s*(yes|true|1)\s*$/i;
$link_in_boot = "Yes" if /link_in_boot\s*=\s*(yes|true|1)\s*$/i;
$do_boot_enable = "Yes" if /do_boot_enable\s*=\s*(yes|true|1)\s*$/i;
$do_bootloader = "Yes" if /do_bootloader\s*=\s*(yes|true|1)\s*$/i;
$explicit_do_loader = "YES" if /do_bootloader\s*=\s*(yes|true|1)\s*$/i;
$use_hard_links = "Yes" if /use_hard_links\s*=\s*(yes|true|1)\s*$/i;
$minimal_swap = 'Yes' if /minimal_swap\s*=\s*(yes|true|1)\s*$/i;
$ignore_depmod_err = 'Yes' if /ignore_depmod_err\s*=\s*(yes|true|1)\s*$/i;
$relink_src_link = 'Yes' if /relink_src_link\s*=\s*(yes|true|1)\s*$/i;
$relink_build_link = 'Yes' if /relink_build_link\s*=\s*(yes|true|1)\s*$/i;
$force_build_link = 'Yes' if /force_build_link\s*=\s*(yes|true|1)\s*$/i;
$image_dest = "$1" if /image_dest\s*=\s*(\S+)/i;
$postinst_hook = "$1" if /postinst_hook\s*=\s*(\S+)/i;
$mkimage = "$1" if /mkimage\s*=\s*(.+)$/i;
$ramdisk = "$1" if /ramdisk\s*=\s*(.+)$/i;
}
close CONF;
$have_conffile = "Yes";
}
}
# For some versions of kernel-package, we had this warning in the
# postinst, but the rules did not really interpolate the value in.
# Here is a sanity check.
my $pattern = "=" . "I";
$initrd=~ s/^$pattern$//;
if ($link_in_boot) {
$image_dest = "/$image_dir/"; # same as realimageloc
}
# Tack on at least one trainling /
$image_dest = "$image_dest/";
$image_dest =~ s|^/*|/|o;
$image_dest =~ s|/+$|/|o;
if (! -d "$image_dest") {
die "Expected Image Destination dir ($image_dest) to be a valid directory!\n";
}
# sanity
if (! $do_bootloader) {
$do_boot_enable = '';
}
if ($do_symlink && $no_symlink) {
warn "Both do_symlinks and no_symlinks options enabled; disabling no_symlinks\n";
$no_symlink = 0;
}
# most of our work is done in $image_dest (nominally /)
chdir("$image_dest") or die "could not chdir to $image_dest:$!\n";
# Paranoid check to make sure that the correct value is put in there
if (! $kimage) { $kimage = "vmlinuz"; } # Hmm. empty
elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz"; } # these produce vmlinuz
elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; }
elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; }
else { $kimage = "vmlinuz"; } # Default
$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch;
die "Internal Error: Could not find image (" . $realimageloc
. "$kimage-$version)\n" unless -e $realimageloc
. "$kimage-$version";
# search for the boot loader in the path
my $loader_exec;
($loader_exec = $loader) =~ s|.*/||;
my ($loaderloc) = grep -x, map "$_/$loader_exec",
map { length($_) ? $_ : "." } split /:/, $ENV{PATH};
######################################################################
## Fix the build link
######################################################################
sub fix_build_link {
return unless -d "$modules_base/$version";
# if we saved a build link in preinst, restore the link
if (! -e "$modules_base/$version/build" &&
-l "$modules_base/$version/build.save" ) {
rename("$modules_base/$version/build.save", "$modules_base/$version/build") ||
die "failed to move $modules_base/$version/build:$!";
}
if ($relink_build_link || $force_build_link) {
my $build_target;
my $real_target = '';
if (-l "$modules_base/$version/build") {
$build_target = readlink "$modules_base/$version/build";
} else {
return;
}
# Determine what the real file name is, and test that for existence
$real_target = abs_path($build_target) if defined($build_target);
if (!defined($build_target) || ! -d "$real_target") { # Danglink link
my $num = unlink "$modules_base/$version/build";
if ($num != 1) {
warn "error unlinking $modules_base/$version/build";
} else {
if ($force_build_link || -d "/usr/src/=ST-headers-$version") {
my $result = symlink ("/usr/src/=ST-headers-$version",
"$modules_base/$version/build");
if (! $result) {
warn "Could not link /usr/src/=ST-headers-$version to $modules_base/$version/build:$!"
}
}
}
}
}
}
if ($relink_build_link || $force_build_link) {
&fix_build_link();
}
######################################################################
## Fix the source link
######################################################################
sub fix_source_link {
return unless -d "$modules_base/$version";
if ($relink_src_link) {
my $source_target;
my $real_target = '';
if (-l "$modules_base/$version/source") {
$source_target = readlink "$modules_base/$version/source";
} else {
return;
}
# Determine what the real file name is, and test that for existence
$real_target = abs_path($source_target) if defined($source_target);
if (!defined($source_target) || ! -d "$real_target") { # Danglink link
my $num = unlink "$modules_base/$version/source";
if ($num != 1) {
warn "error unlinking $modules_base/$version/source";
}
}
}
}
if ($relink_src_link) {
&fix_source_link();
}
######################################################################
######################################################################
########### Test whether a relative symlinkwould be OK #######
######################################################################
######################################################################
sub test_relative {
my %params = @_;
my $cwd;
die "Internal Error: Missing Required paramater 'Old Dir' "
unless $params{'Old Dir'};
die "Internal Error: Missing Required paramater New Dir' "
unless $params{'New Dir'};
die "Internal Error: No such dir $params{'Old Dir'} "
unless -d $params{'Old Dir'};
die "Internal Error: No such dir $params{'New Dir'} "
unless -d $params{'New Dir'};
warn "Test relative: testing $params{'Old Dir'} -> $params{'New Dir'}"
if $DEBUG;
chomp($cwd = `pwd`);
chdir ($params{'New Dir'}) or die "Could not chdir to $params{'New Dir'}:$!";
my $ok = 0;
$params{'Old Dir'} =~ s|^/*||o;
if (-d $params{'Old Dir'} ) {
if (defined $params{'Test File'}) {
if (-e $params{'Old Dir'} . $params{'Test File'}) {
$ok = 1;
}
} else {
$ok = 1; # well, backward compatibility
}
}
chdir ($cwd) or die "Could not chdir to $params{'New Dir'}:$!";
return $ok;
}
sub spath {
my %params = @_;
die "Missing Required paramater 'Old'" unless $params{'Old'};
die "Missing Required paramater 'New'" unless $params{'New'};
my @olddir = split '/', `readlink -q -m $params{'Old'}`;
my @newdir = split '/', `readlink -q -m $params{'New'}`;
my @outdir = @olddir;
my $out = '';
my $i;
for ($i = 0; $i <= $#olddir && $i <= $#newdir; $i++) {
$out++ if ($olddir[$i] ne $newdir[$i]);
shift @outdir unless $out;
unshift @outdir, ".." if $out;
}
if ($#newdir > $#olddir) {
for ($i=0; $i < $#newdir; $i++) {
unshift @outdir, "..";
}
}
return join ('/', @outdir);
}
# This routine is invoked if there is a symbolic link in place
# in $image_dest/$kimage -- so a symlink exists in the destination.
# What we are trying to determine is if we need to move the symbolic link over
# to the the .old location
sub move_p {
my $kimage = $_[0]; # Name of the symbolic link
my $image_dest = $_[1]; # The directory the links goes into
my $image_name = $_[2];
my $src_dir = $_[3];
my $force_move = 0;
warn "Move?: kimage=$kimage, image_dest=$image_dest, \n" .
"\timage_name=$image_name, src_dir=$src_dir" if $DEBUG;
if ($no_symlink) {
# we do not want links, yet we have a symbolic link here!
warn "found a symbolic link in " . $image_dest . "$kimage \n" .
"even though no_symlink is defined\n" if $no_symlink;
# make sure we change this state of affairs
$force_move = 1;
return $force_move;
}
warn "DEBUG: OK. We found symlink, and we should have a symlink here.\n"
if $DEBUG;
my $vmlinuz_target = readlink "$kimage";
my $real_target = '';
my $target = `readlink -q -m "${realimageloc}${kimage}-$version"`;
$real_target = abs_path($vmlinuz_target) if defined($vmlinuz_target);
if (!defined($vmlinuz_target) || ! -f "$real_target") {
# what, a dangling symlink?
warn "The link " . $image_dest . "$kimage is a dangling link" .
"to $real_target\n";
$force_move = 1;
return $force_move;
}
warn "DEBUG: The link $kimage points to ($vmlinuz_target)\n" if $DEBUG;
warn "DEBUG: ($vmlinuz_target) is really ($real_target)\n" if $DEBUG;
my $cwd;
chomp ($cwd=`pwd`);
if ($vmlinuz_target !~ m|^/|o) {
$vmlinuz_target = $cwd . "/" . $vmlinuz_target;
$vmlinuz_target =~ s|/+|/|o;
}
$vmlinuz_target = `readlink -q -m $vmlinuz_target`;
if ("$vmlinuz_target" ne "$target") {
warn "DEBUG: We need to handle this.\n" if $DEBUG;
if ($minimal_swap) {
warn "DEBUG: Minimal swap.\n" if $DEBUG;
if (-l "$kimage.old") {
warn "DEBUG: There is an old link at $kimage.old\n" if $DEBUG;
my $old_target = readlink "$kimage.old";
my $real_old_target = '';
$real_old_target=abs_path($old_target) if defined ($old_target);
if ($real_old_target && -f "$real_old_target") {
if ($old_target !~ m|^/|o) {
$old_target = $cwd . "/" . $old_target;
$old_target =~ s|/+|/|o;
}
$old_target = `readlink -q -m $old_target`;
if ("$old_target" ne "$target") {
$force_move = 1;
warn "DEBUG: Old link ($old_target) does not point to us ($target)\n"
if $DEBUG;
}
else { # The .old points to the current
warn "$kimage.old --> $target -- doing nothing";
$force_move = 0;
}
}
else {
warn "DEBUG: Well, the old link does not exist -- so we move\n"
if $DEBUG;
$force_move = 1;
}
}
else {
warn "DEBUG: No .old link -- OK to move\n"
if $DEBUG;
$force_move = 1;
}
}
else {
warn "DEBUG: ok, minimal swap is no-- so we move.\n"
if $DEBUG;
$force_move = 1;
}
}
else { # already have proper link
warn "$kimage($vmlinuz_target) points to $target ($real_target) -- doing nothing";
$force_move = 0;
}
return $force_move;
}
# This routine moves the symbolic link around (/vmlinuz -> /vmlinuz.old)
# It pays attention to whether we should the fact whether we should be using
# hard links or not.
sub really_move_link {
my $kimage = $_[0]; # Name of the symbolic link
my $image_dest = $_[1]; # The directory the links goes into
my $image_name = $_[2];
my $src_dir = $_[3];
warn "really_move_link: kimage=$kimage, image_dest=$image_dest\n" .
"\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
# don't clobber $kimage.old quite yet
rename("$kimage", "$kimage.$$") ||
die "failed to move " . $image_dest . "$kimage:$!";
my $Old = $src_dir;
my $cwd;
chomp($cwd=`pwd`);
if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd,
'Test File' => "$image_name")) {
$Old =~ s|^/*||o;
}
# Special case is they are in the same dir
my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" );
$Old ="" if $rel_path =~ m/^\s*$/o;
if ($use_hard_links =~ m/YES/i) {
if (! link("${Old}${image_name}", "$kimage")) {
rename("$kimage.$$", "$kimage");
die("Failed to link ${Old}${image_name} to " .
"${image_dest}${kimage}.\n");
}
}
else {
if (! symlink("${Old}${image_name}", "$kimage")) {
rename("$kimage.$$", "$kimage");
die("Failed to symbolic-link ${Old}${image_name} to " .
"${image_dest}${kimage}.\n");
}
}
# Ok, now we may clobber the previous .old file
if (-l "$kimage.old" || ! -e "$kimage.old" ) {
rename("$kimage.$$", "$kimage.old");
}
else {
warn "$kimage.old is not a symlink, not clobbering\n";
warn "rm $kimage.$$";
}
}
# This routine handles a request to do symlinks, but there is no
# symlink file already there. Either we are supposed to use copy, or we are
# installing on a pristine system, or the user does not want symbolic links at
# all. We use a configuration file to tell the last two cases apart, creating
# a config file if needed.
sub handle_missing_link {
my $kimage = $_[0]; # Name of the symbolic link
my $image_dest = $_[1]; # The directory the links goes into
my $image_name = $_[2];
my $src_dir = $_[3];
warn "handle_missing_link: kimage=$kimage, image_dest=$image_dest\n" .
"\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
if ($no_symlink) {
my $ret = system("cp -a --backup=t " . $realimageloc .
"$image_name " . " $kimage");
if ($ret) {
die("Failed to copy " . $realimageloc . "$image_name to "
. $image_dest . "$kimage .\n");
}
} else {
if (! $have_conffile) {
# current default
$do_symlink = "Yes";
if ($loader =~ /palo/i) {
if (open(CONF, ">$CONF_LOC")) {
print CONF "# Kernel Image management overrides\n";
print CONF "link_in_boot = Yes\n";
print CONF "do_symlinks = Yes\n";
print CONF "do_bootloader = No\n";
close CONF;
$have_conffile = "Yes";
}
}
}
}
if (! $no_symlink && $do_symlink =~ /Yes/i) {
my $Old = $realimageloc;
my $New = $image_dest;
my $Name = "$image_name";
my $Link_Dest = "$kimage";
if (test_relative ('Old Dir' => $Old,
'New Dir' => $New,
'Test File' => $Name)) {
$Old =~ s|^/*||o;
}
# Special case is they are in the same dir
my $rel_path = spath('Old' => "$Old", 'New' => "$New" );
$Old ="" if $rel_path =~ m/^\s*$/o;
symlink($Old . "$Name", "$Link_Dest") ||
die("Failed to symbolic-link ${Old}$Name to $Link_Dest.\n");
}
}
# This routine handles the rest of the cases, where the user has requested
# non-traditional handling, like using cp or hard links.
sub handle_non_symlinks {
my $kimage = $_[0]; # Name of the symbolic link
my $image_dest = $_[1]; # The directory the links goes into
my $image_name = $_[2];
my $src_dir = $_[3];
warn "handle_non_link: kimage=$kimage, image_dest=$image_dest\n" .
"\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
# Save the current image. We do this in all four cases
rename("$kimage", "$kimage.$$") ||
die "failed to move " . $image_dest . "$kimage:$!";
##,####
# case One
#`####
if ($no_symlink) {
# Maybe /$image_dest is on a dos system?
my $ret = system("cp -a --backup=t " . $realimageloc
. "$image_name " . "$kimage");
if ($ret) {
if (-e "$kimage.$$") {
rename("$kimage.$$", "$kimage");
}
die("Failed to copy " . $realimageloc . "$image_name to "
. $image_dest . "$kimage .\n");
}
}
##,####
# case Two
#`####
elsif ($use_hard_links =~ m/YES/i ) {
# Ok then. this ought to be a hard link, and hence fair game
# don't clobber $kimage.old quite yet
my $Old = $realimageloc;
my $cwd;
chomp($cwd=`pwd`);
if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd,
'Test File' => "$image_name")) {
$Old =~ s|^/*||o;
}
# Special case is they are in the same dir
my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" );
$Old ="" if $rel_path =~ m/^\s*$/o;
if (! link($Old . "$image_name", "$kimage")) {
rename("$kimage.$$", "$kimage");
die("Failed to hard link " . $realimageloc . "$image_name to "
. $image_dest . "$kimage .\n");
}
}
##,####
# case Three
#`####
else {
# We just use cp
my $ret = system("cp -a --backup=t " . $realimageloc
. "$image_name " . "$kimage");
if ($ret) {
if (-e "$kimage.$$") {
rename("$kimage.$$", "$kimage");
}
die("Failed to copy " . $realimageloc . "$image_name to "
. $image_dest . "$kimage .\n");
}
}
# Ok, now we may clobber the previous .old file
rename("$kimage.$$", "$kimage.old") if -e "$kimage.$$";
}
# This routine is responsible for setting up the symbolic links
# So, the actual kernel image lives in
# $realimageloc/$image_name (/boot/vmlinuz-2.6.12).
# This routine creates symbolic links in $image_dest/$kimage (/vmlinuz)
sub image_magic {
my $kimage = $_[0]; # Name of the symbolic link
my $image_dest = $_[1]; # The directory the links goes into
my $image_name = "$kimage-$version";
my $src_dir = $realimageloc;
warn "image_magic: kimage=$kimage, image_dest=$image_dest\n" .
"\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
if (-l "$kimage") { # There is a symbolic link
warn "DEBUG: There is a symlink for $kimage\n" if $DEBUG;
my $force_move = move_p($kimage, $image_dest, $image_name, $src_dir);
if ($force_move) {
really_move_link($kimage, $image_dest, $image_name, $src_dir);
}
}
elsif (! -e "$kimage") {
# Hmm. Pristine system? How can that be? Installing from scratch?
# Or maybe the user does not want a symbolic link here.
# Possibly they do not want a link here. (we should be in /
# here[$image_dest, really]
handle_missing_link($kimage, $image_dest, $image_name, $src_dir);
}
elsif (-e "$kimage" ) {
# OK, $kimage exists -- but is not a link
handle_non_symlinks($kimage, $image_dest, $image_name, $src_dir);
}
}
######################################################################
######################################################################
######################################################################
######################################################################
sub do_modules {
print STDERR "Running depmod.\n";
my $ret = system("depmod -a -F $realimageloc/System.map-$version $version");
my $exit_value = $? >> 8;
my $signal_num = $? & 127;
my $dumped_core = $? & 128;
if ($ret) {
my $seen;
my $answer;
$question = "${package_name}/postinst/depmod-error-initrd-$version";
($ret,$seen) = fset ("$question", 'seen', 'false');
die "Error setting debconf flags in $question: $seen" if $ret;
$ret = subst("$question", 'modules_base', "$modules_base");
die "Error setting debconf substitutions in $question: $seen" if $ret;
$ret = subst("$question", 'SIGNAL', ", and got a signal $signal_num");
die "Error setting debconf substitutions in $question: $seen" if $ret;
if ($dumped_core) {
$ret = subst("$question", 'CORE', ", and dumped core");
die "Error setting debconf substitutions in $question: $seen" if $ret;
}
else {
$ret = subst("$question", 'CORE', " ");
die "Error setting debconf substitutions in $question: $seen" if $ret;
}
($ret,$seen) = input('medium', "$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";
}
($ret,$answer) = get("$question");
die "Error retreiving answer for $question: $answer" if $ret;
if (! $ignore_depmod_err) {
if ($answer =~ /^(y|t)/i) {
exit(1);
}
else {
print STDERR "Ok, continuing as directed\n";
}
}
}
# 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/;
if ($new_patchlevel > $running_patchlevel) {
my $missing = '';
my %module_paths;
open(DEP, "<$modules_base/$version/modules.dep") or return;
while (<DEP>) {
if (m|(.*/([^/]*)\.ko):|) {
my ($path, $module) = ($1, $2);
$module =~ s/-/_/g;
$module_paths{$module} = $path;
}
}
close(DEP);
open(MODULES, '</proc/modules') or return;
while (<MODULES>) {
s/ .*//s;
my $module = $_;
my $module_path = $module_paths{$module};
if (defined($module_path)) {
my $first = 1;
if ($module_path !~ m|^/|) {
$module_path = "$modules_base/$version/$module_path";
}
open(MODINFO, "modinfo -F firmware '$module_path' |");
while (<MODINFO>) {
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";
}
}
}
}
}
# We may not have any modules installed
if (-d "$modules_base/$version") {
&do_modules();
}
sub find_initramfs_tool {
my $ramdisk = shift;
my (@tools, $initramfs_cmd);
foreach $initramfs_cmd (split(/[:,\s]+/, $ramdisk)) {
if (system("test -x \"\$(command -v $initramfs_cmd)\"") == 0) {
push(@tools, $initramfs_cmd);
}
}
return @tools;
}
if ($initrd) {
my @ramdisklist;
@ramdisklist = find_initramfs_tool($ramdisk) if $ramdisk;
die "Failed to find suitable initramfs generation tool in $ramdisk\n"
if $#ramdisklist < 0;
my $success = 0;
for $ramdisk_cmd (@ramdisklist) {
print STDERR "Running $ramdisk_cmd.\n";
print STDERR "Other valid candidates: @ramdisklist\n" if $#ramdisklist > 0;
my $initrd_path = $realimageloc . "initrd.img-$version";
my $ret = system("$ramdisk_cmd " .
($mkimage ? "-m '$mkimage' " : "") .
"-c -t -k $version >&2");
if ($ret) {
warn "$ramdisk_cmd failed to create initrd image.\n";
} else {
$success = 1;
last;
}
}
die "Failed to create initrd image.\n" unless $success;
if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m/<unknown>/o) {
image_magic("initrd.img", $image_dest);
} else {
if (! -e "initrd.img") {
handle_missing_link("initrd.img", $image_dest, "initrd.img-$version",
$realimageloc);
}
}
}
# Only change the symlinks if we are not being upgraded
if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m/<unknown>/o) {
image_magic($kimage, $image_dest);
}
else {
if (! -e "$kimage") {
handle_missing_link($kimage, $image_dest, "$kimage-$version",
$realimageloc);
}
}
# set the env var stem
$ENV{'STEM'} = "=ST";
sub run_hook {
my $type = shift;
my $script = shift;
print STDERR "Running $script.\n";
system ("$script $version $realimageloc$kimage-$version") &&
print STDERR "User $type hook script [$script] ";
if ($?) {
if ($? == -1) {
print STDERR "failed to execute: $!\n";
}
elsif ($? & 127) {
printf STDERR "died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf STDERR "exited with value %d\n", $? >> 8;
}
exit $? >> 8;
}
}
my $options;
for (@ARGV) {
s,','\\'',g;
$options .= " '$_'";
}
$ENV{'DEB_MAINT_PARAMS'}="$options";
## Run user hook script here, if any
if ($postinst_hook) {
&run_hook("postinst", $postinst_hook);
}
if (-d "/etc/kernel/postinst.d") {
print STDERR "Examining /etc/kernel/postinst.d.\n";
system ("run-parts --verbose --exit-on-error --arg=$version " .
"--arg=$realimageloc$kimage-$version " .
"/etc/kernel/postinst.d") &&
die "Failed to process /etc/kernel/postinst.d";
}
if (-d "/etc/kernel/postinst.d/$version") {
print STDERR "Examining /etc/kernel/postinst.d/$version.\n";
system ("run-parts --verbose --exit-on-error --arg=$version " .
"--arg=$realimageloc$kimage-$version " .
"/etc/kernel/postinst.d/$version") &&
die "Failed to process /etc/kernel/postinst.d/$version";
}
LOADER: {
last unless $do_boot_enable; # Exit if explicitly asked to
last if $loader =~ /silo/i; # SILO does not have to be executed.
last if $loader =~ /yaboot/i; # yaboot does not have to be executed.
last if $loader =~ /milo/i; # MILO does not have to be executed.
last if $loader =~ /nettrom/i; # NETTROM does not have to be executed.
last if $loader =~ /arcboot/i; # ARCBOOT does not have to be executed.
last if $loader =~ /delo/i; # DELO does not have to be executed.
last if $loader =~ /quik/i; # maintainer asked quik invocation to be ignored
last unless $loaderloc;
last unless -x $loaderloc;
last unless $do_bootloader;
if (-T "/etc/$loader.conf") {
# Trust and use the existing lilo.conf.
print STDERR "You already have a $Loader configuration in /etc/$loader.conf\n";
my $ret = &run_lilo();
exit $ret if $ret;
}
}
sub run_lilo (){
my $ret;
# Try and figure out if the user really wants lilo to be run --
# since the default is to run the boot laoder, which is ! grub -- but
# the user may be using grub now, and not changed the default.
# So, if the user has explicitly asked for the loader to be run, or
# if there is no postinst hook, or if there is no grub installed --
# we are OK. Or else, we ask.
if ($explicit_do_loader || (! ($postinst_hook && -x '/sbin/grub'))) {
print STDERR "Running boot loader as requested\n";
}
else {
# Ask the user
my $seen;
my $question = "shared/kernel-image/really-run-bootloader";
print STDERR "Do we really want to run bootloader $loader?\n";
($ret,$seen) = fset ("$question", 'seen', 'false');
die "Error setting debconf flags in $question: $seen" if $ret;
$ret = subst("$question", 'loader', "$loader");
die "Error setting debconf substitutions in $question: $seen" if $ret;
($ret,$seen) = input('critical', "$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";
}
($ret,$answer) = get("$question");
die "Error retreiving answer for $question: $answer" if $ret;
if ($answer =~ /^(y|t)/i) {
print STDERR "Ok, not running $loader\n";
return 0;
}
else {
print STDERR "Ok, continuing as directed.\n";
}
}
if ($loader =~ /^lilo/io or $loader =~ /vmelilo/io) {
print STDERR "Testing $loader.conf ... \n";
unlink $temp_file_name; # security
$ret = system("$loaderloc -t >$temp_file_name 2>&1");
if ($ret) {
my $seen;
my $note = "${package_name}/postinst/bootloader-test-error-$version";
print STDERR "Failed test for bootloader $loader\n";
($ret,$seen) = fset ("$note", 'seen', 'false');
die "Error setting debconf flags in $note: $seen" if $ret;
$ret = subst("$note", 'loader', "$loader");
die "Error setting debconf substitutions in $note: $seen" if $ret;
$ret = subst("$note", 'temp_file_name', "$temp_file_name");
die "Error setting debconf substitutions in $note: $seen" if $ret;
($ret,$seen) = input('critical', "$note");
if ($ret && $ret != 30 ) {
die "Error setting debconf note $note: $seen";
}
($ret,$seen) = go ();
if ($ret && $ret != 30 ) {
die "Error showing debconf note $note: $seen";
}
return $ret;
}
unlink "$temp_file_name";
print STDERR "Testing successful.\n";
print STDERR "Installing the ";
print STDERR "partition " if $loader =~ /^lilo/io;
print STDERR "boot sector... \n";
}
print STDERR "Running $loaderloc ... \n";
if ($loader =~ /^elilo/io) {
$ret = system("$loaderloc 2>&1 | tee $temp_file_name");
} else {
$ret = system("$loaderloc >$temp_file_name 2>&1");
}
if ($ret) {
my $ret;
my $seen;
my $note = "${package_name}/postinst/bootloader-error-$version";
($ret,$seen) = fset ("$note", 'seen', 'false');
die "Error setting debconf flags in $note: $seen" if $ret;
$ret = subst("$note", 'locader', "$loader");
die "Error setting debconf substitutions in $note: $seen" if $ret;
$ret = subst("$note", 'temp_file_name', "$temp_file_name");
die "Error setting debconf substitutions in $note: $seen" if $ret;
($ret,$seen) = input('critical', "$note");
if ($ret && $ret != 30 ) {
die "Error setting debconf note $note: $seen";
}
($ret,$seen) = go ();
if ($ret && $ret != 30 ) {
die "Error asking debconf question $note: $seen";
}
return $ret;
}
unlink $temp_file_name;
print STDERR "Installation successful.\n";
return 0;
}
exit 0;
__END__