Boot Source Override feature problems

Deepak Kodihalli deepak.kodihalli.83 at gmail.com
Fri Jun 11 22:17:10 AEST 2021


Hi!

On Thu, May 27, 2021 at 2:21 AM Konstantin Aladyshev
<aladyshev22 at gmail.com> wrote:
>
> Hello!
> I've merged almost all of my patchsets for the EFI/Legacy support in
> the Boot Override feature (only bmcweb patchset is left
> https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/40970) and I
> want to return to the discussion about the current implementation of
> the Boot Override feature in OpenBMC.
>
> First, here are implementation details from IPMI and Redfish specs for
> this feature:
>
> IPMI specification (Document Revision 1.1 October 1, 2013)
> ```
> IPMI:
> 1b - enabled/disabled
> 1b - one-time/permanent
> 1b - EFI/Legacy
> 4b - BDS (boot device selector)
>   0000b = No override
>   0001b = Force PXE
>   0010b = Force boot from default Hard-drive
>   0011b = Force boot from default Hard-drive, request Safe Mode
>   0100b = Force boot from default Diagnostic Partition
>   0101b = Force boot from default CD/DVD
>   0110b = Force boot into BIOS Setup
>   0111b = Force boot from remotely connected (redirected)
> Floppy/primary removable media
>   1001b = Force boot from primary remote media
>   1000b = Force boot from remotely connected (redirected) CD/DVD
>   1010b = reserved
>   1011b = Force boot from remotely connected (redirected) Hard Drive
>   1100-1110b = Reserved
>   1111b = Force boot from Floppy/primary removable media
> ```
> Redfish specification (DSP2046 2021.1 Redfish Resource and Schema
> Guide 18 May 2021)
> ```
> BootSourceOverrideEnabled - Continuous/Disabled/Once
> BootSourceOverrideMode - Legacy/UEFI
> BootSourceOverrideTarget -
>   BiosSetup = Boot to the BIOS setup utility.
>   Cd = Boot from the CD or DVD.
>   Diags = Boot to the manufacturer's diagnostics program.
>   Floppy = Boot from the floppy disk drive.
>   Hdd = Boot from a hard drive.
>   None = Boot from the normal boot device.
>   Pxe = Boot from the Pre-Boot EXecution (PXE) environment.
>   RemoteDrive (v1.2+) = Boot from a remote drive, such as an iSCSI target.
>   SDCard (v1.1+) = Boot from an SD card.
>   UefiBootNext (v1.5+) = Boot to the UEFI device that the BootNext
> property specifies.
>   UefiHttp (v1.1+) = Boot from a UEFI HTTP network location.
>   UefiShell = Boot to the UEFI Shell.
>   UefiTarget = Boot to the UEFI device specified in the
> UefiTargetBootSourceOverride property.
>   Usb = Boot from a system BIOS-specified USB device.
>   Utilities = Boot to the manufacturer's utilities program or programs
> ```
>
> In the OpenBMC the current Dbus interfaces for the Boot Override feature are:
> ```
> /xyz/openbmc_project/control/host0/boot:
>     - Interface: xyz.openbmc_project.Control.Boot.Source
>     - Interface: xyz.openbmc_project.Control.Boot.Mode
>     - Interface: xyz.openbmc_project.Control.Boot.Type
> /xyz/openbmc_project/control/host0/boot/one_time:
>     - Interface: xyz.openbmc_project.Control.Boot.Source
>     - Interface: xyz.openbmc_project.Control.Boot.Mode
>     - Interface: xyz.openbmc_project.Control.Boot.Type
>     - Interface: xyz.openbmc_project.Object.Enable
> ```
> It works this way:
> - when `xyz.openbmc_project.Object.Enable` property under
> `/xyz/openbmc_project/control/host0/boot/one_time` is set to `true` we
> use Boot.Source/Mode/Type under
> `/xyz/openbmc_project/control/host0/boot/one_time` for the override
> feature.
> - when `xyz.openbmc_project.Object.Enable` property under
> `/xyz/openbmc_project/control/host0/boot/one_time` is set to `false`
> we use Boot.Source/Mode/Type under
> `/xyz/openbmc_project/control/host0/boot` for the override feature.
>
> I don't really get why we split Override Source to `Boot.Source` and
> `Boot.Mode`, but this is the question for another time.
>
> Right now I want to discuss the main problem with this approach... it
> is that OVERRIDE IS ALWAYS ENABLED. This
> `xyz.openbmc_project.Object.Enable` property only indicates if we
> should use permanent or one-time override.
>
> I guess no one have noticed it since but by default override target
> (`Boot.Source`) is set to something like "None". So no one have
> experienced any difficulties. Override is enabled, but it says boot
> default.
>
> Proof that IPMI valid flag is always enabled:
> ```uint1_t validFlag = 1;```
> https://github.com/openbmc/phosphor-host-ipmid/blob/e76a61a2f7c19ed07e2bfe98533d82bc23692fc1/chassishandler.cpp#L1861
>
> `bmcweb` deals with this issue a little bit different (hello
> inconsistency!), it performs weird logic to decide if it should set
> `BootSourceOverrideEnabled` to `Disabled`.
> https://github.com/openbmc/bmcweb/blob/master/redfish-core/lib/systems.hpp#L951
> Which would get even weirder when support for EFI/Legacy selector
> would be merged:
> https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/40970/10/redfish-core/lib/systems.hpp#929
>
> So as you can see, the current approach is kinda buggy, ipmid always
> reports override as valid, bmcweb reports override as disabled when
> you write `BootSourceOverrideTarget = None`.
>
> This all is already a problem, but when we add Legacy/EFI selector
> support, things are getting really messy.
> ipmid can no longer always say that override is valid, since it would
> be overriding boot either to EFI or Legacy.
> bmcweb now can report that override is disabled only when
> `BootSourceOverrideTarget = None` and `BootSourceOverrideMode = EFI`.
> Weird, yeah? We write that we want override to `None/EFI`, but read
> that override is `Disabled`. Weird and obviously wrong.
>
> How to overcome all of this?
> To be honest I don't see any use in splitting Boot Override feature in
> two Dbus objects under `/xyz/openbmc_project/control/host0/boot` and
> `/xyz/openbmc_project/control/host0/boot/one_time`, since we don't
> need to fallback to permanent override after one-time override.
>
> So I think the problem can be solved if we would have something like
> this on Dbus to represent Boot Override feature:
> ```
> /xyz/openbmc_project/control/host0/boot:
>     - Interface: xyz.openbmc_project.Control.Boot.Source
>     - Interface: xyz.openbmc_project.Control.Boot.Mode
>     - Interface: xyz.openbmc_project.Control.Boot.Type
>     - Interface: xyz.openbmc_project.Control.Boot.Permanent # true/false
>     - Interface: xyz.openbmc_project.Object.Enable
> ```
> I don't know if we can reuse any of the current interfaces for the
> `xyz.openbmc_project.Control.Boot.Permanent` feature, but I think
> something like these interfaces are what we need. With
> `Boot.Permanent` we can drop `one-time` object, and with
> `Object.Enable` we can solve all the aforementioned problems.

Sorry for the late response! I think this works. The two different
D-Bus objects were trying to achieve the same thing (as Boot.Permanent
true/false), but as you noted they probably both needed an
Object.Enable interface. Boot.Permanent does seem simpler.

Thanks,
Deepak


More information about the openbmc mailing list