Class: Yast::BootSupportCheckClass

Inherits:
Module
  • Object
show all
Defined in:
src/modules/BootSupportCheck.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) AddNewProblem(description)

Add a new problem description to the list of found problems



39
40
41
42
43
# File 'src/modules/BootSupportCheck.rb', line 39

def AddNewProblem(description)
  @detected_problems = Builtins.add(@detected_problems, description)

  nil
end

- (Object) check_activate_partition



244
245
246
247
248
249
250
# File 'src/modules/BootSupportCheck.rb', line 244

def check_activate_partition
  # activate set or there is already activate flag
  return true if BootCommon.globals["activate"] == "true" || Yast::Storage.GetBootPartition(Yast::BootCommon.mbrDisk)

  AddNewProblem(_("Activate flag is not set by installer. If it is not set at all, some BIOSes could refuse to boot."))
  false
end

- (Boolean) check_BootDevice

Check if boot partition exist check if not on raid0

Returns:

  • (Boolean)

    true on success



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
194
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
# File 'src/modules/BootSupportCheck.rb', line 152

def check_BootDevice
  result = true
  devices = Storage.GetTargetMap

  boot_device = BootCommon.getBootPartition

  found_boot = false
  # check if boot device is on raid0
  Builtins.foreach(devices) do |_k, v|
    Builtins.foreach(Ops.get_list(v, "partitions", [])) do |p|
      if Ops.get_string(p, "device", "") == boot_device
        if Ops.get_string(p, "raid_type", "") != "raid1" &&
            Ops.get(p, "type") == :sw_raid
          AddNewProblem(
            Builtins.sformat(
              _(
                "The boot device is on raid type: %1. System will not boot."
              ),
              Ops.get_string(p, "raid_type", "")
            )
          )
          Builtins.y2error(
            "The boot device: %1 is on raid type: %2",
            boot_device,
            Ops.get_string(p, "raid_type", "")
          )
          result = false
          raise Break
        else
          # bnc#501043 added check for valid configuration
          if Ops.get_string(p, "raid_type", "") == "raid1" &&
              Ops.get(p, "type") == :sw_raid
            if Builtins.tolower(Ops.get_string(p, "fstype", "")) == "md raid" &&
                Ops.get(BootCommon.globals, "boot_mbr", "false") != "true"
              AddNewProblem(
                _(
                  "The boot device is on software RAID1. Select other bootloader location, e.g. Master Boot Record"
                )
              )
              Builtins.y2error(
                "Booting from soft-raid: %1 and bootloader setting are not valid: %2",
                p,
                BootCommon.globals
              )
              result = false
              raise Break
            else
              found_boot = true
              Builtins.y2milestone("Valid configuration for soft-raid")
            end
          else
            found_boot = true
            Builtins.y2milestone(
              "The boot device: %1 is on raid: %2",
              boot_device,
              Ops.get_string(p, "raid_type", "")
            )
          end
        end
        found_boot = true
        Builtins.y2milestone("/boot filesystem is OK")
        raise Break
      end
    end
    raise Break if !result || found_boot
  end if boot_device != ""
  result
end

- (Object) check_gpt_reserved_partition

when grub2 is used and install stage1 to MBR, target /boot is btrfs, label is gpt-like then there must be special partition to install core.img, otherwise grub2-install failed



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'src/modules/BootSupportCheck.rb', line 126

def check_gpt_reserved_partition
  return true if BootCommon.globals["boot_mbr"] != "true"

  devices = Storage.GetTargetMap
  mbr_disk = Storage.GetDisk(devices, BootCommon.FindMBRDisk)
  boot_device = Storage.GetPartition(devices, BootCommon.getBootPartition)
  return true if mbr_disk["label"] != "gpt"
  return true if boot_device["used_fs"] != :btrfs
  return true if mbr_disk["partitions"].any? { |p| p["fsid"] == Partitions.fsid_bios_grub }

  Builtins.y2error("Used together boot from MBR, gpt, btrfs and without bios_grub partition.")
  # TRANSLATORS: description of technical problem. Do not translate technical terms unless native language have well known translation.
  AddNewProblem(
    _(
      "Boot from MBR does not work together with btrfs filesystem and GPT disk label without bios_grub partition." \
      "To fix this issue, create bios_grub partition or use any ext filesystem for boot partition or do not install stage 1 to MBR."
    )
  )
  false
