From Fedora Project Wiki

Make BootLoaderSpec-style configuration files the default

Summary

This change enables the use of per-boot-entry configuration files, similar to those described in Boot Loader Specification (BLS), to populate the bootloader's menu entries.

Owner

  • Release notes owner:

Current status

  • Targeted release: Fedora 30
  • Last updated: 2018-12-03
  • Tracker bug: #1598523
  • Release Notes tracking:

Detailed Description

The Boot Loader Specification (BLS) defines a scheme and file format to manage boot loader configuration for each boot option in a drop-in directory, without the need to manipulate bootloader configuration files. Directories of individual drop-in configuration files are standard for many purposes on Linux nowadays, so the goal is to also extend this concept for boot menu entries. This proposal does not include full implementation of that specification, which is not widely adopted, but merely refers loosely to the format and general layout of the configuration files.

This is especially important in Fedora because the same bootloader is not used in all architectures. GRUB 2 is used in most of them, but there are others such as zipl for s390x and Petitboot for ppc64le. Not all bootloaders have the same configuration file format, so there is a need for an indirection level and per bootloader specific logic to edit these configuration files, when adding or removing a boot entry.

The current component that does this work is grubby, that has support for all the different bootloader configuration file formats and manipulates them on kernel installation or uninstallation. Besides manipulating the bootloader configuration files, grubby also does other things like running dracut to create an initial ramdisk image.

Fedora already has a lot of infrastructure in place to not require modifying bootloader configuration files for boot menu entries. Fedora's grub2 includes a "blscfg" command to load and build menus from configuration files, which the Fedora kernel packages provide, and the kernel-install script can do any additional task that is currently done by grubby. The kernel-install script has a pluggable design that uses a drop-in directory for scripts to extend its functionality, so if needed, any bootloader specific logic can be implemented as kernel-install scripts. With this setup the core bootloader configuration files can be static and not modified after installation.

The missing piece was the lack of support in our bootloaders, but our default bootloaders now have support to parse BLS-like configuration files now. So we can default to install BLS files on kernel installation and drop grubby.

Differences from BootLoaderSpec

There are a couple of differences between this implementation, the original Boot Loader Specification proposal, and Matthew Garrett's proposed update:

  • By default the implementation looks for the "loader/entries" subdirectory relative to ($boot). That means that in Fedora's will normally be in /boot/loader/entries/. But on grub2, the subdirectory is configurable by placing a grubenv file at ($boot)/EFI/fedora/grubenv for EFI or ($boot)/grub2/grubenv for BIOS with a variable set named "blsdir", which specifies a subdirectory relative to ($boot).
  • Only the device grub is loaded from is searched for config files.
  • On other machines, only the grub root device is searched
  • The following keywords have not currently been implemented: multiboot, module, version, machine-id, filesystem, chainload, efi, devicetree. If encountered, they are ignored.
  • On all platforms, the entries are sorted by the BLS filename using the rpmvercmp() version comparison function.
  • multiple initrd entries are allowed, and will be processed in order
  • On grub platforms, the following grub-specific keywords have been implemented:
    • the BLS filename is also used for menuentry's --id parameter, so you can use it in saved_entry
    • grub_hotkey - same as grub's "--hotkey" menuentry parameter
    • grub_users - same as grub's "--users" menuentry parameter; used for password protection
    • grub_class - same as grub's "--class" menuentry paramter
    • grub_arg - passes extra arguments to menuentry

Config files provided by kernel, grub2-switch-to-blscfg, and zipl-switch-to-blscfg

The config files provided look like:

 trillian:~# cat /boot/loader/entries/e97f88e127374c058acbf628315b41bc-4.16.13-300.fc28.x86_64.conf
 title Fedora (4.16.13-300.fc28.x86_64) 28 (Twenty Eight)
 version 4.16.13-300.fc28.x86_64
 linux /vmlinuz-4.16.13-300.fc28.x86_64
 initrd /initramfs-4.16.13-300.fc28.x86_64.img
 options $kernelopts
 id fedora-20180530145228-4.16.13-300.fc28.x86_64
 grub_users $grub_users
 grub_arg --unrestricted
 grub_class kernel

