Class: Yast::BootStorageClass
- Inherits:
-
Module
- Object
- Module
- Yast::BootStorageClass
- Includes:
- Logger
- Defined in:
- src/modules/BootStorage.rb
Instance Attribute Summary (collapse)
-
- (Object) mbr_disk
Returns the value of attribute mbr_disk.
Instance Method Summary (collapse)
-
- (Object) available_swap_partitions
Get map of swap partitions.
-
- (Boolean) bootloader_installable?
FIXME: merge with BootSupportCheck Check if the bootloader can be installed at all with current configuration.
- - (Object) can_boot_from_partition
-
- (Object) checkCallingDiskInfo
Check if function was called or storage change partitionig of disk.
-
- (Boolean) checkDifferentDisks(devices)
FATE#305008: Failover boot configurations for md arrays with redundancy Check if devices has same partition number and if they are from different disks.
-
- (Object) checkMDDevices(tm, device)
FATE#305008: Failover boot configurations for md arrays with redundancy Check if device are build from 2 partitions with same number but from different disks.
-
- (Object) detect_disks
Sets properly boot, root and mbr disk.
-
- (Array) devices_for_redundant_boot
FATE#305008: Failover boot configurations for md arrays with redundancy Function check partitions and set redundancy available if partitioning of disk allows it.
- - (Object) disk_with_boot_partition
- - (Boolean) encrypted_boot?
-
- (Object) extended_partition_for(device)
Get extended partition for given partition or disk.
- - (Object) find_mbr_disk
- - (Boolean) gpt_boot_disk?
-
- (Object) InitDiskInfo
Function init data for perl-Bootloader about disk It means fullfil md_info, multipath_mapping, partinfo and mountpoints.
- - (Object) main
-
- (Object) mapRealDevicesToMultipath
FIXME: grub only.
-
- (Object) Md2Partitions(md_device)
Converts the md device to the list of devices building it.
-
- (Object) possible_locations_for_stage1
Returns list of partitions and disks.
- - (Object) prep_partitions
-
- (Object) real_disks_for_partition(partition)
returns disk names where partition lives.
Instance Attribute Details
- (Object) mbr_disk
Returns the value of attribute mbr_disk
27 28 29 |
# File 'src/modules/BootStorage.rb', line 27 def mbr_disk @mbr_disk end |
Instance Method Details
- (Object) available_swap_partitions
Get map of swap partitions
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
# File 'src/modules/BootStorage.rb', line 537 def available_swap_partitions tm = Storage.GetTargetMap ret = {} tm.each_value do |v| partitions = v["partitions"] || [] partitions.select! do |p| p["mount"] == "swap" && !p["delete"] end partitions.each do |s| # bnc#577127 - Encrypted swap is not properly set up as resume device if s["crypt_device"] && !s["crypt_device"].empty? dev = s["crypt_device"] else dev = s["device"] end ret[dev] = s["size_k"] || 0 end end log.info "Available swap partitions: #{ret}" ret end |
- (Boolean) bootloader_installable?
FIXME: merge with BootSupportCheck Check if the bootloader can be installed at all with current configuration
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
# File 'src/modules/BootStorage.rb', line 431 def bootloader_installable? return true if Mode.config return true if !Arch.i386 && !Arch.x86_64 # the only relevant is the partition holding the /boot filesystem detect_disks Builtins.y2milestone( "Boot partition device: %1", BootStorage.BootPartitionDevice ) dev = Storage.GetDiskPartition(BootStorage.BootPartitionDevice) Builtins.y2milestone("Disk info: %1", dev) # MD, but not mirroring is OK # FIXME: type detection by name deprecated if Ops.get_string(dev, "disk", "") == "/dev/md" tm = Storage.GetTargetMap md = Ops.get_map(tm, "/dev/md", {}) parts = Ops.get_list(md, "partitions", []) info = {} Builtins.foreach(parts) do |p| if Ops.get_string(p, "device", "") == BootStorage.BootPartitionDevice info = deep_copy(p) end end if Builtins.tolower(Ops.get_string(info, "raid_type", "")) != "raid1" Builtins.y2milestone( "Cannot install bootloader on RAID (not mirror)" ) return false end # EVMS # FIXME: type detection by name deprecated elsif Builtins.search(BootPartitionDevice(), "/dev/evms/") == 0 Builtins.y2milestone("Cannot install bootloader on EVMS") return false end true end |
- (Object) can_boot_from_partition
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'src/modules/BootStorage.rb', line 313 def can_boot_from_partition tm = Storage.GetTargetMap partition = @BootPartitionDevice || @RootPartitionDevice part = Storage.GetPartition(tm, partition) if !part log.error "cannot find partition #{partition}" return false end fs = part["used_fs"] log.info "FS for boot partition #{fs}" # cannot install stage one to xfs as it doesn't have reserved space (bnc#884255) fs != :xfs end |
- (Object) checkCallingDiskInfo
Check if function was called or storage change partitionig of disk. It is usefull fo using cached data about disk. Data is send to perl-Bootloader and it includes info about partitions, multi path and md-raid
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'src/modules/BootStorage.rb', line 114 def checkCallingDiskInfo # fix for problem with unintialized storage library in AutoYaST mode # bnc #464090 if Mode.config && !@storage_initialized @storage_initialized = true log.info "Init storage library in yast2-bootloader" Storage.InitLibstorage(true) end if @disk_change_time_checkCallingDiskInfo != Storage.GetTargetChangeTime || @partinfo.empty? # save last change time from storage @disk_change_time_checkCallingDiskInfo = Storage.GetTargetChangeTime log.info "disk was changed by storage or partinfo is empty" log.info "generate partinfo, md_info, mountpoints and multipath_mapping" return true else log.info "Skip genarating partinfo, md_info, mountpoints and multipath_mapping" return false end end |
- (Boolean) checkDifferentDisks(devices)
FATE#305008: Failover boot configurations for md arrays with redundancy Check if devices has same partition number and if they are from different disks
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 |
# File 'src/modules/BootStorage.rb', line 250 def checkDifferentDisks(devices) disks = [] no_partition = "" devices.each do |dev| p_dev = Storage.GetDiskPartition(dev) disk = p_dev["disk"] if disks.include?(disk) log.info "Same disk for md array -> disable synchronize md arrays" return false else disks << disk end # add disk from partition to md_physical_disks @md_physical_disks << disk unless @md_physical_disks.include?(disk) no_p = p_dev["nr"].to_s if no_p == "" log.error "Wrong number of partition: #{dev} from Storage::GetDiskPartition: #{p_dev}" return false end if no_partition == "" no_partition = no_p elsif no_partition != no_p log.info "Different number of partitions -> disable synchronize md arrays" return false end end true end |
- (Object) checkMDDevices(tm, device)
FATE#305008: Failover boot configurations for md arrays with redundancy Check if device are build from 2 partitions with same number but from different disks
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 |
# File 'src/modules/BootStorage.rb', line 287 def checkMDDevices(tm, device) ret = false tm_dm = tm["/dev/md"] || {} # find partitions in target map (tm_dm["partitions"] || []).each do |p| next unless p["device"] == device if p["raid_type"] == "raid1" p_devices = p["devices"] || [] if p_devices.size == 2 # TODO: why only 2? it do not make sense ret = checkDifferentDisks(p_devices) else log.info "Device: #{device} doesn't contain 2 partitions: #{p_devices}" end else log.info "Device: #{device} is not on raid1: #{p["raid_type"]}" end end log.info "device: #{device} is based on md_physical_disks: #{@md_physical_disks}"\ "is #{ret ? "valid" : "invalid"} for enable redundancy" ret end |
- (Object) detect_disks
Sets properly boot, root and mbr disk.
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
# File 'src/modules/BootStorage.rb', line 474 def detect_disks # The AutoYaST config mode does access to the system. # bnc#942360 return :ok if Mode.config mp = Storage.GetMountPoints mountdata_boot = mp["/boot"] || mp["/"] mountdata_root = mp["/"] log.info "mountPoints #{mp}" log.info "mountdata_boot #{mountdata_boot}" @RootPartitionDevice = mountdata_root ? mountdata_root.first || "" : "" raise "No mountpoint for / !!" if @RootPartitionDevice.empty? # if /boot changed, re-configure location @BootPartitionDevice = mountdata_boot.first # get extended partition device (if exists) @ExtendedPartitionDevice = extended_partition_for(@BootPartitionDevice) @mbr_disk = find_mbr_disk end |
- (Array) devices_for_redundant_boot
FATE#305008: Failover boot configurations for md arrays with redundancy Function check partitions and set redundancy available if partitioning of disk allows it. It means if md array is based on 2 partitions with same number but 2 different disks E.g. /dev/md0 is from /dev/sda1 and /dev/sb1 and /dev/md0 is “/” There is possible only boot from MBR (GRUB not generic boot code)
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 |
# File 'src/modules/BootStorage.rb', line 340 def devices_for_redundant_boot tm = Storage.GetTargetMap if !tm["/dev/md"] log.info "Doesn't include md raid" return [] end boot_devices = [@BootPartitionDevice] if @BootPartitionDevice != @RootPartitionDevice boot_devices << @RootPartitionDevice end boot_devices << @ExtendedPartitionDevice boot_devices.delete_if { |d| d.nil? || d.empty? } log.info "Devices for analyse of redundacy md array: #{boot_devices}" boot_devices.each do |dev| ret = checkMDDevices(tm, dev) # only log if device is not suitable, otherwise md redundancy is not # allowed even if there is some suitable device (bnc#917025) log.info "Skip enable redundancy for device #{dev}" unless ret end @md_physical_disks end |
- (Object) disk_with_boot_partition
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
# File 'src/modules/BootStorage.rb', line 514 def disk_with_boot_partition boot_device = BootPartitionDevice() if boot_device.empty? log.error "BootPartitionDevice and RootPartitionDevice are empty" return boot_device end p_dev = Storage.GetDiskPartition(boot_device) boot_disk_device = p_dev["disk"] if boot_disk_device && !boot_disk_device.empty? log.info "Boot device - disk: #{boot_disk_device}" return boot_disk_device end log.error("Finding boot disk failed!") "" end |
- (Boolean) encrypted_boot?
560 561 562 563 564 565 566 567 568 569 570 571 |
# File 'src/modules/BootStorage.rb', line 560 def encrypted_boot? dev = BootPartitionDevice() tm = Yast::Storage.GetTargetMap || {} tm.each_value do |v| partitions = v["partitions"] || [] partition = partitions.find { |p| p["device"] == dev || p["crypt_device"] == dev } next unless partition return partition["crypt_device"] && !partition["crypt_device"].empty? end end |
- (Object) extended_partition_for(device)
Get extended partition for given partition or disk
232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'src/modules/BootStorage.rb', line 232 def extended_partition_for(device) disk_partition = Yast::Storage.GetDiskPartition(device) return nil unless disk_partition["disk"] target_map = Yast::Storage.GetTargetMap disk_map = target_map[disk_partition["disk"]] || {} partitions = disk_map["partitions"] || [] ext_part = partitions.find { |p| p["type"] == :extended } return nil unless ext_part ext_part["device"] end |
- (Object) find_mbr_disk
415 416 417 418 419 420 421 422 423 424 425 426 |
# File 'src/modules/BootStorage.rb', line 415 def find_mbr_disk # use the disk with boot partition mp = Storage.GetMountPoints boot_disk = Ops.get_string( mp, ["/boot", 2], Ops.get_string(mp, ["/", 2], "") ) log.info "Disk with boot partition: #{boot_disk}, using for MBR" boot_disk end |
- (Boolean) gpt_boot_disk?
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'src/modules/BootStorage.rb', line 92 def gpt_boot_disk? require "bootloader/bootloader_factory" current_bl = ::Bootloader::BootloaderFactory.current # efi require gpt disk, so it is always one return true if current_bl.name == "grub2efi" # if bootloader do not know its location, then we do not care return false unless current_bl.respond_to?(:stage1) targets = current_bl.stage1.devices target_map = Yast::Storage.GetTargetMap boot_discs = targets.map { |d| Yast::Storage.GetDisk(target_map, d) } boot_discs.any? { |d| d["label"] == "gpt" } end |
- (Object) InitDiskInfo
Function init data for perl-Bootloader about disk It means fullfil md_info, multipath_mapping, partinfo and mountpoints
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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'src/modules/BootStorage.rb', line 139 def InitDiskInfo return unless checkCallingDiskInfo # delete variables for perl-Bootloader @md_info = {} tm = Storage.GetTargetMap @multipath_mapping = mapRealDevicesToMultipath @mountpoints = Builtins.mapmap(Storage.GetMountPoints) do |k, v| # detect all raid1 md devices and mark them in md_info device = v[0] @md_info[device] = [] if v[3] == "raid1" { k => device } end # filter out temporary mount points from installation tmpdir = SCR.Read(path(".target.tmpdir")) @mountpoints = Builtins.filter(@mountpoints) do |k, v| v.is_a?(::String) && !k.start_with?(tmpdir) end log.info "Detected mountpoints: #{@mountpoints}" @partinfo = tm.reduce([]) do |res, i| disk, info = i next res if [:CT_LVM, :CT_EVMS].include?(info["type"]) partitions = info["partitions"] # disk do not have to be partitioned, so skip it in such case next res unless partitions parts = partitions.map do |p| raid = p["used_by_type"] == :UB_MD ? p["used_by_device"] : nil device = p["device"] || "" # We only pass along RAID1 devices as all other causes # severe breakage in the bootloader stack @md_info[raid] << device if raid && @md_info.include?(raid) nr = (p["nr"] || 0).to_s region = p.fetch("region", []) [ device, disk, nr, p["fsid"].to_i.to_s, p["fstype"] || "unknown", p["type"] || "nil", (region[0] || 0).to_s, (region[1] || 0).to_s, ::Bootloader::UdevMapping.to_mountby_device(device) ] end res.concat(parts) end end |
- (Object) main
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'src/modules/BootStorage.rb', line 29 def main textdomain "bootloader" Yast.import "Storage" Yast.import "StorageDevices" Yast.import "Arch" Yast.import "Mode" # Saved change time from target map - only for checkCallingDiskInfo() @disk_change_time_checkCallingDiskInfo = nil # Storage locked @storage_initialized = false # device mapping between real devices and multipath @multipath_mapping = {} # mountpoints for perl-Bootloader @mountpoints = {} # list of all partitions for perl-Bootloader @partinfo = [] # information about MD arrays for perl-Bootloader @md_info = {} # string sepresenting device name of /boot partition # same as RootPartitionDevice if no separate /boot partition @BootPartitionDevice = "" # string representing device name of / partition @RootPartitionDevice = "" # string representing device name of extended partition @ExtendedPartitionDevice = "" # FATE#305008: Failover boot configurations for md arrays with redundancy # list <string> includes physical disks used for md raid @md_physical_disks = [] end |
- (Object) mapRealDevicesToMultipath
FIXME: grub only
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'src/modules/BootStorage.rb', line 79 def mapRealDevicesToMultipath ret = {} tm = Storage.GetTargetMap tm.each do |disk, disk_info| next if disk_info["type"] != :CT_DMMULTIPATH devices = disk_info["devices"] || [] devices.each { |d| ret[d] = disk } end ret end |
- (Object) Md2Partitions(md_device)
Converts the md device to the list of devices building it
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
# File 'src/modules/BootStorage.rb', line 371 def Md2Partitions(md_device) ret = {} tm = Storage.GetTargetMap tm.each_pair do |_disk, descr| bios_id = (descr["bios_id"] || 256).to_i # maximum + 1 (means: no bios_id found) partitions = descr["partitions"] || [] partitions.each do |partition| if partition["used_by_device"] == md_device ret[partition["device"]] = bios_id end end end log.info "Partitions building #{md_device}: #{ret}" ret end |
- (Object) possible_locations_for_stage1
Returns list of partitions and disks. Requests current partitioning from yast2-storage and creates list of partition and disks usable for grub stage1
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 228 229 |
# File 'src/modules/BootStorage.rb', line 197 def possible_locations_for_stage1 devices = Storage.GetTargetMap all_disks = devices.keys disks_for_stage1 = all_disks.select do |d| [:CT_DISK, :CR_DMRAID].include?(devices[d]["type"]) end partitions = [] devices.each do |k, v| next unless all_disks.include?(k) partitions.concat(v["partitions"] || []) end partitions.delete_if do |p| p["delete"] end partitions.select! do |p| [:primary, :extended, :logical, :sw_raid].include?(p["type"]) && (p["used_fs"] || p["detected_fs"]) != :xfs && ["Linux native", "Extended", "Linux RAID", "MD RAID", "DM RAID"].include?(p["fstype"]) end res = partitions.map { |p| p["device"] || "" } res.concat(disks_for_stage1) res.delete_if(&:empty?) res end |
- (Object) prep_partitions
499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'src/modules/BootStorage.rb', line 499 def prep_partitions target_map = Storage.GetTargetMap partitions = target_map.reduce([]) do |parts, pair| parts.concat(pair[1]["partitions"] || []) end prep_partitions = partitions.select do |partition| [0x41, 0x108].include? partition["fsid"] end y2milestone "detected prep partitions #{prep_partitions.inspect}" prep_partitions.map { |p| p["device"] } end |
- (Object) real_disks_for_partition(partition)
returns disk names where partition lives
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'src/modules/BootStorage.rb', line 389 def real_disks_for_partition(partition) # FIXME: handle somehow if disk are in logical raid partitions = Md2Partitions(partition).keys partitions = [partition] if partitions.empty? res = partitions.map do |part| Storage.GetDiskPartition(part)["disk"] end res.uniq! # handle LVM disks tm = Storage.GetTargetMap res = res.each_with_object([]) do |disk, ret| = tm[disk] next unless if ["lvm2"] devices = (["devices"] || []) + (["devices_add"] || []) disks = devices.map { |d| real_disks_for_partition(d) } ret.concat(disks.flatten) else ret << disk end end res.uniq end |