Class: Yast::BootStorageClass

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

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

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

Returns:

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



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

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
      dev = if s["crypt_device"] && !s["crypt_device"].empty?
        s["crypt_device"]
      else
        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

Returns:

  • (Boolean)

    true if it can



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
# File 'src/modules/BootStorage.rb', line 133

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) crypto_devices

Build map with encrypted partitions (even indirectly)

Returns:

  • map with encrypted partitions



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
# File 'src/modules/BootStorage.rb', line 282

def crypto_devices
  cryptos = {}
  tm = Yast::Storage.GetTargetMap || {}
  log.info "target map = #{tm}"

  # first, find the directly encrypted things
  # that is, target map has a 'crypt_device' key for it
  #
  # FIXME: can the device itself have a 'crypt_device' key?
  tm.each_value do |d|
    partitions = d["partitions"] || []
    partitions.each do |p|
      if p["crypt_device"]
        cryptos[p["device"]] = true
        cryptos[p["used_by_device"]] = true if p["used_by_device"]
      end
    end
  end

  log.info "crypto devices, step 1 = #{cryptos}"

  # second step: check if the encrypted things have itself partitions
  tm.each_value do |d|
    next if !cryptos[d["device"]]
    partitions = d["partitions"] || []
    partitions.each { |p| cryptos[p["device"]] = true }
  end

  log.info "crypto devices, final = #{cryptos}"

  cryptos
end

- (Object) detect_disks

Sets properly boot, root and mbr disk.



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
# File 'src/modules/BootStorage.rb', line 176

def detect_disks
  return unless @RootPartitionDevice.empty? # quit if already detected
  # While calling "yast clone_system" and while cloning bootloader
  # in the AutoYaST module, libStorage has to be set to "normal"
  # mode in order to read mountpoints correctly.
  # (bnc#950105)
  old_mode = Mode.mode
  if Mode.config
    Mode.SetMode("normal")
    log.info "Initialize libstorage in readonly mode" # bnc#942360
    Storage.InitLibstorage(true)
    StorageDevices.InitDone # Set StorageDevices flag disks_valid to true
  end

  # The AutoYaST config mode does access to the system.
  # bnc#942360

  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

  Mode.SetMode(old_mode) if old_mode == "autoinst_config"
end

- (Object) disk_with_boot_partition



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'src/modules/BootStorage.rb', line 230

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?

Returns:

  • (Boolean)


315
316
317
318
319
320
321
322
323
# File 'src/modules/BootStorage.rb', line 315

def encrypted_boot?
  dev = BootPartitionDevice()
  log.info "boot device = #{dev}"
  result = !!crypto_devices[dev]

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

  result
end

- (Object) extended_partition_for(device)

Get extended partition for given partition or disk



104
105
106
107
108
109
110
111
112
113
114
115
# File 'src/modules/BootStorage.rb', line 104

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



117
118
119
120
121
122
123
124
125
126
127
128
# File 'src/modules/BootStorage.rb', line 117

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?

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'src/modules/BootStorage.rb', line 52

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) main



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'src/modules/BootStorage.rb', line 29

def main
  textdomain "bootloader"

  Yast.import "Storage"
  Yast.import "Arch"
  Yast.import "Mode"

  # 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) 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



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
# File 'src/modules/BootStorage.rb', line 69

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



215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'src/modules/BootStorage.rb', line 215

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

- (Boolean) separated_boot?

Returns:

  • (Boolean)


251
252
253
# File 'src/modules/BootStorage.rb', line 251

def separated_boot?
  BootPartitionDevice() != RootPartitionDevice()
end