Module: Yast::BootloaderRoutinesMiscInclude

Defined in:
src/include/bootloader/routines/misc.rb

Instance Method Summary (collapse)

Instance Method Details

- (Boolean) BootloaderInstallable

Check if the bootloader can be installed at all with current configuration

Returns:

  • (Boolean)

    true if it can



274
275
276
277
278
279
280
281
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
314
315
316
# File 'src/include/bootloader/routines/misc.rb', line 274

def BootloaderInstallable
  return true if Mode.config
  if Arch.i386 || Arch.x86_64
    # the only relevant is the partition holding the /boot filesystem
    DetectDisks()
    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(getBootPartition, "/dev/evms/") == 0
      Builtins.y2milestone("Cannot install bootloader on EVMS")
      return false
    end

    return true
  else
    return true
  end
end

- (String) buildConsoleValue(unit, speed, parity, word)

FATE #110038: Serial console Function build value for console from:

Parameters:

  • unit (String)

    no of console

  • speed (String)
  • parity (String)

    (n,o,e)

  • word (String)

    (8)

Returns:

  • (String)

    value of console for kernel append



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
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'src/include/bootloader/routines/misc.rb', line 389

def buildConsoleValue(unit, speed, parity, word)
  ret = ""
  if unit != "" && speed != ""
    # add number of serial console
    if Arch.aarch64
      ret = Ops.add("ttyAMA", unit)
    else
      ret = Ops.add("ttyS", unit)
    end
    # add speed
    ret = Ops.add(Ops.add(ret, ","), speed)
    if parity != ""
      # add parity
      case parity
      when "no"
        ret = Ops.add(ret, "n")
      when "odd"
        ret = Ops.add(ret, "o")
      when "even"
        ret = Ops.add(ret, "e")
      else
        ret = Ops.add(ret, "n")
      end

      # add word
      ret = Ops.add(ret, word) if word != ""
    end
    Builtins.y2milestone("console value for kernel: %1", ret)
  else
    Builtins.y2error(
      "Wrong values unit: %1 , speed: %2 , parity: %3 , word: %4",
      unit,
      speed,
      parity,
      word
    )
  end
  ret
end

- (Object) getAnyTypeAttrib(attrib, defaultv)

Get value of specified bootloader attribute

Parameters:

  • attrib (String)

    string attribute name

  • defaultv (Object)

    any default value of the attribute (if not found)

Returns:

  • (Object)

    value of attribute



92
93
94
95
# File 'src/include/bootloader/routines/misc.rb', line 92

def getAnyTypeAttrib(attrib, defaultv)
  defaultv = deep_copy(defaultv)
  Ops.get(@current_bootloader_attribs, attrib, defaultv)
end

- (Boolean) getBooleanAttrib(attrib)

Get value of specified boolean bootloader attribute

Parameters:

  • attrib (String)

    string attribute name

Returns:

  • (Boolean)

    value of attribute



84
85
86
# File 'src/include/bootloader/routines/misc.rb', line 84

def getBooleanAttrib(attrib)
  Ops.get_boolean(@current_bootloader_attribs, attrib, false)
end

- (String) getBootDisk

FATE #303548 - Grub: limit device.map to devices detected by BIOS Int 13 Function select boot device - disk

Returns:

  • (String)

    name of boot device - disk



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'src/include/bootloader/routines/misc.rb', line 360

def getBootDisk
  boot_device = getBootPartition

  if boot_device == ""
    Builtins.y2milestone(
      "BootPartitionDevice and RootPartitionDevice are empty"
    )
    return boot_device
  end
  p_dev = Storage.GetDiskPartition(boot_device)

  boot_disk_device = Ops.get_string(p_dev, "disk", "")

  if boot_disk_device != "" && !boot_disk_device.nil?
    Builtins.y2milestone("Boot device - disk: %1", boot_disk_device)
    return boot_disk_device
  end

  Builtins.y2milestone("Finding boot disk failed!")
  ""
end

- (String) GetBootloaderDevice

Get bootloader device for specified location FIXME: this function is being phased out. Keeping it around until selected_location and loader_device can be dropped for all bootloader types.

Returns:

  • (String)

    device name



118
119
120
121
122
123
124
125
# File 'src/include/bootloader/routines/misc.rb', line 118

def GetBootloaderDevice
  return @mbrDisk if @selected_location == "mbr"
  return BootStorage.BootPartitionDevice if @selected_location == "boot"
  return BootStorage.RootPartitionDevice if @selected_location == "root"
  return "mbr_md" if @selected_location == "mbr_md"
  return "/dev/null" if @selected_location == "none"
  @loader_device
end

- (Array) GetBootloaderDevices

Get list of bootloader device names for all selected or specified locations

Returns:

  • (Array)

    device names



