diff options
author | Antoine Ginies <aginies@mandriva.com> | 2011-02-17 13:36:24 +0000 |
---|---|---|
committer | Antoine Ginies <aginies@mandriva.com> | 2011-02-17 13:36:24 +0000 |
commit | 59d02f8b7e5f276b648b601715e843f571958e51 (patch) | |
tree | be520d8414588f9fc7ca250bebf480f601a3c50d /perl-install | |
parent | 5e17e08dbbb889005ac09745b3b15a6d7d4076f5 (diff) | |
download | drakx-backup-do-not-use-59d02f8b7e5f276b648b601715e843f571958e51.tar drakx-backup-do-not-use-59d02f8b7e5f276b648b601715e843f571958e51.tar.gz drakx-backup-do-not-use-59d02f8b7e5f276b648b601715e843f571958e51.tar.bz2 drakx-backup-do-not-use-59d02f8b7e5f276b648b601715e843f571958e51.tar.xz drakx-backup-do-not-use-59d02f8b7e5f276b648b601715e843f571958e51.zip |
commit bootloader changes
Diffstat (limited to 'perl-install')
-rw-r--r-- | perl-install/bootloader.pm | 139 |
1 files changed, 94 insertions, 45 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index 60d4c1987..4758c8d3f 100644 --- a/perl-install/bootloader.pm +++ b/perl-install/bootloader.pm @@ -1,4 +1,4 @@ -package bootloader; # $Id: bootloader.pm 266110 2010-02-10 16:59:13Z cfergeau $ +package bootloader; # $Id: bootloader.pm 267511 2010-04-12 12:34:45Z cfergeau $ use diagnostics; use strict; @@ -43,7 +43,7 @@ sub vmlinuz2kernel_str { { basename => $basename, version => $version, - $version =~ /(.*)-(\D.*)-(\d+(mdk|mdv|mnb))$/ ? #- eg: 2.6.22.5-server-1mdv + $version =~ /([\d.]*)-(\D.*)-((\d+|0\.rc\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->{ext} =~ /^xen/ ? 'xen' : $kernel->{basename}; + $kernel->{basename}; } sub basename2initrd_basename { @@ -91,7 +91,7 @@ sub kernel_str2label { _sanitize_ver($kernel); } else { my $short_name = kernel_str2short_name($kernel); - $short_name eq 'vmlinuz' ? 'linux' : $short_name; + $kernel->{ext} =~ /^xen/ ? 'xen' : ($short_name eq 'vmlinuz' ? 'linux' : $short_name); } } @@ -111,11 +111,12 @@ 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, "--ifneeded", $kernel_version, + if_($::isInstall, "-v"), "-f", $initrd, $kernel_version, if_($entry->{initrd_options}, split(' ', $entry->{initrd_options})), ); if (!run_program::rooted($::prefix, 'mkinitrd', @options)) { @@ -161,7 +162,7 @@ sub update_splash { my ($bootloader) = @_; foreach (@{$bootloader->{entries}}) { - bootloader::add_boot_splash($_->{initrd}, $_->{vga} || $bootloader->{vga}) if $_->{initrd}; + add_boot_splash($_->{initrd}, $_->{vga} || $bootloader->{vga}) if $_->{initrd}; } } @@ -174,6 +175,7 @@ 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}))) { @@ -226,6 +228,7 @@ 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 @@ -337,9 +340,16 @@ sub read_grub_menu_lst { #- sanitize foreach my $e (@{$b{entries}}) { if (member($e->{type}, 'other', 'grub_configfile')) { - $e->{kernel_or_dev} = grub2dev($e->{rootnoverify} || $e->{grub_root}, $grub2dev); + eval { $e->{kernel_or_dev} = grub2dev($e->{rootnoverify} || $e->{grub_root}, $grub2dev) }; + $e->{keep_verbatim} = 1 unless $e->{kernel_or_dev}; } elsif ($e->{initrd}) { - $e->{initrd} = grub2file($e->{initrd}, $grub2dev, $fstab, $e); + my $initrd; + eval { $initrd = grub2file($e->{initrd}, $grub2dev, $fstab, $e) }; + if ($initrd) { + $e->{initrd} = $initrd; + } else { + $e->{keep_verbatim} = 1; + } } if ($e->{kernel} =~ /xen/ && @{$e->{modules} || []} == 2 && $e->{modules}[1] =~ /initrd/) { @@ -352,8 +362,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*//; - $e->{kernel_or_dev} = grub2file($kernel, $grub2dev, $fstab, $e); - $e->{keep_verbatim} = 1 if dirname($e->{kernel_or_dev}) ne '/boot'; + 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'; } my ($vga, $other) = partition { /^vga=/ } split(' ', $e->{append}); if (@$vga) { @@ -521,14 +531,16 @@ 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}}, + @{$all_hds->{hds}}, # MBR + if_($bootloader->{method} =~ /lilo/, grep { $_->{level} eq '1' } @{$all_hds->{raids}} ), - (grep { !isFat_or_NTFS($_) } fs::get::fstab($all_hds)), + (grep { !isFat_or_NTFS($_) } fs::get::fstab($all_hds)), # filesystems except those who do not leave space for our bootloaders detect_devices::floppies(), ); } @@ -643,6 +655,7 @@ 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}; @@ -650,6 +663,7 @@ sub get_mbootpack_filename { $entry->{xen} && $mbootpack_file; } +# for lilo & xen sub build_mbootpack { my ($entry) = @_; @@ -713,19 +727,24 @@ 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; - 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 (!$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) { + } + + if (!$b_nolink) { + $v->{kernel_or_dev} = '/boot/' . kernel_str2vmlinuz_short($kernel_str); + _do_the_symlink($bootloader, $v->{kernel_or_dev}, $vmlinuz_long); + + if ($v->{initrd}) { $v->{initrd} = '/boot/' . kernel_str2initrd_short($kernel_str); _do_the_symlink($bootloader, $v->{initrd}, $initrd_long); } @@ -747,6 +766,7 @@ sub rebuild_initrds { } } +# unused (?) sub duplicate_kernel_entry { my ($bootloader, $new_label) = @_; @@ -848,6 +868,7 @@ 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; @@ -883,8 +904,6 @@ sub get_kernel_labels { @kernels_str = (@$kernel_24, @$other); } - $kernels_str[0]{ext} = ''; - my %labels; foreach (@kernels_str) { if ($labels{$_->{ext}}) { @@ -893,6 +912,9 @@ sub get_kernel_labels { $labels{$_->{ext}} = 1; } } + + $kernels_str[0]{ext} = ''; + @kernels_str; } @@ -925,7 +947,7 @@ sub _sanitize_ver { $name = join(' ', grep { $_ } $name, 'multimedia'); } - $v =~ s!md[kv]$!!; + $v =~ s!(md[kv]|mnb)$!!; $v =~ s!-0\.(pre|rc)(\d+)\.!$1$2-!; my $return = join(' ', grep { $_ } $name, short_ext($kernel_str), $v); @@ -937,6 +959,7 @@ sub _sanitize_ver { $return; } +# for lilo sub suggest_message_text { my ($bootloader) = @_; @@ -970,8 +993,16 @@ 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($all_hds->{hds}[0]); + my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($mbr); add2hash_($bootloader, arch() =~ /ppc/ ? { defaultos => "linux", @@ -992,9 +1023,10 @@ sub suggest { timeout => $onmbr && 10, nowarn => 1, if_(arch() !~ /ia64/, - boot => "/dev/" . ($onmbr ? $all_hds->{hds}[0]{device} : $boot), + boot => "/dev/" . ($onmbr ? $mbr->{device} : $boot), map => "/boot/map", compact => 1, + 'large-memory' => 1, color => 'black/cyan yellow/cyan', 'menu-scheme' => 'wb:bw:wb:bw' ), @@ -1011,11 +1043,17 @@ 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} && $kernel->{ext} eq '', vga => $options{vga_fb}), #- using framebuffer + if_($options{vga_fb}, vga => $options{vga_fb}), #- using framebuffer if_($options{vga_fb} && $options{quiet}, append => "splash=silent"), }); @@ -1024,11 +1062,9 @@ 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' }); + { root => $root, label => 'failsafe', append => 'failsafe' }) + if @kernels; if (arch() =~ /ppc/) { #- if we identified a MacOS partition earlier - add it @@ -1042,15 +1078,10 @@ sub suggest { } elsif (arch() !~ /ia64/) { #- search for dos (or windows) boot partition. Do not look in extended partitions! my @windows_boot_parts = - 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/; + grep { $_->{active} + && isFat_or_NTFS($_) && member(fs::type::fs_type_from_magic($_), 'vfat', 'ntfs', 'ntfs-3g') + && !$_->{is_removable} + && !isRecovery($_); } map { @{$_->{primary}{normal}} } @{$all_hds->{hds}}; each_index { @@ -1155,6 +1186,7 @@ sub configured_main_methods() { difference2([ main_method_choices(1) ], \@bad_main_methods); } +# for lilo sub keytable { my ($f) = @_; $f or return; @@ -1357,9 +1389,17 @@ sub write_lilo { my @conf; - #- normalize: RESTRICTED is only valid if PASSWORD is set - delete $bootloader->{restricted} if !$bootloader->{password}; + #- 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}; + } 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(.*)/) { @@ -1374,7 +1414,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 nowarn restricted static-bios-codes); + push @conf, grep { $bootloader->{$_} } qw(linear geometric compact prompt mandatory nowarn restricted static-bios-codes large-memory); 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}; @@ -1408,6 +1448,7 @@ 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); @@ -1428,7 +1469,7 @@ sub write_lilo { } } push @entry_conf, "password=$entry->{password}" if $entry->{password}; - push @entry_conf, grep { $entry->{$_} } qw(restricted vmwarn vmdisable); + push @entry_conf, grep { $entry->{$_} } qw(mandatory vmwarn vmdisable); push @conf, map { "\t$_" } @entry_conf; } @@ -1561,6 +1602,8 @@ 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; @@ -1568,6 +1611,8 @@ 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; @@ -1576,12 +1621,16 @@ 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)); } -# replace dummy "(hdX,Y)" in "(hdX,Y)/boot/vmlinuz..." by appropriate path if needed +# 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 sub grub2file { my ($grub_file, $grub2dev, $fstab, $o_entry) = @_; @@ -1731,7 +1780,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'), @@ -1836,7 +1885,7 @@ sub install_grub { if (!$::testing) { if ($bootloader->{previous_boot} && $bootloader->{previous_boot} eq $bootloader->{boot}) { - # nothing to do + # nothing to do (already installed in {boot}) } else { if ($bootloader->{previous_boot}) { restore_previous_MBR_bootloader(delete $bootloader->{previous_boot}); @@ -1890,7 +1939,7 @@ sub install { sub ensure_pkg_is_installed { my ($do_pkgs, $bootloader) = @_; - my $main_method = bootloader::main_method($bootloader->{method}); + my $main_method = 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') { |