Skip to content

Commit

Permalink
WIP for working RAID
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Dec 21, 2017
1 parent 859f01a commit 0c17032
Show file tree
Hide file tree
Showing 16 changed files with 252 additions and 753 deletions.
12 changes: 6 additions & 6 deletions src/lib/bootloader/autoyast_converter.rb
Expand Up @@ -124,10 +124,10 @@ def import_device_map(data, bootloader)
end

STAGE1_DEVICES_MAPPING = {
"boot_root" => :root_partition,
"boot_boot" => :boot_partition,
"boot_mbr" => :mbr_disk,
"boot_extended" => :extended_partition
"boot_root" => :boot_devices,
"boot_boot" => :boot_devices,
"boot_mbr" => :mbr_devices,
"boot_extended" => :boot_devices
}.freeze
def import_stage1(data, bootloader)
return unless bootloader.name == "grub2"
Expand Down Expand Up @@ -156,9 +156,9 @@ def import_stage1_devices(data, stage1)
raise "boot_extended used in autoyast profile, but there is no extended partition"
end

STAGE1_DEVICES_MAPPING.each do |key, device|
STAGE1_DEVICES_MAPPING.each do |key, method|
if data["global"][key] == "true" || data["boot_#{key}"]
stage1.add_udev_device(Yast::BootStorage.public_send(device).name)
stage1.add_udev_device(stage1.public_send(device))
end
end

Expand Down
6 changes: 0 additions & 6 deletions src/lib/bootloader/boot_record_backup.rb
Expand Up @@ -47,12 +47,6 @@ def write
# save MBR to yast2 log directory
logs_path = "/var/log/YaST2/" + device_file
copy_br(device, logs_path)

# special backup only if device is mbr disk
Yast.import "BootStorage"
return if device != Yast::BootStorage.mbr_disk.name

copy_br(device, "/boot/backup_mbr")
end

# Restore backup
Expand Down
4 changes: 2 additions & 2 deletions src/lib/bootloader/config_dialog.rb
Expand Up @@ -44,9 +44,9 @@ def guarded_run

# F#300779 - Install diskless client (NFS-root)
# additional warning that root partition is nfs type -> bootloader will not be installed
device = Yast::BootStorage.disk_with_boot_partition.name
nfs = Yast::BootStorage.boot_mountpoint.is?(:nfs)

