diff options
-rw-r--r-- | perl-install/bootloader.pm | 139 |
1 files changed, 45 insertions, 94 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index 4758c8d3f..60d4c1987 100644 --- a/perl-install/bootloader.pm +++ b/perl-install/bootloader.pm @@ -1,4 +1,4 @@ -package bootloader; # $Id: bootloader.pm 267511 2010-04-12 12:34:45Z cfergeau $ +package bootloader; # $Id: bootloader.pm 266110 2010-02-10 16:59:13Z cfergeau $ use diagnostics; use strict; @@ -43,7 +43,7 @@ sub vmlinuz2kernel_str { { basename => $basename, version => $version, - $version =~ /([\d.]*)-(\D.*)-((\d+|0\.rc\d+.*)(mdk|mdv|mnb))$/ ? #- eg: 2.6.22.5-server-1mdv + $version =~ /(.*)-(\D.*)-(\d+(mdk|mdv|mnb))$/ ? #- eg: 2.6.22.5-server-1mdv (ext => $2, version_no_ext => "$1-$3") : $version =~ /(.*md[kv])-?(.*)/ ? #- (old) eg: 2.6.17-13mdventerprise (ext => $2, version_no_ext => $1) : (version_no_ext => $version), @@ -52,7 +52,7 @@ sub vmlinuz2kernel_str { sub kernel_str2short_name { my ($kernel) = @_; - $kernel->{basename}; + $kernel->{ext} =~ /^xen/ ? 'xen' : $kernel->{basename}; } sub basename2initrd_basename { @@ -91,7 +91,7 @@ sub kernel_str2label { _sanitize_ver($kernel); } else { my $short_name = kernel_str2short_name($kernel); - $kernel->{ext} =~ /^xen/ ? 'xen' : ($short_name eq 'vmlinuz' ? 'linux' : $short_name); + $short_name eq 'vmlinuz' ? 'linux' : $short_name; } } @@ -111,12 +111,11 @@ sub mkinitrd { $::testing || -e "$::prefix/$initrd" and return $initrd; - # for /boot on dos partitions when installing on loopback file on dos partition my $loop_boot = fs::loopback::prepare_boot(); modules::load('loop'); my @options = ( - if_($::isInstall, "-v"), "-f", $initrd, $kernel_version, + if_($::isInstall, "-v"), "-f", $initrd, "--ifneeded", $kernel_version, if_($entry->{initrd_options}, split(' ', $entry->{initrd_options})), ); if (!run_program::rooted($::prefix, 'mkinitrd', @options)) { @@ -162,7 +161,7 @@ sub update_splash { my ($bootloader) = @_; foreach (@{$bootloader->{entries}}) { - add_boot_splash($_->{initrd}, $_->{vga} || $bootloader->{vga}) if $_->{initrd}; + bootloader::add_boot_splash($_->{initrd}, $_->{vga} || $bootloader->{vga}) if $_->{initrd}; } } @@ -175,7 +174,6 @@ sub read { cleanup_entries($bootloader); - # handle raid-extra-boot (lilo) my @devs = $bootloader->{boot}; if ($bootloader->{'raid-extra-boot'} =~ /mbr/ && (my $md = fs::get::device2part($bootloader->{boot}, $all_hds->{raids}))) { @@ -228,7 +226,6 @@ sub read_grub { $bootloader; } -# adapts device.map (aka $grub2dev) when for example hda is now sda # nb: # - $boot_part comes from /boot/grub/install.sh "root (hd...)" line # - $grub2dev is /boot/grub/device.map @@ -340,16 +337,9 @@ sub read_grub_menu_lst { #- sanitize foreach my $e (@{$b{entries}}) { if (member($e->{type}, 'other', 'grub_configfile')) { - eval { $e->{kernel_or_dev} = grub2dev($e->{rootnoverify} || $e->{grub_root}, $grub2dev) }; - $e->{keep_verbatim} = 1 unless $e->{kernel_or_dev}; + $e->{kernel_or_dev} = grub2dev($e->{rootnoverify} || $e->{grub_root}, $grub2dev); } elsif ($e->{initrd}) { - my $initrd; - eval { $initrd = grub2file($e->{initrd}, $grub2dev, $fstab, $e) }; - if ($initrd) { - $e->{initrd} = $initrd; - } else { - $e->{keep_verbatim} = 1; - } + $e->{initrd} = grub2file($e->{initrd}, $grub2dev, $fstab, $e); } if ($e->{kernel} =~ /xen/ && @{$e->{modules} || []} == 2 && $e->{modules}[1] =~ /initrd/) { @@ -362,8 +352,8 @@ sub read_grub_menu_lst { (my $kernel, $e->{append}) = split(' ', $v, 2); $e->{append} = join(' ', grep { !/^BOOT_IMAGE=/ } split(' ', $e->{append})); $e->{root} = $1 if $e->{append} =~ s/root=(\S*)\s*//; - eval { $e->{kernel_or_dev} = grub2file($kernel, $grub2dev, $fstab, $e) }; - $e->{keep_verbatim} = 1 unless $e->{kernel_or_dev} && dirname($e->{kernel_or_dev}) eq '/boot'; + $e->{kernel_or_dev} = grub2file($kernel, $grub2dev, $fstab, $e); + $e->{keep_verbatim} = 1 if dirname($e->{kernel_or_dev}) ne '/boot'; } my ($vga, $other) = partition { /^vga=/ } split(' ', $e->{append}); if (@$vga) { @@ -531,16 +521,14 @@ sub suggest_onmbr { ($onmbr, $unsafe); } -# list of places where we can install the bootloader sub allowed_boot_parts { my ($bootloader, $all_hds) = @_; ( - @{$all_hds->{hds}}, # MBR - + @{$all_hds->{hds}}, if_($bootloader->{method} =~ /lilo/, grep { $_->{level} eq '1' } @{$all_hds->{raids}} ), - (grep { !isFat_or_NTFS($_) } fs::get::fstab($all_hds)), # filesystems except those who do not leave space for our bootloaders + (grep { !isFat_or_NTFS($_) } fs::get::fstab($all_hds)), detect_devices::floppies(), ); } @@ -655,7 +643,6 @@ sub cmp_kernel_versions { $r || $rel_a <=> $rel_b || $rel_a cmp $rel_b; } -# for lilo & xen sub get_mbootpack_filename { my ($entry) = @_; my $mbootpack_file = $entry->{initrd}; @@ -663,7 +650,6 @@ sub get_mbootpack_filename { $entry->{xen} && $mbootpack_file; } -# for lilo & xen sub build_mbootpack { my ($entry) = @_; @@ -727,24 +713,19 @@ sub add_kernel { $b_nolink ||= $kernel_str->{use_long_name}; - #- do not link /boot/vmlinuz to xen - $b_nolink ||= $v->{xen}; - my $vmlinuz_long = kernel_str2vmlinuz_long($kernel_str); - my $initrd_long = kernel_str2initrd_long($kernel_str); $v->{kernel_or_dev} = "/boot/$vmlinuz_long"; -e "$::prefix$v->{kernel_or_dev}" or log::l("unable to find kernel image $::prefix$v->{kernel_or_dev}"), return; - log::l("adding $v->{kernel_or_dev}"); - - if (!$b_no_initrd) { - $v->{initrd} = mkinitrd($kernel_str->{version}, $bootloader, $v, "/boot/$initrd_long"); - } - if (!$b_nolink) { $v->{kernel_or_dev} = '/boot/' . kernel_str2vmlinuz_short($kernel_str); _do_the_symlink($bootloader, $v->{kernel_or_dev}, $vmlinuz_long); + } + log::l("adding $v->{kernel_or_dev}"); - if ($v->{initrd}) { + if (!$b_no_initrd) { + my $initrd_long = kernel_str2initrd_long($kernel_str); + $v->{initrd} = mkinitrd($kernel_str->{version}, $bootloader, $v, "/boot/$initrd_long"); + if ($v->{initrd} && !$b_nolink) { $v->{initrd} = '/boot/' . kernel_str2initrd_short($kernel_str); _do_the_symlink($bootloader, $v->{initrd}, $initrd_long); } @@ -766,7 +747,6 @@ sub rebuild_initrds { } } -# unused (?) sub duplicate_kernel_entry { my ($bootloader, $new_label) = @_; @@ -868,7 +848,6 @@ sub set_append_netprofile { $e->{append} = pack_append($simple, $dict); } -# used when a bootloader $entry has been modified (eg: $entry->{vga}) sub configure_entry { my ($bootloader, $entry) = @_; $entry->{type} eq 'image' or return; @@ -904,6 +883,8 @@ sub get_kernel_labels { @kernels_str = (@$kernel_24, @$other); } + $kernels_str[0]{ext} = ''; + my %labels; foreach (@kernels_str) { if ($labels{$_->{ext}}) { @@ -912,9 +893,6 @@ sub get_kernel_labels { $labels{$_->{ext}} = 1; } } - - $kernels_str[0]{ext} = ''; - @kernels_str; } @@ -947,7 +925,7 @@ sub _sanitize_ver { $name = join(' ', grep { $_ } $name, 'multimedia'); } - $v =~ s!(md[kv]|mnb)$!!; + $v =~ s!md[kv]$!!; $v =~ s!-0\.(pre|rc)(\d+)\.!$1$2-!; my $return = join(' ', grep { $_ } $name, short_ext($kernel_str), $v); @@ -959,7 +937,6 @@ sub _sanitize_ver { $return; } -# for lilo sub suggest_message_text { my ($bootloader) = @_; @@ -993,16 +970,8 @@ sub suggest { my $boot = fs::get::root($fstab, 'boot')->{device}; #- PPC xfs module requires enlarged initrd my $xfsroot = $root_part->{fs_type} eq 'xfs'; - my $mbr; - - # If installing onto an USB drive, put the mbr there, else on the first non removable drive - if ($root_part->{is_removable}) { - $mbr = fs::get::part2hd($root_part, $all_hds); - } else { - $mbr = find { !$_->{is_removable} } @{$all_hds->{hds}}; - } - my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($mbr); + my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($all_hds->{hds}[0]); add2hash_($bootloader, arch() =~ /ppc/ ? { defaultos => "linux", @@ -1023,10 +992,9 @@ sub suggest { timeout => $onmbr && 10, nowarn => 1, if_(arch() !~ /ia64/, - boot => "/dev/" . ($onmbr ? $mbr->{device} : $boot), + boot => "/dev/" . ($onmbr ? $all_hds->{hds}[0]{device} : $boot), map => "/boot/map", compact => 1, - 'large-memory' => 1, color => 'black/cyan yellow/cyan', 'menu-scheme' => 'wb:bw:wb:bw' ), @@ -1043,17 +1011,11 @@ sub suggest { my @kernels = get_kernels_and_labels() or die "no kernel installed"; - my %old_kernels = map { vmlinuz2version($_->{kernel_or_dev}) => 1 } @{$bootloader->{entries}}; - @kernels = grep { !$old_kernels{$_->{version}} } @kernels; - - #- remove existing failsafe and linux-nonfb, do not care if the previous one was modified by the user? - @{$bootloader->{entries}} = grep { !member($_->{label}, qw(failsafe linux-nonfb)) } @{$bootloader->{entries}}; - foreach my $kernel (@kernels) { my $e = add_kernel($bootloader, $kernel, { root => $root, - if_($options{vga_fb}, vga => $options{vga_fb}), #- using framebuffer + if_($options{vga_fb} && $kernel->{ext} eq '', vga => $options{vga_fb}), #- using framebuffer if_($options{vga_fb} && $options{quiet}, append => "splash=silent"), }); @@ -1062,9 +1024,11 @@ sub suggest { } } + #- remove existing failsafe, do not care if the previous one was modified by the user? + @{$bootloader->{entries}} = grep { $_->{label} ne 'failsafe' } @{$bootloader->{entries}}; + add_kernel($bootloader, $kernels[0], - { root => $root, label => 'failsafe', append => 'failsafe' }) - if @kernels; + { root => $root, label => 'failsafe', append => 'failsafe' }); if (arch() =~ /ppc/) { #- if we identified a MacOS partition earlier - add it @@ -1078,10 +1042,15 @@ sub suggest { } elsif (arch() !~ /ia64/) { #- search for dos (or windows) boot partition. Do not look in extended partitions! my @windows_boot_parts = - grep { $_->{active} - && isFat_or_NTFS($_) && member(fs::type::fs_type_from_magic($_), 'vfat', 'ntfs', 'ntfs-3g') - && !$_->{is_removable} - && !isRecovery($_); + grep { + my $handle = any::inspect($_, $::prefix); + my $dir = $handle && $handle->{dir}; + my @root_files = map { lc($_) } all($dir); + log::l("found the following files on potential windows partition $_->{device}: " . join(' ', @root_files)); + intersection(\@root_files, [ "windows", "winnt" ]); + } + grep { isFat_or_NTFS($_) && member(fs::type::fs_type_from_magic($_), 'vfat', 'ntfs', 'ntfs-3g') + && fs::type::part2type_name($_) !~ /^Hidden/; } map { @{$_->{primary}{normal}} } @{$all_hds->{hds}}; each_index { @@ -1186,7 +1155,6 @@ sub configured_main_methods() { difference2([ main_method_choices(1) ], \@bad_main_methods); } -# for lilo sub keytable { my ($f) = @_; $f or return; @@ -1389,17 +1357,9 @@ sub write_lilo { my @conf; - #- normalize: RESTRICTED and MANDATORY are only valid if PASSWORD is set - if ($bootloader->{password}) { - # lilo defaults to mandatory, use restricted by default to have - # the same behaviour as with grub - $bootloader->{restricted} = 1; - } else { - delete $bootloader->{mandatory} if !$bootloader->{password}; - delete $bootloader->{restricted} if !$bootloader->{password}; - } + #- normalize: RESTRICTED is only valid if PASSWORD is set + delete $bootloader->{restricted} if !$bootloader->{password}; foreach my $entry (@{$bootloader->{entries}}) { - delete $entry->{mandatory} if !$entry->{password} && !$bootloader->{password}; delete $entry->{restricted} if !$entry->{password} && !$bootloader->{password}; } if (get_append_with_key($bootloader, 'console') =~ /ttyS(.*)/) { @@ -1414,7 +1374,7 @@ sub write_lilo { push @conf, "# WARNING: do not forget to run lilo after modifying this file\n"; push @conf, "default=" . make_label_lilo_compatible($bootloader->{default}) if $bootloader->{default}; push @conf, map { $_ . '=' . $quotes_if_needed->($bootloader->{$_}) } grep { $bootloader->{$_} } qw(boot root map install serial vga keytable raid-extra-boot menu-scheme vmdefault); - push @conf, grep { $bootloader->{$_} } qw(linear geometric compact prompt mandatory nowarn restricted static-bios-codes large-memory); + push @conf, grep { $bootloader->{$_} } qw(linear geometric compact prompt nowarn restricted static-bios-codes); push @conf, "append=" . $quotes->($bootloader->{append}) if $bootloader->{append}; push @conf, "password=" . $bootloader->{password} if $bootloader->{password}; #- also done by msec push @conf, "timeout=" . round(10 * $bootloader->{timeout}) if $bootloader->{timeout}; @@ -1448,7 +1408,6 @@ sub write_lilo { push @entry_conf, "append=" . $quotes->($append) if $append; push @entry_conf, "vga=$entry->{vga}" if $entry->{vga}; push @entry_conf, grep { $entry->{$_} } qw(read-write read-only optional); - push @entry_conf, "mandatory" if $entry->{lock}; } else { delete $entry->{unsafe} if $entry->{table}; #- we can't have both push @entry_conf, map { "$_=$entry->{$_}" } grep { $entry->{$_} } qw(table boot-as); @@ -1469,7 +1428,7 @@ sub write_lilo { } } push @entry_conf, "password=$entry->{password}" if $entry->{password}; - push @entry_conf, grep { $entry->{$_} } qw(mandatory vmwarn vmdisable); + push @entry_conf, grep { $entry->{$_} } qw(restricted vmwarn vmdisable); push @conf, map { "\t$_" } @entry_conf; } @@ -1602,8 +1561,6 @@ sub write_grub_device_map { (map_index { "(hd$::i) /dev/$_->{device}\n" } @$sorted_hds)); } -# parses things like "(hd0,4)/boot/vmlinuz" -# returns: ("hd0", 4, "boot/vmlinuz") sub parse_grub_file { my ($grub_file) = @_; my ($grub_dev, $rel_file) = $grub_file =~ m!\((.*?)\)/?(.*)! or return; @@ -1611,8 +1568,6 @@ sub parse_grub_file { ($hd, $part, $rel_file); } -# takes things like "(hd0,4)/boot/vmlinuz" -# returns: ("/dev/sda5", "boot/vmlinuz") sub grub2dev_and_file { my ($grub_file, $grub2dev, $o_block_device) = @_; my ($hd, $part, $rel_file) = parse_grub_file($grub_file) or return; @@ -1621,16 +1576,12 @@ sub grub2dev_and_file { my $device = '/dev/' . ($part eq '' ? $grub2dev->{$hd} : devices::prefix_for_dev($grub2dev->{$hd}) . $part); $device, $rel_file; } -# takes things like "(hd0,4)/boot/vmlinuz" -# returns: "/dev/sda5" sub grub2dev { my ($grub_file, $grub2dev, $o_block_device) = @_; first(grub2dev_and_file($grub_file, $grub2dev, $o_block_device)); } -# replaces -# - "/vmlinuz" with "/boot/vmlinuz" when "root" or "rootnoverify" is set for the entry -# - "(hdX,Y)" in "(hdX,Y)/boot/vmlinuz..." by appropriate path if possible/needed +# replace dummy "(hdX,Y)" in "(hdX,Y)/boot/vmlinuz..." by appropriate path if needed sub grub2file { my ($grub_file, $grub2dev, $fstab, $o_entry) = @_; @@ -1780,7 +1731,7 @@ sub write_grub { my $vga = $entry->{vga} || $bootloader->{vga}; push @conf, join(' ', $entry->{xen} ? 'module' : 'kernel', $file2grub->($entry->{kernel_or_dev}), - $entry->{xen} ? () : 'BOOT_IMAGE=' . simplify_label($entry->{label}), + $entry->{xen} ? '' : 'BOOT_IMAGE=' . simplify_label($entry->{label}), if_($entry->{root}, $entry->{root} =~ /loop7/ ? "root=707" : "root=$entry->{root}"), #- special to workaround bug in kernel (see #ifdef CONFIG_BLK_DEV_LOOP) $entry->{append}, if_($entry->{'read-write'}, 'rw'), @@ -1885,7 +1836,7 @@ sub install_grub { if (!$::testing) { if ($bootloader->{previous_boot} && $bootloader->{previous_boot} eq $bootloader->{boot}) { - # nothing to do (already installed in {boot}) + # nothing to do } else { if ($bootloader->{previous_boot}) { restore_previous_MBR_bootloader(delete $bootloader->{previous_boot}); @@ -1939,7 +1890,7 @@ sub install { sub ensure_pkg_is_installed { my ($do_pkgs, $bootloader) = @_; - my $main_method = main_method($bootloader->{method}); + my $main_method = bootloader::main_method($bootloader->{method}); if ($main_method eq 'grub' || $main_method eq 'lilo') { $do_pkgs->ensure_binary_is_installed($main_method, $main_method, 1) or return 0; if ($bootloader->{method} eq 'grub-graphic') { |