#! /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 () { chomp; s/\#.*$//g; next if /^\s*$/; $do_symlink = "" if /do_symlinks\s*=\s*(no|false|0)\s*$/ig; $no_symlink = "" if /no_symlinks\s*=\s*(no|false|0)\s*$/ig; $link_in_boot = "" if /link_in_boot\s*=\s*(no|false|0)\s*$/ig; $do_boot_enable = '' if /do_boot_enable\s*=\s*(no|false|0)\s*$/ig; $do_bootloader = '' if /do_bootloader\s*=\s*(no|false|0)\s*$/ig; $use_hard_links = '' if /use_hard_links\s*=\s*(no|false|0)\s*$/ig; $minimal_swap = '' if /minimal_swap\s*=\s*(no|false|0)\s*$/ig; $ignore_depmod_err = '' if /ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; $relink_src_link = '' if /relink_src_link\s*=\s*(no|false|0)\s*$/ig; $relink_build_link = '' if /relink_build_link\s*=\s*(no|false|0)\s*$/ig; $force_build_link = '' if /force_build_link\s*=\s*(no|false|0)\s*$/ig; $do_symlink = "Yes" if /do_symlinks\s*=\s*(yes|true|1)\s*$/ig; $no_symlink = "Yes" if /no_symlinks\s*=\s*(yes|true|1)\s*$/ig; $link_in_boot = "Yes" if /link_in_boot\s*=\s*(yes|true|1)\s*$/ig; $do_boot_enable = "Yes" if /do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; $do_bootloader = "Yes" if /do_bootloader\s*=\s*(yes|true|1)\s*$/ig; $explicit_do_loader = "YES" if /do_bootloader\s*=\s*(yes|true|1)\s*$/ig; $use_hard_links = "Yes" if /use_hard_links\s*=\s*(yes|true|1)\s*$/ig; $minimal_swap = 'Yes' if /minimal_swap\s*=\s*(yes|true|1)\s*$/ig; $ignore_depmod_err = 'Yes' if /ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; $relink_src_link = 'Yes' if /relink_src_link\s*=\s*(yes|true|1)\s*$/ig; $relink_build_link = 'Yes' if /relink_build_link\s*=\s*(yes|true|1)\s*$/ig; $force_build_link = 'Yes' if /force_build_link\s*=\s*(yes|true|1)\s*$/ig; $image_dest = "$1" if /image_dest\s*=\s*(\S+)/ig; $postinst_hook = "$1" if /postinst_hook\s*=\s*(\S+)/ig; $mkimage = "$1" if /mkimage\s*=\s*(.+)$/ig; $ramdisk = "$1" if /ramdisk\s*=\s*(.+)$/ig; } 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 (open(CONF, ">$CONF_LOC")) { print CONF "# Kernel Image management overrides\n"; if ($loader =~ /palo/i) { 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 () { 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; if ($module_path !~ m|^/|) { $module_path = "$modules_base/$version/$module_path"; } open(MODINFO, "modinfo -F firmware '$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"; } } } } } # 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//og) { 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//og) { 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__