end

- (Object) check_mbr



252
253
254
255
256
257
# File 'src/modules/BootSupportCheck.rb', line 252

def check_mbr
  return true if BootCommon.globals["generic_mbr"] == "true" || BootCommon.globals["boot_mbr"] == "true"

  AddNewProblem(_("The installer will not modify the MBR of the disk. Unless it already contains boot code, the BIOS won't be able to boot disk."))
  false
end

- (Object) check_zipl_part



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'src/modules/BootSupportCheck.rb', line 228

def check_zipl_part
  # if partitioning worked before upgrade, it will keep working (bnc#886604)
  return true if Mode.update

  boot_part = Storage.GetEntryForMountpoint("/boot/zipl")
  boot_part = Storage.GetEntryForMountpoint("/boot") if boot_part.empty?
  boot_part = Storage.GetEntryForMountpoint("/") if boot_part.empty?

  if [:ext2, :ext3, :ext4].include? boot_part["used_fs"]
    return true
  else
    AddNewProblem(_("Missing ext partition for booting. Cannot install boot code."))
    return false
  end
end

- (Object) CorrectLoaderType

Check that bootloader matches current hardware



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
102
103
104
105
# File 'src/modules/BootSupportCheck.rb', line 75

def CorrectLoaderType
  lt = Bootloader.getLoaderType
  return true if lt == "none"

  # grub2 is sooo cool...
  return true if lt == "grub2" && !Arch.aarch64

  if Arch.i386 || Arch.x86_64
    if efi?
      return true if lt == "grub2-efi"
    else
      return true if lt == "grub2"
    end
  end

  return true if lt == "grub2-efi" && Arch.aarch64

  Builtins.y2error(
    "Unsupported combination of hardware platform %1 and bootloader %2",
    Arch.architecture,
    lt
  )
  AddNewProblem(
    Builtins.sformat(
      _("Unsupported combination of hardware platform %1 and bootloader %2"),
      Arch.architecture,
      lt
    )
  )
  false
end

- (Boolean) efi?

Check if EFI is needed

Returns:

  • (Boolean)


222
223
224
225
226
# File 'src/modules/BootSupportCheck.rb', line 222

def efi?
  cmd = "modprobe efivars 2>/dev/null"
  SCR.Execute(path(".target.bash_output"), cmd)
  FileUtils.Exists("/sys/firmware/efi/systab")
end

- (Object) EndOfBootOrRootPartition



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'src/modules/BootSupportCheck.rb', line 310

def EndOfBootOrRootPartition
  part = Storage.GetEntryForMountpoint("/boot")
  part = Storage.GetEntryForMountpoint("/") if Builtins.isempty(part)

  device = Ops.get_string(part, "device", "")
  Builtins.y2milestone("device:%1", device)

  end_cyl = Region.End(Ops.get_list(part, "region", []))

  cyl_size = 82_252_800
  target_map = Storage.GetTargetMap
  Builtins.foreach(target_map) do |_dev, disk|
    partition = (disk["partitions"] || []).find do |p|
      p["device"] == device
    end

    cyl_size = disk["cyl_size"] || 82_252_800 if partition
  end

  ret = Ops.multiply(end_cyl, cyl_size)

  Builtins.y2milestone(
    "end_cyl:%1 cyl_size:%2 end:%3",
    end_cyl,
    cyl_size,
    ret
  )
  ret
end

- (Object) GptPartitionTable

  • Checks for GPT partition table



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'src/modules/BootSupportCheck.rb', line 108

