2008-05-30 Robert Millan <rmh@aybabtu.com>

* commands/search.c (options): Add --fs_uuid option.
        (search_fs_uuid): New function.
        (grub_cmd_search): Fix --set argument passing.
        Use search_fs_uuid() when requested via --fs_uuid.
        (grub_search_init): Update help message.
        * fs/ext2.c (struct grub_ext2_sblock): Rename `unique_id' to `uuid'
        and redeclare it as an array of 16-bit words.
        (grub_ext2_uuid): New function.
        (grub_ext2_fs): Reference grub_ext2_uuid() in `uuid' struct member.
        * include/grub/fs.h (struct grub_fs): Add `uuid' struct member.
        * util/update-grub.in (GRUB_DEVICE_UUID, GRUB_DEVICE_BOOT)
        (GRUB_DEVICE_BOOT_UUID): New variables.
        (GRUB_DRIVE. GRUB_DRIVE_BOOT. GRUB_DRIVE_BOOT_GRUB): Remove.
        * util/grub.d/00_header.in: Set root using `search --fs_uuid' command
        whenever possible.
        * util/grub.d/10_hurd.in: Avoid explicit use of root drive.  Instead,
        just assume `root' variable has the right value.
        * util/grub.d/10_linux.in: Likewise.
        * util/grub-probe.c (probe): Probe for filesystem UUID when requested
        via PRINT_FS_UUID.
        (main): Recognise `-t fs_uuid' argument.
This commit is contained in:
robertmh 2008-05-30 11:04:08 +00:00
parent 01b73ec8eb
commit 6219127445
9 changed files with 159 additions and 37 deletions

View file

@ -1,7 +1,7 @@
/* search.c - search devices based on a file or a filesystem label */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2005,2007,2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,6 +32,7 @@ static const struct grub_arg_option options[] =
{
{"file", 'f', 0, "search devices by a file (default)", 0, 0},
{"label", 'l', 0, "search devices by a filesystem label", 0, 0},
{"fs_uuid", 'u', 0, "search devices by a filesystem UUID", 0, 0},
{"set", 's', GRUB_ARG_OPTION_OPTIONAL, "set a variable to the first device found", "VAR", ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
@ -84,6 +85,54 @@ search_label (const char *key, const char *var)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
}
static void
search_fs_uuid (const char *key, const char *var)
{
int count = 0;
auto int iterate_device (const char *name);
int iterate_device (const char *name)
{
grub_device_t dev;
dev = grub_device_open (name);
if (dev)
{
grub_fs_t fs;
fs = grub_fs_probe (dev);
if (fs && fs->uuid)
{
char *uuid;
(fs->uuid) (dev, &uuid);
if (grub_errno == GRUB_ERR_NONE && uuid)
{
if (grub_strcmp (uuid, key) == 0)
{
/* Found! */
grub_printf (" %s", name);
if (count++ == 0 && var)
grub_env_set (var, name);
}
grub_free (uuid);
}
}
grub_device_close (dev);
}
grub_errno = GRUB_ERR_NONE;
return 0;
}
grub_device_iterate (iterate_device);
if (count == 0)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
}
static void
search_file (const char *key, const char *var)
{
@ -136,11 +185,13 @@ grub_cmd_search (struct grub_arg_list *state, int argc, char **args)
if (argc == 0)
return grub_error (GRUB_ERR_INVALID_COMMAND, "no argument specified");
if (state[2].set)
var = state[2].arg ? : "root";
if (state[3].set)
var = state[3].arg ? state[3].arg : "root";
if (state[1].set)
search_label (args[0], var);
else if (state[2].set)
search_fs_uuid (args[0], var);
else
search_file (args[0], var);
@ -151,8 +202,8 @@ GRUB_MOD_INIT(search)
{
(void) mod; /* To stop warning. */
grub_register_command ("search", grub_cmd_search, GRUB_COMMAND_FLAG_BOTH,
"search [-f|-l|-s] NAME",
"Search devices by a file or a filesystem label."
"search [-f|-l|-u|-s] NAME",
"Search devices by file, filesystem label or filesystem UUID."
" If --set is specified, the first device found is"
" set to a variable. If no variable name is"
" specified, \"root\" is used.",