#2001 PR merged: fedora29 grub2-efi-x64-modules does not contain linuxefi module

Labels: fixed / solved / done, minor bug

gdha opened issue at 2018-12-10 17:03:

jsmeix commented at 2018-12-11 08:10:

@gdha
I wonder if the currently unconditioned test for /etc/fedora-release
to skip the linuxefi GRUB module is sufficiently backward compatible
so that things still work with Fedora before 29?

rmetrich commented at 2018-12-11 10:14:

@jsmeix that's what I'm testing now

rmetrich commented at 2018-12-11 10:57:

@gdha @jsmeix I don't know exactly what this Grub linuxefi module is but it still works without it on Fedora 27.

jsmeix commented at 2018-12-11 13:02:

By Googling for "Grub linuxefi module" I found only
https://lists.gnu.org/archive/html/grub-devel/2014-01/msg00120.html
as the best explanation what that Grub linuxefi module is.

By Googling for "GRUB_USE_LINUXEFI" (cf. /etc/default/grub) I also found
https://lists.gnu.org/archive/html/help-grub/2016-08/msg00014.html
which reads (excerpt)

linuxefi.mod ... I need that for the EFI based boot

so that you may have to test on UEFI systems if things still
work with older Fedora even without the Grub linuxefi module.

If someone here may know more about it I could only think of
@gozora

gozora commented at 2018-12-11 16:06:

@rmetrich

I don't know exactly what this Grub linuxefi module is but it still works without it on Fedora 27.

It might very well be, that it is working because linuxefi and initrdefi options might be built in directly into Grub or might be part of other module, even more interesting is that linuxefi and initrdefi options might be substituted by linux and initrd options

In general I would say that if you can boot ReaR rescue system, you did not broke anything.

V.

gozora commented at 2018-12-11 16:47:

In my https://github.com/rear/rear/pull/2001#issuecomment-446258448, I was partially right ...
I've installed Fedora29 and used UEFI boot, my default entry in grub.cfg looked something like this:

...
linux   /vmlinuz-4.19.7-300.fc29.x86_64 root=/dev/mapper/fedora-root ro resume=/dev/mapper/fedora-swap rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap rhgb quiet LANG=en_US.UTF-8
initrdefi /initramfs-4.19.7-300.fc29.x86_64.img
...

However, I've noticed entry for rescue which showed something like this:

...
linux   /vmlinuz-0-rescue-1acdfce117504294b63a270c24b2afc8 root=/dev/mapper/fedora-root ro resume=/dev/mapper/fedora-swap rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap rhgb quiet
initrd  /initramfs-0-rescue-1acdfce117504294b63a270c24b2afc8.img
...

When I've tried to change initrdefi to initrd for my default entry, everything booted just fine.

Apart from all this, initrdefi looks to be part linux.mod on Fedora29

[root@fedora29 x86_64-efi]# grep initrdefi *
command.lst:initrdefi: linux
Binary file linux.mod matches

[root@fedora29 x86_64-efi]# grep linuxefi *
Binary file chain.mod matches
command.lst:linuxefi: linux
Binary file linux.mod matches

So for Fedora 29 it is save to omit linuxefi.mod as it functionality was moved to linux.mod.

I'll now download Fedora 28 (unfortunately my test Fedora 28 is booting Legacy BIOS) to check Grub behavior there ...

Will keep you posted.

V.

gozora commented at 2018-12-11 18:12:

Every day you learn something new is a good day!
I just found out that on Fedora 28 you can safely omit linuxefi.mod since it looks to be somehow replaceable by chain.mod. This IMHO makes this PR backward compatible.

I've successfully created UEFI bootloader (test1.efi) and booted with following options:
Fedora 28

grub2-mkimage -O x86_64-efi -o /boot/efi/EFI/tst/test1.efi -p "/EFI/BOOT" part_gpt part_msdos fat ext2 normal boot configfile linux chain multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs

Fedora 29

grub2-mkimage -O x86_64-efi -o /boot/efi/EFI/tst/test1.efi -p "/EFI/BOOT" part_gpt part_msdos fat ext2 normal boot configfile linux chain jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs

Notice also that on Fedora 29 I had to drop multiboot.mod as it does not exist on my installation.

@gdha, @rmetrich
Are you missing /usr/lib/grub/x86_64-efi/multiboot.mod as well on your Fedora 29 ?

