EFI Boot order with CentOS 7: Network Boot vs. Local Boot

Problem:
Provisioning a CentOS 7 host:
Anaconda adds an EFI boot entry named “CentOS” and puts it first in the boot order so subsequent boots are always done without trying the network boot first. This means that in case i want to build the host again, i would have to manually change the boot order first.
When i remove the boot entry using efibootmgr, the network boot works by auto-detecting the installation (done with this: https://github.com/theforeman/community-templates/blob/develop/provisioning_templates/snippet/pxegrub2_chainload.erb) but i also want the host to boot without the Foreman host being available.

Any ideas? I would assume this is a quite common issue …?

Hello Peter,

you described Foreman workflow correctly, we assume that hosts always boot from network. There is this nasty trick to chainload from disk via grub2 in EFI mode to allow that. We don’t provide any functionality to modify boot loaders either for BIOS or EFI in order to set hosts for reprovisioning.

This would require Foreman being able to manage host BIOS entries and/or EFI entries remotely. This is a huge task, every single vendor has a different protocol. While there are some common APIs like IPMI, it’s not very reliable but some users might do this and there might be even some Foreman plugin I am not aware of.

Well, we see someone asking for this from time to time, but as I described earlier this is not en easy job to implement. Unless you have some idea doing different approach - let me ask then: how you would like this to work?

thx, understandable that this is not done by Foreman. I was thinking of adding something like the following snippet to the provisioning template so it is executed after the installation to move the newly created boot entry to the end of the boot order:

# the EFI boot manager is only installed on UEFI hosts by Anaconda
if [[ -f /sbin/efibootmgr ]]; then
    echo "- Changing EFI boot order to preserve network boot ..."
    created_entry=$(efibootmgr | grep "BootOrder" | cut -d " " -f 2 | cut -d "," -f 1)
    others=$(efibootmgr | grep "BootOrder" | cut -d " " -f 2 | cut -d "," -f 2-)
    new_order="${others},${created_entry}"
    efibootmgr -q -o ${new_order}
fi

Its an ugly workaround but seems to work.

thx,
Peter

2 Likes

Wait, are you saying that after you install an EFI host via PXE, it then boots into the system avoiding PXE booting completely so you can’t actually reprovision it with Foreman? I was assuming this simply works, but looks like I haven’t tried this myself. Looks like you are not alone, Anaconda don’t have any option right now.

https://www.redhat.com/archives/kickstart-list/2016-September/msg00000.html

Then I would say let’s have this snippet in our community-templates, can you send a PR into kickstart and also debian templates? The script is fine, but I’d execute it only in EFI environment. Can you also test existance of /sys/firmware/efi/ prior trying to perform the steps?

Wait, are you saying that after you install an EFI host via PXE, it then boots into the system avoiding PXE booting completely so you can’t actually reprovision it with Foreman?

Exactly, thats the problem.

Then I would say let’s have this snippet in our community-templates, can you send a PR into kickstart and also debian templates? The script is fine, but I’d execute it only in EFI environment. Can you also test existance of /sys/firmware/efi/ prior trying to perform the steps?

I would also like to add an additional check for whether the first entry in the boot order is really the entry recently added by Anaconda, just in case this behavior changes in the future.

Can you make it work under BIOS (basically skipping the block on non-EFI system) and make PR into https://github.com/theforeman/community-templates/blob/develop/provisioning_templates/provision/kickstart_default.erb ?

I am bit puzzled why I did not hit this with libvirt VMs…

I guess that’s no, let me take a closer look. I do see the same on a server which has American Megatrends UEFI bios, that snippet will be likely helpful.

Hi,

If this gets into Foreman, can we make it as an option so we can enable/disable?

The default boot order for all vendors that I had contact so far (Dell, HP, Supermicro, Quanta and Gigabyte) is to boot from disk first and not network (legacy and UEFI). Then, when you want to reinstall a box, you just ask it to PXE boot (via BMC or IPMI).

Changing the boot order to always network boot is not good because chain loading from PXE to disk is not reliable. I have seem many GRUB issues and RSODs because of that. We even changed the local boot templates to just reboot in case someone force a box that’s not supposed to be reinstalled to PXE boot.

Thank you.

I was thinking about exactly same yesterday but the challenge is how to set this via efibootmgr because I believe that every single EFI firmware have different name for the netboot entry. There is nothing generic we can grep from the output and find out the ID of the netboot entry.

What could work however is to have a parameter, when set this entry will be set as the default after provisioning, you’d need to create a parameter with contents like “IPv4 PXE: Intel Gigabyte XYZ” which is the case on my board here.

It needs to be custom for each individual vendor I guess. More than that, if there are multiple NICs, there are also multiple entries:

[root@mac525400131301 ~]# efibootmgr
BootCurrent: 0008
Timeout: 0 seconds
BootOrder: 0002,0003,0004,0005,0007,000B,000C,000D,0008,0001,0000,0006,0009,000A
Boot0000* UiApp
Boot0001* UEFI Misc Device
Boot0002* UEFI QEMU DVD-ROM QM00005
Boot0003* UEFI PXEv4 (MAC:525400131301)
Boot0004* UEFI PXEv6 (MAC:525400131301)
Boot0005* UEFI HTTPv4 (MAC:525400131301)
Boot0006* EFI Internal Shell
Boot0007* UEFI HTTPv6 (MAC:525400131301)
Boot0008* CentOS
Boot0009* UEFI Floppy
Boot000A* UEFI Floppy 2
Boot000B* UEFI HTTP
Boot000C* UEFI HTTP
Boot000D* UEFI HTTP sdfsd

Example from Intel server board:

[root@mac00c03ad1018f ~]# efibootmgr
BootCurrent: 0003
Timeout: 3 seconds
BootOrder: 0003,000A,000B,0001,0000,0002
Boot0000* CentOS
Boot0001  UEFI: Built-in EFI Shell
Boot0002  Fedora
Boot0003* Red Hat Enterprise Linux
Boot000A* UEFI: IP4 Intel(R) I210 Gigabit Network Connection
Boot000B* RedHat Boot Manager

Example from ASUS Mobo:

[root@mac11aa002e21f1 ~]# efibootmgr
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0003,0004,0002,0001,0005,0006
Boot0000* Fedora
Boot0001* UEFI:CD/DVD Drive
Boot0002* Windows Boot Manager
Boot0003* Hard Drive
Boot0004* CD/DVD Drive
Boot0005* UEFI:Removable Device
Boot0006* UEFI:Network Device

Not sure how to approach this.

Here is my answer to the problem, adopted your hack as a opt in and also provides ability to “search” for an entry via egrep:

https://github.com/theforeman/community-templates/pull/557

Do you know why it changes boot order automatically? Or what is the thing responsible for the edit?

EFI firmware manages the entries, it depends on the EFI setting and vendor defaults. But generally, when a new entry is added it’s set as the default (first) entry.

1 Like