Note that $grub_users will normally be set via grub2-setpassword, and grub2-mkconfig will set $kernelopts in grubenv to:

 root=${linux_root_device} ro ${GRUB_CMDLINE_LINUX}

On my system that means it's:

 kernelopts=root=UUID=37c11eda-04c1-4013-9e17-247993003b84 ro rhgb quiet

Benefit to Fedora

grubby is a monolithic C program with thousands lines of code that grew organically over the last 17 years. So it has become complex and hard to maintain, it also has a lot of legacy code for bootloaders and architectures that are no longer supported by Fedora such as lilo (x86), elilo (IA64), silo (SPARC) and yaboot (PowerPC).

Getting rid of grubby and using BLS fragments will simplify the kernel installation process significantly and make it more consistent across the different architectures. This will also make it easier for automation tools to manage the bootloader menu options since it will just be a matter of adding, removing or editing individual boot entry files in a directory.

Scope

  • Proposal owners:
    • Generate boot entry config files at kernel build time and ship in the kernel packages.
    • Make kernel-install scripts to install the boot entry configurations, create the initramfs images, and do any architecture specific task.
    • Make GRUB 2, zipl and Petitboot bootloaders to populate their boot menu entries from the information in boot entry config files.
    • Provide a script to provide backward compatbility, where possible, for tools that that manipulates boot entry config files.
    • Modify packages that use grubby to instead install boot entry config files (memtest86+, tuned).
    • Make sure this is all properly documented in release-notes, etc.
  • Other developers:
    • The anaconda developers will need to review and merge the patches to change the default to BLS.
    • Test and watch for regressions.
  • Release engineering:

RelEng review ticket: #7572

  • Policies and guidelines: The policies and guidelines do not need to be updated.
  • Trademark approval: No changes needed.

Upgrade/compatibility impact

The changes are in the bootloader configuration files (grub.cfg, zipl.conf) that are generated at install time and modified by grubby on kernel installations. So these need to be modified to support BLS.

Users can manually enable BLS support in Fedora 29 by using a helper script that switches from the current configuration to one using BLS. This helper script is grub2-switch-to-blscfg for GRUB 2 and Petitboot and zipl-switch-to-blscfg for zipl.

On Fedora 30, the script to switch to a BLS configuration will be automatically executed on grubby upgrade, and the old grubby tool will be moved to a grubby-deprecated package. So users can switch back to a non-BLS configuration by restoring the old configuration from a backup file and installing the grubby-deprecated package.

Proper documentation will be provided with detailed instructions on how to switch back and forth between the two types of configurations. Something to keep in mind is that kernels installed after switching to a BLS configuration won't be present in the old configuration backup file. On platforms using grub, users can also switch back by installing the grubby-deprecated package, removing "GRUB_ENABLE_BLSCFG=true" from /etc/default/grub , and using grub2-mkconfig to re-generate their configuration file.

In the grubby package, a grubby wrapper script is provided for compatibility with other functions of grubby, such as determining or setting the next kernel to boot, and other functionality. This wrapper script supports the same grubby options and arguments but underneaths modifies the BLS files.

32-bit ARM

On ARMv7 machines, the u-boot bootloader is used that still doesn't have BLS support. This bootloader parses an extlinux.conf file that is updated by grubby every time that a new kernel is installed. Since u-boot doesn't support it, BLS won't be available on ARMv7 and the old grubby tool will still be used. The grubby-deprecated package is now a dependency of syslinux-extlinux and it will be automatically installed when the package is upgraded.

How To Test

  • Architectures using the GRUB 2 or Petitboot bootloaders

Run the grub2-switch-to-blscfg script

 $ grub2-switch-to-blscfg
  • Architectures using the zipl bootloader

Run the zipl-switch-to-blscfg script

 $ zipl-switch-to-blscfg

or

  • Any architecture

Upgrade to rawhide / Fedora 30.

When the system is rebooted, the boot menu entries would had been populated from the information contained in the BLS fragments files.

User Experience

No visible changes are expected, the bootloaders will populate the same boot menu entries. The only thing that changes is from where this information is taken.

Dependencies

None

Contingency Plan

  • Contingency mechanism: Revert the anaconda changes
  • Contingency deadline: Beta Freeze
  • Blocks release? No
  • Blocks product? None

Documentation

Release Notes

TODO