V.

rmetrich commented at 2018-12-12 08:24:

I would propose to keep the actual list of modules and modify that as a for loop and include available ones. All we need to find out is the directory computation (/usr/lib/grub/$(uname -r)-efi) on Fedora, different on SuSE ...)

gdha commented at 2018-12-12 09:45:

@gozora @rmetrich I have no UEFI system anymore, so I cannot fully test it out. However, I like the idea mentioned by https://github.com/rear/rear/pull/2001#issuecomment-446502109

jsmeix commented at 2018-12-12 09:50:

@rmetrich @gozora
could you post where GRUB modules are located
on your various systems that you currently can access
like I did in
https://github.com/rear/rear/issues/1996#issuecomment-446246942

@gozora
regarding the GRUB modules directory e.g. /usr/lib/grub2/x86_64-efi/linuxefi.mod
versus /boot/grub2/x86_64-efi/linuxefi.mod see my question in
https://github.com/rear/rear/issues/1996#issuecomment-446246942

If the GRUB modules that are actually used by GRUB when booting
are in general somewhere under the /boot/ directory it is probably
much simpler to search for them only in /boot/ by something like

grub_modules=""
for grub_module in part_gpt part_msdos fat ext2 normal chain boot configfile linux linuxefi multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs ; do
    test "$( find /boot -type f -name "$grub_module.mod" )" && grub_modules="$grub_modules $grub_module"
done
...
$gmkimage $v -O x86_64-efi -c $TMP_DIR/mnt/EFI/BOOT/embedded_grub.cfg -o $TMP_DIR/mnt/EFI/BOOT/BOOTX64.efi -p "/EFI/BOOT" "$grub_modules"

rmetrich commented at 2018-12-12 10:04:

Fedora and RHEL (7, 8) have them in /usr/lib/grub/$(uname -p)-efi/

jsmeix commented at 2018-12-12 10:19:

When on Fedora and RHEL (7, 8)
there are no GRUB modules below /boot/
but only below /usr/lib/grub*/ then something like

    test "$( find /boot /usr/lib/grub* -type f -name "$grub_module.mod" 2>/dev/null )" && ...

should find them both on SUSE and Red Hat systems.

jsmeix commented at 2018-12-12 10:36:

FYI regarding "what this Grub linuxefi module is":

Sleeping over things always helps :-)

I remember now that I had asked our GRUB maintainer
about linuxefi some time ago and here excerpts
from my mail and his reply:

Date: Wed, 8 Jun 2016 19:02:31 +0800
Subject: Re: Is linuxefi in grub2 a SUSE specific thing?

> I am wondering if 'linuxefi' (and 'initrdefi')
> in our grub2 RPM is a SUSE specific thing?

NO. It's a UEFI Secure Boot specfic thing.

> I am wondering if loading the kernel
> and initrd in grub.cfg via
> ---------------------------------------------------------
> menuentry ...
>     linuxefi /boot/vmlinuz...
>     initrdefi /boot/initrd...
> ---------------------------------------------------------
> is a SUSE specific way how to configure GRUB2
> to boot on (U)EFI systems?

We have to support UEFI Secure Boot
so we have to use linuxefi as it implemented
the need verification mechanism via
shim-lock protocol to loaded the grub2 image ..

Moreover it leverages the kernel UEFI handover
protcol to boot the kernel via its own efistub and
beneficial from kernel bug fixing for firmware issues. ..

> According to your grub2 RPM changelog entry
> ---------------------------------------------------------------
> * Mon Nov 26 2012 mchang@suse.com
> - ship a Secure Boot UEFI compatible bootloader (fate#314485)
> - added secureboot patches which introduces new linuxefi module
>   that is able to perform verifying signed images via exported
>   protocol from shim.
>   ...
>   - grub2-secureboot-add-linuxefi.patch
> ---------------------------------------------------------------
> it seems linuxefi in grub2 is a SUSE specific thing
> that is not in upstream GRUB2.

It's not upstreamed for various reasons .. Although
down-stream distros like SUSE and RedHat already
used that for a while, upstream is still have problem
accepting it ..

> Background information:
> 
> The reason why I am interested in 'linuxefi' and 'initrdefi'
> is that the Relax-and-Recover (rear) recovery system also
> needs to boot on (U)EFI systems and to do that the
> bootloader of the rear recovery system needs to
> be configured appropriately.
> When grub2 in SUSE needs specific configuration that
> is different compared to upstream GRUB2, then I must
> adapt rear to create its recovery system different
> on SUSE systems.

Please consider it a standard to boot
in UEFI Secure Boot for now, until someone
could convince upstream to include it,
there no other grub command could be used
for now in UEFI Secure Boot as Microsoft only
recongize linuxefi as a they audit the code
to issue their certifcates for shim loader ...

Hmmm... somehow this looks very similar to
https://github.com/rear/rear/issues/866#issuecomment-224569648
;-))

