diff options
| -rw-r--r-- | stand/efi/libefi/efizfs.c | 10 | ||||
| -rw-r--r-- | 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. |