def GptPartitionTable
  ret = true
  tm = Storage.GetTargetMap
  devices = [BootStorage.BootPartitionDevice]
  # TODO: add more devices
  Builtins.foreach(devices) do |dev|
    p_dev = Storage.GetDiskPartition(dev)
    num = p_dev["nr"].to_i
    mbr_dev = Ops.get_string(p_dev, "disk", "")
    label = Ops.get_string(tm, [mbr_dev, "label"], "")
    Builtins.y2milestone("Label: %1", label)
    Builtins.y2milestone("Partition number: %1", num)
  end
  ret
end

- (Object) GRUB

GRUB-related check



260
261
262
263
264
# File 'src/modules/BootSupportCheck.rb', line 260

def GRUB
  ret = GptPartitionTable()
  ret = check_BootDevice if ret && Arch.x86_64
  ret
end

- (Object) GRUB2

GRUB2-related check



267
268
269
270
271
272
273
274
275
276
# File 'src/modules/BootSupportCheck.rb', line 267

def GRUB2
  ret = [GRUB()]
  # ensure that s390 have ext* partition for booting (bnc#873951)
  ret << check_zipl_part if Arch.s390
  ret << check_gpt_reserved_partition if Arch.x86_64
  ret << check_activate_partition if Arch.x86_64 || Arch.ppc64
  ret << check_mbr if Arch.x86_64

  ret.all?
end

- (Object) GRUB2EFI

GRUB2EFI-related check



279
280
281
# File 'src/modules/BootSupportCheck.rb', line 279

def GRUB2EFI
  true
end

- (Object) KnownLoader

Check that bootloader is known and supported



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'src/modules/BootSupportCheck.rb', line 60

def KnownLoader
  if !["grub2", "grub2-efi", "none"].include?(Bootloader.getLoaderType)
    Builtins.y2error("Unknown bootloader: %1", Bootloader.getLoaderType)
    AddNewProblem(
      Builtins.sformat(
        _("Unknown bootloader: %1"),
        Bootloader.getLoaderType
      )
    )
    return false
  end
  true
end

- (Object) main



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'src/modules/BootSupportCheck.rb', line 21

def main
  textdomain "bootloader"

  Yast.import "Bootloader"
  Yast.import "Arch"
  Yast.import "Storage"
  Yast.import "Partitions"
  Yast.import "Region"
  Yast.import "BootCommon"
  Yast.import "BootStorage"
  Yast.import "FileUtils"
  Yast.import "Mode"

  # List of problems found during last check
  @detected_problems = []
end

- (Boolean) StringProblems

Formated string of detected problems Always run SystemSupported before calling this function

Returns:

  • (Boolean)

    a list of problems, empty if no was found



48
49
50
51
52
53
54
55
56
57
# File 'src/modules/BootSupportCheck.rb', line 48

def StringProblems
  ret = ""
  if Ops.greater_than(Builtins.size(@detected_problems), 0)
    Builtins.foreach(@detected_problems) do |s|
      ret = Ops.add(Ops.add(ret, s), "\n")
    end
  end

  ret
end

- (Boolean) SystemSupported

Check if the system configuraiton is supported Also sets the founds problems into internal variable Always run this function before calling DetectedProblems()

Returns:

  • (Boolean)

    true if supported



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'src/modules/BootSupportCheck.rb', line 287

def SystemSupported
  @detected_problems = []

  # check if the bootloader is known and supported
  supported = KnownLoader()

  lt = Bootloader.getLoaderType
  return true if lt == "none"

  # detect correct bootloader type
  supported = CorrectLoaderType() && supported

  # check specifics for individual loaders
  if lt == "grub2"
    supported = GRUB2() && supported
  elsif lt == "grub2-efi"
    supported = GRUB2EFI() && supported
  end

  Builtins.y2milestone("Configuration supported: %1", supported)
  supported
end