From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20M=C3=A9trich?= Date: Tue, 8 Feb 2022 08:39:11 +0100 Subject: [PATCH] search: new --efidisk-only option on EFI systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using 'search' on EFI systems, we sometimes want to exclude devices that are not EFI disks (e.g. md, lvm). This is typically used when wanting to chainload when having a software raid (md) for EFI partition: with no option, 'search --file /EFI/redhat/shimx64.efi' sets root envvar to 'md/boot_efi' which cannot be used for chainloading since there is no effective EFI device behind. This commit also refactors handling of --no-floppy option. Signed-off-by: Renaud Métrich [rharwood: apply rmetrich's flags initialization fix] Signed-off-by: Robbie Harwood --- grub-core/commands/search.c | 27 +++++++++++++++++++++++---- grub-core/commands/search_wrap.c | 18 ++++++++++++------ include/grub/search.h | 15 ++++++++++++--- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c index 51656e361cc..57d26ced8a8 100644 --- a/grub-core/commands/search.c +++ b/grub-core/commands/search.c @@ -47,7 +47,7 @@ struct search_ctx { const char *key; const char *var; - int no_floppy; + enum search_flags flags; char **hints; unsigned nhints; int count; @@ -62,10 +62,29 @@ iterate_device (const char *name, void *data) int found = 0; /* Skip floppy drives when requested. */ - if (ctx->no_floppy && + if (ctx->flags & SEARCH_FLAGS_NO_FLOPPY && name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') return 0; + /* Limit to EFI disks when requested. */ + if (ctx->flags & SEARCH_FLAGS_EFIDISK_ONLY) + { + grub_device_t dev; + dev = grub_device_open (name); + if (! dev) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (! dev->disk || dev->disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID) + { + grub_device_close (dev); + grub_errno = GRUB_ERR_NONE; + return 0; + } + grub_device_close (dev); + } + #ifdef DO_SEARCH_FS_UUID #define compare_fn grub_strcasecmp #else @@ -261,13 +280,13 @@ try (struct search_ctx *ctx) } void -FUNC_NAME (const char *key, const char *var, int no_floppy, +FUNC_NAME (const char *key, const char *var, enum search_flags flags, char **hints, unsigned nhints) { struct search_ctx ctx = { .key = key, .var = var, - .no_floppy = no_floppy, + .flags = flags, .hints = hints, .nhints = nhints, .count = 0, diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 47fc8eb9966..0b62acf8535 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -40,6 +40,7 @@ static const struct grub_arg_option options[] = N_("Set a variable to the first device found."), N_("VARNAME"), ARG_TYPE_STRING}, {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, + {"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0}, {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, N_("First try the device HINT. If HINT ends in comma, " "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING}, @@ -73,6 +74,7 @@ enum options SEARCH_FS_UUID, SEARCH_SET, SEARCH_NO_FLOPPY, + SEARCH_EFIDISK_ONLY, SEARCH_HINT, SEARCH_HINT_IEEE1275, SEARCH_HINT_BIOS, @@ -89,6 +91,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) const char *id = 0; int i = 0, j = 0, nhints = 0; char **hints = NULL; + enum search_flags flags = 0; if (state[SEARCH_HINT].set) for (i = 0; state[SEARCH_HINT].args[i]; i++) @@ -180,15 +183,18 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) goto out; } + if (state[SEARCH_NO_FLOPPY].set) + flags |= SEARCH_FLAGS_NO_FLOPPY; + + if (state[SEARCH_EFIDISK_ONLY].set) + flags |= SEARCH_FLAGS_EFIDISK_ONLY; + if (state[SEARCH_LABEL].set) - grub_search_label (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); + grub_search_label (id, var, flags, hints, nhints); else if (state[SEARCH_FS_UUID].set) - grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); + grub_search_fs_uuid (id, var, flags, hints, nhints); else if (state[SEARCH_FILE].set) - grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); + grub_search_fs_file (id, var, flags, hints, nhints); else grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); diff --git a/include/grub/search.h b/include/grub/search.h index d80347df34b..4190aeb2cbf 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -19,11 +19,20 @@ #ifndef GRUB_SEARCH_HEADER #define GRUB_SEARCH_HEADER 1 -void grub_search_fs_file (const char *key, const char *var, int no_floppy, +enum search_flags + { + SEARCH_FLAGS_NO_FLOPPY = 1, + SEARCH_FLAGS_EFIDISK_ONLY = 2 + }; + +void grub_search_fs_file (const char *key, const char *var, + enum search_flags flags, char **hints, unsigned nhints); -void grub_search_fs_uuid (const char *key, const char *var, int no_floppy, +void grub_search_fs_uuid (const char *key, const char *var, + enum search_flags flags, char **hints, unsigned nhints); -void grub_search_label (const char *key, const char *var, int no_floppy, +void grub_search_label (const char *key, const char *var, + enum search_flags flags, char **hints, unsigned nhints); #endif