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:
parent
01b73ec8eb
commit
6219127445
9 changed files with 159 additions and 37 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
|||
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.
|
||||
|
||||
2008-05-30 Robert Millan <rmh@aybabtu.com>
|
||||
|
||||
* util/biosdisk.c (map): Redefine structure to hold information
|
||||
|
|
|
@ -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.",
|
||||
|
|
37
fs/ext2.c
37
fs/ext2.c
|
@ -120,7 +120,7 @@ struct grub_ext2_sblock
|
|||
grub_uint32_t feature_compatibility;
|
||||
grub_uint32_t feature_incompat;
|
||||
grub_uint32_t feature_ro_compat;
|
||||
grub_uint32_t unique_id[4];
|
||||
grub_uint16_t uuid[8];
|
||||
char volume_name[16];
|
||||
char last_mounted_on[64];
|
||||
grub_uint32_t compression_info;
|
||||
|
@ -861,7 +861,39 @@ grub_ext2_label (grub_device_t device, char **label)
|
|||
if (data)
|
||||
*label = grub_strndup (data->sblock.volume_name, 14);
|
||||
else
|
||||
*label = 0;
|
||||
*label = NULL;
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
grub_dl_unref (my_mod);
|
||||
#endif
|
||||
|
||||
grub_free (data);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_ext2_uuid (grub_device_t device, char **uuid)
|
||||
{
|
||||
struct grub_ext2_data *data;
|
||||
grub_disk_t disk = device->disk;
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
grub_dl_ref (my_mod);
|
||||
#endif
|
||||
|
||||
data = grub_ext2_mount (disk);
|
||||
if (data)
|
||||
{
|
||||
*uuid = grub_malloc (40 + sizeof ('\0'));
|
||||
grub_sprintf (*uuid, "%02x%02x-%02x-%02x-%02x-%02x%02x%02x",
|
||||
grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7]));
|
||||
}
|
||||
else
|
||||
*uuid = NULL;
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
grub_dl_unref (my_mod);
|
||||
|
@ -881,6 +913,7 @@ static struct grub_fs grub_ext2_fs =
|
|||
.read = grub_ext2_read,
|
||||
.close = grub_ext2_close,
|
||||
.label = grub_ext2_label,
|
||||
.uuid = grub_ext2_uuid,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ struct grub_fs
|
|||
caller. */
|
||||
grub_err_t (*label) (grub_device_t device, char **label);
|
||||
|
||||
/* Return the uuid of the device DEVICE in UUID. The uuid is
|
||||
returned in a grub_malloc'ed buffer and should be freed by the
|
||||
caller. */
|
||||
grub_err_t (*uuid) (grub_device_t device, char **uuid);
|
||||
|
||||
/* The next filesystem. */
|
||||
struct grub_fs *next;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
enum {
|
||||
PRINT_FS,
|
||||
PRINT_FS_UUID,
|
||||
PRINT_DRIVE,
|
||||
PRINT_DEVICE,
|
||||
PRINT_PARTMAP,
|
||||
|
@ -110,6 +111,7 @@ probe (const char *path, char *device_name)
|
|||
char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
|
||||
int abstraction_type;
|
||||
grub_device_t dev = NULL;
|
||||
grub_fs_t fs;
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
|
@ -185,10 +187,13 @@ probe (const char *path, char *device_name)
|
|||
goto end;
|
||||
}
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
grub_util_error ("%s", grub_errmsg);
|
||||
|
||||
if (print == PRINT_FS)
|
||||
{
|
||||
struct stat st;
|
||||
grub_fs_t fs;
|
||||
|
||||
stat (path, &st);
|
||||
|
||||
|
@ -210,19 +215,21 @@ probe (const char *path, char *device_name)
|
|||
|
||||
if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
|
||||
grub_util_error ("files differ");
|
||||
|
||||
fs = file->fs;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
grub_util_error ("%s", grub_errmsg);
|
||||
}
|
||||
|
||||
printf ("%s\n", fs->name);
|
||||
}
|
||||
|
||||
if (print == PRINT_FS_UUID)
|
||||
{
|
||||
char *uuid;
|
||||
if (! fs->uuid)
|
||||
grub_util_error ("%s does not support UUIDs", fs->name);
|
||||
|
||||
fs->uuid (dev, &uuid);
|
||||
|
||||
printf ("%s\n", uuid);
|
||||
}
|
||||
|
||||
end:
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
|
@ -257,7 +264,7 @@ Probe device information for a given path (or device, if the -d option is given)
|
|||
\n\
|
||||
-d, --device given argument is a system device, not a path\n\
|
||||
-m, --device-map=FILE use FILE as the device map [default=%s]\n\
|
||||
-t, --target=(fs|drive|device|partmap|abstraction)\n\
|
||||
-t, --target=(fs|fs_uuid|drive|device|partmap|abstraction)\n\
|
||||
print filesystem module, GRUB drive, system device, partition map module or abstraction module [default=fs]\n\
|
||||
-h, --help display this message and exit\n\
|
||||
-V, --version print version information and exit\n\
|
||||
|
@ -302,6 +309,8 @@ main (int argc, char *argv[])
|
|||
case 't':
|
||||
if (!strcmp (optarg, "fs"))
|
||||
print = PRINT_FS;
|
||||
else if (!strcmp (optarg, "fs_uuid"))
|
||||
print = PRINT_FS_UUID;
|
||||
else if (!strcmp (optarg, "drive"))
|
||||
print = PRINT_DRIVE;
|
||||
else if (!strcmp (optarg, "device"))
|
||||
|
|
|
@ -38,8 +38,12 @@ set default=${GRUB_DEFAULT}
|
|||
set timeout=${GRUB_TIMEOUT}
|
||||
EOF
|
||||
|
||||
if [ "x${GRUB_DRIVE}" = "x" ] ; then : ; else
|
||||
echo "set root=${GRUB_DRIVE}"
|
||||
# If there's a filesystem UUID that GRUB is capable of identifiing, use it;
|
||||
# otherwise set root as per value in device.map.
|
||||
if [ "x${GRUB_DEVICE_BOOT_UUID}" = "x" ] ; then
|
||||
echo "set root=`grub-probe --device ${GRUB_DEVICE_BOOT} --target=drive`"
|
||||
else
|
||||
echo "search --fs_uuid ${GRUB_DEVICE_BOOT_UUID} --set"
|
||||
fi
|
||||
|
||||
case ${platform}:${GRUB_TERMINAL} in
|
||||
|
|
|
@ -31,9 +31,9 @@ for i in /boot/gnumach.gz /boot/gnumach ; do
|
|||
if test -e $i ; then
|
||||
basename=`basename $i`
|
||||
dirname=`dirname $i`
|
||||
grub_dirname=`echo ${dirname} | sed -e "s%^/boot%${GRUB_DRIVE_BOOT}%g"`
|
||||
rel_dirname=`make_system_path_relative_to_its_root $dirname`
|
||||
echo "Found GNU Mach: $i" >&2
|
||||
kernel=${grub_dirname}/${basename}
|
||||
kernel=${rel_dirname}/${basename}
|
||||
at_least_one=true
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -87,7 +87,7 @@ while [ "x$list" != "x" ] ; do
|
|||
echo "Found linux image: $linux" >&2
|
||||
basename=`basename $linux`
|
||||
dirname=`dirname $linux`
|
||||
grub_dirname=`echo ${dirname} | sed -e "s%^/boot%${GRUB_DRIVE_BOOT}%g"`
|
||||
rel_dirname=`make_system_path_relative_to_its_root $dirname`
|
||||
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
|
||||
alt_version=`echo $version | sed -e "s,\.old$,,g"`
|
||||
|
||||
|
@ -105,11 +105,11 @@ while [ "x$list" != "x" ] ; do
|
|||
|
||||
cat << EOF
|
||||
menuentry "${OS}, linux ${version}" {
|
||||
linux ${grub_dirname}/${basename} root=${GRUB_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}
|
||||
linux ${rel_dirname}/${basename} root=${GRUB_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}
|
||||
EOF
|
||||
if test -n "${initrd}" ; then
|
||||
cat << EOF
|
||||
initrd ${grub_dirname}/${initrd}
|
||||
initrd ${rel_dirname}/${initrd}
|
||||
EOF
|
||||
fi
|
||||
cat << EOF
|
||||
|
@ -118,11 +118,11 @@ EOF
|
|||
|
||||
cat << EOF
|
||||
menuentry "${OS}, linux ${version} (single-user mode)" {
|
||||
linux ${grub_dirname}/${basename} root=${GRUB_DEVICE} ro single ${GRUB_CMDLINE_LINUX}
|
||||
linux ${rel_dirname}/${basename} root=${GRUB_DEVICE} ro single ${GRUB_CMDLINE_LINUX}
|
||||
EOF
|
||||
if test -n "${initrd}" ; then
|
||||
cat << EOF
|
||||
initrd ${grub_dirname}/${initrd}
|
||||
initrd ${rel_dirname}/${initrd}
|
||||
EOF
|
||||
fi
|
||||
cat << EOF
|
||||
|
|
|
@ -102,20 +102,16 @@ fi
|
|||
|
||||
# Device containing our userland. Typically used for root= parameter.
|
||||
GRUB_DEVICE="`grub-probe --target=device /`"
|
||||
GRUB_DEVICE_UUID="`grub-probe --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`"
|
||||
|
||||
# Device containing our /boot partition. Usually the same as GRUB_DEVICE.
|
||||
GRUB_DEVICE_BOOT="`grub-probe --target=device /boot`"
|
||||
GRUB_DEVICE_BOOT_UUID="`grub-probe --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`"
|
||||
|
||||
# Filesystem for the device containing our userland. Used for stuff like
|
||||
# choosing Hurd filesystem module.
|
||||
GRUB_FS="`grub-probe --target=fs / 2> /dev/null || echo unknown`"
|
||||
|
||||
# GRUB path to /. Only used for "set root=". Not critical.
|
||||
GRUB_DRIVE="`grub-probe --target=drive /`" || true
|
||||
|
||||
# GRUB path to /boot
|
||||
GRUB_DRIVE_BOOT="`convert_system_path_to_grub_path /boot`"
|
||||
|
||||
# GRUB path to /boot/grub
|
||||
GRUB_DRIVE_BOOT_GRUB="`convert_system_path_to_grub_path /boot/grub`"
|
||||
|
||||
if test -f ${sysconfdir}/default/grub ; then
|
||||
. ${sysconfdir}/default/grub
|
||||
fi
|
||||
|
@ -155,7 +151,7 @@ esac
|
|||
|
||||
# These are defined in this script, export them here so that user can
|
||||
# override them.
|
||||
export GRUB_DEVICE GRUB_FS GRUB_DRIVE GRUB_DRIVE_BOOT GRUB_DRIVE_BOOT_GRUB GRUB_FONT_PATH GRUB_PRELOAD_MODULES
|
||||
export GRUB_DEVICE GRUB_DEVICE_UUID GRUB_DEVICE_BOOT GRUB_DEVICE_BOOT_UUID GRUB_FS GRUB_FONT_PATH GRUB_PRELOAD_MODULES
|
||||
|
||||
# These are optional, user-defined variables.
|
||||
export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL GRUB_SERIAL_COMMAND
|
||||
|
|
Loading…
Reference in a new issue