diff options
Diffstat (limited to 'perl-install/bootloader.pm')
-rw-r--r-- | perl-install/bootloader.pm | 512 |
1 files changed, 277 insertions, 235 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index 844b6a911..9e7516658 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; use diagnostics; use strict; @@ -19,9 +19,26 @@ use partition_table::raw; use run_program; use modules; -#-##################################################################################### -#- Functions -#-##################################################################################### +=head1 SYNOPSYS + +B<bootloader> enables to configure various boot loaders (LILO, GRUB Legacy, GRUB2, ...) + +Example of usage: + + $all_hds = fsedit::get_hds(); + fs::get_raw_hds('', $all_hds); + fs::get_info_from_fstab($all_hds); + $fstab = [ fs::get::fstab($all_hds) ]; + $bootloader = bootloader::read($all_hds); + (...) + bootloader::action($bootloader, 'write', $all_hds); + +=head1 Functions + +=over + +=cut + my $vmlinuz_regexp = 'vmlinu[xz]|win4lin|uImage'; my $decompose_vmlinuz_name = qr/((?:$vmlinuz_regexp).*?)-(\d+\.\d+.*)/; @@ -57,7 +74,7 @@ sub kernel_str2short_name { sub basename2initrd_basename { my ($basename) = @_; - $basename =~ s!(vmlinu[zx]|uImage)-?!!; #- here we do not use $vmlinuz_regexp since we explictly want to keep all that is not "vmlinuz" + $basename =~ s!(vmlinu[zx]|uImage)-?!!; #- here we do not use $vmlinuz_regexp since we explicitly want to keep all that is not "vmlinuz" 'initrd' . ($basename ? "-$basename" : ''); } sub kernel_str2vmlinuz_long { @@ -106,6 +123,12 @@ sub get_label { undef; } +=item mkinitrd($kernel_version, $bootloader, $entry, $initrd) + +Regenerates kernel's initrd. + +=cut + sub mkinitrd { my ($kernel_version, $bootloader, $entry, $initrd) = @_; @@ -143,6 +166,13 @@ sub mkinitrd { -e "$::prefix/$initrd" && $initrd; } +=item rebuild_initrd($kernel_version, $bootloader, $entry, $initrd) + +Saves the old initrd then regenerate it. +If it fails, restore the old initrd. + +=cut + sub rebuild_initrd { my ($kernel_version, $bootloader, $entry, $initrd) = @_; @@ -187,6 +217,12 @@ sub update_splash { } } +=item read($all_hds) + +Reads bootloader config by calling the proper read_XYZ function. + +=cut + sub read { my ($all_hds) = @_; my $fstab = [ fs::get::fstab($all_hds) ]; @@ -209,7 +245,7 @@ sub read { if (m!/fd\d+$!) { warn "not checking the method on floppy, assuming $main_method is right\n"; $main_method; - } elsif (member($main_method, qw(yaboot cromwell silo pmon2000 uboot))) { + } elsif (member($main_method, qw(cromwell pmon2000 uboot))) { #- not checking, there's only one bootloader anyway :) $main_method; } elsif (my $type = partition_table::raw::typeOfMBR($_)) { @@ -233,6 +269,46 @@ sub read { } } +=item read_grub2 ($o_fstab) + +Read back GRUB2 config + C</boot/grub2/drakboot.conf> + +=cut + +sub read_grub2 { + my %bootloader = getVarsFromSh("$::prefix/boot/grub2/drakboot.conf"); + my %h = getVarsFromSh("$::prefix/etc/default/grub"); + $bootloader{timeout} = $h{GRUB_TIMEOUT}; + $bootloader{entries} = []; + my $entry; + foreach (cat_utf8("$::prefix/boot/grub2/grub.cfg")) { + next if /^#/; + if (/menuentry\s+['"]([^']+)["']/) { + push @{$bootloader{entries}}, $entry if $entry; + $entry = { label => $1 }; + } elsif (/linux\s+(\S+)\s+(.*)?/ || /module\s+(\S+vmlinu\S+)\s+(.*)?/) { + $entry->{type} = 'image'; + @$entry{qw(kernel_or_dev append)} = ($1, $2); + } elsif (/initrd\s+(\S+)/ || /module\s+(\S+initrd\S+)\s+(.*)?/) { + $entry->{initrd} = $1; + } + } + + # get default entry: + foreach (run_program::rooted_get_stdout($::prefix, qw(grub2-editenv list))) { + $bootloader{default} = $1 if /saved_entry=(.*)/; + } + + $bootloader{method} = 'grub2'; + \%bootloader; +} + +=item read_grub($fstab) + +Reads back Grub Legacy config. + +=cut + sub read_grub { my ($fstab) = @_; @@ -249,10 +325,22 @@ 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 + +=item _may_fix_grub2dev($fstab, $grub2dev, $boot_part) + +Adapts device.map (aka $grub2dev) when for example hda is now sda. +nb: + +=over 4 + +=item * $boot_part comes from C</boot/grub/install.sh> "C<root (hd...)>" line + +=item * $grub2dev is C</boot/grub/device.map> + +=back + +=cut + sub _may_fix_grub2dev { my ($fstab, $grub2dev, $boot_part) = @_; @@ -279,6 +367,12 @@ sub _may_fix_grub2dev { $grub2dev->{$hd_grub} = $real_boot_dev; } +=item read_grub_install_sh() { + +Reads "config" from /boot/grub/install.sh (mainly used partitions) + +=cut + sub read_grub_install_sh() { my $s = cat_("$::prefix/boot/grub/install.sh"); my %h; @@ -344,11 +438,24 @@ sub _parse_grub_menu_lst() { %b; } + +=item is_already_crypted($password) + +Returns whether grub password is already encrypted or not + +=cut + sub is_already_crypted { my ($password) = @_; $password =~ /^--md5 (.*)/; } +=item read_grub_menu_lst($fstab, $grub2dev) + +Read config from /boot/grub/menu.lst + +=cut + sub read_grub_menu_lst { my ($fstab, $grub2dev) = @_; @@ -404,33 +511,6 @@ sub read_grub_menu_lst { \%b; } -sub yaboot2dev { - my ($of_path) = @_; - find { dev2yaboot($_) eq $of_path } map { "/dev/$_->{dev}" } fs::proc_partitions::read_raw(); -} - -# assumes file is in /boot -# to do: use yaboot2dev for files as well -#- example of of_path: /pci@f4000000/ata-6@d/disk@0:3,/initrd-2.6.8.1-8mdk.img -sub yaboot2file { - my ($of_path) = @_; - - if ($of_path =~ /,/) { - "$::prefix/boot/" . basename($of_path); - } else { - yaboot2dev($of_path); - } -} - -sub read_silo() { - my $bootloader = read_lilo_like("/boot/silo.conf", sub { - my ($f) = @_; - "/boot$f"; - }); - $bootloader->{method} = 'silo'; - $bootloader; -} - # FIXME: actually read back previous conf sub read_pmon2000() { +{ method => 'pmon2000' }; @@ -443,11 +523,6 @@ sub read_cromwell() { } -sub read_yaboot() { - my $bootloader = read_lilo_like("/etc/yaboot.conf", \&yaboot2file); - $bootloader->{method} = 'yaboot'; - $bootloader; -} sub read_lilo() { my $bootloader = read_lilo_like("/etc/lilo.conf", sub { $_[0] }); @@ -552,7 +627,7 @@ sub suggest_onmbr { if (my $type = partition_table::raw::typeOfMBR($hd->{device})) { if (member($type, qw(dos dummy empty))) { $unsafe = 0; - } elsif (!member($type, qw(lilo grub))) { + } elsif (!member($type, qw(lilo grub grub2))) { $onmbr = 0; } log::l("bootloader::suggest_onmbr: type $type, onmbr $onmbr, unsafe $unsafe"); @@ -560,7 +635,13 @@ sub suggest_onmbr { ($onmbr, $unsafe); } -# list of places where we can install the bootloader + +=item allowed_boot_parts($bootloader, $all_hds) + +Returns list of places where we can install the bootloader + +=cut + sub allowed_boot_parts { my ($bootloader, $all_hds) = @_; ( @@ -601,7 +682,7 @@ sub add_entry { my $to_add = $v; my $label = $v->{label}; - for (my $i = 0; $i < 10;) { + for (my $i = 0; $i < 100;) { my $conflicting = get_label($label, $bootloader); $to_add->{label} = $label; @@ -735,8 +816,6 @@ sub add_kernel { $v->{append} = pack_append($simple, $dict); } - #- new versions of yaboot do not handle symlinks - $b_nolink ||= arch() =~ /ppc/; $b_no_initrd //= arch() =~ /mips|arm/ && !detect_devices::is_mips_gdium(); $b_nolink ||= $kernel_str->{use_long_name}; @@ -752,10 +831,6 @@ sub add_kernel { if (!$b_no_initrd) { $v->{initrd} = mkinitrd($kernel_str->{version}, $bootloader, $v, "/boot/$initrd_long"); - } else { - # we just set up copy of the universal initrd, and we need to add proper info - # in bootloader configuration - $v->{initrd} = '/boot/initrd.img'; } if (!$b_nolink) { @@ -768,7 +843,7 @@ sub add_kernel { _do_the_symlink($bootloader, $v->{kernel_or_dev}, $vmlinuz_long); } - if ($v->{initrd} && !$b_no_initrd) { + if ($v->{initrd}) { $v->{initrd} = '/boot/' . kernel_str2initrd_short($kernel_str); if (arch() =~ /mips/) { log::l("link $::prefix/boot/$initrd_long -> $::prefix$v->{initrd}"); @@ -785,6 +860,12 @@ sub add_kernel { add_entry($bootloader, $v); } +=item rebuild_initrds($bootloader) + +Rebuilds all initrds + +=cut + sub rebuild_initrds { my ($bootloader) = @_; @@ -900,7 +981,12 @@ sub set_append_netprofile { $e->{append} = pack_append($simple, $dict); } -# used when a bootloader $entry has been modified (eg: $entry->{vga}) +=item configure_entry($bootloader, $entry) + +Used when a bootloader $entry has been modified (eg: $entry->{vga}) + +=cut + sub configure_entry { my ($bootloader, $entry) = @_; $entry->{type} eq 'image' or return; @@ -956,12 +1042,6 @@ sub short_ext { $short_ext || $kernel_str->{ext}; } -# deprecated, only for compatibility (nov 2007) -sub sanitize_ver { - my ($_name, $kernel_str) = @_; - _sanitize_ver($kernel_str); -} - sub _sanitize_ver { my ($kernel_str) = @_; @@ -985,11 +1065,16 @@ sub _sanitize_ver { $return; } -# for lilo +=item suggest_message_text($bootloader) + +Provides a description text for Lilo + +=cut + sub suggest_message_text { my ($bootloader) = @_; - if (!$bootloader->{message} && !$bootloader->{message_text} && arch() !~ /ia64/) { + if (!$bootloader->{message} && !$bootloader->{message_text}) { my $msg_en = #-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit) N_("Welcome to the operating system chooser! @@ -999,7 +1084,7 @@ wait for default boot. "); my $msg = translate($msg_en); - #- use the english version if more than 40% of 8bits chars + #- use the English version if more than 40% of 8bits chars #- else, use the translation but force a conversion to ascii #- to be sure there won't be undisplayable characters if (int(grep { $_ & 0x80 } unpack "c*", $msg) / length($msg) > 0.4) { @@ -1017,11 +1102,9 @@ sub suggest { my $root_part = fs::get::root($fstab); my $root = isLoopback($root_part) ? '/dev/loop7' : fs::wild_device::from_part('', $root_part); 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 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 { @@ -1029,33 +1112,18 @@ sub suggest { } my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($mbr); - add2hash_($bootloader, arch() =~ /ppc/ ? - { - defaultos => "linux", - entries => [], - 'init-message' => "Welcome to %s!", - delay => 30, #- OpenFirmware delay - timeout => 50, - enableofboot => 1, - enablecdboot => 1, - if_(detect_devices::get_mac_model() =~ /IBM/, - boot => "/dev/sda1", - ), - xfsroot => $xfsroot, - } : + add2hash_($bootloader, { bootUnsafe => $unsafe, entries => [], timeout => $onmbr && 10, nowarn => 1, - if_(arch() !~ /ia64/, 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' - ), }); suggest_message_text($bootloader); @@ -1082,27 +1150,17 @@ sub suggest { if_($options{vga_fb}, vga => $options{vga_fb}), #- using framebuffer if_($options{vga_fb} && $options{splash}, append => "splash"), if_($options{quiet}, append => "splash quiet"), - }, "", 1); + }); if ($options{vga_fb} && $e->{label} eq 'linux') { - add_kernel($bootloader, $kernel, { root => $root, label => 'linux-nonfb' }, "", 1); + add_kernel($bootloader, $kernel, { root => $root, label => 'linux-nonfb' }); } } add_kernel($bootloader, $kernels[0], - { root => $root, label => 'failsafe', append => 'failsafe' }, "", 1) + { root => $root, label => 'failsafe', append => 'failsafe' }) if @kernels; - if (arch() =~ /ppc/) { - #- if we identified a MacOS partition earlier - add it - if (defined $partition_table::mac::macos_part) { - add_entry($bootloader, - { - type => "macos", - kernel_or_dev => $partition_table::mac::macos_part - }); - } - } elsif (arch() !~ /ia64/) { #- search for dos (or windows) boot partition. Do not look in extended partitions! my @windows_boot_parts = grep { $_->{active} @@ -1121,7 +1179,6 @@ sub suggest { makeactive => 1, }); } @windows_boot_parts; - } my @preferred = map { "linux-$_" } 'p3-smp-64GB', 'secure', 'enterprise', 'smp', 'i686-up-4GB'; if (my $preferred = find { get_label($_, $bootloader) } @preferred) { @@ -1185,27 +1242,25 @@ sub method2text { my ($method) = @_; +{ 'lilo-menu' => N("LILO with text menu"), + 'grub2' => N("GRUB2 with graphical menu"), 'grub-graphic' => N("GRUB with graphical menu"), 'grub-menu' => N("GRUB with text menu"), - 'yaboot' => N("Yaboot"), - 'silo' => N("SILO"), }->{$method}; } sub method_choices_raw { my ($b_prefix_mounted) = @_; detect_devices::is_xbox() ? 'cromwell' : - arch() =~ /ppc/ ? 'yaboot' : - arch() =~ /ia64/ ? 'lilo' : - arch() =~ /sparc/ ? 'silo' : arch() =~ /mips/ ? 'pmon2000' : arch() =~ /arm/ ? 'uboot' : - ( + if_(!$b_prefix_mounted || whereis_binary('grub2-reboot', $::prefix), + 'grub2'), + if_(!is_uefi(), ( if_(!$b_prefix_mounted || whereis_binary('grub', $::prefix), 'grub-graphic', 'grub-menu'), if_(!$b_prefix_mounted || whereis_binary('lilo', $::prefix), 'lilo-menu'), - ); + )); } sub method_choices { my ($all_hds, $b_prefix_mounted) = @_; @@ -1216,7 +1271,7 @@ sub method_choices { grep { !(/lilo/ && (isLoopback($root_part) || $have_dmraid)) - && !(/grub/ && isRAID($boot_part)) + && (/grub2/ || $boot_part->{fs_type} ne 'btrfs') && !(/grub-graphic/ && cat_("/proc/cmdline") =~ /console=ttyS/); } method_choices_raw($b_prefix_mounted); } @@ -1242,127 +1297,12 @@ sub keytable { -r "$::prefix/$f" && $f; } - -sub create_link_source() { - #- we simply do it for all kernels :) - #- so this can be used in %post of kernel and also of kernel-source - foreach (all("$::prefix/usr/src")) { - my ($version) = /^linux-(\d+\.\d+.*)/ or next; - foreach (glob("$::prefix/lib/modules/$version*")) { - -d $_ or next; - log::l("creating symlink $_/build"); - symlink "/usr/src/linux-$version", "$_/build"; - log::l("creating symlink $_/source"); - symlink "/usr/src/linux-$version", "$_/source"; - } - } -} - -sub dev2yaboot { - my ($dev) = @_; - - devices::make("$::prefix$dev"); #- create it in the chroot - - my $of_dev; - run_program::rooted_or_die($::prefix, "/usr/sbin/ofpath", ">", \$of_dev, $dev); - chomp($of_dev); - log::l("OF Device: $of_dev"); - $of_dev; -} - sub check_enough_space() { my $e = "$::prefix/boot/.enough_space"; output $e, 1; -s $e or die N("not enough room in /boot"); unlink $e; } -sub write_yaboot { - my ($bootloader, $all_hds) = @_; - - my $fstab = [ fs::get::fstab($all_hds) ]; - - my $file2yaboot = sub { - my ($part, $file) = fs::get::file2part($fstab, $_[0]); - dev2yaboot('/dev/' . $part->{device}) . "," . $file; - }; - - #- do not write yaboot.conf for old-world macs - my $mac_type = detect_devices::get_mac_model(); - return if $mac_type =~ /Power Macintosh/; - - $bootloader->{prompt} ||= $bootloader->{timeout}; - - if ($bootloader->{message_text}) { - eval { output("$::prefix/boot/message", $bootloader->{message_text}) } - and $bootloader->{message} = '/boot/message'; - } - - my @conf; - - if (!get_label($bootloader->{default}, $bootloader)) { - log::l("default bootloader entry $bootloader->{default} is invalid, choosing another one"); - $bootloader->{default} = $bootloader->{entries}[0]{label}; - } - push @conf, "# yaboot.conf - generated by DrakX/drakboot"; - push @conf, "# WARNING: do not forget to run ybin after modifying this file\n"; - push @conf, "default=" . make_label_lilo_compatible($bootloader->{default}) if $bootloader->{default}; - 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=" . dev2yaboot($bootloader->{boot}) if $mac_type !~ /IBM/; - } else { - die "no bootstrap partition defined."; - } - - push @conf, map { "$_=$bootloader->{$_}" } grep { $bootloader->{$_} } (qw(delay timeout), if_($mac_type !~ /IBM/, 'defaultos')); - push @conf, "install=/usr/lib/yaboot/yaboot"; - if ($mac_type =~ /IBM/) { - push @conf, 'nonvram'; - } else { - push @conf, 'magicboot=/usr/lib/yaboot/ofboot'; - push @conf, grep { $bootloader->{$_} } qw(enablecdboot enableofboot); - } - foreach my $entry (@{$bootloader->{entries}}) { - - if ($entry->{type} eq "image") { - push @conf, "$entry->{type}=" . $file2yaboot->($entry->{kernel_or_dev}); - my @entry_conf; - push @entry_conf, "label=" . make_label_lilo_compatible($entry->{label}); - push @entry_conf, "root=$entry->{root}"; - push @entry_conf, "initrd=" . $file2yaboot->($entry->{initrd}) if $entry->{initrd}; - #- xfs module on PPC requires larger initrd - say 6MB? - push @entry_conf, "initrd-size=6144" if $bootloader->{xfsroot}; - push @entry_conf, qq(append=" $entry->{append}") if $entry->{append}; - push @entry_conf, grep { $entry->{$_} } qw(read-write read-only); - push @conf, map { "\t$_" } @entry_conf; - } else { - my $of_dev = dev2yaboot($entry->{kernel_or_dev}); - push @conf, "$entry->{type}=$of_dev"; - } - } - my $f = "$::prefix/etc/yaboot.conf"; - log::l("writing yaboot config to $f"); - renamef($f, "$f.old"); - output($f, map { "$_\n" } @conf); -} - -sub install_yaboot { - my ($bootloader, $all_hds) = @_; - log::l("Installing boot loader..."); - write_yaboot($bootloader, $all_hds); - when_config_changed_yaboot($bootloader); -} -sub when_config_changed_yaboot { - my ($bootloader) = @_; - $::testing and return; - if (defined $partition_table::mac::new_bootstrap) { - run_program::run("hformat", $bootloader->{boot}) or die "hformat failed"; - } - my $error; - run_program::rooted($::prefix, "/usr/sbin/ybin", "2>", \$error) or die "ybin failed: $error"; -} - sub install_pmon2000 { my ($_bootloader, $_all_hds) = @_; log::l("Mips/pmon2000 - nothing to install..."); @@ -1373,7 +1313,7 @@ sub write_pmon2000 { } sub when_config_changed_pmon2000 { my ($_bootloader) = @_; - log::l("Mips/pmon2000 - nothing to do..."); + #- do not do anything } sub install_uboot { @@ -1386,7 +1326,7 @@ sub write_uboot { } sub when_config_changed_uboot { my ($_bootloader) = @_; - log::l("uboot - nothing to do..."); + #- do not do anything } sub install_cromwell { @@ -1399,7 +1339,7 @@ sub write_cromwell { } sub when_config_changed_cromwell { my ($_bootloader) = @_; - log::l("XBox/Cromwell - nothing to do..."); + #- do not do anything } sub simplify_label { @@ -1588,7 +1528,7 @@ sub install_raw_lilo { sub when_config_changed_lilo { my ($bootloader) = @_; - if (!$::testing && arch() !~ /ia64/ && $bootloader->{method} =~ /lilo/) { + if (!$::testing && $bootloader->{method} =~ /lilo/) { log::l("Installing boot loader on $bootloader->{boot}..."); install_raw_lilo($bootloader->{force_lilo_answer}); } @@ -1671,8 +1611,14 @@ 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") +=item parse_grub_file($grub_file) + +Parses things like "C<(hd0,4)/boot/vmlinuz>" + +Returns: ("hd0", 4, "boot/vmlinuz") + +=cut + sub parse_grub_file { my ($grub_file) = @_; my ($grub_dev, $rel_file) = $grub_file =~ m!\((.*?)\)/?(.*)! or return; @@ -1680,8 +1626,14 @@ sub parse_grub_file { ($hd, $part, $rel_file); } -# takes things like "(hd0,4)/boot/vmlinuz" -# returns: ("/dev/sda5", "boot/vmlinuz") +=item grub2dev_and_file($grub_file, $grub2dev, $o_block_device) + +Takes things like "C<(hd0,4)/boot/vmlinuz>" + +Returns: ("/dev/sda5", "boot/vmlinuz") + +=cut + sub grub2dev_and_file { my ($grub_file, $grub2dev, $o_block_device) = @_; my ($hd, $part, $rel_file) = parse_grub_file($grub_file) or return; @@ -1690,16 +1642,34 @@ 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" + +=item grub2devd($grub_file, $grub2dev, $o_block_device) + +Takes things like "C<(hd0,4)/boot/vmlinuz>" + +Returns: "/dev/sda5" + +=cut + 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 +=item grub2file($grub_file, $grub2dev, $fstab, $o_entry) + +Replaces + +=over 4 + +=item * "C</vmlinuz>" with "C</boot/vmlinuz>" when "root" or "rootnoverify" is set for the entry + +=item * "C<(hdX,Y)>" in "C<(hdX,Y)/boot/vmlinuz...>" by appropriate path if possible/needed + +=back + +=cut + sub grub2file { my ($grub_file, $grub2dev, $fstab, $o_entry) = @_; @@ -1772,6 +1742,31 @@ sub crypt_grub_password { chomp_($res); } +sub write_grub2 { + my ($bootloader, $_all_hds, $o_backup_extension) = @_; + my $error; + + # set default parameters: + my ($entry) = grep { $_->{kernel_or_dev} =~ /vmlin/ } @{$bootloader->{entries}}; + my $append = $entry->{append}; + $append =~ s/root=\S+//g; + $append =~ s/\bro\b//g; + $append =~ s/\s+/ /g; + + my $f = "$::prefix/etc/default/grub"; + my %conf = getVarsFromSh($f); + $conf{GRUB_CMDLINE_LINUX_DEFAULT} = $append; + $conf{GRUB_TIMEOUT} = $bootloader->{timeout}; + setVarsInSh($f, \%conf); + + my $grub2_cfg = '/boot/grub2/grub.cfg'; + run_program::rooted($::prefix, 'grub2-mkconfig', '2>', \$error, '-o', $grub2_cfg) or die "grub2-mkconfig failed: $error"; + + # set default entry: + eval { + run_program::rooted($::prefix, 'grub2-set-default', '2>', \$error, $bootloader->{default}) or die "grub2-mkconfig failed: $error"; + }; +} sub write_grub { my ($bootloader, $all_hds, $o_backup_extension) = @_; @@ -1859,7 +1854,7 @@ sub write_grub { # split partition from initrd path and place # it to a separate 'root' entry. # Grub2's mkconfig takes initrd entry 'as is', - # but gru2 fails to load smth like '(hd0,1)/boot/initrd' taken from grub-legacy + # but grub2 fails to load smth like '(hd0,1)/boot/initrd' taken from grub-legacy my $initrd_path = $file2grub->($entry->{initrd}); if ($initrd_path =~ /^(\([^\)]+\))/) { push @conf, "root $1"; @@ -1964,6 +1959,20 @@ sub restore_previous_MBR_bootloader { output($dev, scalar cat_(_dev_to_MBR_backup($dev))); } +sub install_grub2 { + my ($bootloader, $all_hds) = @_; + my $error; + write_grub2($bootloader, $all_hds); + my $boot = $bootloader->{boot}; + # if (member($boot, map { "/dev/$_->{device}" } @{$all_hds->{hds}}) { + if ($boot =~ /\d$/) { + run_program::rooted($::prefix, 'grub2-install', '2>', \$error, '--grub-setup=/bin/true', $boot) or die "grub2-install failed: $error"; + } else { + run_program::rooted($::prefix, 'grub2-install', '2>', \$error, $boot) or die "grub2-install failed: $error"; + } + setVarsInSh("$::prefix/boot/grub2/drakboot.conf", { boot => $boot }); +} + sub install_grub { my ($bootloader, $all_hds) = @_; @@ -1996,6 +2005,11 @@ sub install_raw_grub() { run_program::rooted($::prefix, "sh", "2>", \$error, '/boot/grub/install.sh') or die "grub failed: $error"; } +sub when_config_changed_grub2 { + my ($_bootloader) = @_; + #- do not do anything +} + sub when_config_changed_grub { my ($_bootloader) = @_; #- do not do anything @@ -2003,6 +2017,16 @@ sub when_config_changed_grub { update_copy_in_boot($_) foreach glob($::prefix . boot_copies_dir() . '/*.link'); } +=item action($bootloader, $action, @para) + +Calls the C<$action> function with @para parameters: + + $actions->($bootloader, @para) + +If needed, the function name will be resolved to call a boot loader specific function (eg: for LILO/GRUB/...) + +=cut + sub action { my ($bootloader, $action, @para) = @_; @@ -2011,6 +2035,12 @@ sub action { $f->($bootloader, @para); } +=item install($bootloader, $all_hds) + +Writes back the boot loader config. Calls the proper write_XYZ() function. + +=cut + sub install { my ($bootloader, $all_hds) = @_; @@ -2025,9 +2055,11 @@ sub install { sub ensure_pkg_is_installed { my ($do_pkgs, $bootloader) = @_; + my %pkg = ('grub2' => glob_("/sys/firmware/efi/*") ? 'grub2-efi' : 'grub2'); + my %h = ('grub2' => 'grub2-install'); 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 (member($main_method, qw(grub grub2 lilo))) { + $do_pkgs->ensure_binary_is_installed($pkg{$main_method} || $main_method, $h{$main_method} || $main_method, 1) or return 0; if ($bootloader->{method} eq 'grub-graphic') { $do_pkgs->ensure_is_installed('mageia-gfxboot-theme', '/usr/share/gfxboot/themes/Mageia/boot/message', 1) or return 0; } @@ -2072,6 +2104,12 @@ sub parse_grub2_config { } } +=item find_other_distros_grub_conf($fstab) + +Returns a list of other distros' grub.conf + +=cut + sub find_other_distros_grub_conf { my ($fstab) = @_; @@ -2140,7 +2178,7 @@ sub find_other_distros_grub_conf { } else { log::l("could not recognise the distribution for $e->{grub_conf} in $e->{bootpart}{device}"); } - $e->{name} = $e->{menuentry} || "Linux $e->{bootpart}{device}"; + $e->{name} ||= "Linux $e->{bootpart}{device}"; push @found, $e; } } @@ -2201,4 +2239,8 @@ sub update_for_renumbered_partitions { 1; } +=back + +=cut + 1; |