dracutdevs / dracut

dracut the event driven initramfs infrastructure
https://github.com/dracutdevs/dracut/wiki
GNU General Public License v2.0
573 stars 396 forks source link

dracut uses wrong version description for Unified Kernel Images #2639

Closed ErikSteiner closed 3 months ago

ErikSteiner commented 3 months ago

Describe the bug I am on Nobara, a Fedora 39 based distro. I replaced GRUB with systemd-boot, and activated Unified Kernel Images with this tutorial.

The key is, that kernel-install finally runs dracut --kernel-cmdline "${BOOT_OPTIONS[*]}" -f ${noimageifnotneeded:+--noimageifnotneeded} --uefi "$LOADER_ENTRY" "$KERNEL_VERSION" at /etc/kernel/install.d/90-loaderentry.install

To build the Kernel modules of NVIDIA, Fedora uses akmods. akmods reads out the Kernel version either from GRUB's, or systemd-boot's default entry from version.

If I execute bootctl list it shows the entries like this:

         type: Boot Loader Specification Type #2 (.efi)
        title: Nobara Linux 39 (GNOME Edition) (39 (GNOME Edition)) (x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsyn>
           id: x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsync.fc39.x86_64.efi
       source: /efi//EFI/Linux/x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsync.fc39.x86_64.efi
     sort-key: nobara
      version: 39 (GNOME Edition)
        linux: /efi//EFI/Linux/x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsync.fc39.x86_64.efi
      options: root=UUID=5f674150-g147-46ni-bfcf-kbj42ph3bhxp ro rootflags=subvol=@ quiet rd.luks.uuid=5h59xbnk-fe33>

The version that akmods uses is 39 (GNOME Edition), however, it expects to find the Kernel version there. I already opened a bug report on RedHat for akmods, because the procedure of it compares this version string with uname-r and thinks that it must also build the modules for this kernel and adds it to the list of kernels to be processed. The whole procedure may not be ideal.

default_kernel="$(bootctl list --json=short | jq -r '.[] | select(.isDefault).version')" and gets 39 (GNOME Edition)

# fall back to current kernel if user didn't provide one
if [[ ! -n "${kernels}" ]] ; then
    kernels="$(uname -r)"
fi

if ! $(echo "${kernels}" | grep -q "${default_kernel}") ; then
    kernels="${kernels} ${default_kernel}"
fi

The list of Kernels looks then like this 6.7.6-201.fsync.fc39.x86_64 39 (GNOME Edition)

The for loop now takes each entry of ${kernels} and executes check_kmods and fails when processing 39:

for kernel in ${kernels} ; do
    check_kmods ${kernel}
done

The log reads accordingly:

Checking kmods exists for 6.7.5-200.fsync.fc39.x86_64 [OK]
Checking kmods exists for 39 [OK]
Files needed for building modules against kernel
39 could not be found as the following
directories are missing
/usr/src/kernels/39/
/lib/modules/39/build/Is the correct kernel-devel package i[FAILED]

I already looked in the source code of dracut and it seems like the version is parsed from /etc/os-release which states VERSION="39 (GNOME Edition)"

Distribution used Nobara Linux, based on Fedora 39

Dracut version

# dracut --version
dracut 059-16.fc39

Init system systemd-boot 254.10-1.fc39

To Reproduce Easiest procedure would be to either install Fedora or Nobara, replace GRUB with systemd-boot, as it is written in the tutorial. Maybe with just the dracut command and systemd-boot, one could get a similar and easier result. As long as /etc/os-release is written like this.

Expected behavior

# bootctl list
         type: Boot Loader Specification Type #2 (.efi)
        title: Nobara Linux 39 (GNOME Edition) (6.7.6-201.fsync.fc39.x86_64) (x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsyn>
           id: x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsync.fc39.x86_64.efi
       source: /efi//EFI/Linux/x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsync.fc39.x86_64.efi
     sort-key: nobara
      version: 6.7.6-201.fsync.fc39.x86_64
        linux: /efi//EFI/Linux/x2ghneaig2s5bvwa4r9xhanv79koho9d-6.7.6-201.fsync.fc39.x86_64.efi
      options: root=UUID=5f674150-g147-46ni-bfcf-kbj42ph3bhxp ro rootflags=subvol=@ quiet rd.luks.uuid=5h59xbnk-fe33>

Pay attention to the kernel string, that states 39 (GNOME Edition) in the original output.

Additional context Because the problem and the tools involved were not clear from the start, I also opened the following tickets:

aafeijoo-suse commented 3 months ago

https://github.com/uapi-group/specifications/blob/85c5d51953769b1aee636d5bd37cfa107fa7923f/specs/boot_loader_specification.md?plain=1#L390-L391

The `PRETTY_NAME=` and `VERSION_ID=` fields in the embedded `os-release` file
are used the same as `title` and `version` in the Type #1 entries.

https://github.com/uapi-group/specifications/blob/85c5d51953769b1aee636d5bd37cfa107fa7923f/specs/boot_loader_specification.md?plain=1#L224-L226

* `version` is a human-readable version for this menu item. This is usually the
  kernel version and is intended for use by OSes to install multiple kernel
  versions with the same `title` field.

vs

https://www.freedesktop.org/software/systemd/man/latest/os-release.html#VERSION_ID=

VERSION_ID=

A lower-case string (mostly numeric, no spaces or other characters outside of 0–9, a–z, ".", "_" and "-")
identifying the operating system version

The OS version is not the kernel version. dracut should not alter the system os-release file, I think you should open an issue here instead: https://github.com/uapi-group/specifications/issues

ErikSteiner commented 3 months ago

My concern is aimed at the different way in which title: and version: are filled. Once with systemd's kernel-install and once with dracut as UKI.

While I could live with the way the title: comes about, the information used is too generic for version:. I am talking about the output of bootctl.

My point is not to change the /etc/os-release file or any other system file. My point is first to highlight that both tools use different information to display title and version and then to talk about a better display for type 2 entries.

Unlike Type 1 entries, Type 2 entries cannot be customized by adapting a .conf file, but dracut integrates this information for Type 2 entries in the image. I know about the possibility of using .conf files for Type 2 entries, but I would like to leave these out for practical reasons.

This shows the entries under Fedora 39, where GRUB has been replaced by systemd-boot. It shows Type 1 entries:

$ sudo bootctl list
         type: Boot Loader Specification Type #1 (.conf)
        title: Fedora Linux 39 (Workstation Edition) (default) (selected)
           id: 1e011fbc121d4549861233adcff0e0b6-6.5.6-300.fc39.x86_64.conf
       source: /efi//loader/entries/1e011fbc121d4549861233adcff0e0b6-6.5.6-300.fc39.x86_64.conf
     sort-key: fedora
      version: 6.5.6-300.fc39.x86_64
   machine-id: 1e011fbc121d4549861233adcff0e0b6
        linux: /efi//1e011fbc121d4549861233adcff0e0b6/6.5.6-300.fc39.x86_64/linux
       initrd: /efi//1e011fbc121d4549861233adcff0e0b6/6.5.6-300.fc39.x86_64/initrd
      options: root=UUID=15a20237-f5f2-4175-bcf7-3eac8af22537 ro rootflags=subvol=root rhgb quiet systemd.machine_id=>

         type: Boot Loader Specification Type #1 (.conf)
        title: Fedora Linux 39 (Workstation Edition) - Rescue Image
           id: 1e011fbc121d4549861233adcff0e0b6-0-rescue.conf
       source: /efi//loader/entries/1e011fbc121d4549861233adcff0e0b6-0-rescue.conf
      version: 6.5.6-300.fc39.x86_64
   machine-id: 1e011fbc121d4549861233adcff0e0b6
        linux: /efi//1e011fbc121d4549861233adcff0e0b6/0-rescue/linux
       initrd: /efi//1e011fbc121d4549861233adcff0e0b6/0-rescue/initrd
      options: root=UUID=15a20237-f5f2-4175-bcf7-3eac8af22537 ro rootflags=subvol=root rhgb quiet rd.auto=1

         type: Automatic
        title: Reboot Into Firmware Interface
           id: auto-reboot-to-firmware-setup
       source: /sys/firmware/efi/efivars/LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f

This shows the entries under Fedora 39, where UKIs have been activated in addition to the previous procedure.

$ sudo bootctl list
         type: Boot Loader Specification Type #2 (.efi)
        title: Fedora Linux 39 (Workstation Edition) (39 (Workstation Edition)) (6.5.6-300.fc39.x86_64-1e011fbc121d4>
           id: 6.5.6-300.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
       source: /efi//EFI/Linux/6.5.6-300.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
     sort-key: fedora
      version: 39 (Workstation Edition)
        linux: /efi//EFI/Linux/6.5.6-300.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
      options: root=UUID=15a20237-f5f2-4175-bcf7-3eac8af22537 ro rootflags=subvol=root rhgb quiet

         type: Boot Loader Specification Type #2 (.efi)
        title: Fedora Linux 39 (Workstation Edition) (39 (Workstation Edition)) (0-rescue-1e011fbc121d4549861233adcf>
           id: 0-rescue-1e011fbc121d4549861233adcff0e0b6.efi
       source: /efi//EFI/Linux/0-rescue-1e011fbc121d4549861233adcff0e0b6.efi
     sort-key: fedora
      version: 39 (Workstation Edition)
        linux: /efi//EFI/Linux/0-rescue-1e011fbc121d4549861233adcff0e0b6.efi
      options: root=UUID=15a20237-f5f2-4175-bcf7-3eac8af22537 ro rootflags=subvol=root rhgb quiet

         type: Automatic
        title: Reboot Into Firmware Interface
           id: auto-reboot-to-firmware-setup
       source: /sys/firmware/efi/efivars/LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f

While I'm not a fan of how the title of Type 1 entries are generated, it at least meets the requirement of the boot loader specifications.

However, the version: for Type 2 is not declared with the kernel version, but with VERSION from /etc/os-release , which results in 39 (Workstation Edition) for every entry.

This is not ideal considering the background of

This is usually the kernel version and is intended for use by OSes to install multiple kernel versions [...].

Especially when multiple kernels are installed and Type 1 specifies the kernel version anyway.

These are typical entries, when two kernel versions are installed. Both entries share the same version: version: 39 (Workstation Edition)

# bootctl list
         type: Boot Loader Specification Type #2 (.efi)
        title: Fedora Linux 39 (Workstation Edition) (39 (Workstation Edition)) (6.7.9-200.fc39.x86_64-1e011fbc121d4>
           id: 6.7.9-200.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
       source: /efi//EFI/Linux/6.7.9-200.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
     sort-key: fedora
      version: 39 (Workstation Edition)
        linux: /efi//EFI/Linux/6.7.9-200.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
      options: root=UUID=15a20237-f5f2-4175-bcf7-3eac8af22537 ro rootflags=subvol=root rhgb quiet

         type: Boot Loader Specification Type #2 (.efi)
        title: Fedora Linux 39 (Workstation Edition) (39 (Workstation Edition)) (6.5.6-300.fc39.x86_64-1e011fbc121d4>
           id: 6.5.6-300.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
       source: /efi//EFI/Linux/6.5.6-300.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
     sort-key: fedora
      version: 39 (Workstation Edition)
        linux: /efi//EFI/Linux/6.5.6-300.fc39.x86_64-1e011fbc121d4549861233adcff0e0b6.efi
      options: root=UUID=15a20237-f5f2-4175-bcf7-3eac8af22537 ro rootflags=subvol=root rhgb quiet

I therefore assume that my request was not clearly communicated by me at the beginning and so I am looking forward to your feedback.

aafeijoo-suse commented 3 months ago

My concern is aimed at the different way in which title: and version: are filled. Once with systemd's kernel-install and once with dracut as UKI.

Wrong, read my previous comment. UKIs can also be created with ukify, which belongs to systemd, and the version for type #2 entries is the OS version (os-release VERSION_ID). Your concern is how the specification is defined, which btw it makes sense not to display the kernel version as the version field for type #2 entries (multiple UKIs can have the same kernel version).

While I could live with the way the title: comes about, the information used is too generic for version:. I am talking about the output of bootctl.

This tool belongs to systemd, not to dracut.

My point is not to change the /etc/os-release file or any other system file. My point is first to highlight that both tools use different information to display title and version and then to talk about a better display for type 2 entries.

Unlike Type 1 entries, Type 2 entries cannot be customized by adapting a .conf file, but dracut integrates this information for Type 2 entries in the image.

dracut doesn't do anything special, the way systemd-boot displays the menu just follows the BLS.

ErikSteiner commented 3 months ago

I dug a little deeper into the source code of systemd and now understand your statement about the os-release file: systemd-boot reads the properties from the embedded os-release file: https://github.com/systemd/systemd/blob/4651e1428dae935bb32dec082db5155f2e8b1c98/src/boot/efi/boot.c#L2142

Your concern is how the specification is defined, which btw it makes sense not to display the kernel version as the version field for type #2 entries (multiple UKIs can have the same kernel version).

From the point of view of the os-release file, it naturally makes no sense to display a kernel version under VERSION, because VERSION shows the operating system version. An operating system version can have several different kernel versions. And here I think we've been talking past each other the whole time.

According to your written source, the bootloader should not display the content of VERSION from the os-release file under version (bootloader), but "usually the kernel version and is intended for use by OSes to install multiple kernel versions".

From this it appears to me that nothing can be done by Dracut, but that the approach of systemd to read the os-release file completely and use the information of VERSION as version in the bootloader is not ideal. Especially since systemd uses $KERNEL_VERSION as version for type 1.

I hope that this has lifted the mood a little ;)

aafeijoo-suse commented 3 months ago

From this it appears to me that nothing can be done by Dracut

Closing this issue then.

but that the approach of systemd to read the os-release file completely and use the information of VERSION as version in the bootloader is not ideal. Especially since systemd uses $KERNEL_VERSION as version for type 1.

I think you already wrote an issue there.

I hope that this has lifted the mood a little ;)

No problem at all :)