Class: Yast::BootStorageClass
- Inherits:
-
Module
- Object
- Module
- Yast::BootStorageClass
- Includes:
- Logger
- Defined in:
- src/modules/BootStorage.rb
Instance Attribute Summary (collapse)
-
- (Object) device_map
Returns the value of attribute device_map.
Instance Method Summary (collapse)
-
- (Object) available_swap_partitions
Get map of swap partitions.
- - (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) DisksOrder
Get the order of disks according to BIOS mapping.
-
- (Object) extended_partition_for(device)
Get extended partition for given partition or 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) device_map
Returns the value of attribute device_map
28 29 30 |
# File 'src/modules/BootStorage.rb', line 28 def device_map @device_map end |
Instance Method Details
- (Object) available_swap_partitions
Get map of swap partitions
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
# File 'src/modules/BootStorage.rb', line 481 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 |
- (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
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'src/modules/BootStorage.rb', line 104 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.
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 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
# File 'src/modules/BootStorage.rb', line 418 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) if BootCommon.mbrDisk == "" || BootCommon.mbrDisk.nil? # mbr detection. BootCommon.mbrDisk = BootCommon.FindMBRDisk end # device map may be implicitly proposed in FindMBRDisk above # - but not always... device_map.propose if device_map.empty? # 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. bldevs = BootCommon.GetBootloaderDevices return :empty if bldevs.empty? all_boot_partitions = possible_locations_for_stage1 invalid = bldevs.any? do |dev| !all_boot_partitions.include?(dev) end invalid ? :invalid : :ok 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) DisksOrder
Get the order of disks according to BIOS mapping
187 188 189 190 191 |
# File 'src/modules/BootStorage.rb', line 187 def DisksOrder @device_map.propose if @device_map.empty? @device_map.disks_order 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) InitDiskInfo
Function init data for perl-Bootloader about disk It means fullfil md_info, multipath_mapping, partinfo and mountpoints
129 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'src/modules/BootStorage.rb', line 129 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
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 70 71 72 73 74 |
# File 'src/modules/BootStorage.rb', line 30 def main textdomain "bootloader" Yast.import "BootCommon" 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 = {} # device mapping between Linux and firmware @device_map = ::Bootloader::DeviceMap.new # 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
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'src/modules/BootStorage.rb', line 84 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
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 228 229 |
# File 'src/modules/BootStorage.rb', line 195 def possible_locations_for_stage1 devices = Storage.GetTargetMap all_disks = devices.keys # Devices which is not in device map cannot be used to boot all_disks.select! { |d| device_map.contain_disk?(d) } 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
464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
# File 'src/modules/BootStorage.rb', line 464 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 |