The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=784150fd25351f4a38f4d983882f4a26cc5d3272
commit 784150fd25351f4a38f4d983882f4a26cc5d3272 Author: Warner Losh <[email protected]> AuthorDate: 2026-02-27 00:57:39 +0000 Commit: Warner Losh <[email protected]> CommitDate: 2026-02-27 01:01:36 +0000 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 --- stand/efi/libefi/efizfs.c | 10 +++++++--- stand/efi/loader/main.c | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/stand/efi/libefi/efizfs.c b/stand/efi/libefi/efizfs.c index 563cf841143a..8ad410488b9c 100644 --- a/stand/efi/libefi/efizfs.c +++ b/stand/efi/libefi/efizfs.c @@ -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); } } } diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index d8508d7d91a0..f83db2e0668d 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -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.
