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:
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user