summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Ginies <aginies@mandriva.com>2011-02-17 13:36:24 +0000
committerAntoine Ginies <aginies@mandriva.com>2011-02-17 13:36:24 +0000
commit59d02f8b7e5f276b648b601715e843f571958e51 (patch)
treebe520d8414588f9fc7ca250bebf480f601a3c50d
parent5e17e08dbbb889005ac09745b3b15a6d7d4076f5 (diff)
downloaddrakx-59d02f8b7e5f276b648b601715e843f571958e51.tar
drakx-59d02f8b7e5f276b648b601715e843f571958e51.tar.gz
drakx-59d02f8b7e5f276b648b601715e843f571958e51.tar.bz2
drakx-59d02f8b7e5f276b648b601715e843f571958e51.tar.xz
drakx-59d02f8b7e5f276b648b601715e843f571958e51.zip
commit bootloader changes
-rw-r--r--perl-install/bootloader.pm139
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') {