130
131
132
133
134
135
136
137
138
139
140
# File 'src/include/bootloader/routines/misc.rb', line 130

def GetBootloaderDevices
  ret = []
  ret << BootStorage.BootPartitionDevice if @globals["boot_boot"] == "true"
  ret << BootStorage.RootPartitionDevice if @globals["boot_root"] == "true"
  ret << @mbrDisk if @globals["boot_mbr"] == "true"
  ret << BootStorage.ExtendedPartitionDevice if @globals["boot_extended"] == "true"
  ret << @globals["boot_custom"] if @globals["boot_custom"] && !@globals["boot_custom"].empty?
  Builtins.y2warning("Empty bootloader devices. Globals #{@globals.inspect}") if ret.empty?

  ret
end

- (String) getBootPartition

Function return boot device it means return boot partition or root partition if boot partition deosn't exist function return “” if boot partition or root partition is not defined (autoyast)

Returns:

  • (String)

    name of boot device (partition)



344
345
346
347
348
349
350
351
352
353
# File 'src/include/bootloader/routines/misc.rb', line 344

def getBootPartition
  boot_device = ""
  if BootStorage.BootPartitionDevice != ""
    boot_device = BootStorage.BootPartitionDevice
  elsif BootStorage.RootPartitionDevice != ""
    boot_device = BootStorage.RootPartitionDevice
  end

  boot_device
end

- (String) getConsoleValue

FATE #110038: Serial console Function check value from globals (serial and terminal) after that build value of console append for kernel if it is possible

Returns:

  • (String)

    value of console for kernel append



452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'src/include/bootloader/routines/misc.rb', line 452

def getConsoleValue
  ret = ""
  if Ops.get(@globals, "serial", "") != "" &&
      Ops.get(@globals, "terminal", "") != ""
    list_serial = Builtins.splitstring(Ops.get(@globals, "serial", ""), " ")
    Builtins.y2milestone("list of serial args: %1", list_serial)
    unit = ""
    speed = ""
    parity = ""
    word = ""
    Builtins.foreach(list_serial) do |key|
      unit = getKeyValue(key) unless Builtins.search(key, "--unit").nil?
      speed = getKeyValue(key) unless Builtins.search(key, "--speed").nil?
      parity = getKeyValue(key) unless Builtins.search(key, "--parity").nil?
      word = getKeyValue(key) unless Builtins.search(key, "--word").nil?
    end
    # build value
    ret = buildConsoleValue(unit, speed, parity, word)
  end

  ret
end

- (String+) getKernelParamFromLine(line, key)

get kernel parameter values from kernel command line

Parameters:

  • line (String)

    string original line

  • key (String)

    string parameter key

Returns:

  • (String, Array<String>)

    value, “false” if not present or “true” if present without value. If the parameter has on more than 1 value, an array will be returned.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'src/include/bootloader/routines/misc.rb', line 148

def getKernelParamFromLine(line, key)
  # FIXME: this doesn't work with quotes and spaces
  res = "false"
  # we can get nil if params is not yet proposed, so return not there (bnc#902397)
  return res unless line
  params = line.split(" ").reject(&:empty?)
  values = params.map { |p| kernel_param_parts(p) }.select { |p| p[0] == key }.map(&:last).uniq
  if values.empty? # not present
    "false"
  elsif values.size == 1 # only one value
    values.first
  else # more than 1 value
    values
  end
end

- (String) getKeyValue(key)

FATE #110038: Serial console Function parse string key (e.g. –speed=9600) and return value of key

Parameters:

  • key (String)

    e.g. –unit=0

Returns:

  • (String)

    value of key



435
436
437
438
439
440
441
442
443
444
445
# File 'src/include/bootloader/routines/misc.rb', line 435

def getKeyValue(key)
  ret = ""
  value = []
  if key != ""
    value = Builtins.splitstring(key, "=")
    ret = Ops.get(value, 1, "") if Ops.get(value, 1, "") != ""
  end

  Builtins.y2debug("parse: %1 and return value: %2", key, ret)
  ret
end

- (String) getLoaderName(bootloader, mode)

return printable name of bootloader

Parameters:

  • bootloader (String)

    string bootloader type internal string

  • mode (Symbol)

    symbol combo orsummary (because of capitalization)

Returns:

  • (String)

    printable bootloader name



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
75
76
77
78
79
# File 'src/include/bootloader/routines/misc.rb', line 47

def getLoaderName(bootloader, mode)
  if bootloader == "none"
    if mode == :summary
      # summary string
      return _("Do not install any boot loader")
    else
      # combo box item
      return _("Do Not Install Any Boot Loader")
    end
  end
  if bootloader == "default"
    if mode == :summary
      # summary string
      return _("Install the default boot loader")
    else
      # combo box item
      return _("Install Default Boot Loader")
    end
  end
  if mode == :summary
    # summary string
    fallback_name = _("Boot loader")
  else
    # combo box item
    fallback_name = _("Boot Loader")
  end
  # fallback bootloader name, keep short
  Ops.get_string(
    @bootloader_attribs,
    [bootloader, "loader_name"],
    fallback_name
  )
