Class: Yast::BootStorageClass

Inherits:
Module
  • Object
show all
Includes:
Logger
Defined in:
src/modules/BootStorage.rb

Instance Method Summary collapse

Instance Method Details

#available_swap_partitionsObject

Get map of swap partitions

Returns:

  • a map where key is partition name and value its size in KiB



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'src/modules/BootStorage.rb', line 117

def available_swap_partitions
  ret = {}

  mounted = Y2Storage::MountPoint.find_by_path(staging, Y2Storage::MountPoint::SWAP_PATH.to_s)
  if mounted.empty?
    log.info "No mounted swap found, using fallback."
    staging.filesystems.select { |f| f.type.is?(:swap) }.each do |swap|
      blk_device = swap.blk_devices[0]
      ret[blk_device.name] = blk_device.size.to_i / 1024
    end
  else
    log.info "Mounted swap found: #{mounted.inspect}"
    mounted.each do |mp|
      blk_device = mp.filesystem.blk_devices[0]
      ret[blk_device.name] = blk_device.size.to_i / 1024
    end
  end

  log.info "Available swap partitions: #{ret}"
  ret
end

#boot_disksObject

shortcut to get stage1 disks for /boot



244
245
246
# File 'src/modules/BootStorage.rb', line 244

def boot_disks
  stage1_disks_for(boot_filesystem)
end

#boot_filesystemY2Storage::Filesystem

Moint point for /boot. If there is not separated /boot, / is used instead.

Returns:

  • (Y2Storage::Filesystem)


32
33
34
35
36
# File 'src/modules/BootStorage.rb', line 32

def boot_filesystem
  detect_disks

  @boot_fs
end

#boot_partitionsObject

shortcut to get stage1 partitions for /boot



249
250
251
# File 'src/modules/BootStorage.rb', line 249

def boot_partitions
  stage1_partitions_for(boot_filesystem)
end

#bootloader_installable?Boolean

FIXME: merge with BootSupportCheck Check if the bootloader can be installed at all with current configuration

Returns:

  • (Boolean)

    true if it can



98
99
100
# File 'src/modules/BootStorage.rb', line 98

def bootloader_installable?
  true
end

#encrypted_boot?Boolean

Returns:

  • (Boolean)


146
147
148
149
150
151
152
153
154
155
# File 'src/modules/BootStorage.rb', line 146

def encrypted_boot?
  fs = boot_filesystem
  log.info "boot mp = #{fs.inspect}"
  # check if fs is on an encryption
  result = fs.ancestors.any? { |a| a.is?(:encryption) }

  log.info "encrypted_boot? = #{result}"

  result
end

#extended_for_logical(partition) ⇒ Object

If the passed partition is a logical one (sda7), return its extended "parent" (sda4), otherwise return the argument



205
206
207
# File 'src/modules/BootStorage.rb', line 205

def extended_for_logical(partition)
  partition.type.is?(:logical) ? extended_partition(partition) : partition
end

#gpt_boot_disk?Boolean

Returns if any of boot disks has gpt

Returns:

  • (Boolean)


75
76
77
# File 'src/modules/BootStorage.rb', line 75

def gpt_boot_disk?
  boot_disks.any? { |d| d.gpt? }
end

#gpt_disks(devices) ⇒ Array<String>

Returns detected gpt disks

Parameters:

  • devices (Array<String>)

    devices to inspect, can be disk, partition or its udev links

Returns:

  • (Array<String>)

    gpt disks only



82
83
84
85
86
87
88
89
90
91
92
93
# File 'src/modules/BootStorage.rb', line 82

def gpt_disks(devices)
  targets = devices.map do |dev_name|
    staging.find_by_any_name(dev_name) or handle_unknown_device(dev_name)
  end
  boot_disks = targets.each_with_object([]) { |t, r| r.concat(stage1_disks_for(t)) }

  result = boot_disks.select { |disk| disk.gpt? }

  log.info "Found these gpt boot disks: #{result.inspect}"

  result.map(&:name)
end

#mainObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'src/modules/BootStorage.rb', line 46

def main
  textdomain "bootloader"

  Yast.import "Arch"
  Yast.import "Mode"
  Yast.import "Kernel"

  # FATE#305008: Failover boot configurations for md arrays with redundancy
  # list <string> includes physical disks used for md raid

  @md_physical_disks = []

  # Revision to recognize if cached values are still valid
  @storage_revision = nil
end

#prep_partitionsObject



109
110
111
112
113
# File 'src/modules/BootStorage.rb', line 109

def prep_partitions
  partitions = Y2Storage::Partitionable.all(staging).map(&:prep_partitions).flatten
  log.info "detected prep partitions #{partitions.inspect}"
  partitions
end

#propose_resumeObject



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'src/modules/BootStorage.rb', line 258

def propose_resume
  swap_parts = Yast::BootStorage.available_swap_partitions
  largest_swap_name, largest_swap_size = (swap_parts.max_by { |_part, size| size } || [])

  propose = Yast::Kernel.propose_hibernation? && largest_swap_name

  return "" unless propose

  if largest_swap_size < Yast::BootStorage.ram_size
    log.info "resume parameter is not added because swap (#{largest_swap_name}) is too small"

    return ""
  end

  # try to use label or udev id for device name... FATE #302219
  ::Bootloader::UdevMapping.to_mountby_device(largest_swap_name)
