1
0
mirror of https://git.FreeBSD.org/src.git synced 2026-06-02 11:24:32 +00:00

stand/efi: Allow RELAXED or STRICT boot policies

The RELAXED boot policy will automatically search for any root
filesystem (currently zfs only) on any device. STRICT policy only
searches on the boot device. RELEAXED will still prefer the device we
booted from, which is the smallest behavior change we should do. STRICT
may be needed for releases, though.

Sponsored by:		Netflix
Reviewed by:		glebius
Differential Revision:	https://reviews.freebsd.org/D55107
This commit is contained in:
Warner Losh
2026-02-26 17:57:39 -07:00
parent d69fc3a9dc
commit 784150fd25
2 changed files with 42 additions and 8 deletions
+7 -3
View File
@@ -76,7 +76,7 @@ efizfs_get_guid_by_handle(EFI_HANDLE handle, uint64_t *guid)
}
static void
insert_zfs(EFI_HANDLE handle, uint64_t guid)
insert_zfs(EFI_HANDLE handle, uint64_t guid, bool head)
{
zfsinfo_t *zi;
@@ -84,7 +84,10 @@ insert_zfs(EFI_HANDLE handle, uint64_t guid)
if (zi != NULL) {
zi->zi_handle = handle;
zi->zi_pool_guid = guid;
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);
if (head)
STAILQ_INSERT_HEAD(&zfsinfo, zi, zi_link);
else
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);
}
}
@@ -110,7 +113,8 @@ efi_zfs_probe(void)
snprintf(devname, sizeof(devname), "%s%dp%d:",
efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit);
if (zfs_probe_dev(devname, &guid, false) == 0)
insert_zfs(pd->pd_handle, guid);
insert_zfs(pd->pd_handle, guid,
pd->pd_handle == boot_img->DeviceHandle);
}
}
}
+35 -5
View File
@@ -143,6 +143,16 @@ UINT16 boot_current;
*/
EFI_LOADED_IMAGE *boot_img;
enum boot_policies {
STRICT,
RELAXED,
} boot_policy = RELAXED;
const char *policy_map[] = {
[STRICT] = "strict",
[RELAXED] = "relaxed",
};
static bool
has_keyboard(void)
{
@@ -592,13 +602,14 @@ find_currdev(bool do_bootmgr, char *boot_info, size_t boot_info_sz)
zfsinfo_t *zi;
/*
* Did efi_zfs_probe() detect the boot pool? If so, use the zpool
* it found, if it's sane. ZFS is the only thing that looks for
* disks and pools to boot. This may change in the future, however,
* if we allow specifying which pool to boot from via UEFI variables
* rather than the bootenv stuff that FreeBSD uses today.
* First try the zfs pool(s) that were on the boot device, then
* try any other pool if we have a relaxed policy. zfsinfo has
* the pools that had elements on the boot device first.
*/
STAILQ_FOREACH(zi, zfsinfo, zi_link) {
if (boot_policy == STRICT &&
zi->zi_handle != boot_img->DeviceHandle)
continue;
printf("Trying ZFS pool 0x%jx\n", zi->zi_pool_guid);
if (probe_zfs_currdev(zi->zi_pool_guid))
return (0);
@@ -1189,6 +1200,23 @@ efi_smbios_detect(void)
(void)smbios_detect(smbios_v2_ptr);
}
static void
set_boot_policy(void)
{
const char *policy;
if ((policy = getenv("boot_policy")) == NULL)
return;
for (int i = 0; i < nitems(policy_map); i++) {
if (strcmp(policy, policy_map[i]) == 0) {
boot_policy = i;
return;
}
}
printf("Unknown boot_policy '%s', defaulting to %s\n",
policy, policy_map[boot_policy]);
}
EFI_STATUS
main(int argc, CHAR16 *argv[])
{
@@ -1287,6 +1315,8 @@ main(int argc, CHAR16 *argv[])
read_loader_env("LoaderEnv", "/efi/freebsd/loader.env", false);
read_loader_env("NextLoaderEnv", NULL, true);
set_boot_policy();
/*
* We now have two notions of console. howto should be viewed as
* overrides. If console is already set, don't set it again.