end

- (Object) GetSerialFromAppend

This function gets bootloader's serial settings from append (bnc#862388)



476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'src/include/bootloader/routines/misc.rb', line 476

def GetSerialFromAppend
  append = @globals["append"] || ""
  type = Builtins.regexpsub(append, "^.*console=([[:alpha:]]+)[[:digit:]]*,*[[:digit:]]*[noe]*[[:digit:]]*.*[[:space:]]*.*$", "\\1")
  args = Builtins.regexpsub(append, "^.*console=[[:alpha:]]+([[:digit:]]*,*[[:digit:]]*[noe]*[[:digit:]]*).*[[:space:]]*.*$", "\\1")

  Builtins.y2milestone("BuildSerialFromAppend: %1, %2", type, args)
  return "" if (type != "ttyS" && type != "ttyAMA") || args.empty?

  unit = Builtins.regexpsub(args, "([[:digit:]]+),*[[:digit:]]*[noe]*[[:digit:]]*", "\\1")
  return ""  if unit == ""

  ret = "serial --unit=#{unit}"

  speed = Builtins.regexpsub(args, "[[:digit:]]+,*([[:digit:]]*)[noe]*[[:digit:]]*", "\\1")
  speed = "9600" if speed.empty?
  ret << " --speed=#{speed}"

  parity = Builtins.regexpsub(args, "[[:digit:]]+,*[[:digit:]]*([noe]*)[[:digit:]]*", "\\1")
  case parity
  when "n"
    ret << " --parity=no"
  when "o"
    ret << " --parity=odd"
  when "e"
    ret << " --parity=even"
  when ""
    # no parity, do nothing
  else
    raise "unknown parity flag #{parity}"
  end

  word = Builtins.regexpsub(args, "[[:digit:]]+,*[[:digit:]]*[noe]*([[:digit:]]*)", "\\1")
  ret << " --word=#{word}" unless word.empty?

  ret
end

- (Object) HandleConsole2

FATE #110038: Serial console Add console arg for kernel if there is defined serial console



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
# File 'src/include/bootloader/routines/misc.rb', line 516

def HandleConsole2
  if @globals["terminal"] != "serial"
    # if bootloader is not set to serial console, we should leave the
    # kernel append as is to allow it's serial console be enabled
    # for debugging output and so on (bnc#866710)
    return
  end

  if !@globals["serial"] || @globals["serial"].empty?
    # http://www.gnu.org/software/grub/manual/grub.html#serial
    # https://www.kernel.org/doc/Documentation/serial-console.txt
    # default settings is the same, we should at least tell kernel the
    # port (aka unit) to use and grub2 defaults to 0.
    # speed is also required by builkConsoleValue
    @globals["serial"] = "serial --unit=0 --speed=9600"
  end

  console_value = getConsoleValue

  if !Ops.get(@globals, "append").nil?
    updated_append = ""
    if console_value != "" || !console_value.nil?
      updated_append = UpdateSerialConsole(
        Ops.get(@globals, "append", ""),
        console_value
      )
    else
      updated_append = UpdateSerialConsole(
        Ops.get(@globals, "append", ""),
        ""
      )
    end
    Ops.set(@globals, "append", updated_append) if !updated_append.nil?
  end

  nil
end

- (Object) initialize_bootloader_routines_misc(_include_target)



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'src/include/bootloader/routines/misc.rb', line 26

def initialize_bootloader_routines_misc(_include_target)
  textdomain "bootloader"
  Yast.import "Mode"
  Yast.import "Stage"

  Yast.import "Storage"
  Yast.import "StorageDevices"
  Yast.import "Report"
  Yast.import "Kernel"
  Yast.import "Misc"
  Yast.import "ProductFeatures"
  Yast.import "Directory"
  Yast.import "Installation"
  Yast.import "FileUtils"
  Yast.import "String"
end

- (Object) kernel_param_key(param)



164
165
166
# File 'src/include/bootloader/routines/misc.rb', line 164

def kernel_param_key(param)
  param.split("=").first
end

- (Array<String>) kernel_param_parts(param)

Split kernel parameters into [key, value] form

It also takes care about converting parameters without a value (ie. “quiet” will be [“quiet”, “true”]).

Parameters:

  • param (String)

    Parameter string in “key=value” form.

Returns:

  • (Array<String>)

    Parameter key and value.



175
176
177
178
# File 'src/include/bootloader/routines/misc.rb', line 175

def kernel_param_parts(param)
  key, value = param.split("=")
  [key, value || "true"]