end

#ram_sizeIntenger

Ram size in KiB

Returns:

  • (Intenger)


142
143
144
# File 'src/modules/BootStorage.rb', line 142

def ram_size
  Y2Storage::StorageManager.instance.arch.ram_size / 1024
end

#reset_disksObject

Sets properly boot, root and mbr disk. resets disk configuration. Clears cache from #detect_disks



104
105
106
107
# File 'src/modules/BootStorage.rb', line 104

def reset_disks
  @boot_fs = nil
  @root_fs = nil
end

#root_filesystemY2Storage::Filesystem

Moint point for /.

Returns:

  • (Y2Storage::Filesystem)


40
41
42
43
44
# File 'src/modules/BootStorage.rb', line 40

def root_filesystem
  detect_disks

  @root_fs
end

#root_partitionsObject

shortcut to get stage1 partitions for /



254
255
256
# File 'src/modules/BootStorage.rb', line 254

def root_partitions
  stage1_partitions_for(root_filesystem)
end

#stage1_devices_for_name(dev_name) ⇒ Array<Y2Storage::Device>

Find the devices (disks or partitions) to whose boot records we should put stage1.

In simple setups it will be one device, but for RAIDs and LVMs and other multi-device setups we need to put stage1 to all the underlying boot records so that the (Legacy) BIOS does not have a chance to pick an empty BR to boot from. See bsc#1072908.

Parameters:

  • dev_name (String)

    device name including udev links

Returns:

  • (Array<Y2Storage::Device>)

    list of suitable devices



167
168
169
170
171
172
173
174
175
176
# File 'src/modules/BootStorage.rb', line 167

def stage1_devices_for_name(dev_name)
  device = staging.find_by_any_name(dev_name)
  handle_unknown_device(dev_name) unless device

  if device.is?(:partition) || device.is?(:filesystem)
    stage1_partitions_for(device)
  else
    stage1_disks_for(device)
  end
end

#stage1_disks_for(device) ⇒ Array<Y2Storage::Device>

Find the disks to whose MBRs we should put stage1. (In simple setups it will be one disk)

Parameters:

  • device (Y2Storage::Device)

    to check eg. a Y2Storage::Filesystems::Base (for a new installation) or a Y2Storage::Disk (for an upgrade)

Returns:

  • (Array<Y2Storage::Device>)

    devices suitable for stage1



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'src/modules/BootStorage.rb', line 215

def stage1_disks_for(device)
  # Usually we want just the ancestors, but in the upgrade case
  # we may start with just 1 of multipath wires and have to
  # traverse descendants to find the Y2Storage::Multipath to use.
  component = [device] + device.ancestors + device.descendants

  # The simple case: just get the disks.
  disks = component.select { |a| a.is?(:disk) }
  # Eg. 2 Disks are parents of 1 Multipath, the disks are just "wires"
  # to the real disk.
  multipaths = component.select { |a| a.is?(:multipath) }
  multipath_wires = multipaths.each_with_object([]) { |m, r| r.concat(m.parents) }
  log.info "multipath devices #{multipaths.inspect} and its wires #{multipath_wires.inspect}"

  # And same for bios raids
  bios_raids = component.select { |a| a.is?(:bios_raid) }
  # raid can be more complex, so we need not only direct parents but all
  # ancestors involved in RAID
  raid_members = bios_raids.each_with_object([]) { |m, r| r.concat(m.ancestors) }
  log.info "bios_raids devices #{bios_raids.inspect} and its members #{raid_members.inspect}"

  result = multipaths + disks + bios_raids - multipath_wires - raid_members

  log.info "stage1 disks for #{device.inspect} are #{result.inspect}"

  result
end

#stage1_partitions_for(device) ⇒ Array<Y2Storage::Device>

Find the partitions to whose boot records we should put stage1. (In simple setups it will be one partition)

Parameters:

  • device (Y2Storage::Device)

    to check eg. a Y2Storage::Filesystems::Base (for a new installation) or a Y2Storage::Partition (for an upgrade)

Returns:

  • (Array<Y2Storage::Device>)

    devices suitable for stage1



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'src/modules/BootStorage.rb', line 184

def stage1_partitions_for(device)
  # so how to do search? at first find first partition with parents
  # that is on disk or multipath (as ancestors method is not sorted)
  partitions = select_ancestors(device) do |ancestor|
    if ancestor.is?(:partition)
      partitionable = ancestor.partitionable
      partitionable.is?(:disk) || partitionable.is?(:multipath) || partitionable.is?(:bios_raid)
    else
      false
    end
  end

  partitions.uniq!

  log.info "stage1 partitions for #{device.inspect} are #{partitions.inspect}"

  partitions
end

#stagingObject



66
67
68
# File 'src/modules/BootStorage.rb', line 66

def staging
  Y2Storage::StorageManager.instance.staging
end

#storage_changed?Boolean

Returns:

  • (Boolean)


62
63
64
# File 'src/modules/BootStorage.rb', line 62

def storage_changed?
  @storage_revision != Y2Storage::StorageManager.instance.staging_revision
end

#storage_read?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'src/modules/BootStorage.rb', line 70

def storage_read?
  !@storage_revision.nil?
end