diff options
Diffstat (limited to 'perl-install/bootloader.pm')
| -rw-r--r-- | perl-install/bootloader.pm | 314 |
1 files changed, 190 insertions, 124 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index 62ae0e16e..066335e0b 100644 --- a/perl-install/bootloader.pm +++ b/perl-install/bootloader.pm @@ -8,10 +8,11 @@ use vars qw(%vga_modes); #- misc imports #-###################################################################################### use common; -use partition_table qw(:types); +use partition_table; +use fs::type; +use fs::get; use log; use any; -use fsedit; use devices; use loopback; use detect_devices; @@ -23,8 +24,8 @@ use modules; #-##################################################################################### #- Functions #-##################################################################################### -my $vmlinuz_regexp = 'vmlinuz'; -my $decompose_vmlinuz_name = qr/((?:$vmlinuz_regexp).*)-(\d+\.\d+.*)/; +my $vmlinuz_regexp = 'vmlinuz|win4lin'; +my $decompose_vmlinuz_name = qr/((?:$vmlinuz_regexp).*?)-(\d+\.\d+.*)/; sub expand_vmlinuz_symlink { my ($vmlinuz) = @_; @@ -85,9 +86,10 @@ sub vmlinuz2kernel_str { } sub kernel_str2label { my ($kernel, $o_use_long_name) = @_; + my $base = $kernel->{basename} eq 'vmlinuz' ? 'linux' : $kernel->{basename}; $o_use_long_name || $kernel->{use_long_name} ? - sanitize_ver("linux-$kernel->{version}") : - $kernel->{ext} ? "linux$kernel->{ext}" : 'linux'; + sanitize_ver("$base-$kernel->{version}") : + $kernel->{ext} ? "$base-$kernel->{ext}" : $base; } sub get { @@ -116,7 +118,7 @@ sub mkinitrd { ); if (!run_program::rooted($::prefix, 'mkinitrd', @options)) { unlink("$::prefix/$initrd"); - die "mkinitrd failed"; + die "mkinitrd failed:\n(mkinitrd @options))"; } add_boot_splash($entry->{initrd}, $entry->{vga}); @@ -148,7 +150,8 @@ sub read { foreach my $main_method (uniq(map { main_method($_) } @methods)) { my $f = $bootloader::{"read_$main_method"} or die "unknown bootloader method $main_method (read)"; my $bootloader = $f->($fstab); - my $type = partition_table::raw::typeOfMBR($bootloader->{boot}); + my $type = $bootloader->{boot} =~ m!/fd\d+$! ? $main_method : partition_table::raw::typeOfMBR($bootloader->{boot}); + warn "typeOfMBR $type on $bootloader->{boot} for method $main_method\n" if $ENV{DEBUG}; if ($type eq $main_method) { my @prefered_entries = map { get_label($_, $bootloader) } $bootloader->{default}, 'linux'; @@ -308,6 +311,18 @@ sub suggest_onmbr { ($onmbr, $unsafe); } +sub allowed_boot_parts { + my ($bootloader, $all_hds) = @_; + ( + @{$all_hds->{hds}}, + if_($bootloader->{method} =~ /lilo/, + grep { $_->{level} eq '1' } @{$all_hds->{raids}} + ), + (grep { !isFat_or_NTFS($_) } fs::get::hds_fstab(@{$all_hds->{hds}})), + detect_devices::floppies(), + ); +} + sub same_entries { my ($a, $b) = @_; @@ -315,7 +330,7 @@ sub same_entries { if ($_ eq 'label') { next; } elsif ($_ eq 'append') { - next if join(' ', sort split(' ', $a->{$_})) eq join(' ', sort split(' ', $b->{$_})) + next; } else { next if $a->{$_} eq $b->{$_}; @@ -353,16 +368,33 @@ sub add_entry { } $to_add = $conflicting; - my $new_label = $v->{label} eq 'linux' && kernel_str2label(vmlinuz2kernel_str($to_add->{kernel_or_dev}), 'use_long_name'); - $label = $new_label && $label ne $new_label ? $new_label : 'alt' . ($i++ ? $i : '') . "_$label"; + if ($to_add->{label} eq 'linux') { + expand_entry_symlinks($bootloader, $to_add); + $label = kernel_str2label(vmlinuz2kernel_str($to_add->{kernel_or_dev}), 'use_long_name'); + } else { + $label =~ s/^alt\d*_//; + $label = 'alt' . ($i++ ? $i : '') . "_$label"; + } } die 'add_entry'; } +sub expand_entry_symlinks { + my ($bootloader, $entry) = @_; + + foreach my $kind ('kernel_or_dev', 'initrd') { + my $old_long_name = $bootloader->{old_long_names} && $bootloader->{old_long_names}{$entry->{$kind}} or next; + + #- replace all the {$kind} using this symlink to the real file + log::l("replacing $entry->{$kind} with $old_long_name for bootloader label $entry->{label}"); + $entry->{$kind} = $old_long_name; + } +} + sub _do_the_symlink { - my ($bootloader, $entry, $kind, $long_name) = @_; + my ($bootloader, $link, $long_name) = @_; - my $existing_link = readlink("$::prefix$entry->{$kind}"); + my $existing_link = readlink("$::prefix$link"); if ($existing_link && $existing_link eq $long_name) { #- nothing to do :) return; @@ -372,21 +404,14 @@ sub _do_the_symlink { #- replace all the {$kind} using this symlink to the real file my $old_long_name = $existing_link =~ m!^/! ? $existing_link : "/boot/$existing_link"; if (-e "$::prefix$old_long_name") { - foreach (@{$bootloader->{entries}}) { - if ($_->{$kind} eq $entry->{$kind} - #- we don't modify existing failsafe or linux-nonfb unless we overwrite them - && ($_->{label} eq $entry->{label} || !member($_->{label}, 'failsafe', 'linux-nonfb'))) { - log::l("replacing $_->{$kind} with $old_long_name for bootloader label $_->{labe}"); - $_->{$kind} = $old_long_name; - } - } + $bootloader->{old_long_names}{$link} = $old_long_name; } else { - log::l("ERROR: $entry->{$kind} points to $old_long_name which doesn't exist"); + log::l("ERROR: $link points to $old_long_name which doesn't exist"); } #- changing the symlink - symlinkf($long_name, "$::prefix$entry->{$kind}") - or cp_af("$::prefix/boot/$long_name", "$::prefix$entry->{$kind}"); + symlinkf($long_name, "$::prefix$link") + or cp_af("$::prefix/boot/$long_name", "$::prefix$link"); } sub add_kernel { @@ -397,7 +422,16 @@ sub add_kernel { type => 'image', label => kernel_str2label($kernel_str), }); - $v->{append} = normalize_append("$bootloader->{perImageAppend} $v->{append}"); + + #- normalize append and handle special options + { + my ($simple, $dict) = unpack_append("$bootloader->{perImageAppend} $v->{append}"); + if (-e "$::prefix/sbin/udev" && $kernel_str->{version} =~ /^2\.(\d+\.\d+)/ && $1 >= 6.8) { + log::l("it is a recent kernel, so we remove any existing devfs= kernel option to enable udev"); + @$dict = grep { $_->[0] ne 'devfs' } @$dict; + } + $v->{append} = pack_append($simple, $dict); + } #- new versions of yaboot don't handle symlinks $b_nolink ||= arch() =~ /ppc/; @@ -409,7 +443,7 @@ sub add_kernel { -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); + _do_the_symlink($bootloader, $v->{kernel_or_dev}, $vmlinuz_long); } log::l("adding $v->{kernel_or_dev}"); @@ -419,7 +453,7 @@ sub add_kernel { mkinitrd($kernel_str->{version}, $v) or undef $v->{initrd}; if ($v->{initrd} && !$b_nolink) { $v->{initrd} = '/boot/' . kernel_str2initrd_short($kernel_str); - _do_the_symlink($bootloader, $v, 'initrd', $initrd_long); + _do_the_symlink($bootloader, $v->{initrd}, $initrd_long); } } @@ -498,11 +532,21 @@ sub set_append { modify_append($b, sub { my ($simple, $dict) = @_; if ($has_val) { - @$dict = grep { $_->[0] ne $key || $key eq 'mem' && append__mem_is_memsize($_->[1]) != append__mem_is_memsize($val) } @$dict; - push @$dict, [ $key, $val ] if !($val eq '' || $key eq 'mem' && !$val); + my $to_add = $key eq 'mem' ? $val : $val ne ''; + @$dict = map { + if ($_->[0] ne $key || $key eq 'mem' && append__mem_is_memsize($_->[1]) != append__mem_is_memsize($val)) { + $_; + } elsif ($to_add) { + $to_add = 0; + [ $key, $val ]; + } else { + (); + } + } @$dict; + + push @$dict, [ $key, $val ] if $to_add; } else { - @$simple = grep { $_ ne $key } @$simple; - push @$simple, $key; + @$simple = uniq(@$simple, $key); } }); } @@ -511,6 +555,19 @@ sub may_append { set_append($b, $key, $val) if !get_append($b, $key); } +sub get_append_netprofile { + my ($e) = @_; + my ($simple, $dict) = unpack_append($e->{append}); + my ($p, $dict_) = partition { $_->[0] eq 'PROFILE' } @$dict; + pack_append($simple, $dict_), $p->[0][1]; +} +sub set_append_netprofile { + my ($e, $append, $profile) = @_; + my ($simple, $dict) = unpack_append($append); + push @$dict, [ 'PROFILE', $profile ] if $profile; + $e->{append} = pack_append($simple, $dict); +} + sub configure_entry { my ($entry) = @_; $entry->{type} eq 'image' or return; @@ -521,16 +578,24 @@ sub configure_entry { } } +sub get_kernels_and_labels_before_kernel_remove { + my ($to_remove_kernel) = @_; + my @kernels = grep { $_ ne $to_remove_kernel } installed_vmlinuz(); + map { kernel_str2label($_) => $_ } get_kernel_labels(\@kernels); +} + sub get_kernels_and_labels { my ($b_prefer_24) = @_; + get_kernel_labels([ installed_vmlinuz() ], $b_prefer_24); +} - my @kernels = installed_vmlinuz(); +sub get_kernel_labels { + my ($kernels, $b_prefer_24) = @_; - require pkgs; my @kernels_str = sort { c::rpmvercmp($b->{version_no_ext}, $a->{version_no_ext}) } grep { -d "$::prefix/lib/modules/$_->{version}" } - map { vmlinuz2kernel_str($_) } @kernels; + map { vmlinuz2kernel_str($_) } @$kernels; if ($b_prefer_24) { my ($kernel_24, $other) = partition { $_->{ext} eq '' && $_->{version} =~ /^\Q2.4/ } @kernels_str; @@ -557,14 +622,15 @@ sub get_kernels_and_labels { sub sanitize_ver { my ($string) = @_; - my ($main_version, undef, $extraversion, $rest) = - $string =~ m!(\d+\.\d+\.\d+)(-((?:pre|rc)\d+))?(.*)!; + my ($name, $main_version, undef, $extraversion, $rest) = + $string =~ m!^(.*?-)(\d+(?:\.\d+)*)(-((?:pre|rc)\d+))?(.*)$!; if (my ($mdkver, $cpu, $nproc, $mem) = $rest =~ m|-(.+)-(.+)-(.+)-(.+)|) { $rest = "$cpu$nproc$mem-$mdkver"; } + $name = '' if $name eq 'linux-'; - my $return = "$main_version$extraversion$rest"; + my $return = "$name$main_version$extraversion$rest"; $return =~ s|\.||g; $return =~ s|mdk||; @@ -577,15 +643,15 @@ sub sanitize_ver { } sub suggest { - my ($bootloader, $hds, %options) = @_; - my $fstab = [ fsedit::get_fstab(@$hds) ]; - my $root_part = fsedit::get_root($fstab); + my ($bootloader, $all_hds, %options) = @_; + my $fstab = [ fs::get::fstab($all_hds) ]; + my $root_part = fs::get::root($fstab); my $root = '/dev/' . (isLoopback($root_part) ? 'loop7' : $root_part->{device}); - my $boot = fsedit::get_root($fstab, 'boot')->{device}; + my $boot = fs::get::root($fstab, 'boot')->{device}; #- PPC xfs module requires enlarged initrd - my $xfsroot = isThisFs("xfs", $root_part); + my $xfsroot = $root_part->{fs_type} eq 'xfs'; - my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($hds->[0]); + my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($all_hds->{hds}[0]); add2hash_($bootloader, arch() =~ /ppc/ ? { defaultos => "linux", @@ -604,7 +670,7 @@ sub suggest { timeout => $onmbr && 10, nowarn => 1, if_(arch() !~ /ia64/, - boot => "/dev/" . ($onmbr ? $hds->[0]{device} : fsedit::get_root($fstab, 'boot')->{device}), + boot => "/dev/" . ($onmbr ? $all_hds->{hds}[0]{device} : $boot), map => "/boot/map", color => 'black/cyan yellow/cyan', ), @@ -662,14 +728,14 @@ wait for default boot. my @kernels = get_kernels_and_labels() or die "no kernel installed"; foreach my $kernel (@kernels) { - add_kernel($bootloader, $kernel, + 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} && $options{quiet}, append => "splash=silent"), }); - if ($options{vga_fb} && $kernel->{ext} eq '') { + if ($options{vga_fb} && $e->{label} eq 'linux') { add_kernel($bootloader, $kernel, { root => $root, label => 'linux-nonfb' }); } } @@ -692,8 +758,8 @@ wait for default boot. } elsif (arch() !~ /ia64/) { #- search for dos (or windows) boot partition. Don't look in extended partitions! my @windows_boot_parts = - grep { isFat_or_NTFS($_) && isFat_or_NTFS({ pt_type => fsedit::typeOfPart($_->{device}) }) } - map { @{$_->{primary}{normal}} } @$hds; + grep { isFat_or_NTFS($_) && member(fs::type::fs_type_from_magic($_), 'vfat', 'ntfs') } + map { @{$_->{primary}{normal}} } @{$all_hds->{hds}}; each_index { add_entry($bootloader, { @@ -743,11 +809,12 @@ sub method_choices_raw() { } sub method_choices { my ($fstab) = @_; + my $root_part = fs::get::root($fstab); grep { - !(/lilo/ && isLoopback(fsedit::get_root($fstab))) - && !(/lilo-graphic/ && detect_devices::matching_desc('ProSavageDDR')) - && !(/grub/ && isRAID(fsedit::get_root($fstab))); + !(/lilo/ && isLoopback($root_part)) + && !(/lilo-graphic/ && detect_devices::matching_desc__regexp('ProSavageDDR')) + && !(/grub/ && isRAID($root_part)); } method_choices_raw(); } @@ -777,27 +844,11 @@ sub create_link_source() { } } -sub has_profiles { my ($b) = @_; to_bool(get_label("office", $b)) } -sub set_profiles { - my ($b, $want_profiles) = @_; - - my $office = get_label("office", $b); - if ($want_profiles xor $office) { - my $e = get_label("linux", $b); - if ($want_profiles) { - push @{$b->{entries}}, { %$e, label => "office", append => "$e->{append} prof=Office" }; - $e->{append} .= " prof=Home"; - } else { - # remove profiles - $e->{append} =~ s/\s*prof=\w+//; - @{$b->{entries}} = grep { $_ != $office } @{$b->{entries}}; - } - } - -} - sub get_of_dev { my ($unix_dev) = @_; + + devices::make("$::prefix$unix_dev"); + my $of_dev; run_program::rooted_or_die($::prefix, "/usr/sbin/ofpath", ">", \$of_dev, $unix_dev); chomp($of_dev); @@ -812,7 +863,11 @@ sub check_enough_space() { } sub write_yaboot { - my ($bootloader, $_hds) = @_; + my ($bootloader, $_all_hds) = @_; + + my $mac_type = detect_devices::get_mac_model(); + return if $mac_type =~ /Power Macintosh/; + $bootloader->{prompt} ||= $bootloader->{timeout}; if ($bootloader->{message}) { @@ -822,21 +877,26 @@ sub write_yaboot { { my @conf; push @conf, "#yaboot.conf - generated by DrakX"; - push @conf, qq(init-message="\\n$bootloader->{'init-message'}\\n") if $bootloader->{'init-message'}; + push @conf, sprintf('init-message="\n%s\n"', $bootloader->{'init-message'}) if $bootloader->{'init-message'}; if ($bootloader->{boot}) { push @conf, "boot=$bootloader->{boot}"; - push @conf, "ofboot=", get_of_dev($bootloader->{boot}) + push @conf, "ofboot=" . get_of_dev($bootloader->{boot}) + } elsif ($mac_type =~ /IBM/) { + push @conf, "boot=/dev/sda1"; } else { die "no bootstrap partition defined." } - push @conf, map { "$_=$bootloader->{$_}" } grep { $bootloader->{$_} } qw(delay timeout defaultos default); + push @conf, map { "$_=$bootloader->{$_}" } grep { $bootloader->{$_} } (qw(delay timeout default), if_($mac_type !~ /IBM/, 'defaultos')); push @conf, "install=/usr/lib/yaboot/yaboot"; - push @conf, "magicboot=/usr/lib/yaboot/ofboot"; - push @conf, grep { $bootloader->{$_} } qw(enablecdboot enableofboot); - #- push @conf, "nonvram"; - my $boot = "/dev/" . $bootloader->{useboot} if $bootloader->{useboot}; + if ($mac_type =~ /IBM/) { + push @conf, 'nonvram'; + } else { + push @conf, 'magicboot=/usr/lib/yaboot/ofboot'; + push @conf, grep { $bootloader->{$_} } qw(enablecdboot enableofboot); + } + my $boot = $bootloader->{useboot} && "/dev/" . $bootloader->{useboot}; foreach (@{$bootloader->{entries}}) { @@ -849,7 +909,7 @@ sub write_yaboot { $of_dev = get_of_dev($_->{root}); push @conf, "$_->{type}=$of_dev,$_->{kernel_or_dev}"; } - push @conf, "\tlabel=", make_label_lilo_compatible($_->{label}); + push @conf, "\tlabel=" . make_label_lilo_compatible($_->{label}); push @conf, "\troot=$_->{root}"; if ($boot !~ /$_->{root}/ && $boot) { push @conf, "\tinitrd=$of_dev," . substr($_->{initrd}, 5) if $_->{initrd}; @@ -874,16 +934,17 @@ sub write_yaboot { } sub install_yaboot { - my ($bootloader, $hds) = @_; + my ($bootloader, $all_hds) = @_; log::l("Installing boot loader..."); - write_yaboot($bootloader, $hds); + write_yaboot($bootloader, $all_hds); when_config_changed_yaboot($bootloader); } sub when_config_changed_yaboot { my ($bootloader) = @_; - my $f = "$::prefix/tmp/of_boot_dev"; - my $of_dev = get_of_dev($bootloader->{boot}); - output($f, "$of_dev\n"); + if ($bootloader->{boot}) { + my $of_dev = get_of_dev($bootloader->{boot}); + output("$::prefix/tmp/of_boot_dev", "$of_dev\n"); + } $::testing and return; if (defined $install_steps_interactive::new_bootstrap) { run_program::run("hformat", $bootloader->{boot}) or die "hformat failed"; @@ -901,25 +962,28 @@ sub make_label_lilo_compatible { } sub write_lilo { - my ($bootloader, $hds) = @_; + my ($bootloader, $all_hds) = @_; $bootloader->{prompt} ||= $bootloader->{timeout}; my $file2fullname = sub { my ($file) = @_; if (arch() =~ /ia64/) { - my $fstab = [ fsedit::get_fstab(@$hds) ]; - (my $part, $file) = fsedit::file2part($fstab, $file); + my $fstab = [ fs::get::fstab($all_hds) ]; + (my $part, $file) = fs::get::file2part($fstab, $file); my %hds = map_index { $_ => "hd$::i" } map { $_->{device} } - sort { isFat($b) <=> isFat($a) || $a->{device} cmp $b->{device} } @$fstab; + sort { + my ($a_is_fat, $b_is_fat) = ($a->{fs_type} eq 'vfat', $b->{fs_type} eq 'vfat'); + $a_is_fat <=> $b_is_fat || $a->{device} cmp $b->{device}; + } @$fstab; $hds{$part->{device}} . ":" . $file; } else { $file } }; - my @sorted_hds = sort_hds_according_to_bios($bootloader, $hds); + my @sorted_hds = sort_hds_according_to_bios($bootloader, $all_hds); - if (is_empty_hash_ref($bootloader->{bios} ||= {}) && $hds->[0] != $sorted_hds[0]) { + if (is_empty_hash_ref($bootloader->{bios} ||= {}) && $all_hds->{hds}[0] != $sorted_hds[0]) { log::l("Since we're booting on $sorted_hds[0]{device}, make it bios=0x80"); $bootloader->{bios} = { "/dev/$sorted_hds[0]{device}" => '0x80' }; } @@ -936,8 +1000,8 @@ sub write_lilo { push @conf, "# File generated by DrakX/drakboot"; 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 { "$_=$bootloader->{$_}" } grep { $bootloader->{$_} } qw(boot map install vga keytable); - push @conf, grep { $bootloader->{$_} } qw(linear geometric compact prompt nowarn restricted); + push @conf, map { "$_=$bootloader->{$_}" } grep { $bootloader->{$_} } qw(boot map install vga keytable raid-extra-boot); + push @conf, grep { $bootloader->{$_} } qw(linear geometric compact prompt nowarn restricted static-bios-codes); push @conf, qq(append="$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}; @@ -967,7 +1031,7 @@ sub write_lilo { push @entry_conf, "unsafe" if $entry->{unsafe} && !$entry->{table}; if ($entry->{table}) { - my $hd = fs::device2part($entry->{table}, $hds); + my $hd = fs::get::device2part($entry->{table}, $all_hds->{hds}); if ($hd != $sorted_hds[0]) { #- boot off the nth drive, so reverse the BIOS maps my $nb = sprintf("0x%x", 0x80 + (find_index { $hd == $_ } @sorted_hds)); @@ -988,7 +1052,7 @@ sub write_lilo { } sub install_lilo { - my ($bootloader, $hds) = @_; + my ($bootloader, $all_hds) = @_; if (my ($install) = $bootloader->{method} =~ /lilo-(text|menu)/) { $bootloader->{install} = $install; @@ -998,7 +1062,7 @@ sub install_lilo { output("$::prefix/boot/message-text", $bootloader->{message}) if $bootloader->{message}; symlinkf "message-" . ($bootloader->{method} ne 'lilo-graphic' ? 'text' : 'graphic'), "$::prefix/boot/message"; - write_lilo($bootloader, $hds); + write_lilo($bootloader, $all_hds); when_config_changed_lilo($bootloader); } @@ -1009,7 +1073,8 @@ sub when_config_changed_lilo { if (!$::testing && arch() !~ /ia64/ && $bootloader->{method} =~ /lilo/) { log::l("Installing boot loader on $bootloader->{boot}..."); my $error; - run_program::rooted($::prefix, "lilo", "2>", \$error) or die "lilo failed: $error"; + my $answer = $bootloader->{force_lilo_answer} || ''; + run_program::rooted($::prefix, "echo $answer | lilo", '2>', \$error) or die "lilo failed: $error"; } } @@ -1025,8 +1090,8 @@ sub mixed_kind_of_disks { } sub sort_hds_according_to_bios { - my ($bootloader, $hds) = @_; - my $boot_hd = fs::device2part($bootloader->{first_hd_device} || $bootloader->{boot}, $hds); #- $boot_hd is undefined when installing on floppy + my ($bootloader, $all_hds) = @_; + my $boot_hd = fs::get::device2part($bootloader->{first_hd_device} || $bootloader->{boot}, $all_hds->{hds}); #- $boot_hd is undefined when installing on floppy my $boot_kind = $boot_hd && hd2bios_kind($boot_hd); my $translate = sub { @@ -1034,14 +1099,14 @@ sub sort_hds_according_to_bios { my $kind = hd2bios_kind($hd); $boot_hd ? ($hd == $boot_hd ? 0 : $kind eq $boot_kind ? 1 : 2) . "_$kind" : $kind; }; - sort { $translate->($a) cmp $translate->($b) } @$hds; + sort { $translate->($a) cmp $translate->($b) } @{$all_hds->{hds}}; } sub device_string2grub { my ($dev, $legacy_floppies, $sorted_hds) = @_; - if (my $device = fs::device2part($dev, [ @$sorted_hds, fsedit::get_fstab(@$sorted_hds) ])) { + if (my $device = fs::get::device2part($dev, [ @$sorted_hds, fs::get::hds_fstab(@$sorted_hds) ])) { device2grub($device, $sorted_hds); - } elsif (my $floppy = fs::device2part($dev, $legacy_floppies)) { + } elsif (my $floppy = fs::get::device2part($dev, $legacy_floppies)) { my $bios = find_index { $floppy eq $_ } @$legacy_floppies; "(fd$bios)"; } else { @@ -1052,7 +1117,7 @@ sub device2grub { my ($device, $sorted_hds) = @_; my ($hd, $part_nb) = $device->{rootDevice} ? - (fs::device2part($device->{rootDevice}, $sorted_hds), $device->{device} =~ /(\d+)$/) : + (fs::get::device2part($device->{rootDevice}, $sorted_hds), $device->{device} =~ /(\d+)$/) : $device; my $bios = find_index { $hd eq $_ } @$sorted_hds; my $part_string = defined $part_nb ? ',' . ($part_nb - 1) : ''; @@ -1089,7 +1154,7 @@ sub grub2dev { sub grub2file { my ($grub_file, $grub2dev, $fstab) = @_; if (my ($device, $rel_file) = grub2dev_and_file($grub_file, $grub2dev)) { - my $part = fs::device2part($device, $fstab) or log::l("ERROR: unknown device $device (computed from $grub_file)"); + my $part = fs::get::device2part($device, $fstab) or log::l("ERROR: unknown device $device (computed from $grub_file)"); my $mntpoint = $part->{mntpoint} || ''; ($mntpoint eq '/' ? '' : $mntpoint) . '/' . $rel_file; } else { @@ -1098,24 +1163,27 @@ sub grub2file { } sub write_grub { - my ($bootloader, $hds) = @_; + my ($bootloader, $all_hds) = @_; - my $fstab = [ fsedit::get_fstab(@$hds) ]; + my $fstab = [ fs::get::fstab($all_hds) ]; my @legacy_floppies = detect_devices::floppies(); - my @sorted_hds = sort_hds_according_to_bios($bootloader, $hds); - + my @sorted_hds = sort_hds_according_to_bios($bootloader, $all_hds); write_grub_device_map(\@legacy_floppies, \@sorted_hds); + if (get_append($bootloader, 'console') =~ /ttyS(\d),(\d+)/) { + $bootloader->{serial} ||= "--unit=$1 --speed=$2"; + $bootloader->{terminal} ||= "--timeout=" . ($bootloader->{timeout} || 0) . " console serial"; + } + my $file2grub = sub { - my ($part, $file) = fsedit::file2part($fstab, $_[0], 'keep_simple_symlinks'); + my ($part, $file) = fs::get::file2part($fstab, $_[0], 'keep_simple_symlinks'); device2grub($part, \@sorted_hds) . $file; }; { my @conf; - push @conf, map { "$_ $bootloader->{$_}" } grep { $bootloader->{$_} } qw(timeout color); + push @conf, map { "$_ $bootloader->{$_}" } grep { $bootloader->{$_} } qw(timeout color serial terminal); push @conf, map { $_ . ' ' . $file2grub->($bootloader->{$_}) } grep { $bootloader->{$_} } qw(splashimage); - push @conf, "serial --unit=$1 --speed=$2\nterminal --timeout=" . ($bootloader->{timeout} || 0) . " console serial" if get_append($bootloader, 'console') =~ /ttyS(\d),(\d+)/; eval { push @conf, "default " . (find_index { $_->{label} eq $bootloader->{default} } @{$bootloader->{entries}}); @@ -1142,7 +1210,7 @@ sub write_grub { push @conf, $title, "root $dev"; if ($_->{table}) { - if (my $hd = fs::device2part($_->{table}, \@sorted_hds)) { + if (my $hd = fs::get::device2part($_->{table}, \@sorted_hds)) { if (my $bios = find_index { $hd eq $_ } @sorted_hds) { #- boot off the nth drive, so reverse the BIOS maps my $nb = sprintf("0x%x", 0x80 + $bios); @@ -1179,16 +1247,14 @@ EOF } sub install_grub { - my ($bootloader, $hds) = @_; + my ($bootloader, $all_hds) = @_; - write_grub($bootloader, $hds); + write_grub($bootloader, $all_hds); if (!$::testing) { log::l("Installing boot loader..."); - symlink "$::prefix/boot", "/boot"; my $error; - run_program::run("sh", '/boot/grub/install.sh', "2>", \$error) or die "grub failed: $error"; - unlink "/boot"; + run_program::rooted($::prefix, "sh", '/boot/grub/install.sh', "2>", \$error) or die "grub failed: $error"; } } sub when_config_changed_grub { @@ -1205,18 +1271,18 @@ sub action { } sub install { - my ($bootloader, $hds) = @_; + my ($bootloader, $all_hds) = @_; - if (my $part = fs::device2part($bootloader->{boot}, [ fsedit::get_fstab(@$hds) ])) { - die N("You can't install the bootloader on a %s partition\n", partition_table::type2fs($part)) - if isThisFs('xfs', $part); + if (my $part = fs::get::device2part($bootloader->{boot}, [ fs::get::fstab($all_hds) ])) { + die N("You can't install the bootloader on a %s partition\n", $part->{fs_type}) + if $part->{fs_type} eq 'xfs'; } $bootloader->{keytable} = keytable($bootloader->{keytable}); - action($bootloader, 'install', $hds); + action($bootloader, 'install', $all_hds); } sub update_for_renumbered_partitions { - my ($in, $renumbering, $hds) = @_; + my ($in, $renumbering, $all_hds) = @_; my %files = ( lilo => '/etc/lilo.conf', @@ -1235,7 +1301,7 @@ sub update_for_renumbered_partitions { my @sorted_hds; { my $grub2dev = read_grub_device_map(); map_each { - $sorted_hds[$1] = fs::device2part($::b, $hds) if $::a =~ /hd(\d+)/; + $sorted_hds[$1] = fs::get::device2part($::b, $all_hds->{hds}) if $::a =~ /hd(\d+)/; } %$grub2dev; }; @@ -1262,7 +1328,7 @@ sub update_for_renumbered_partitions { } } - my $main_method = detect_main_method([ fsedit::get_fstab(@$hds) ]); + my $main_method = detect_main_method([ fs::get::fstab($all_hds) ]); my @needed = $main_method ? $main_method : ('lilo', 'grub'); if (find { my $config = $_ eq 'grub' ? 'grub_install' : $_; |