if device == "/dev/nfs" && Yast::Mode.installation
if nfs && Yast::Mode.installation
Yast::Popup.Message(
_(
"The boot partition is of type NFS. Bootloader cannot be installed."
Expand Down
86 changes: 2 additions & 84 deletions src/lib/bootloader/device_map.rb
@@ -1,7 +1,6 @@
require "yast"

require "bootloader/udev_mapping"
require "bootloader/stage1_device"

require "yast2/target_file"
require "cfa/grub2/device_map"
Expand Down Expand Up @@ -118,80 +117,20 @@ def order_boot_device
# For us priority disk is device where /boot or / lives as we control this disk and
# want to modify its MBR. So we get disk of such partition and change order to add it
# to top of device map. For details see bnc#887808,bnc#880439
boot_disk = Yast::BootStorage.disk_with_boot_partition
priority_disks = ::Bootloader::Stage1Device.new(boot_disk.name).real_devices
priority_disks = Yast::BootStorage.boot_disks
# if none of priority disk is hd0, then choose one and assign it
return if any_first_device?(priority_disks)

change_order(priority_disks.first)
end

def fill_mapping
# storage-ng
# BIOS-ID is not supported in libstorage-ng, so let's simply create a
# mapping entry per disk for the time being (see commented code for the
# real expected behavior)
# mapping entry per disk for the time being and then ensure pick priority one
staging = Y2Storage::StorageManager.instance.staging
staging.disk_devices.each_with_index do |disk, index|
add_mapping("hd#{index}", disk.name)
end
# rubocop:disable Style/BlockComments
=begin
target_map = filtered_target_map
log.info("Filtered target map: #{target_map}")
# add devices with known bios_id
# collect BIOS IDs which are used
ids = {}
target_map.each do |target_dev, target|
bios_id = target["bios_id"] || ""
next if bios_id.empty?
index = if Yast::Arch.x86_64 || Yast::Arch.i386
# it looks like 0x81. It is boot drive unit see http://en.wikipedia.org/wiki/Master_boot_record
bios_id[2..-1].to_i(16) - 0x80
else
raise "no support for bios id '#{bios_id}' on #{Yast::Arch.architecture}"
end
# FATE #303548 - doesn't add disk with same bios_id with different name (multipath machine)
if !ids[index]
add_mapping("hd#{index}", target_dev)
ids[index] = true
end
end
# and guess other devices
# don't use already used BIOS IDs
target_map.each do |target_dev, target|
next unless target.fetch("bios_id", "").empty?
index = 0 # find free index
index += 1 while ids[index]
add_mapping("hd#{index}", target_dev)
ids[index] = true
end
log.info "complete initial device map filling: #{self}"
=end
end

def filtered_target_map
target_map = Yast::Storage.GetTargetMap.dup

# select only disk devices
target_map.select! do |_k, v|
[:CT_DMRAID, :CT_DISK, :CT_DMMULTIPATH].include?(v["type"]) ||
(v["type"] == :CT_MDPART &&
mdraid_on_disk?(v["devices"] || [], target_map))
end

# filter out members of BIOS RAIDs and multipath devices
target_map.delete_if do |k, v|
[:UB_DMRAID, :UB_DMMULTIPATH].include?(v["used_by_type"]) ||
(v["used_by_type"] == :UB_MDPART && disk_in_mdraid?(k, target_map))
end

target_map
end

# Returns true if any device from list devices is in device_mapping
Expand Down Expand Up @@ -219,26 +158,5 @@ def change_order(priority_device)
# if bios_id is defined, but not for 0x80
add_mapping(grub_dev, replaced_dev) if replaced_dev
end

# Check if MD raid is build on disks not on paritions
# @param [Array<String>] devices - list of devices from MD raid
# @param [Hash{String => map}] tm - unfiltered target map
# @return - true if MD RAID is build on disks (not on partitions)
def mdraid_on_disk?(devices, tm)
devices.all? do |key|
key == "" || tm[key]
end
end

# Check if disk is in MDRaid it means completed disk is used in RAID
# @param [String] disk (/dev/sda)
# @param [Hash{String => map}] tm - target map
# @return - true if disk (not only part of disk) is in MDRAID
def disk_in_mdraid?(disk, tm)
tm.values.any? do |disk_info|
disk_info["type"] == :CT_MDPART &&
(disk_info["devices"] || []).include?(disk)
end
end
end
end
2 changes: 0 additions & 2 deletions src/lib/bootloader/device_map_dialog.rb
Expand Up @@ -157,8 +157,6 @@ def available_devices
end

def store_order
Yast::BootStorage.assign_mbr_disk_by_name(disks.first)

@device_map.clear_mapping
disks.each_with_index do |disk, index|
@device_map.add_mapping("hd#{index}", disk)
Expand Down
45 changes: 8 additions & 37 deletions src/lib/bootloader/grub2.rb
Expand Up @@ -184,34 +184,18 @@ def disk_order_summary
def locations
locations = []

partition_location = boot_partition_location
locations << partition_location unless partition_location.empty?
if stage1.extended_partition?
# TRANSLATORS: extended is here for extended partition. Keep translation short.
locations << Yast::BootStorage.extended_partition.name + _(" (extended)")
end
partition_location = Yast::BootStorage.boot_partitions.map(&:name).join(", ")
locations << partition_location + _(" (/boot)") unless partition_location.empty?
if stage1.mbr?
# TRANSLATORS: MBR is acronym for Master Boot Record, if nothing locally specific
# is used in your language, then keep it as it is.
locations << Yast::BootStorage.mbr_disk.name + _(" (MBR)")
locations << Yast::BootStorage.boot_disks.map(&:name) + _(" (MBR)")
end
locations << stage1.custom_devices if !stage1.custom_devices.empty?

locations
end

def boot_partition_location
if Yast::BootStorage.separated_boot?
if stage1.boot_partition?
return Yast::BootStorage.boot_partition.name + " (\"/boot\")"
end
elsif stage1.root_partition?
return Yast::BootStorage.root_partition.name + " (\"/\")"
end

""
end

def mbr_line
if stage1.mbr?
_(
Expand All @@ -225,28 +209,15 @@ def mbr_line
end

def partition_line
# check for separated boot partition, use root otherwise
if Yast::BootStorage.separated_boot?
if stage1.boot_partition?
_(
"Install bootcode into /boot partition " \
"(<a href=\"disable_boot_boot\">do not install</a>)"
)
else
_(
"Do not install bootcode into /boot partition " \
"(<a href=\"enable_boot_boot\">install</a>)"
)
end
elsif stage1.root_partition?
if stage1.boot_partition?
_(
"Install bootcode into \"/\" partition " \
"(<a href=\"disable_boot_root\">do not install</a>)"
"Install bootcode into partition " \
"(<a href=\"disable_boot_boot\">do not install</a>)"
)
else
_(
"Do not install bootcode into \"/\" partition " \
"(<a href=\"enable_boot_root\">install</a>)"
"Do not install bootcode into partition " \
"(<a href=\"enable_boot_boot\">install</a>)"
)
end
end
Expand Down
31 changes: 15 additions & 16 deletions src/lib/bootloader/grub2_widgets.rb
Expand Up @@ -708,32 +708,33 @@ def handle(event)
end

def init
if locations[:boot]
if locations.include?(:boot)
Yast::UI.ChangeWidget(Id(:boot), :Value, stage1.boot_partition?)
end
if locations[:root]
Yast::UI.ChangeWidget(Id(:root), :Value, stage1.root_partition?)
end
if locations[:extended]
Yast::UI.ChangeWidget(Id(:extended), :Value, stage1.extended_partition?)
end
Yast::UI.ChangeWidget(Id(:mbr), :Value, stage1.mbr?) if locations[:mbr]
Yast::UI.ChangeWidget(Id(:mbr), :Value, stage1.mbr?) if locations.include?(:mbr)

init_custom_devices(stage1.custom_devices)
end

def store
locations = stage1.available_locations
stage1.clear_devices
locations.each_pair do |id, dev|
stage1.add_udev_device(dev) if Yast::UI.QueryWidget(Id(id), :Value)
locations.each do |id|
next unless Yast::UI.QueryWidget(Id(id), :Value)

case id
when :boot
stage1.boot_devices.each { |d| stage1.add_udev_device(d) }
when :mbr
stage1.mbr_devices.each { |d| stage1.add_udev_device(d) }
end
end

return unless Yast::UI.QueryWidget(:custom, :Value)

devs = Yast::UI.QueryWidget(:custom_list, :Value)
devs.split(",").each do |dev|
stage1.add_udev_device(dev.strip)
# add it exactly how user specify
stage1.add_device(dev.strip)
end
end

Expand Down Expand Up @@ -769,10 +770,8 @@ def locations

def location_checkboxes
checkboxes = []
checkboxes << checkbox(:boot, _("Boo&t from Boot Partition")) if locations[:boot]
checkboxes << checkbox(:root, _("Boo&t from Root Partition")) if locations[:root]
checkboxes << checkbox(:mbr, _("Boot from &Master Boot Record")) if locations[:mbr]
checkboxes << checkbox(:extended, _("Boot from &Extended Partition")) if locations[:extended]
checkboxes << checkbox(:boot, _("Boo&t from Partition")) if locations.include?(:boot)
checkboxes << checkbox(:mbr, _("Boot from &Master Boot Record")) if locations.include?(:mbr)

checkboxes.concat(custom_partition_content)
end
Expand Down
28 changes: 12 additions & 16 deletions src/lib/bootloader/grub2efi.rb
Expand Up @@ -4,10 +4,10 @@
require "bootloader/grub2base"
require "bootloader/grub_install"
require "bootloader/sysconfig"
require "bootloader/stage1_device"
require "y2storage"

Yast.import "Arch"
Yast.import "BootStorage"

module Bootloader
# Represents grub2 bootloader with efi target
Expand Down Expand Up @@ -35,25 +35,21 @@ def write
# super have to called as first as grub install require some config written in ancestor
super

if pmbr_action && Yast::BootStorage.gpt_boot_disk?
efi_partition = filesystems.find { |f| f.mountpoint == "/boot/efi" }
efi_partition ||= filesystems.find { |f| f.mountpoint == "/boot" }
efi_partition ||= filesystems.find { |f| f.mountpoint == "/" }
if pmbr_action
fs = filesystems
efi_partition = fs.find { |f| f.mountpoint == "/boot/efi" }
efi_partition ||= fs.find { |f| f.mountpoint == "/boot" }
efi_partition ||= fs.find { |f| f.mountpoint == "/" }

raise "could not find boot partiton" unless efi_partition

efi_partition = efi_partition.plain_blk_devices.first
disks = Yast::BootStorage.stage1_disks_for(efi_partition)
# set only gpt disks
disks.select! do { |disk| disk.gpt? }

efi_disk = efi_partition.disk

# storage-ng
# rubocop:disable Style/BlockComments
=begin
# get underlaying disk as it have to be set there and not on virtual one (bnc#981977)
device = ::Bootloader::Stage1Device.new(efi_disk)
=end

pmbr_setup(efi_disk.name)
disks.each do |efi_disk|
pmbr_setup(efi_disk.name)
end
end

@grub_install.execute(secure_boot: @secure_boot, trusted_boot: trusted_boot)
Expand Down

0 comments on commit 0c17032

Please sign in to comment.