Module: Yast::BootloaderGrub2MiscInclude
- Defined in:
- src/include/bootloader/grub2/misc.rb
Instance Method Summary (collapse)
- - (Boolean) gpt_boot_disk?
-
- (String) grub_ConfigureLocation
grub_ConfigureLocation() Where to install the bootloader.
-
- (Object) grub_DetectDisks
Detect “/boot”, “/” (root), extended partition device and MBR disk device.
-
- (Hash) grub_DisksChanged
Check whether any disk settings for the disks we currently use were changed since last checking.
-
- (String) grub_GetExtendedPartitionDev
Find extended partition device (if it exists) on the same device where the BootPartitionDevice is located.
-
- (Object) grub_getMbrsToRewrite
Get the list of MBR disks that should be rewritten by generic code if user wants to do so.
-
- (Object) grub_getPartitionsToActivate
Get a list of partitions to activate if user wants to activate boot partition.
-
- (Object) grub_getPartitionToActivate(loader_device)
Given a device name to which we install the bootloader (loader_device), get the name of the partition which should be activated.
-
- (Object) grub_LocationProposal
Propose the boot loader location for grub - if no proposal has been made, collects the devices for “/”, “/boot”, MBR and makes a new proposal - if no device mapping exists, creates a device mapping - if the devices that were somehow (proposal, user interface) selected for bootloader installation do not match the current partitioning any more (e.g. “/boot” partition was selected but is not available anymore (and “/” did not move there), “/” was selected but has moved, etc.), then also re-collect the devices for “/”, “/boot”, MBR and make a new proposal.
-
- (Boolean) grub_updateMBR
Update contents of MBR (active partition and booting code) FIXME move tis function to lilolike.ycp.
- - (Object) initialize_bootloader_grub2_misc(include_target)
-
- (Boolean) ReduceDeviceMapTo8
FATE #303548 - Grub: limit device.map to devices detected by BIOS Int 13 The function reduces records (devices) in device.map Grub doesn't support more than 8 devices in device.map.
-
- (Object) SetBootloaderDevice(selected_location)
SetBootloaderDevice() Set “boot_*” flags in the globals map according to the boot device selected with parameter selected_location.
-
- (String) soft_MDraid_boot_disk(partitions)
function check all partitions and it tries to find /boot partition if it is MD Raid and soft-riad return correct device for analyse MBR.
Instance Method Details
- (Boolean) gpt_boot_disk?
643 644 645 646 647 |
# File 'src/include/bootloader/grub2/misc.rb', line 643 def gpt_boot_disk? targets = BootCommon.GetBootloaderDevices boot_discs = targets.map {|d| Storage.GetDisk(Storage.GetTargetMap, d)} boot_discs.any? {|d| d["label"] == "gpt" } end |
- (String) grub_ConfigureLocation
grub_ConfigureLocation() Where to install the bootloader. Returns the type
of device where to install: one of boot
root
mbr
extended `mbr_md Also sets the boot_* keys in the internal
global variable globals accordingly.
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
# File 'src/include/bootloader/grub2/misc.rb', line 456 def grub_ConfigureLocation # NOTE: selected_location is a temporary local variable now; the global # variable is not used for grub anymore selected_location = :mbr # default to mbr vista_mbr = false # check whether the /boot partition # - is primary: is_logical -> false # - is on the first disk (with the MBR): boot_partition_is_on_mbr_disk -> true tm = Storage.GetTargetMap dp = Storage.GetDiskPartition(BootStorage.BootPartitionDevice) boot_partition_disk = Ops.get_string(dp, "disk", "") boot_partition_is_on_mbr_disk = boot_partition_disk == BootCommon.mbrDisk dm = Ops.get_map(tm, boot_partition_disk, {}) partitions_on_boot_partition_disk = Ops.get_list(dm, "partitions", []) is_logical = false is_logical_and_btrfs = false extended = nil # determine the underlying devices for the "/boot" partition (either the # BootPartitionDevice, or the devices from which the soft-RAID device for # "/boot" is built) = [BootStorage.BootPartitionDevice] md_info = BootCommon.Md2Partitions(BootStorage.BootPartitionDevice) if md_info != nil && Ops.greater_than(Builtins.size(md_info), 0) boot_partition_is_on_mbr_disk = false = Builtins.maplist(md_info) do |dev, bios_id| pdp = Storage.GetDiskPartition(dev) p_disk = Ops.get_string(pdp, "disk", "") boot_partition_is_on_mbr_disk = true if p_disk == BootCommon.mbrDisk dev end end Builtins.y2milestone( "Boot partition devices: %1", ) Builtins.foreach(partitions_on_boot_partition_disk) do |p| if Ops.get(p, "type") == :extended extended = Ops.get_string(p, "device") elsif Builtins.contains( , Ops.get_string(p, "device", "") ) && Ops.get(p, "type") == :logical # If any of the underlying_boot_partition_devices can be found on # the boot_partition_disk AND is a logical partition, set # is_logical to true. # For soft-RAID this will not match anyway ("/dev/[hs]da*" does not # match "/dev/md*"). is_logical = true is_logical_and_btrfs = true if Ops.get(p, "used_fs") == :btrfs end end Builtins.y2milestone( "/boot is on 1st disk: %1", boot_partition_is_on_mbr_disk ) Builtins.y2milestone("/boot is in logical partition: %1", is_logical) Builtins.y2milestone( "/boot is in logical partition and use btrfs: %1", is_logical_and_btrfs ) Builtins.y2milestone("The extended partition: %1", extended) # if is primary, store bootloader there exit = 0 # there was check if boot device is on logical partition # IMO it is good idea check MBR also in this case # see bug #279837 comment #53 if boot_partition_is_on_mbr_disk selected_location = BootStorage.BootPartitionDevice != BootStorage.RootPartitionDevice ? :boot : :root Ops.set(BootCommon.globals, "activate", "true") BootCommon.activate_changed = true # check if there is raid and if it soft-raid select correct device for analyse MBR # bnc #398356 if Ops.greater_than(Builtins.size(), 1) boot_partition_disk = soft_MDraid_boot_disk( partitions_on_boot_partition_disk ) end if boot_partition_disk == "" boot_partition_disk = Ops.get_string(dp, "disk", "") end # bnc #483797 cannot read 512 bytes from... out = "" if boot_partition_disk != "" out = BootCommon.examineMBR(boot_partition_disk) else Builtins.y2error("Boot partition disk not found") end Ops.set( BootCommon.globals, "generic_mbr", out != "vista" ? "true" : "false" ) if out == "vista" Builtins.y2milestone("Vista MBR...") vista_mbr = true end elsif Ops.greater_than( Builtins.size(), 1 ) # FIXME: `mbr_md is probably unneeded; AFA we can see, this decision is # automatic anyway and perl-Bootloader should be able to make it without help # from the user or the proposal. # In one or two places yast2-bootloader needs to find out all underlying MBR # devices, if we install stage 1 to a soft-RAID. These places need to find out # themselves if we have MBRs on a soft-RAID or not. # selected_location = `mbr_md; selected_location = :mbr end if is_logical_and_btrfs Builtins.y2milestone( "/boot is on logical parititon and uses btrfs, mbr is favored in this situration" ) selected_location = :mbr end if !BootStorage.can_boot_from_partition Builtins.y2milestone("/boot cannot be used to install stage1") selected_location = :mbr end SetBootloaderDevice(selected_location) if !Builtins.contains( BootStorage.getPartitionList(:boot, "grub"), Ops.get(BootCommon.GetBootloaderDevices, 0) ) selected_location = :mbr # default to mbr SetBootloaderDevice(selected_location) end Builtins.y2milestone( "grub_ConfigureLocation (%1 on %2)", selected_location, BootCommon.GetBootloaderDevices ) # set active flag, if needed if selected_location == :mbr && Ops.less_or_equal(Builtins.size(), 1) # We are installing into MBR: # If there is an active partition, then we do not need to activate # one (otherwise we do). # Reason: if we use our own MBR code, we do not rely on the activate # flag in the partition table to boot Linux. Thus, the activated # partition can remain activated, which causes less problems with # other installed OSes like Windows (older versions assign the C: # drive letter to the activated partition). Ops.set( BootCommon.globals, "activate", Builtins.size(Storage.GetBootPartition(BootCommon.mbrDisk)) == 0 ? "true" : "false" ) else # if not installing to MBR, always activate (so the generic MBR will # boot Linux) # kokso: fix the problem with proposing installation generic boot code to "/" or "/boot" # kokso: if boot device is on logical partition if is_logical && extended != nil && (Ops.get(BootCommon.globals, "generic_mbr", "") == "true" || vista_mbr) selected_location = :extended end Ops.set(BootCommon.globals, "activate", "true") SetBootloaderDevice(selected_location) end # for GPT remove protective MBR flag otherwise some systems won't boot if gpt_boot_disk? BootCommon.pmbr_action = :remove end Builtins.y2milestone("location configured. Resulting globals #{BootCommon.globals}") selected_location end |
- (Object) grub_DetectDisks
Detect “/boot”, “/” (root), extended partition device and MBR disk device
If no bootloader device has been set up yet (globals), or the first (FIXME(!)) device is not available as a boot partition, also call grub_ConfigureLocation to configure globals and set the globals and globals flags if needed all these settings are stored in internal variables
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 |
# File 'src/include/bootloader/grub2/misc.rb', line 685 def grub_DetectDisks # #151501: AutoYaST also needs to know the activate flag and the # "boot_*" settings (formerly the loader_device); jsrain also said # that skipping setting these variables is probably a bug: # commenting out the skip code, but this may need to be changed and made dependent # on a "clone" flag (i.e. make the choice to provide minimal (i.e. let # YaST do partial proposals on the target system) or maximal (i.e. # stay as closely as possible to this system) info in the AutoYaST XML # file) # if (Mode::config ()) # return; mp = Storage.GetMountPoints mountdata_boot = Ops.get_list(mp, "/boot", Ops.get_list(mp, "/", [])) mountdata_root = Ops.get_list(mp, "/", []) Builtins.y2milestone("mountPoints %1", mp) Builtins.y2milestone("mountdata_boot %1", mountdata_boot) BootStorage.RootPartitionDevice = Ops.get_string(mp, ["/", 0], "") if BootStorage.RootPartitionDevice == "" Builtins.y2error("No mountpoint for / !!") end # if /boot changed, re-configure location BootStorage.BootPartitionDevice = Ops.get_string( mountdata_boot, 0, BootStorage.RootPartitionDevice ) # get extended partition device (if exists) BootStorage.ExtendedPartitionDevice = grub_GetExtendedPartitionDev if BootCommon.mbrDisk == "" || BootCommon.mbrDisk == nil # mbr detection. BootCommon.mbrDisk = BootCommon.FindMBRDisk end # if no bootloader devices have been set up, or any of the set up # bootloader devices have become unavailable, then re-propose the # bootloader location. all_boot_partitions = BootStorage.getPartitionList(:boot, "grub") bldevs = BootCommon.GetBootloaderDevices need_location_reconfigure = false if bldevs == nil || bldevs == ["/dev/null"] need_location_reconfigure = true else Builtins.foreach(bldevs) do |dev| if !Builtins.contains(all_boot_partitions, dev) need_location_reconfigure = true end end end grub_ConfigureLocation if need_location_reconfigure nil end |
- (Hash) grub_DisksChanged
Check whether any disk settings for the disks we currently use were changed since last checking
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 |
# File 'src/include/bootloader/grub2/misc.rb', line 750 def grub_DisksChanged ret = { "changed" => false, "reason" => "" } return deep_copy(ret) if Mode.config mp = Storage.GetMountPoints actual_root = Ops.get_string(mp, ["/", 0], "") actual_boot = Ops.get_string(mp, ["/boot", 0], actual_root) actual_extended = grub_GetExtendedPartitionDev if Ops.get(BootCommon.globals, "boot_boot", "false") == "true" && actual_boot != BootStorage.BootPartitionDevice ret = { "changed" => true, "reason" => Ops.add( Ops.add( Ops.add( Ops.get_string(ret, "reason", ""), "Selected bootloader location \"/boot\" is not on " ), BootStorage.BootPartitionDevice ), " any more.\n" ) } end if Ops.get(BootCommon.globals, "boot_root", "false") == "true" && actual_root != BootStorage.RootPartitionDevice ret = { "changed" => true, "reason" => Ops.add( Ops.add( Ops.add( Ops.get_string(ret, "reason", ""), "Selected bootloader location \"/\" is not on " ), BootStorage.RootPartitionDevice ), " any more.\n" ) } end if Ops.get(BootCommon.globals, "boot_mbr", "false") == "true" actual_mbr = BootCommon.FindMBRDisk if actual_mbr != BootCommon.mbrDisk ret = { "changed" => true, "reason" => Ops.add( Ops.add( Ops.add( Ops.get_string(ret, "reason", ""), "Selected bootloader location MBR is not on " ), BootCommon.mbrDisk ), " any more.\n" ) } end end if Ops.get(BootCommon.globals, "boot_extended", "false") == "true" && actual_extended != BootStorage.ExtendedPartitionDevice ret = { "changed" => true, "reason" => Ops.add( Ops.add( Ops.add( Ops.get_string(ret, "reason", ""), "Selected bootloader location \"extended partition\" is not on " ), BootStorage.ExtendedPartitionDevice ), " any more.\n" ) } end if Ops.get(BootCommon.globals, "boot_custom") != nil && Ops.get(BootCommon.globals, "boot_custom") != "" all_boot_partitions = BootStorage.getPartitionList(:boot, "grub") if !Builtins.contains( all_boot_partitions, Ops.get(BootCommon.globals, "boot_custom") ) ret = { "changed" => true, "reason" => Ops.add( Ops.add( Ops.add( Ops.get_string(ret, "reason", ""), "Selected custom bootloader partition " ), Ops.get(BootCommon.globals, "boot_custom") ), " is not available any more.\n" ) } end end if Ops.get_boolean(ret, "changed", false) Builtins.y2milestone("Location should be set again") end deep_copy(ret) end |
- (String) grub_GetExtendedPartitionDev
Find extended partition device (if it exists) on the same device where the BootPartitionDevice is located
BootPartitionDevice must be set
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
# File 'src/include/bootloader/grub2/misc.rb', line 655 def grub_GetExtendedPartitionDev ret = nil tm = Storage.GetTargetMap device = "" if BootStorage.BootPartitionDevice != "" device = BootStorage.BootPartitionDevice else device = BootStorage.RootPartitionDevice end dp = Storage.GetDiskPartition(device) disk = Ops.get_string(dp, "disk", "") dm = Ops.get_map(tm, disk, {}) partitions = Ops.get_list(dm, "partitions", []) Builtins.foreach(partitions) do |p| ret = Ops.get_string(p, "device") if Ops.get(p, "type") == :extended end ret end |
- (Object) grub_getMbrsToRewrite
Get the list of MBR disks that should be rewritten by generic code if user wants to do so
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'src/include/bootloader/grub2/misc.rb', line 174 def grub_getMbrsToRewrite ret = [BootCommon.mbrDisk] md = {} = [] devs = [] boot_devices = [] # bnc#494630 - add also boot partitions from soft-raids boot_device = BootCommon.getBootPartition if Builtins.substring(boot_device, 0, 7) == "/dev/md" boot_devices = Builtins.add(boot_devices, boot_device) Builtins.foreach(BootCommon.GetBootloaderDevices) do |dev| boot_devices = Builtins.add(boot_devices, dev) end else boot_devices = BootCommon.GetBootloaderDevices end # get a list of all bootloader devices or their underlying soft-RAID # devices, if necessary = Builtins.maplist(boot_devices) do |dev| md = BootCommon.Md2Partitions(dev) if Ops.greater_than(Builtins.size(md), 0) devs = Builtins.maplist(md) { |k, v| k } next deep_copy(devs) end [dev] end bootloader_base_devices = Builtins.flatten() # find the MBRs on the same disks as the devices underlying the boot # devices; if for any of the "underlying" or "base" devices no device # for acessing the MBR can be determined, include mbrDisk in the list mbrs = Builtins.maplist(bootloader_base_devices) do |dev| dev = Ops.get_string( grub_getPartitionToActivate(dev), "mbr", BootCommon.mbrDisk ) dev end # FIXME: the exact semantics of this check is unclear; but it seems OK # to keep this as a sanity check and a check for an empty list; # mbrDisk _should_ be included in mbrs; the exact cases for this need # to be found and documented though if Builtins.contains(mbrs, BootCommon.mbrDisk) ret = Convert.convert( Builtins.merge(ret, mbrs), :from => "list", :to => "list <string>" ) end Builtins.toset(ret) end |
- (Object) grub_getPartitionsToActivate
Get a list of partitions to activate if user wants to activate boot partition
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'src/include/bootloader/grub2/misc.rb', line 130 def grub_getPartitionsToActivate md = {} = [] devs = [] boot_devices = [] # bnc#494630 - add also boot partitions from soft-raids boot_device = BootCommon.getBootPartition if Builtins.substring(boot_device, 0, 7) == "/dev/md" boot_devices = Builtins.add(boot_devices, boot_device) Builtins.foreach(BootCommon.GetBootloaderDevices) do |dev| boot_devices = Builtins.add(boot_devices, dev) end else boot_devices = BootCommon.GetBootloaderDevices end # get a list of all bootloader devices or their underlying soft-RAID # devices, if necessary = Builtins.maplist(boot_devices) do |dev| md = BootCommon.Md2Partitions(dev) if Ops.greater_than(Builtins.size(md), 0) devs = Builtins.maplist(md) { |k, v| k } next deep_copy(devs) end [dev] end bootloader_base_devices = Builtins.flatten() if Builtins.size(bootloader_base_devices) == 0 bootloader_base_devices = BootCommon.GetBootloaderDevices end ret = Builtins.maplist(bootloader_base_devices) do |partition| grub_getPartitionToActivate(partition) end ret.delete({}) Builtins.toset(ret) end |
- (Object) grub_getPartitionToActivate(loader_device)
Given a device name to which we install the bootloader (loader_device), get the name of the partition which should be activated. Also return the device file name of the disk device that corresponds to loader_device (i.e. where the corresponding MBR can be found). string loader_device)
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'src/include/bootloader/grub2/misc.rb', line 54 def grub_getPartitionToActivate(loader_device) p_dev = Storage.GetDiskPartition(loader_device) num = BootCommon.myToInteger(Ops.get(p_dev, "nr")) mbr_dev = Ops.get_string(p_dev, "disk", "") # If loader_device is /dev/md* (which means bootloader is installed to # /dev/md*), return the info map for the first device in BIOS ID order # that underlies the soft-RAID and that has a BIOS ID (devices without # BIOS ID are excluded). # If no device is found in this way, return the info map for the # soft-RAID device ("/dev/md", "/dev/md[0-9]*"). # FIXME: use ::storage to detect md devices, not by name! # FIXME: return info for ALL underlying soft-RAID devices here, so # that all MBRs can be backed-up and all partitions that need to be # activated can be activated. This requires a map<map<...>> return # value, and code on the caller side that evaluates this. if Builtins.substring(loader_device, 0, 7) == "/dev/md" md = BootCommon.Md2Partitions(loader_device) # max. is 255; 256 means "no bios_id found", so to have at least one # underlaying device use higher min = 257 device = "" Builtins.foreach(md) do |d, id| if Ops.less_than(id, min) min = id device = d end end if device != "" p_dev2 = Storage.GetDiskPartition(device) num = BootCommon.myToInteger(Ops.get(p_dev2, "nr")) mbr_dev = Ops.get_string(p_dev2, "disk", "") end end tm = Storage.GetTargetMap partitions = Ops.get_list(tm, [mbr_dev, "partitions"], []) # do not select swap and do not select BIOS grub partition # as it clear its special flags (bnc#894040) partitions.select! { |p| p["used_fs"] != :swap && p["fsid"] != Partitions.fsid_bios_grub } # (bnc # 337742) - Unable to boot the openSUSE (32 and 64 bits) after installation # if loader_device is disk Choose any partition which is not swap to # satisfy such bios (bnc#893449) if num == 0 # strange, no partitions on our mbr device, we probably won't boot if partitions.empty? Builtins.y2warning("no non-swap partitions for mbr device #{mbr_dev}") return {} end num = partitions.first["nr"] Builtins.y2milestone("loader_device is disk device, so use its #{num} partition") end if Ops.greater_than(num, 4) Builtins.y2milestone("Bootloader partition type can be logical") Builtins.foreach(partitions) do |p| if Ops.get(p, "type") == :extended num = Ops.get_integer(p, "nr", num) Builtins.y2milestone("Using extended partition %1 instead", num) end end end ret = { "num" => num, "mbr" => mbr_dev, "dev" => Storage.GetDeviceName(mbr_dev, num) } Builtins.y2milestone("Partition for activating: %1", ret) deep_copy(ret) end |
- (Object) grub_LocationProposal
Propose the boot loader location for grub - if no proposal has been made, collects the devices for “/”, “/boot”, MBR and makes a new proposal - if no device mapping exists, creates a device mapping - if the devices that were somehow (proposal, user interface) selected for bootloader installation do not match the current partitioning any more (e.g. “/boot” partition was selected but is not available anymore (and “/” did not move there), “/” was selected but has moved, etc.), then also re-collect the devices for “/”, “/boot”, MBR and make a new proposal
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 |
# File 'src/include/bootloader/grub2/misc.rb', line 872 def grub_LocationProposal Builtins.y2milestone("globals: %1", BootCommon.globals) Builtins.y2milestone("Mode::autoinst: %1", Mode.autoinst) Builtins.y2milestone("Mode::autoupg: %1", Mode.autoupgrade) Builtins.y2milestone( "haskey( BootCommon::globals, boot_boot ): %1", Builtins.haskey(BootCommon.globals, "boot_boot") ) md_mbr = "" if !BootCommon.was_proposed || # During autoinstall, the autoyast profile must contain a bootloader # device specification (we currently really only support system # *cloning* with autoyast...). But as a convenience, and because # this kind of magic is available for empty globals and sections, we # propose a bootloader location if none was specified. # Note that "no bootloader device" can be specified by explicitly # setting this up, e.g. by setting one or all boot_* flags to # "false". # FIXME: add to LILO, ELILO; POWERLILO already should have this # (check again) (Mode.autoinst || Mode.autoupgrade) && !Builtins.haskey(BootCommon.globals, "boot_boot") && !Builtins.haskey(BootCommon.globals, "boot_root") && !Builtins.haskey(BootCommon.globals, "boot_mbr") && !Builtins.haskey(BootCommon.globals, "boot_extended") && !# ! haskey( BootCommon::globals, "boot_mbr_md" ) && Builtins.haskey(BootCommon.globals, "boot_custom") grub_DetectDisks # check whether edd is loaded; if not: load it lsmod_command = "lsmod | grep edd" Builtins.y2milestone("Running command %1", lsmod_command) lsmod_out = Convert.to_map( SCR.Execute(path(".target.bash_output"), lsmod_command) ) Builtins.y2milestone("Command output: %1", lsmod_out) edd_loaded = Ops.get_integer(lsmod_out, "exit", 0) == 0 if !edd_loaded command = "/sbin/modprobe edd" Builtins.y2milestone("Loading EDD module, running %1", command) out = Convert.to_map( SCR.Execute(path(".target.bash_output"), command) ) Builtins.y2milestone("Command output: %1", out) end md_mbr = BootStorage.addMDSettingsToGlobals Ops.set(BootCommon.globals, "boot_md_mbr", md_mbr) if md_mbr != "" end Builtins.y2milestone("(2) globals: %1", BootCommon.globals) # refresh device map if BootStorage.device_mapping == nil || Builtins.size(BootStorage.device_mapping) == 0 || BootCommon.cached_settings_base_data_change_time != Storage.GetTargetChangeTime && # bnc#585824 - Bootloader doesn't use defined device map from autoyast !((Mode.autoinst || Mode.autoupgrade) && BootCommon.cached_settings_base_data_change_time == nil) BootStorage.ProposeDeviceMap md_mbr = BootStorage.addMDSettingsToGlobals Ops.set(BootCommon.globals, "boot_md_mbr", md_mbr) if md_mbr != "" BootCommon.InitializeLibrary(true, "grub2") end if !Mode.autoinst && !Mode.autoupgrade changed = grub_DisksChanged if Ops.get_boolean(changed, "changed", false) if BootCommon.askLocationResetPopup( Ops.get_string(changed, "reason", "Disk configuration changed.\n") ) SetBootloaderDevice(:none) Builtins.y2milestone("Reconfiguring locations") grub_DetectDisks end end end nil end |
- (Boolean) grub_updateMBR
Update contents of MBR (active partition and booting code) FIXME move tis function to lilolike.ycp
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'src/include/bootloader/grub2/misc.rb', line 232 def grub_updateMBR # FIXME: do the real thing in perl_Bootloader activate = Ops.get(BootCommon.globals, "activate", "false") == "true" generic_mbr = Ops.get(BootCommon.globals, "generic_mbr", "false") == "true" Builtins.y2milestone( "Updating disk system area, activate partition: %1, " + "install generic boot code in MBR: %2", activate, generic_mbr ) # After a proposal is done, Bootloader::Propose() always sets # backup_mbr to true. The default is false. No other parts of the code # currently change this flag. if BootCommon.backup_mbr Builtins.y2milestone( "Doing MBR backup: MBR Disk: %1, loader devices: %2", BootCommon.mbrDisk, BootCommon.GetBootloaderDevices ) disks_to_rewrite = Convert.convert( Builtins.toset( Builtins.merge( grub_getMbrsToRewrite, Builtins.merge( [BootCommon.mbrDisk], BootCommon.GetBootloaderDevices ) ) ), :from => "list", :to => "list <string>" ) Builtins.y2milestone( "Creating backup of boot sectors of %1", disks_to_rewrite ) backups = disks_to_rewrite.map do |d| ::Bootloader::BootRecordBackup.new(d) end backups.each(&:write) end ret = true # if the bootloader stage 1 is not installed in the MBR, but # ConfigureLocation() asked us to replace some problematic existing # MBR, then overwrite the boot code (only, not the partition list!) in # the MBR with generic (currently DOS?) bootloader stage1 code if generic_mbr && !Builtins.contains( BootCommon.GetBootloaderDevices, BootCommon.mbrDisk ) PackageSystem.Install("syslinux") if !Stage.initial Builtins.y2milestone( "Updating code in MBR: MBR Disk: %1, loader devices: %2", BootCommon.mbrDisk, BootCommon.GetBootloaderDevices ) mbr_type = Ops.get_string( Ops.get(Storage.GetTargetMap, BootCommon.mbrDisk, {}), "label", "" ) Builtins.y2milestone("mbr type = %1", mbr_type) mbr_file = mbr_type == "gpt" ? "/usr/share/syslinux/gptmbr.bin" : "/usr/share/syslinux/mbr.bin" disks_to_rewrite = grub_getMbrsToRewrite Builtins.foreach(disks_to_rewrite) do |d| Builtins.y2milestone("Copying generic MBR code to %1", d) # added fix 446 -> 440 for Vista booting problem bnc #396444 command = Builtins.sformat( "/bin/dd bs=440 count=1 if=%1 of=%2", mbr_file, d ) Builtins.y2milestone("Running command %1", command) out = Convert.to_map( SCR.Execute(path(".target.bash_output"), command) ) exit = Ops.get_integer(out, "exit", 0) Builtins.y2milestone("Command output: %1", out) ret = ret && 0 == exit end end Builtins.foreach(grub_getPartitionsToActivate) do |m_activate| num = Ops.get_integer(m_activate, "num", 0) mbr_dev = Ops.get_string(m_activate, "mbr", "") raise "INTERNAL ERROR: Data for partition to activate is invalid." if num == 0 || mbr_dev.empty? gpt_disk = Storage.GetDisk(Storage.GetTargetMap, BootCommon.mbrDisk)["label"] == "gpt" # if primary partition on old DOS MBR table, GPT do not have such limit if !(Arch.ppc && gpt_disk) && (gpt_disk || num <= 4) Builtins.y2milestone("Activating partition %1 on %2", num, mbr_dev) # FIXME: this is the most rotten code since molded sliced bread # move to bootloader/Core/GRUB.pm or similar # TESTME: make sure that parted does not destroy BSD # slices (#suse24740): cf. section 5.1 of "info parted": # Parted only supports the BSD disk label system. # Parted is unlikely to support the partition slice # system in the future because the semantics are rather # strange, and don't work like "normal" partition tables # do. # FIXED: investigate proper handling of the activate flag # (kernel ioctls in parted etc.) and fix parted # this is needed only on gpt disks but we run it always # anyway; parted just fails, then command = Builtins.sformat( "/usr/sbin/parted -s %1 set %2 legacy_boot on", mbr_dev, num ) Builtins.y2milestone("Running command %1", command) out = Convert.to_map( WFM.Execute(path(".local.bash_output"), command) ) Builtins.y2milestone("Command output: %1", out) command = Builtins.sformat( "/usr/sbin/parted -s %1 set %2 boot on", mbr_dev, num ) Builtins.y2milestone("Running command %1", command) out = Convert.to_map( WFM.Execute(path(".local.bash_output"), command) ) exit = Ops.get_integer(out, "exit", 0) Builtins.y2milestone("Command output: %1", out) ret = ret && 0 == exit end end if activate ret end |
- (Object) initialize_bootloader_grub2_misc(include_target)
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'src/include/bootloader/grub2/misc.rb', line 26 def initialize_bootloader_grub2_misc(include_target) textdomain "bootloader" Yast.import "Arch" Yast.import "BootCommon" Yast.import "BootStorage" Yast.import "Map" Yast.import "Mode" Yast.import "PackageSystem" Yast.import "Partitions" Yast.import "Storage" Yast.import "StorageDevices" end |
- (Boolean) ReduceDeviceMapTo8
FATE #303548 - Grub: limit device.map to devices detected by BIOS Int 13 The function reduces records (devices) in device.map Grub doesn't support more than 8 devices in device.map
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
# File 'src/include/bootloader/grub2/misc.rb', line 958 def ReduceDeviceMapTo8 result = false if Ops.greater_than(Builtins.size(BootStorage.device_mapping), 8) result = true bios_order = Convert.convert( Map.Values(BootStorage.device_mapping), :from => "list", :to => "list <string>" ) #delete all grub devices with order more than 9 bios_order = Builtins.filter(bios_order) do |key| Ops.less_than(Builtins.size(key), 4) end bios_order = Builtins.lsort(bios_order) Builtins.y2debug("ordered values (grub devices): %1", bios_order) inverse_device_map = {} new_device_map = {} Builtins.y2milestone( "Device map before reducing: %1", BootStorage.device_mapping ) Builtins.foreach(BootStorage.device_mapping) do |key, value| Ops.set(inverse_device_map, value, key) end Builtins.y2debug("inverse_device_map: %1", inverse_device_map) index = 0 Builtins.foreach(bios_order) do |key| device_name = Ops.get(inverse_device_map, key, "") if Ops.less_than(index, 8) Builtins.y2debug( "adding device: %1 with key: %2 and index is: %3", device_name, key, index ) Ops.set(new_device_map, device_name, key) index = Ops.add(index, 1) else raise Break end end BootStorage.device_mapping = deep_copy(new_device_map) Builtins.y2milestone( "Device map after reducing: %1", BootStorage.device_mapping ) else Builtins.y2milestone( "Device map includes less than 9 devices. It is not reduced. device_map: %1", BootStorage.device_mapping ) end result end |
- (Object) SetBootloaderDevice(selected_location)
SetBootloaderDevice() Set “boot_*” flags in the globals map according to the boot device selected with parameter selected_location. Only a single boot device can be selected with this function. The function cannot be used to set a custom boot device. It will always be deleted.
FIXME: `mbr_md is probably unneeded; AFA we can see, this decision is automatic anyway and perl-Bootloader should be able to make it without help from the user or the proposal.
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'src/include/bootloader/grub2/misc.rb', line 389 def SetBootloaderDevice(selected_location) # first, default to all off: Builtins.foreach(["boot_boot", "boot_root", "boot_mbr", "boot_extended"]) do |flag| Ops.set(BootCommon.globals, flag, "false") end # need to remove the boot_custom key to switch this value off if Builtins.haskey(BootCommon.globals, "boot_custom") BootCommon.globals = Builtins.remove(BootCommon.globals, "boot_custom") end if selected_location == :root Ops.set(BootCommon.globals, "boot_root", "true") elsif selected_location == :boot Ops.set(BootCommon.globals, "boot_boot", "true") elsif selected_location == :mbr Ops.set(BootCommon.globals, "boot_mbr", "true") # Disable generic MBR as we want grub2 there Ops.set(BootCommon.globals, "generic_mbr", "false") elsif selected_location == :extended Ops.set(BootCommon.globals, "boot_extended", "true") end nil end |
- (String) soft_MDraid_boot_disk(partitions)
function check all partitions and it tries to find /boot partition if it is MD Raid and soft-riad return correct device for analyse MBR
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'src/include/bootloader/grub2/misc.rb', line 418 def soft_MDraid_boot_disk(partitions) partitions = deep_copy(partitions) result = "" boot_device = "" if BootStorage.BootPartitionDevice != nil && BootStorage.BootPartitionDevice != "" boot_device = BootStorage.BootPartitionDevice else boot_device = BootStorage.RootPartitionDevice end Builtins.foreach(partitions) do |p| if Ops.get_string(p, "device", "") == boot_device if Ops.get(p, "type") == :sw_raid && Builtins.tolower(Ops.get_string(p, "fstype", "")) == "md raid" device_1 = Ops.get_string(p, ["devices", 0], "") Builtins.y2debug("device_1: %1", device_1) dp = Storage.GetDiskPartition(device_1) Builtins.y2debug("dp: %1", dp) result = Ops.get_string(dp, "disk", "") end end end Builtins.y2milestone( "Device for analyse MBR from soft-raid (MD-Raid only): %1", result ) result end |