From Fedora Project Wiki
(Fix the list of omitted keywords.)
 
(19 intermediate revisions by 7 users not shown)
Line 3: Line 3:
== Summary ==
== Summary ==


This change enables the use of per-boot-entry configuration files, similar to those described in [https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ Boot Loader Specification (BLS)], to populate the bootloader's menu entries.
This change enables the use of per-boot-entry configuration files, similar to those described in [https://systemd.io/BOOT_LOADER_SPECIFICATION Boot Loader Specification (BLS)], to populate the bootloader's menu entries.


== Owner ==
== Owner ==
Line 17: Line 17:
== Current status ==
== Current status ==


* Targeted release: [[Releases/29 | Fedora 29 ]]  
* Targeted release: [[Releases/30 | Fedora 30 ]]  
* Last updated: {{REVISIONYEAR}}-{{REVISIONMONTH}}-{{REVISIONDAY2}}  
* Last updated: {{REVISIONYEAR}}-{{REVISIONMONTH}}-{{REVISIONDAY2}}  
* Tracker bug:
* Tracker bug: [https://bugzilla.redhat.com/show_bug.cgi?id=1598523 #1598523]
* Release Notes tracking:
* Release Notes tracking:


Line 36: Line 36:
=== Differences from BootLoaderSpec ===
=== Differences from BootLoaderSpec ===
There are a couple of differences between this implementation, the original [https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ Boot Loader Specification proposal], and Matthew Garrett's [https://www.freedesktop.org/wiki/MatthewGarrett/BootLoaderSpec/ proposed update]:
There are a couple of differences between this implementation, the original [https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ Boot Loader Specification proposal], and Matthew Garrett's [https://www.freedesktop.org/wiki/MatthewGarrett/BootLoaderSpec/ proposed update]:
* This implementation leaves the EFI system Partition mounted at /boot/efi/, and on UEFI machines it looks for the "loader/entries" subdirectories under each vendor directory on the ESP. That means Fedora's will normally be in /boot/efi/EFI/fedora/loader/entries/.  Note that on grub2, the subdirectory is configurable by placing a grubenv file at ($boot)/EFI/fedora/grubenv with a variable set named "blsdir", which specifies a subdirectory relative to ($boot)/EFI/fedora/.  This allows for atomic updates by maintaining a second config directory and switching between them with the variable. On BIOS machines ($boot)/grub2/grubenv is loaded for this functionality, and blsdir is relative to ($boot).
* 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.
* Only the device grub is loaded from is searched for config files.
* On other machines, only the grub root device is searched
* 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.
* 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 following implementation specific keywords have been implemented:
* On all platforms, the entries are sorted by the BLS filename using the rpmvercmp() version comparison function.
* id - provides us with a sort key, sorted using rpm's version comparison function. Generally of the form:
  fedora-20180530145228-4.16.13-300.fc28.x86_64
* multiple initrd entries are allowed, and will be processed in order
* multiple initrd entries are allowed, and will be processed in order
* On grub platforms, the following grub-specific keywords have been implemented:
* On grub platforms, the following grub-specific keywords have been implemented:
** id is also used for menuentry's --id parameter, so you can use it in saved_entry
** 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_hotkey - same as grub's "--hotkey" menuentry parameter
** grub_users - same as grub's "--users" menuentry parameter; used for password protection
** grub_users - same as grub's "--users" menuentry parameter; used for password protection
Line 53: Line 51:
=== Config files provided by kernel, grub2-switch-to-blscfg, and zipl-switch-to-blscfg ===
=== Config files provided by kernel, grub2-switch-to-blscfg, and zipl-switch-to-blscfg ===
The config files provided look like:
The config files provided look like:
   trillian:~# cat /boot/efi/EFI/fedora/loader/entries/e97f88e127374c058acbf628315b41bc-4.16.13-300.fc28.x86_64.conf
   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)
   title Fedora (4.16.13-300.fc28.x86_64) 28 (Twenty Eight)
   version 4.16.13-300.fc28.x86_64
   version 4.16.13-300.fc28.x86_64
Line 59: Line 57:
   initrd /initramfs-4.16.13-300.fc28.x86_64.img
   initrd /initramfs-4.16.13-300.fc28.x86_64.img
   options $kernelopts
   options $kernelopts
  id fedora-20180530145228-4.16.13-300.fc28.x86_64
   grub_users $grub_users
   grub_users $grub_users
   grub_arg --unrestricted
   grub_arg --unrestricted
Line 70: Line 67:
== Benefit to Fedora ==
== 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 became 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).
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.
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.
Line 98: Line 95:
== Upgrade/compatibility impact ==
== Upgrade/compatibility impact ==


The changes are in the bootloader configuration files (grub.cfg, zipl.conf) that are generated at install time, so users upgrading from a previous version of Fedora will keep the old behaviour.
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 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. The helper script is automatically executed on grubby uninstallation, so another way for users to switch to a BLS based configuration is by removing the grubby package.
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.


Users can also switch back to a non-BLS configuration by restoring the old configuration from a backup file. 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 re-installing grubby, removing "GRUB_ENABLE_BLSCFG=true" from /etc/default/grub , and using grub2-mkconfig to re-generate their configuration file.
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.


Another program is also provided for compatibility with other functions of grubby, such as determining or setting the next kernel to boot, and other functionality.
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, setting "GRUB_ENABLE_BLSCFG=false" in /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.
 
=== Return from User Experience ===
 
A number of people ran into problems with BLS, cf https://bugzilla.redhat.com/show_bug.cgi?id=1636466 or https://bugzilla.redhat.com/show_bug.cgi?id=1651686 as examples. The main issue appears to be that a number of places document a way to pass kernel options that is no longer working with BLS, i.e. edit /etc/default/grub before running grub2-mkconfig.
 
Samples of documentation that BLS invalidates:
 
* https://doc-stage.usersys.redhat.com/documentation/en-us/red_hat_enterprise_linux/8_test/html-single/configuring_and_managing_virtualization
* https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sec-customizing_the_grub_2_configuration_file
* https://access.redhat.com/solutions/23216
* https://wiki.centos.org/HowTos/Grub2
* https://opensource.com/article/17/3/introduction-grub2-configuration-linux
* https://help.ubuntu.com/community/Grub2/Setup
* https://access.redhat.com/discussions/916973
 
Documentation in RHEL is being updated to promote a method that works with BLS, but web search will still point users to various techniques that no longer do, and fail silently (i.e. you do as documented, no error, but nothing happens).
 
== 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 ==
== How To Test ==
Line 121: Line 140:


* Any architecture
* Any architecture
Remove the grubby package
Upgrade to rawhide / Fedora 30.
 
  $ sudo dnf remove grubby


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


[[Category:ChangeAnnounced]]
[[Category:ChangeAcceptedF30]]
[[Category:SystemWideChange]]
[[Category:SystemWideChange]]

Latest revision as of 12:28, 8 April 2022

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: 2022-04-08
  • 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
 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, setting "GRUB_ENABLE_BLSCFG=false" in /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.

Return from User Experience

A number of people ran into problems with BLS, cf https://bugzilla.redhat.com/show_bug.cgi?id=1636466 or https://bugzilla.redhat.com/show_bug.cgi?id=1651686 as examples. The main issue appears to be that a number of places document a way to pass kernel options that is no longer working with BLS, i.e. edit /etc/default/grub before running grub2-mkconfig.

Samples of documentation that BLS invalidates:

Documentation in RHEL is being updated to promote a method that works with BLS, but web search will still point users to various techniques that no longer do, and fail silently (i.e. you do as documented, no error, but nothing happens).

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