end

- (Boolean) PartitionInstallable

Check if the bootloader can be installed on partition boot record

Returns:

  • (Boolean)

    true if it can



320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'src/include/bootloader/routines/misc.rb', line 320

def PartitionInstallable
  lt = getLoaderType(false)

  return true if lt != "grub2" && lt != "grub2-efi"

  if Arch.i386 || Arch.x86_64
    DetectDisks()
    dev = Storage.GetDiskPartition(BootStorage.BootPartitionDevice)
    Builtins.y2milestone("Disk info: %1", dev)
    if Ops.get_string(dev, "disk", "") == "/dev/md"
      return false
    elsif !Ops.is_integer?(Ops.get(dev, "nr", 0))
      return false
    end
  end

  true
end

- (Hash{String => String}) remapGlobals(globals_set)

Function remap globals settings “boot_custom” device name (/dev/sda) or to label (ufo_partition)

Parameters:

  • map (string, string)

    globals

Returns:

  • (Hash{String => String})

    globals



104
105
106
107
108
109
110
111
# File 'src/include/bootloader/routines/misc.rb', line 104

def remapGlobals(globals_set)
  return globals_set if !Arch.ppc && Storage.GetDefaultMountBy == :label

  globals_set["boot_custom"] &&=
    ::Bootloader::UdevMapping.to_kernel_device(globals_set["boot_custom"])

  globals_set
end

- (Boolean) restoreMBR(device)

Rewrite current MBR with /var/lib/YaST2/backup_boot_sectors/%device Warning!!! don't use for bootsectors, 440 bytes of sector are written

Parameters:

  • device (String)

    string device to rewrite MBR to

Returns:

  • (Boolean)

    true on success



235
236
237
238
239
240
241
242
243
# File 'src/include/bootloader/routines/misc.rb', line 235

def restoreMBR(device)
  backup = ::Bootloader::BootRecordBackup.new(device)
  begin
    backup.restore
  rescue ::Bootloader::BootRecordBackup::Missing
    Report.Error("Can't restore MBR. No saved MBR found")
    return false
  end
end

- (String) setKernelParamToLine(line, key, values)

set kernel parameter to GRUB command line

Parameters:

  • line (String)

    string original line

  • key (String)

    string parameter key

  • values (String, Array<String>)

    string (or array of strings) containing values, “false” to remove key, “true” to add key without value

Returns:

  • (String)

    new kernel command line



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
220
221
222
223
224
225
226
227
228
229
# File 'src/include/bootloader/routines/misc.rb', line 186

def setKernelParamToLine(line, key, values)
  line ||= ""
  # bnc#945479, see last line of this method
  line = "" if line == '""'
  # FIXME: this doesn't work with quotes and spaces
  params = line.split(" ").reject(&:empty?)
  # count occurences of every parameter, initial value is 0
  occurences = Hash.new { |_k| 0 }
  params.each do |param|
    k = kernel_param_key(param)
    occurences[k] += 1
  end
  done = false
  params = params.each_with_object([]) do |param, res|
    k = kernel_param_key(param)
    if k != key # not our param
      res << param
    elsif values == "false"
      next # do nothing as we want to remove this param
    elsif occurences[k] == 1 # last parameter with given key
      done = true
      if values == "true"
        res << key
      elsif values != "false"
        Array(values).each do |v|
          res << Builtins.sformat("%1=%2", key, v)
        end
      end
    else
      occurences[k] -= 1
    end
  end
  if !done
    if values == "true"
      params << key
    elsif values != "false"
      Array(values).each do |v|
        params << Builtins.sformat("%1=%2", key, v)
      end
    end
  end
  # bnc#945479 perl-bootloader does not cope well with empty strings
  params.empty? ? '""' : params.join(" ")
end

- (Object) UpdateInstallationKernelParameters

Update the Kernel::vgaType value to the saved one if not defined



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'src/include/bootloader/routines/misc.rb', line 246

def UpdateInstallationKernelParameters
  saved_params = {}
  if !Stage.initial
    saved_params = Convert.convert(
      SCR.Read(path(".target.ycp"), "/var/lib/YaST2/bootloader.ycp"),
      :from => "any",
      :to   => "map <string, any>"
    )
  end
  if Kernel.GetVgaType == ""
    vgaType = Ops.get_string(saved_params, "vgamode", "")
    Kernel.SetVgaType(vgaType) if !vgaType.nil? && vgaType != ""
  end
  if !Stage.initial
    Kernel.SetCmdLine(
      Ops.get_string(saved_params, "installation_kernel_params", "")
    )
  else
    if SCR.Read(path(".etc.install_inf.NoPCMCIA")) == "1"
      Kernel.SetCmdLine(Ops.add(Kernel.GetCmdLine, " NOPCMCIA"))
    end
  end

  nil
end