From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Marta Lewandowska Date: Mon, 9 Oct 2023 08:53:18 +0200 Subject: [PATCH] search command: add flag to only search root dev bz#2223437 Signed-off-by: Marta Lewandowska --- grub-core/commands/search.c | 36 ++++++++++++++++++++++++++++++++++++ grub-core/commands/search_wrap.c | 5 +++++ grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++ include/grub/misc.h | 1 + include/grub/search.h | 3 ++- 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c index 57d26ced8a8e..94fe8b2872a1 100644 --- a/grub-core/commands/search.c +++ b/grub-core/commands/search.c @@ -85,6 +85,42 @@ iterate_device (const char *name, void *data) grub_device_close (dev); } + /* Skip it if it's not the root device when requested. */ + if (ctx->flags & SEARCH_FLAGS_ROOTDEV_ONLY) + { + const char *root_dev; + root_dev = grub_env_get ("root"); + if (root_dev != NULL && *root_dev != '\0') + { + char *root_disk = grub_malloc (grub_strlen(root_dev) + 1); + char *name_disk = grub_malloc (grub_strlen(name) + 1); + char *rem_1 = grub_malloc(grub_strlen(root_dev) + 1); + char *rem_2 = grub_malloc(grub_strlen(name) + 1); + + if (root_disk != NULL && name_disk != NULL && + rem_1 != NULL && rem_2 != NULL) + { + /* get just the disk name; partitions will be different. */ + grub_str_sep (root_dev, root_disk, ',', rem_1); + grub_str_sep (name, name_disk, ',', rem_2); + if (root_disk != NULL && *root_disk != '\0' && + name_disk != NULL && *name_disk != '\0') + if (grub_strcmp(root_disk, name_disk) != 0) + { + grub_free (root_disk); + grub_free (name_disk); + grub_free (rem_1); + grub_free (rem_2); + return 0; + } + } + grub_free (root_disk); + grub_free (name_disk); + grub_free (rem_1); + grub_free (rem_2); + } + } + #ifdef DO_SEARCH_FS_UUID #define compare_fn grub_strcasecmp #else diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 0b62acf85359..06b5f51eefb5 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -41,6 +41,7 @@ static const struct grub_arg_option options[] = 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}, + {"root-dev-only", 'r', 0, N_("Only probe root device."), 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}, @@ -75,6 +76,7 @@ enum options SEARCH_SET, SEARCH_NO_FLOPPY, SEARCH_EFIDISK_ONLY, + SEARCH_ROOTDEV_ONLY, SEARCH_HINT, SEARCH_HINT_IEEE1275, SEARCH_HINT_BIOS, @@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) if (state[SEARCH_EFIDISK_ONLY].set) flags |= SEARCH_FLAGS_EFIDISK_ONLY; + if (state[SEARCH_ROOTDEV_ONLY].set) + flags |= SEARCH_FLAGS_ROOTDEV_ONLY; + if (state[SEARCH_LABEL].set) grub_search_label (id, var, flags, hints, nhints); else if (state[SEARCH_FS_UUID].set) diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index cb454614022f..50af9ee1bdd9 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -619,6 +619,36 @@ grub_reverse (char *str) } } +/* Separate string into two parts, broken up by delimiter delim. */ +void +grub_str_sep (const char *s, char *p, char delim, char *r) +{ + char* t = grub_strndup(s, grub_strlen(s)); + + if (t != NULL && *t != '\0') + { + char* tmp = t; + + while (((*p = *t) != '\0') && ((*p = *t) != delim)) + { + p++; + t++; + } + *p = '\0'; + + if (*t != '\0') + { + t++; + while ((*r++ = *t++) != '\0') + ; + *r = '\0'; + } + grub_free (tmp); + } + else + grub_free (t); +} + /* Divide N by D, return the quotient, and store the remainder in *R. */ grub_uint64_t grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) diff --git a/include/grub/misc.h b/include/grub/misc.h index faae0ae8606c..981526644d29 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -314,6 +314,7 @@ void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT; int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); +void EXPORT_FUNC(grub_str_sep) (const char *s, char *p, char delim, char *r); /* Replace all `ch' characters of `input' with `with' and copy the result into `output'; return EOS address of `output'. */ diff --git a/include/grub/search.h b/include/grub/search.h index 4190aeb2cbf5..321d1400e451 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -22,7 +22,8 @@ enum search_flags { SEARCH_FLAGS_NO_FLOPPY = 1, - SEARCH_FLAGS_EFIDISK_ONLY = 2 + SEARCH_FLAGS_EFIDISK_ONLY = 2, + SEARCH_FLAGS_ROOTDEV_ONLY = 4 }; void grub_search_fs_file (const char *key, const char *var,