From 7b74857658250b261fa7b89e27c405ceaf95f16e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 14:02:23 +0100 Subject: [PATCH 1/4] Search hinting support --- commands/search.c | 24 ++++++++++++++++++------ commands/search_wrap.c | 11 +++++++---- include/grub/search.h | 9 ++++++--- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/commands/search.c b/commands/search.c index 01e83739b..c3626d352 100644 --- a/commands/search.c +++ b/commands/search.c @@ -30,7 +30,8 @@ #include void -FUNC_NAME (const char *key, const char *var, int no_floppy) +FUNC_NAME (const char *key, const char *var, int no_floppy, + const char **hints, unsigned nhints) { int count = 0; char *buf = NULL; @@ -118,22 +119,32 @@ FUNC_NAME (const char *key, const char *var, int no_floppy) return (found && var); } + auto void try (void); + void try (void) + { + unsigned i; + for (i = 0; i < nhints; i++) + if (iterate_device (hints[i])) + return; + grub_device_iterate (iterate_device); + } + /* First try without autoloading if we're setting variable. */ if (var) { saved_autoload = grub_fs_autoload_hook; grub_fs_autoload_hook = 0; - grub_device_iterate (iterate_device); + try (); /* Restore autoload hook. */ grub_fs_autoload_hook = saved_autoload; /* Retry with autoload if nothing found. */ if (grub_errno == GRUB_ERR_NONE && count == 0) - grub_device_iterate (iterate_device); + try (); } else - grub_device_iterate (iterate_device); + try (); grub_free (buf); @@ -148,7 +159,8 @@ grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc, if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified"); - FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0); + FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (const char **) (args + 2), + argc > 2 ? argc - 2 : 0); return grub_errno; } @@ -165,7 +177,7 @@ GRUB_MOD_INIT(search_fs_label) { cmd = grub_register_command (COMMAND_NAME, grub_cmd_do_search, - "NAME [VARIABLE]", + "NAME [VARIABLE] [HINTS]", "Search devices by " SEARCH_TARGET "." " If VARIABLE is specified, " "the first device found is set to a variable."); diff --git a/commands/search_wrap.c b/commands/search_wrap.c index 2891d85d7..eb9279e87 100644 --- a/commands/search_wrap.c +++ b/commands/search_wrap.c @@ -62,11 +62,14 @@ grub_cmd_search (grub_extcmd_t cmd, int argc, char **args) var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root"; if (state[SEARCH_LABEL].set) - grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set); + grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set, + (const char **) (args + 1), argc - 1); else if (state[SEARCH_FS_UUID].set) - grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set); + grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set, + (const char **) (args + 1), argc - 1); else if (state[SEARCH_FILE].set) - grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set); + grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set, + (const char **) (args + 1), argc - 1); else return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); @@ -80,7 +83,7 @@ GRUB_MOD_INIT(search) cmd = grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_BOTH, - N_("search [-f|-l|-u|-s|-n] NAME"), + N_("[-f|-l|-u|-s|-n] NAME [HINTS]"), N_("Search devices by file, filesystem label" " or filesystem UUID." " If --set is specified, the first device found is" diff --git a/include/grub/search.h b/include/grub/search.h index e8f9db285..3c56f0305 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -19,8 +19,11 @@ #ifndef GRUB_SEARCH_HEADER #define GRUB_SEARCH_HEADER 1 -void grub_search_fs_file (const char *key, const char *var, int no_floppy); -void grub_search_fs_uuid (const char *key, const char *var, int no_floppy); -void grub_search_label (const char *key, const char *var, int no_floppy); +void grub_search_fs_file (const char *key, const char *var, int no_floppy, + const char **hints, unsigned nhints); +void grub_search_fs_uuid (const char *key, const char *var, int no_floppy, + const char **hints, unsigned nhints); +void grub_search_label (const char *key, const char *var, int no_floppy, + const char **hints, unsigned nhints); #endif From 53d4ca1afcb194cf67426e9c423476497d393c80 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 13 Sep 2010 11:48:01 +0200 Subject: [PATCH 2/4] Change from direct arguments to --hint --- grub-core/commands/search_wrap.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 14028bec7..68497fa0d 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -37,6 +37,8 @@ static const struct grub_arg_option options[] = {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING}, {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, + {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, + N_("First try the device HINT"), N_("HINT"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -47,6 +49,7 @@ enum options SEARCH_FS_UUID, SEARCH_SET, SEARCH_NO_FLOPPY, + SEARCH_HINT }; static grub_err_t @@ -54,6 +57,11 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; const char *var = 0; + int nhints = 0; + + if (state[SEARCH_HINT].set) + while (state[SEARCH_HINT].args[nhints]) + nhints++; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified"); @@ -63,13 +71,13 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) if (state[SEARCH_LABEL].set) grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set, - (const char **) (args + 1), argc - 1); + (const char **) state[SEARCH_HINT].args, nhints); else if (state[SEARCH_FS_UUID].set) grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set, - (const char **) (args + 1), argc - 1); + (const char **) state[SEARCH_HINT].args, nhints); else if (state[SEARCH_FILE].set) grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set, - (const char **) (args + 1), argc - 1); + (const char **) state[SEARCH_HINT].args, nhints); else return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); @@ -83,7 +91,8 @@ GRUB_MOD_INIT(search) cmd = grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_BOTH, - N_("[-f|-l|-u|-s|-n] NAME [HINTS]"), + N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]" + " NAME"), N_("Search devices by file, filesystem label" " or filesystem UUID." " If --set is specified, the first device found is" From 1f1dd48a1748e8bff5b5d7cb293d30468d403ed7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 13 Sep 2010 12:16:22 +0200 Subject: [PATCH 3/4] support subpartition hints --- grub-core/commands/search.c | 64 ++++++++++++++++++++++++++++++-- grub-core/commands/search_wrap.c | 9 +++-- include/grub/search.h | 6 +-- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c index 9b693e76f..f265f86d6 100644 --- a/grub-core/commands/search.c +++ b/grub-core/commands/search.c @@ -28,10 +28,12 @@ #include #include #include +#include +#include void FUNC_NAME (const char *key, const char *var, int no_floppy, - const char **hints, unsigned nhints) + char **hints, unsigned nhints) { int count = 0; grub_fs_autoload_hook_t saved_autoload; @@ -115,13 +117,67 @@ FUNC_NAME (const char *key, const char *var, int no_floppy, return (found && var); } + auto int part_hook (grub_disk_t disk, const grub_partition_t partition); + int part_hook (grub_disk_t disk, const grub_partition_t partition) + { + char *partition_name, *devname; + int ret; + + partition_name = grub_partition_get_name (partition); + if (! partition_name) + return 1; + + devname = grub_xasprintf ("%s,%s", disk->name, partition_name); + grub_free (partition_name); + if (!devname) + return 1; + ret = iterate_device (devname); + grub_free (devname); + + return ret; + } + auto void try (void); void try (void) { unsigned i; for (i = 0; i < nhints; i++) - if (iterate_device (hints[i])) - return; + { + char *end; + if (!hints[i][0]) + continue; + end = hints[i] + grub_strlen (hints[i]) - 1; + if (*end == ',') + *end = 0; + if (iterate_device (hints[i])) + { + if (!*end) + *end = ','; + return; + } + if (!*end) + { + grub_device_t dev; + int ret; + dev = grub_device_open (hints[i]); + if (!dev) + { + *end = ','; + continue; + } + if (!dev->disk) + { + grub_device_close (dev); + *end = ','; + continue; + } + ret = grub_partition_iterate (dev->disk, part_hook); + *end = ','; + grub_device_close (dev); + if (ret) + return; + } + } grub_device_iterate (iterate_device); } @@ -153,7 +209,7 @@ grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc, if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified"); - FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (const char **) (args + 2), + FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2), argc > 2 ? argc - 2 : 0); return grub_errno; diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 68497fa0d..61eb78203 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -38,7 +38,8 @@ static const struct grub_arg_option options[] = N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING}, {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT"), N_("HINT"), ARG_TYPE_STRING}, + N_("First try the device HINT. If HINT ends in comma, " + "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -71,13 +72,13 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) if (state[SEARCH_LABEL].set) grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set, - (const char **) state[SEARCH_HINT].args, nhints); + state[SEARCH_HINT].args, nhints); else if (state[SEARCH_FS_UUID].set) grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set, - (const char **) state[SEARCH_HINT].args, nhints); + state[SEARCH_HINT].args, nhints); else if (state[SEARCH_FILE].set) grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set, - (const char **) state[SEARCH_HINT].args, nhints); + state[SEARCH_HINT].args, nhints); else return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); diff --git a/include/grub/search.h b/include/grub/search.h index 3c56f0305..d80347df3 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -20,10 +20,10 @@ #define GRUB_SEARCH_HEADER 1 void grub_search_fs_file (const char *key, const char *var, int no_floppy, - const char **hints, unsigned nhints); + char **hints, unsigned nhints); void grub_search_fs_uuid (const char *key, const char *var, int no_floppy, - const char **hints, unsigned nhints); + char **hints, unsigned nhints); void grub_search_label (const char *key, const char *var, int no_floppy, - const char **hints, unsigned nhints); + char **hints, unsigned nhints); #endif From 0fd75223cca283694ffec2f74b2635604e1a3d5d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 13 Sep 2010 12:17:22 +0200 Subject: [PATCH 4/4] Add missing ChangeLog --- ChangeLog.hints | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ChangeLog.hints diff --git a/ChangeLog.hints b/ChangeLog.hints new file mode 100644 index 000000000..16ae1cc90 --- /dev/null +++ b/ChangeLog.hints @@ -0,0 +1,6 @@ +2009-12-28 Vladimir Serbinenko + + Search hints support. + + * commands/search.c (FUNC_NAME): New arguments hints and nhints. + All users updated.