gdha commented at 2018-12-12 10:37:

@jsmeix on my fedora29 (bios with efi tools present) I get:

# grub_modules=""
# for grub_module in part_gpt part_msdos fat ext2 normal chain boot configfile linux linuxefi multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs ; do
    test "$( find /boot -type f -name "$grub_module.mod" )" && grub_modules="$grub_modules $grub_module"
done
# echo $grub_modules
part_gpt part_msdos fat ext2 normal chain boot configfile linux multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio reboot search test echo btrfs

gozora commented at 2018-12-12 16:36:

@jsmeix

When on Fedora and RHEL (7, 8)
there are no GRUB modules below /boot/
but only below /usr/lib/grub*/ then something like

test "$( find /boot /usr/lib/grub* -type f -name "$grub_module.mod" 2>/dev/null )" && ...

should find them both on SUSE and Red Hat systems.

There is yet another complication. On Fedora 29, it looks like multiboot module is available for Legacy boot but not for UEFI boot:

[root@fedora29 grub]# pwd
/usr/lib/grub
[root@fedora29 grub]# ll
total 32
drwxr-xr-x.  4 root root    39 Dec 11 17:31 .
dr-xr-xr-x. 33 root root  4096 Dec 11 17:16 ..
drwxr-xr-x.  2 root root 12288 Dec 11 17:15 i386-pc
drwxr-xr-x.  2 root root  8192 Dec 11 17:31 x86_64-efi
[root@fedora29 grub]# find . -name "multiboot*"
./i386-pc/multiboot.mod
./i386-pc/multiboot2.mod

Should user have (for whatever reason) installed Legacy boot modules next to UEFI modules, output would give false positive for presence of (at least) multiboot module:

# for grub_module in part_gpt part_msdos fat ext2 normal chain boot configfile linux linuxefi multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs ; do
>     test "$( find /boot /usr/lib/grub* -type f -name "$grub_module.mod" 2>/dev/null )" && grub_modules="$grub_modules $grub_module"
> done
# echo $grub_modules
part_gpt part_msdos fat ext2 normal chain boot configfile linux multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs

Notice multiboot module presence, despite it is not available in x86_64-efi.

V.

jsmeix commented at 2018-12-12 16:51:

https://github.com/rear/rear/pull/2001#issuecomment-446541365
from @gdha indicates that on "fedora29" GRUB modules exist in /boot/
so that we would not need to search also elsewhere (like in /usr/lib/grub*)
but it contradicts what @rmetrich wrote in
https://github.com/rear/rear/pull/2001#issuecomment-446531360
which idicates GRUB modules do not exist in /boot/ on "Fedora and RHEL (7, 8)".

And there is still my question from
https://github.com/rear/rear/issues/1996#issuecomment-446246942
where I wonder if the GRUB modules that are actually used when booting
must be under /boot/ and not elsewhere (like in /usr/lib/grub*).
But I don't know how GRUB finds its modules when booting.
I would like to search in ReaR for GRUB modules at the same place(s)
where GRUB will look for its modules when booting.

jsmeix commented at 2018-12-12 17:01:

Because we are here in the function build_bootx86_efi
we know we are in the UEFI case here so that we could
restrict where to search for GRUB modules
e.g. as a quick and dirty hack additionally check
that what was found contains 'efi' (ignore case) like

grub_modules=""
for grub_module in part_gpt qqq part_msdos QQQ fat ext2 normal chain boot configfile linux linuxefi multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo qqq btrfs ; do
    test "$( find /boot -type f -name "$grub_module.mod" 2>/dev/null | grep -i efi )" && grub_modules="$grub_modules $grub_module"
done

[Export of Github issue for rear/rear.]