merge with mainline
This commit is contained in:
commit
dc4ca99e2e
20 changed files with 939 additions and 77 deletions
253
ChangeLog
253
ChangeLog
|
@ -1,3 +1,256 @@
|
|||
2010-08-04 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Support OpenSolaris in ZFS device resolution.
|
||||
|
||||
* configure.ac: Check for getmntany().
|
||||
* kern/emu/misc.c [HAVE_GETMNTANY]: Include `<sys/mnttab.h>'.
|
||||
[HAVE_GETMNTANY] (grub_find_zpool_from_mount_point): Add OpenSolaris
|
||||
support.
|
||||
|
||||
2010-08-03 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Fix grub-emu build.
|
||||
|
||||
* include/grub/util/misc.h: Move `<grub/util/libzfs.h>' to ...
|
||||
* include/grub/emu/misc.h: ... here.
|
||||
|
||||
* include/grub/util/misc.h (grub_get_libzfs_handle): Move function ...
|
||||
* include/grub/emu/misc.h (grub_get_libzfs_handle): ... here.
|
||||
|
||||
* util/misc.c: Remove `<grub/util/libzfs.h>'.
|
||||
[HAVE_LIBZFS] (libzfs_handle, fini_libzfs)
|
||||
(grub_get_libzfs_handle): Move to ...
|
||||
* kern/emu/misc.c [HAVE_LIBZFS] (__libzfs_handle, fini_libzfs)
|
||||
(grub_get_libzfs_handle): ... here.
|
||||
|
||||
2010-08-03 BVK Chaitanya <bvk.groups@gmail.com>
|
||||
|
||||
* script/execute.c (grub_script_execute_cmdline): Check for NULL
|
||||
as command name case.
|
||||
|
||||
2010-08-02 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* disk/raid.c (insert_array): Select unique numbers for named arrays
|
||||
as well, for use as keys in the disk cache.
|
||||
|
||||
2010-08-01 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub.d/10_kfreebsd.in: Initialize ${kfreebsd_device} as the
|
||||
kFreeBSD device name, except on ZFS where the filesystem label is
|
||||
used.
|
||||
(kfreebsd_entry): On ZFS root, load `opensolaris.ko', `zfs.ko' and
|
||||
`/boot/zfs/zpool.cache'.
|
||||
Set mountfrom kernel variable using ${kfreebsd_device}.
|
||||
|
||||
2010-08-01 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Make it even harder to use uninitialized `libzfs_handle' (and
|
||||
make the interface a bit simpler).
|
||||
|
||||
* include/grub/util/misc.h (grub_util_init_libzfs)
|
||||
(libzfs_handle): Remove.
|
||||
(grub_get_libzfs_handle): New prototype.
|
||||
|
||||
* util/misc.c [HAVE_LIBZFS] (libzfs_handle): Add `static'
|
||||
attribute.
|
||||
(grub_util_init_libzfs): Remove.
|
||||
(grub_get_libzfs_handle): New function.
|
||||
|
||||
* kern/emu/getroot.c (find_root_device_from_libzfs): Use
|
||||
grub_get_libzfs_handle() to obtain a libzfs handle instead of
|
||||
accessing `libzfs_handle' directly.
|
||||
|
||||
2010-08-01 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
|
||||
(grub_find_zpool_from_mount_point): New function prototypes.
|
||||
|
||||
* kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
|
||||
* kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.
|
||||
|
||||
* kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
|
||||
* kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove
|
||||
`static' attribute.
|
||||
|
||||
* kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
|
||||
finding zpool from mount point into ...
|
||||
* kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.
|
||||
|
||||
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
|
||||
requested path is part of a ZFS pool, use
|
||||
grub_find_zpool_from_mount_point() to detect its filesystem name,
|
||||
and generate a path with `/fsname@path' syntax.
|
||||
|
||||
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* include/grub/util/libzfs.h (libzfs_init): Set argument list to
|
||||
(void) rather than () so that this is a proper prototype.
|
||||
|
||||
2010-08-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* lib/arg.c (grub_arg_show_help): Add the necessary spacing.
|
||||
|
||||
2010-08-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* kern/emu/getroot.c (find_mount_point_from_dir): Compile only if
|
||||
[HAVE_LIBZFS && HAVE_LIBNVPAIR]
|
||||
|
||||
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* util/grub-mkrescue.in: Remove ${efi_dir} after building efi.img.
|
||||
|
||||
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* script/yylex.l (NAME): Remove [:digit:], redundant with [:alnum:].
|
||||
|
||||
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* docs/grub.texi (Simple configuration): Document GRUB_CMDLINE_XEN
|
||||
and GRUB_CMDLINE_XEN_DEFAULT. Recommend setting
|
||||
GRUB_GFXPAYLOAD_LINUX=text rather than unsetting it in order to
|
||||
disable gfxpayload.
|
||||
(Shell-like scripting): Add real content.
|
||||
(Serial terminal): Suggest `terminal_input serial; terminal_output
|
||||
serial' rather than putting the two commands on separate lines,
|
||||
since console input will be inoperative after the first command.
|
||||
(menuentry): Document --class, --users, and --hotkey options.
|
||||
(terminfo): Describe what `visually-ordered UTF-8' means (thanks,
|
||||
Vladimir Serbinenko).
|
||||
|
||||
2010-08-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* kern/misc.c (grub_memset): Optimise to reduce cache stalls.
|
||||
|
||||
2010-08-01 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
|
||||
(grub_find_zpool_from_mount_point): New function prototypes.
|
||||
|
||||
* kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
|
||||
* kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.
|
||||
|
||||
* kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
|
||||
* kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove
|
||||
`static' attribute.
|
||||
|
||||
* kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
|
||||
finding zpool from mount point into ...
|
||||
* kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.
|
||||
|
||||
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
|
||||
requested path is part of a ZFS pool, use
|
||||
grub_find_zpool_from_mount_point() to detect its filesystem name,
|
||||
and generate a path with `/fsname@path' syntax.
|
||||
|
||||
2010-08-01 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Prevent accidental use of uninitialized libzfs_handle.
|
||||
|
||||
* util/grub-probe.c (main): Move grub_util_init_libzfs() call to ...
|
||||
* kern/emu/getroot.c (find_root_device_from_libzfs): ... here.
|
||||
* util/misc.c (grub_util_init_libzfs): Make this function idempotent.
|
||||
|
||||
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* util/grub.d/20_linux_xen.in: Don't use UUID for LVM root (matching
|
||||
util/grub.d/10_linux.in). Fixes Debian bug #591093.
|
||||
|
||||
2010-08-01 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* kern/emu/getroot.c: Include `<grub/util/misc.h>'.
|
||||
|
||||
2010-07-31 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub.d/10_kfreebsd.in: Make module handling more generic.
|
||||
|
||||
2010-07-31 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* kern/emu/misc.c: Add missing license header.
|
||||
|
||||
2010-07-31 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* configure.ac: Check for `libzfs.h' and `libnvpair.h'.
|
||||
|
||||
* include/grub/util/libnvpair.h: Include `<config.h>'.
|
||||
[HAVE_LIBNVPAIR_H]: Include `<libnvpair.h>' instead of
|
||||
declaring libnvpair prototypes ourselves.
|
||||
* include/grub/util/libzfs.h: Include `<config.h>'.
|
||||
[HAVE_LIBZFS_H]: Include `<libzfs.h>' instead of
|
||||
declaring libzfs prototypes ourselves.
|
||||
|
||||
(libzfs_handle): Moved to ...
|
||||
* include/grub/util/misc.h (libzfs_handle): ... here.
|
||||
Include `<grub/util/libzfs.h>'.
|
||||
|
||||
2010-07-30 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* include/grub/emu/misc.h: Add missing license header.
|
||||
|
||||
2010-07-30 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Enable `grub-probe -t device' resolution on ZFS.
|
||||
|
||||
* configure.ac: Check for getfsstat(), libzfs and libnvpair.
|
||||
* include/grub/util/libnvpair.h: New file.
|
||||
* include/grub/util/libzfs.h: New file.
|
||||
|
||||
* kern/emu/getroot.c: Include `<assert.h>' and `<error.h>'.
|
||||
[HAVE_LIBZFS && HAVE_LIBNVPAIR]: Include `<grub/util/libzfs.h>' and
|
||||
`<grub/util/libnvpair.h>'.
|
||||
[HAVE_GETFSSTAT]: Include `<sys/mount.h>'.
|
||||
|
||||
(find_mount_point_from_dir): New static function.
|
||||
[HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_root_device_from_libzfs): New
|
||||
function.
|
||||
[HAVE_LIBZFS && HAVE_LIBNVPAIR] (grub_guess_root_device): Use
|
||||
find_root_device_from_libzfs() before ressorting to find_root_device().
|
||||
|
||||
* include/grub/util/misc.h (grub_util_init_libzfs): New function
|
||||
prototype.
|
||||
* util/misc.c: Include `<grub/util/libzfs.h>'.
|
||||
(grub_util_init_libzfs): New function.
|
||||
[HAVE_LIBZFS] (libzfs_handle): New global variable.
|
||||
[HAVE_LIBZFS] (fini_libzfs): New static function.
|
||||
(grub_util_init_libzfs): New function.
|
||||
* util/grub-probe.c (main): Call grub_util_init_libzfs().
|
||||
|
||||
2010-07-30 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* include/grub/emu/misc.h (grub_make_system_path_relative_to_its_root)
|
||||
(xmalloc, xrealloc, xstrdup, xasprintf): Add
|
||||
`warn_unused_result' attribute.
|
||||
* include/grub/misc.h (grub_strdup, grub_strndup, grub_strlen)
|
||||
(grub_xasprintf, grub_xvasprintf): Likewise.
|
||||
* include/grub/emu/misc.h (xasprintf): Remove duplicate prototype.
|
||||
|
||||
2010-07-29 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub-probe.c (PRINT_FS_LABEL): New enum value.
|
||||
(probe): Handle `PRINT_FS_LABEL'.
|
||||
(main): Handle `-t fs_label'.
|
||||
|
||||
2010-07-29 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* configure.ac: Remove grub-mkisofs checks.
|
||||
|
||||
2010-07-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/ieee1275/grub-install.in: Don't use empty grub_device.
|
||||
Reported by: Lennart Sorensen.
|
||||
|
||||
2010-07-20 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/grub.d/00_header.in: Remove compatibility with terminal.mod
|
||||
prior to terminal_input/terminal_output separation. It's been over 1.5
|
||||
years and those versions weren't widely deployed.
|
||||
|
||||
2010-07-22 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* disk/raid.c (insert_array): Don't count named arrays when looking
|
||||
for unused array numbers.
|
||||
Reported and tested by: Michael Guntsche.
|
||||
|
||||
2010-07-20 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* bus/usb/emu/usb.c (grub_usb_poll_devices): Add a dummy
|
||||
|
|
21
configure.ac
21
configure.ac
|
@ -246,15 +246,9 @@ else
|
|||
AC_PATH_PROG(HELP2MAN, help2man)
|
||||
fi
|
||||
|
||||
# Check for functions.
|
||||
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf)
|
||||
|
||||
# For grub-mkisofs
|
||||
AC_HEADER_MAJOR
|
||||
AC_HEADER_DIRENT
|
||||
AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid)
|
||||
AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
|
||||
AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h limits.h)
|
||||
# Check for functions and headers.
|
||||
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat getmntany)
|
||||
AC_CHECK_HEADERS(libzfs.h libnvpair.h)
|
||||
|
||||
# For opendisk() and getrawpartition() on NetBSD.
|
||||
# Used in util/deviceiter.c and in util/hostdisk.c.
|
||||
|
@ -806,6 +800,15 @@ if test x"$device_mapper_excuse" = x ; then
|
|||
[device_mapper_excuse="need devmapper library"])
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([zfs], [libzfs_init],
|
||||
[LDFLAGS="$LDFLAGS -lzfs"
|
||||
AC_DEFINE([HAVE_LIBZFS], [1],
|
||||
[Define to 1 if you have the ZFS library.])],)
|
||||
AC_CHECK_LIB([nvpair], [nvlist_print],
|
||||
[LDFLAGS="$LDFLAGS -lnvpair"
|
||||
AC_DEFINE([HAVE_LIBNVPAIR], [1],
|
||||
[Define to 1 if you have the NVPAIR library.])],)
|
||||
|
||||
AC_SUBST(ASFLAGS)
|
||||
|
||||
# Output files.
|
||||
|
|
19
disk/raid.c
19
disk/raid.c
|
@ -528,19 +528,22 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
grub_memset (&array->device, 0, sizeof (array->device));
|
||||
grub_memset (&array->start_sector, 0, sizeof (array->start_sector));
|
||||
|
||||
if (array->name)
|
||||
goto skip_duplicate_check;
|
||||
/* Check whether we don't have multiple arrays with the same number. */
|
||||
if (! array->name)
|
||||
{
|
||||
for (p = array_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (p->number == array->number)
|
||||
if (! p->name && p->number == array->number)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
if (array->name || p)
|
||||
{
|
||||
/* The number is already in use, so we need to find a new one. */
|
||||
int i = 0;
|
||||
/* The number is already in use, so we need to find a new one.
|
||||
(Or, in the case of named arrays, the array doesn't have its
|
||||
own number, but we need one that doesn't clash for use as a key
|
||||
in the disk cache. */
|
||||
int i = array->name ? 0x40000000 : 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -560,7 +563,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
i++;
|
||||
}
|
||||
}
|
||||
skip_duplicate_check:
|
||||
|
||||
/* mdraid 1.x superblocks have only a name stored not a number.
|
||||
Use it directly as GRUB device. */
|
||||
if (! array->name)
|
||||
|
|
182
docs/grub.texi
182
docs/grub.texi
|
@ -1062,6 +1062,11 @@ only to the default menu entry, after those listed in
|
|||
As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for
|
||||
NetBSD.
|
||||
|
||||
@item GRUB_CMDLINE_XEN
|
||||
@itemx GRUB_CMDLINE_XEN_DEFAULT
|
||||
As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for
|
||||
Linux and Xen.
|
||||
|
||||
@item GRUB_DISABLE_LINUX_UUID
|
||||
Normally, @command{grub-mkconfig} will generate menu entries that use
|
||||
universally-unique identifiers (UUIDs) to identify the root filesystem to
|
||||
|
@ -1113,8 +1118,8 @@ try several modes in sequence.
|
|||
Depending on your kernel, your distribution, your graphics card, and the
|
||||
phase of the moon, note that using this option may cause GNU/Linux to suffer
|
||||
from various display problems, particularly during the early part of the
|
||||
boot sequence. If you have problems, simply unset this option and GRUB will
|
||||
tell Linux to boot in normal text mode.
|
||||
boot sequence. If you have problems, set this option to @samp{text} and
|
||||
GRUB will tell Linux to boot in normal text mode.
|
||||
|
||||
@item GRUB_DISABLE_OS_PROBER
|
||||
Normally, @command{grub-mkconfig} will try to use the external
|
||||
|
@ -1143,6 +1148,142 @@ that file, making sure to leave at least the first two lines intact.
|
|||
@node Shell-like scripting
|
||||
@section Writing full configuration files directly
|
||||
|
||||
@c Some of this section is derived from the GNU Bash manual page, also
|
||||
@c copyrighted by the FSF.
|
||||
|
||||
@file{grub.cfg} is written in GRUB's built-in scripting language, which has
|
||||
a syntax quite similar to that of GNU Bash and other Bourne shell
|
||||
derivatives.
|
||||
|
||||
@heading Words
|
||||
|
||||
A @dfn{word} is a sequence of characters considered as a single unit by
|
||||
GRUB. Words are separated by @dfn{metacharacters}, which are the following
|
||||
plus space, tab, and newline:
|
||||
|
||||
@example
|
||||
@{ @} | & $ ; < >
|
||||
@end example
|
||||
|
||||
Quoting may be used to include metacharacters in words; see below.
|
||||
|
||||
@heading Reserved words
|
||||
|
||||
Reserved words have a special meaning to GRUB. The following words are
|
||||
recognised as reserved when unquoted and either the first word of a simple
|
||||
command or the third word of a @code{for} command:
|
||||
|
||||
@example
|
||||
! [[ ]] @{ @}
|
||||
case do done elif else esac fi for function
|
||||
if in menuentry select then time until while
|
||||
@end example
|
||||
|
||||
Not all of these reserved words have a useful purpose yet; some are reserved
|
||||
for future expansion.
|
||||
|
||||
@heading Quoting
|
||||
|
||||
Quoting is used to remove the special meaning of certain characters or
|
||||
words. It can be used to treat metacharacters as part of a word, to prevent
|
||||
reserved words from being recognised as such, and to prevent variable
|
||||
expansion.
|
||||
|
||||
There are three quoting mechanisms: the escape character, single quotes, and
|
||||
double quotes.
|
||||
|
||||
A non-quoted backslash (\) is the @dfn{escape character}. It preserves the
|
||||
literal value of the next character that follows, with the exception of
|
||||
newline.
|
||||
|
||||
Enclosing characters in single quotes preserves the literal value of each
|
||||
character within the quotes. A single quote may not occur between single
|
||||
quotes, even when preceded by a backslash.
|
||||
|
||||
Enclosing characters in double quotes preserves the literal value of all
|
||||
characters within the quotes, with the exception of @samp{$} and @samp{\}.
|
||||
The @samp{$} character retains its special meaning within double quotes.
|
||||
The backslash retains its special meaning only when followed by one of the
|
||||
following characters: @samp{$}, @samp{"}, @samp{\}, or newline. A
|
||||
backslash-newline pair is treated as a line continuation (that is, it is
|
||||
removed from the input stream and effectively ignored). A double quote may
|
||||
be quoted within double quotes by preceding it with a backslash.
|
||||
|
||||
@heading Variable expansion
|
||||
|
||||
The @samp{$} character introduces variable expansion. The variable name to
|
||||
be expanded may be enclosed in braces, which are optional but serve to
|
||||
protect the variable to be expanded from characters immediately following it
|
||||
which could be interpreted as part of the name.
|
||||
|
||||
Normal variable names begin with an alphabetic character, followed by zero
|
||||
or more alphanumeric characters.
|
||||
|
||||
Positional variable names consist of one or more digits. These are reserved
|
||||
for future expansion.
|
||||
|
||||
The special variable name @samp{?} expands to the exit status of the most
|
||||
recently executed command.
|
||||
|
||||
@heading Comments
|
||||
|
||||
A word beginning with @samp{#} causes that word and all remaining characters
|
||||
on that line to be ignored.
|
||||
|
||||
@heading Simple commands
|
||||
|
||||
A @dfn{simple command} is a sequence of words separated by spaces or tabs
|
||||
and terminated by a semicolon or a newline. The first word specifies the
|
||||
command to be executed. The remaining words are passed as arguments to the
|
||||
invoked command.
|
||||
|
||||
The return value of a simple command is its exit status.
|
||||
|
||||
@heading Compound commands
|
||||
|
||||
A @dfn{compound command} is one of the following:
|
||||
|
||||
@table @asis
|
||||
@item for @var{name} in @var{word} @dots{}; do @var{list}; done
|
||||
The list of words following @code{in} is expanded, generating a list of
|
||||
items. The variable @var{name} is set to each element of this list in turn,
|
||||
and @var{list} is executed each time. The return value is the exit status
|
||||
of the last command that executes. If the expansion of the items following
|
||||
@code{in} results in an empty list, no commands are executed, and the return
|
||||
status is 0.
|
||||
|
||||
@item if @var{list}; then @var{list}; [elif @var{list}; then @var{list};] @dots{} [else @var{list};] fi
|
||||
The @code{if} @var{list} is executed. If its exit status is zero, the
|
||||
@code{then} @var{list} is executed. Otherwise, each @code{elif} @var{list}
|
||||
is executed in turn, and if its exit status is zero, the corresponding
|
||||
@code{then} @var{list} is executed and the command completes. Otherwise,
|
||||
the @code{else} @var{list} is executed, if present. The exit status is the
|
||||
exit status of the last command executed, or zero if no condition tested
|
||||
true.
|
||||
|
||||
@item while @var{cond}; do @var{list}; done
|
||||
@itemx until @var{cond}; do @var{list}; done
|
||||
The @code{while} command continuously executes the @code{do} @var{list} as
|
||||
long as the last command in @var{cond} returns an exit status of zero. The
|
||||
@code{until} command is identical to the @code{while} command, except that
|
||||
the test is negated; the @code{do} @var{list} is executed as long as the
|
||||
last command in @var{cond} returns a non-zero exit status. The exit status
|
||||
of the @code{while} and @code{until} commands is the exit status of the last
|
||||
@code{do} @var{list} command executed, or zero if none was executed.
|
||||
|
||||
@item function @var{name} @{ @var{command}; @dots{} @}
|
||||
This defines a function named @var{name}. The @dfn{body} of the function is
|
||||
the list of commands within braces, each of which must be terminated with a
|
||||
semicolon or a newline. This list of commands will be executed whenever
|
||||
@var{name} is specified as the name of a simple command. Function
|
||||
definitions do not affect the exit status in @code{$?}. When executed, the
|
||||
exit status of a function is the exit status of the last command executed in
|
||||
the body.
|
||||
|
||||
@item menuentry @var{title} [@option{--class=class} @dots{}] [@option{--users=users}] [@option{--hotkey=key}] @{ @var{command}; @dots{} @}
|
||||
@xref{menuentry}.
|
||||
@end table
|
||||
|
||||
|
||||
@node Embedded configuration
|
||||
@section Embedding a configuration file into GRUB
|
||||
|
@ -1308,8 +1449,7 @@ simple. Here is an example:
|
|||
@example
|
||||
@group
|
||||
grub> @kbd{serial --unit=0 --speed=9600}
|
||||
grub> @kbd{terminal_input serial}
|
||||
grub> @kbd{terminal_output serial}
|
||||
grub> @kbd{terminal_input serial; terminal_output serial}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
|
@ -1320,11 +1460,14 @@ command accepts many other options, so please refer to @ref{serial},
|
|||
for more details.
|
||||
|
||||
The commands @command{terminal_input} (@pxref{terminal_input}) and
|
||||
@command{terminal_output} (@pxref{terminal_output} choose which type of
|
||||
@command{terminal_output} (@pxref{terminal_output}) choose which type of
|
||||
terminal you want to use. In the case above, the terminal will be a
|
||||
serial terminal, but you can also pass @code{console} to the command,
|
||||
as @samp{terminal serial console}. In this case, a terminal in which
|
||||
you press any key will be selected as a GRUB terminal.
|
||||
you press any key will be selected as a GRUB terminal. In the example above,
|
||||
note that you need to put both commands on the same command line, as you
|
||||
will lose the ability to type commands on the console after the first
|
||||
command.
|
||||
|
||||
However, note that GRUB assumes that your terminal emulator is
|
||||
compatible with VT100 by default. This is true for most terminal
|
||||
|
@ -1789,9 +1932,26 @@ These commands can only be used in the menu:
|
|||
@node menuentry
|
||||
@subsection menuentry
|
||||
|
||||
@deffn Command title name @dots{}
|
||||
Start a new boot entry, and set its name to the contents of the rest of
|
||||
the line, starting with the first non-space character.
|
||||
@deffn Command menuentry @var{title} @
|
||||
[@option{--class=class} @dots{}] [@option{--users=users}] @
|
||||
[@option{--hotkey=key}] @
|
||||
@{ @var{command}; @dots{} @}
|
||||
This defines a GRUB menu entry named @var{title}. When this entry is
|
||||
selected from the menu, GRUB will set the @var{chosen} environment variable
|
||||
to @var{title}, execute the list of commands given within braces, and if the
|
||||
last command in the list returned successfully and a kernel was loaded it
|
||||
will execute the @command{boot} command.
|
||||
|
||||
The @option{--class} option may be used any number of times to group menu
|
||||
entries into classes. Menu themes may display different classes using
|
||||
different styles.
|
||||
|
||||
The @option{--users} option grants specific users access to specific menu
|
||||
entries. @xref{Security}.
|
||||
|
||||
The @option{--hotkey} option associates a hotkey with a menu entry.
|
||||
@var{key} may be a single letter, or one of the aliases @samp{backspace},
|
||||
@samp{tab}, or @samp{delete}.
|
||||
@end deffn
|
||||
|
||||
|
||||
|
@ -1885,7 +2045,9 @@ The @option{-a} (@option{--ascii}), @option{-u} (@option{--utf8}), and
|
|||
@option{-v} (@option{--visual-utf8}) options control how non-ASCII text is
|
||||
displayed. @option{-a} specifies an ASCII-only terminal; @option{-u}
|
||||
specifies logically-ordered UTF-8; and @option{-v} specifies
|
||||
visually-ordered UTF-8.
|
||||
"visually-ordered UTF-8" (in other words, arranged such that a terminal
|
||||
emulator without bidirectional text support will display right-to-left text
|
||||
in the proper order; this is not really proper UTF-8, but a workaround).
|
||||
|
||||
If no option or terminal type is specified, the current terminal type is
|
||||
printed.
|
||||
|
|
|
@ -1,8 +1,27 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_EMU_MISC_H
|
||||
#define GRUB_EMU_MISC_H 1
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/util/libzfs.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# include <sys/fcntl.h>
|
||||
|
@ -26,12 +45,18 @@ extern const char *program_name;
|
|||
void grub_init_all (void);
|
||||
void grub_fini_all (void);
|
||||
|
||||
char *grub_make_system_path_relative_to_its_root (const char *path);
|
||||
char *grub_find_mount_point_from_dir (const char *dir)
|
||||
__attribute__ ((warn_unused_result));
|
||||
void grub_find_zpool_from_mount_point (const char *mnt_point,
|
||||
char **poolname, char **poolfs);
|
||||
|
||||
void * EXPORT_FUNC(xmalloc) (grub_size_t size);
|
||||
void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size);
|
||||
char * EXPORT_FUNC(xstrdup) (const char *str);
|
||||
char * EXPORT_FUNC(xasprintf) (const char *fmt, ...);
|
||||
char *grub_make_system_path_relative_to_its_root (const char *path)
|
||||
__attribute__ ((warn_unused_result));
|
||||
|
||||
void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result));
|
||||
void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result));
|
||||
char * EXPORT_FUNC(xstrdup) (const char *str) __attribute__ ((warn_unused_result));
|
||||
char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((warn_unused_result));
|
||||
|
||||
void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...);
|
||||
void EXPORT_FUNC(grub_util_info) (const char *fmt, ...);
|
||||
|
@ -45,11 +70,12 @@ int EXPORT_FUNC(vasprintf) (char **buf, const char *fmt, va_list ap);
|
|||
int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
char * EXPORT_FUNC(xasprintf) (const char *fmt, ...);
|
||||
extern char * canonicalize_file_name (const char *path);
|
||||
|
||||
#ifdef HAVE_DEVICE_MAPPER
|
||||
int grub_device_mapper_supported (void);
|
||||
#endif
|
||||
|
||||
libzfs_handle_t *grub_get_libzfs_handle (void);
|
||||
|
||||
#endif /* GRUB_EMU_MISC_H */
|
||||
|
|
|
@ -231,10 +231,10 @@ grub_strtol (const char *str, char **end, int base)
|
|||
}
|
||||
}
|
||||
|
||||
char *EXPORT_FUNC(grub_strdup) (const char *s);
|
||||
char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n);
|
||||
char *EXPORT_FUNC(grub_strdup) (const char *s) __attribute__ ((warn_unused_result));
|
||||
char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) __attribute__ ((warn_unused_result));
|
||||
void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
|
||||
grub_size_t EXPORT_FUNC(grub_strlen) (const char *s);
|
||||
grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) __attribute__ ((warn_unused_result));
|
||||
int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
|
@ -261,8 +261,8 @@ int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...)
|
|||
int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
|
||||
va_list args);
|
||||
char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args);
|
||||
__attribute__ ((format (printf, 1, 2))) __attribute__ ((warn_unused_result));
|
||||
char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) __attribute__ ((warn_unused_result));
|
||||
void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
|
||||
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
|
||||
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
|
|
39
include/grub/util/libnvpair.h
Normal file
39
include/grub/util/libnvpair.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_LIBNVPAIR_UTIL_HEADER
|
||||
#define GRUB_LIBNVPAIR_UTIL_HEADER 1
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_LIBNVPAIR_H
|
||||
#include <libnvpair.h>
|
||||
#else /* ! HAVE_LIBNVPAIR_H */
|
||||
|
||||
#include <stdio.h> /* FILE */
|
||||
|
||||
typedef void nvlist_t;
|
||||
|
||||
int nvlist_lookup_string (nvlist_t *, const char *, char **);
|
||||
int nvlist_lookup_nvlist (nvlist_t *, const char *, nvlist_t **);
|
||||
int nvlist_lookup_nvlist_array (nvlist_t *, const char *, nvlist_t ***, unsigned int *);
|
||||
void nvlist_print (FILE *, nvlist_t *);
|
||||
|
||||
#endif /* ! HAVE_LIBNVPAIR_H */
|
||||
|
||||
#endif
|
45
include/grub/util/libzfs.h
Normal file
45
include/grub/util/libzfs.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_LIBZFS_UTIL_HEADER
|
||||
#define GRUB_LIBZFS_UTIL_HEADER 1
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_LIBZFS_H
|
||||
#include <libzfs.h>
|
||||
#else /* ! HAVE_LIBZFS_H */
|
||||
|
||||
#include <grub/util/libnvpair.h>
|
||||
|
||||
typedef void libzfs_handle_t;
|
||||
typedef void zpool_handle_t;
|
||||
|
||||
extern libzfs_handle_t *libzfs_init (void);
|
||||
extern void libzfs_fini (libzfs_handle_t *);
|
||||
|
||||
extern zpool_handle_t *zpool_open (libzfs_handle_t *, const char *);
|
||||
extern void zpool_close (zpool_handle_t *);
|
||||
|
||||
extern int zpool_get_physpath (zpool_handle_t *, const char *);
|
||||
|
||||
extern nvlist_t *zpool_get_config (zpool_handle_t *, nvlist_t **);
|
||||
|
||||
#endif /* ! HAVE_LIBZFS_H */
|
||||
|
||||
#endif
|
|
@ -20,14 +20,17 @@
|
|||
#include <config.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <grub/util/misc.h>
|
||||
|
||||
#ifdef __GNU__
|
||||
#include <hurd.h>
|
||||
|
@ -41,6 +44,11 @@
|
|||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||
# include <grub/util/libzfs.h>
|
||||
# include <grub/util/libnvpair.h>
|
||||
#endif
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/emu/misc.h>
|
||||
|
@ -166,6 +174,58 @@ find_root_device_from_mountinfo (const char *dir)
|
|||
|
||||
#endif /* __linux__ */
|
||||
|
||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||
static char *
|
||||
find_root_device_from_libzfs (const char *dir)
|
||||
{
|
||||
char *device;
|
||||
char *poolname;
|
||||
char *poolfs;
|
||||
char *mnt_point;
|
||||
|
||||
mnt_point = grub_find_mount_point_from_dir (dir);
|
||||
grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs);
|
||||
if (! poolname)
|
||||
{
|
||||
free (mnt_point);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
zpool_handle_t *zpool;
|
||||
nvlist_t *nvlist;
|
||||
nvlist_t **nvlist_array;
|
||||
unsigned int nvlist_count;
|
||||
|
||||
zpool = zpool_open (grub_get_libzfs_handle (), poolname);
|
||||
nvlist = zpool_get_config (zpool, NULL);
|
||||
|
||||
if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0)
|
||||
error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
|
||||
|
||||
if (nvlist_lookup_nvlist_array (nvlist, "children", &nvlist_array, &nvlist_count) != 0)
|
||||
error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
|
||||
|
||||
do
|
||||
{
|
||||
assert (nvlist_count > 0);
|
||||
} while (nvlist_lookup_nvlist_array (nvlist_array[0], "children",
|
||||
&nvlist_array, &nvlist_count) == 0);
|
||||
|
||||
if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0)
|
||||
error (1, errno, "nvlist_lookup_string (\"path\")");
|
||||
|
||||
zpool_close (zpool);
|
||||
}
|
||||
|
||||
free (poolname);
|
||||
if (poolfs)
|
||||
free (poolfs);
|
||||
|
||||
return device;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
static char *
|
||||
|
@ -458,6 +518,12 @@ grub_guess_root_device (const char *dir)
|
|||
return os_dev;
|
||||
#endif /* __linux__ */
|
||||
|
||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||
os_dev = find_root_device_from_libzfs (dir);
|
||||
if (os_dev)
|
||||
return os_dev;
|
||||
#endif
|
||||
|
||||
if (stat (dir, &st) < 0)
|
||||
grub_util_error ("cannot stat `%s'", dir);
|
||||
|
||||
|
|
205
kern/emu/misc.c
205
kern/emu/misc.c
|
@ -1,6 +1,25 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
@ -13,6 +32,10 @@
|
|||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETMNTANY
|
||||
# include <sys/mnttab.h>
|
||||
#endif
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/env.h>
|
||||
|
@ -26,6 +49,18 @@
|
|||
# include <libdevmapper.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZFS
|
||||
# include <grub/util/libzfs.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBNVPAIR
|
||||
# include <grub/util/libnvpair.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETFSSTAT
|
||||
# include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
int verbosity;
|
||||
|
||||
void
|
||||
|
@ -218,6 +253,154 @@ get_win32_path (const char *path)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZFS
|
||||
static libzfs_handle_t *__libzfs_handle;
|
||||
|
||||
static void
|
||||
fini_libzfs (void)
|
||||
{
|
||||
libzfs_fini (__libzfs_handle);
|
||||
}
|
||||
|
||||
libzfs_handle_t *
|
||||
grub_get_libzfs_handle (void)
|
||||
{
|
||||
if (! __libzfs_handle)
|
||||
{
|
||||
__libzfs_handle = libzfs_init ();
|
||||
atexit (fini_libzfs);
|
||||
}
|
||||
|
||||
return __libzfs_handle;
|
||||
}
|
||||
#endif /* HAVE_LIBZFS */
|
||||
|
||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||
/* Not ZFS-specific in itself, but for now it's only used by ZFS-related code. */
|
||||
char *
|
||||
grub_find_mount_point_from_dir (const char *dir)
|
||||
{
|
||||
struct stat st;
|
||||
typeof (st.st_dev) fs;
|
||||
char *prev, *next, *slash, *statdir;
|
||||
|
||||
if (stat (dir, &st) == -1)
|
||||
error (1, errno, "stat (%s)", dir);
|
||||
|
||||
fs = st.st_dev;
|
||||
|
||||
prev = xstrdup (dir);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Remove last slash. */
|
||||
next = xstrdup (prev);
|
||||
slash = strrchr (next, '/');
|
||||
if (! slash)
|
||||
{
|
||||
free (next);
|
||||
free (prev);
|
||||
return NULL;
|
||||
}
|
||||
*slash = '\0';
|
||||
|
||||
/* A next empty string counts as /. */
|
||||
if (next[0] == '\0')
|
||||
statdir = "/";
|
||||
else
|
||||
statdir = next;
|
||||
|
||||
if (stat (statdir, &st) == -1)
|
||||
error (1, errno, "stat (%s)", next);
|
||||
|
||||
if (st.st_dev != fs)
|
||||
{
|
||||
/* Found mount point. */
|
||||
free (next);
|
||||
return prev;
|
||||
}
|
||||
|
||||
free (prev);
|
||||
prev = next;
|
||||
|
||||
/* We've already seen an empty string, which means we
|
||||
reached /. Nothing left to do. */
|
||||
if (prev[0] == '\0')
|
||||
{
|
||||
free (prev);
|
||||
return xstrdup ("/");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||
|
||||
/* ZFS has similar problems to those of btrfs (see above). */
|
||||
void
|
||||
grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char **poolfs)
|
||||
{
|
||||
char *slash;
|
||||
|
||||
*poolname = *poolfs = NULL;
|
||||
|
||||
#if defined(HAVE_GETFSSTAT) /* FreeBSD and GNU/kFreeBSD */
|
||||
{
|
||||
int mnt_count = getfsstat (NULL, 0, MNT_WAIT);
|
||||
if (mnt_count == -1)
|
||||
error (1, errno, "getfsstat");
|
||||
|
||||
struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt));
|
||||
|
||||
mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT);
|
||||
if (mnt_count == -1)
|
||||
error (1, errno, "getfsstat");
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < (unsigned) mnt_count; i++)
|
||||
if (!strcmp (mnt[i].f_fstypename, "zfs")
|
||||
&& !strcmp (mnt[i].f_mntonname, mnt_point))
|
||||
{
|
||||
*poolname = xstrdup (mnt[i].f_mntfromname);
|
||||
break;
|
||||
}
|
||||
|
||||
free (mnt);
|
||||
}
|
||||
#elif defined(HAVE_GETMNTANY) /* OpenSolaris */
|
||||
{
|
||||
FILE *mnttab = fopen ("/etc/mnttab", "r");
|
||||
struct mnttab mp;
|
||||
struct mnttab mpref =
|
||||
{
|
||||
.mnt_special = NULL,
|
||||
.mnt_mountp = mnt_point,
|
||||
.mnt_fstype = "zfs",
|
||||
.mnt_mntopts = NULL,
|
||||
.mnt_time = NULL,
|
||||
};
|
||||
|
||||
if (getmntany (mnttab, &mp, &mpref) == 0)
|
||||
*poolname = xstrdup (mp.mnt_special);
|
||||
|
||||
fclose (mnttab);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! *poolname)
|
||||
return;
|
||||
|
||||
slash = strchr (*poolname, '/');
|
||||
if (slash)
|
||||
{
|
||||
*slash = '\0';
|
||||
*poolfs = xstrdup (slash + 1);
|
||||
}
|
||||
else
|
||||
*poolfs = xstrdup ("");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function never prints trailing slashes (so that its output
|
||||
can be appended a slash unconditionally). */
|
||||
char *
|
||||
|
@ -225,16 +408,26 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
|||
{
|
||||
struct stat st;
|
||||
char *p, *buf, *buf2, *buf3;
|
||||
char *mnt_point, *poolname = NULL, *poolfs = NULL, *ret;
|
||||
uintptr_t offset = 0;
|
||||
dev_t num;
|
||||
size_t len;
|
||||
|
||||
/* canonicalize. */
|
||||
p = canonicalize_file_name (path);
|
||||
|
||||
if (p == NULL)
|
||||
grub_util_error ("failed to get canonical path of %s", path);
|
||||
|
||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||
/* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */
|
||||
mnt_point = grub_find_mount_point_from_dir (p);
|
||||
if (mnt_point)
|
||||
{
|
||||
grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs);
|
||||
free (mnt_point);
|
||||
}
|
||||
#endif
|
||||
|
||||
len = strlen (p) + 1;
|
||||
buf = xstrdup (p);
|
||||
free (p);
|
||||
|
@ -313,7 +506,15 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
|||
len--;
|
||||
}
|
||||
|
||||
return buf3;
|
||||
if (poolfs)
|
||||
{
|
||||
ret = xasprintf ("/%s@%s", poolfs, buf3);
|
||||
free (buf3);
|
||||
}
|
||||
else
|
||||
ret = buf3;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEVICE_MAPPER
|
||||
|
|
35
kern/misc.c
35
kern/misc.c
|
@ -518,12 +518,39 @@ grub_strndup (const char *s, grub_size_t n)
|
|||
}
|
||||
|
||||
void *
|
||||
grub_memset (void *s, int c, grub_size_t n)
|
||||
grub_memset (void *s, int c, grub_size_t len)
|
||||
{
|
||||
unsigned char *p = (unsigned char *) s;
|
||||
void *p = s;
|
||||
grub_uint8_t pattern8 = c;
|
||||
|
||||
while (n--)
|
||||
*p++ = (unsigned char) c;
|
||||
if (len >= 3 * sizeof (unsigned long))
|
||||
{
|
||||
unsigned long patternl = 0;
|
||||
grub_size_t i;
|
||||
|
||||
for (i = 0; i < sizeof (unsigned long); i++)
|
||||
patternl |= ((unsigned long) pattern8) << (8 * i);
|
||||
|
||||
while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1)))
|
||||
{
|
||||
*(grub_uint8_t *) p = pattern8;
|
||||
p = (grub_uint8_t *) p + 1;
|
||||
len--;
|
||||
}
|
||||
while (len >= sizeof (unsigned long))
|
||||
{
|
||||
*(unsigned long *) p = patternl;
|
||||
p = (unsigned long *) p + 1;
|
||||
len -= sizeof (unsigned long);
|
||||
}
|
||||
}
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
*(grub_uint8_t *) p = pattern8;
|
||||
p = (grub_uint8_t *) p + 1;
|
||||
len--;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -144,8 +144,10 @@ grub_arg_show_help (grub_extcmd_t cmd)
|
|||
}
|
||||
}
|
||||
|
||||
/* FIXME: add spacing back. */
|
||||
grub_xputs (_(opt->doc));
|
||||
while (spacing--)
|
||||
grub_xputs (" ");
|
||||
|
||||
grub_printf ("%s\n", _(opt->doc));
|
||||
|
||||
switch (opt->shortarg)
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ COMMENT #.*$
|
|||
|
||||
CHAR [^{}|&$;<> \t\n\'\"\\]
|
||||
DIGITS [[:digit:]]+
|
||||
NAME [[:alpha:]_][[:alnum:][:digit:]_]*
|
||||
NAME [[:alpha:]_][[:alnum:]_]*
|
||||
|
||||
ESC \\.
|
||||
SPECIAL \?|\#|\*|\@
|
||||
|
|
|
@ -296,6 +296,7 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then
|
|||
|
||||
mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img ::
|
||||
mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/
|
||||
rm -rf ${efi_dir}
|
||||
grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img"
|
||||
fi
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
enum {
|
||||
PRINT_FS,
|
||||
PRINT_FS_UUID,
|
||||
PRINT_FS_LABEL,
|
||||
PRINT_DRIVE,
|
||||
PRINT_DEVICE,
|
||||
PRINT_PARTMAP,
|
||||
|
@ -291,6 +292,16 @@ probe (const char *path, char *device_name)
|
|||
|
||||
printf ("%s\n", uuid);
|
||||
}
|
||||
else if (print == PRINT_FS_LABEL)
|
||||
{
|
||||
char *label;
|
||||
if (! fs->label)
|
||||
grub_util_error ("%s does not support labels", fs->name);
|
||||
|
||||
fs->label (dev, &label);
|
||||
|
||||
printf ("%s\n", label);
|
||||
}
|
||||
|
||||
end:
|
||||
if (dev)
|
||||
|
@ -326,7 +337,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|fs_uuid|drive|device|partmap|abstraction)\n\
|
||||
-t, --target=(fs|fs_uuid|fs_label|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\
|
||||
|
@ -375,6 +386,8 @@ main (int argc, char *argv[])
|
|||
print = PRINT_FS;
|
||||
else if (!strcmp (optarg, "fs_uuid"))
|
||||
print = PRINT_FS_UUID;
|
||||
else if (!strcmp (optarg, "fs_label"))
|
||||
print = PRINT_FS_LABEL;
|
||||
else if (!strcmp (optarg, "drive"))
|
||||
print = PRINT_DRIVE;
|
||||
else if (!strcmp (optarg, "device"))
|
||||
|
|
|
@ -137,11 +137,7 @@ case x${GRUB_TERMINAL_INPUT} in
|
|||
;;
|
||||
x*)
|
||||
cat << EOF
|
||||
if terminal_input ${GRUB_TERMINAL_INPUT} ; then true ; else
|
||||
# For backward compatibility with versions of terminal.mod that don't
|
||||
# understand terminal_input
|
||||
terminal ${GRUB_TERMINAL_INPUT}
|
||||
fi
|
||||
terminal_input ${GRUB_TERMINAL_INPUT}
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
|
@ -152,11 +148,7 @@ case x${GRUB_TERMINAL_OUTPUT} in
|
|||
;;
|
||||
x*)
|
||||
cat << EOF
|
||||
if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
|
||||
# For backward compatibility with versions of terminal.mod that don't
|
||||
# understand terminal_output
|
||||
terminal ${GRUB_TERMINAL_OUTPUT}
|
||||
fi
|
||||
terminal_output ${GRUB_TERMINAL_OUTPUT}
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -51,6 +51,10 @@ kfreebsd_entry ()
|
|||
if [ -z "${prepare_boot_cache}" ]; then
|
||||
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
|
||||
fi
|
||||
if [ -z "${prepare_module_dir_cache}" ]; then
|
||||
prepare_module_dir_cache="$(prepare_grub_to_access_device $(grub-probe -t device "${module_dir}") | sed -e "s/^/\t/")"
|
||||
fi
|
||||
|
||||
printf '%s\n' "${prepare_boot_cache}"
|
||||
cat << EOF
|
||||
echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})'
|
||||
|
@ -63,14 +67,34 @@ EOF
|
|||
EOF
|
||||
fi
|
||||
|
||||
if test -n "${acpi_ko}" ; then
|
||||
if test -e "${module_dir}/acpi.ko" ; then
|
||||
printf '%s\n' "${prepare_module_dir_cache}"
|
||||
cat << EOF
|
||||
kfreebsd_module_elf ${acpi_ko_rel_dirname}/${acpi_ko_basename}
|
||||
kfreebsd_module_elf ${module_dir_rel}/acpi.ko
|
||||
EOF
|
||||
fi
|
||||
|
||||
case "${kfreebsd_fs}" in
|
||||
zfs)
|
||||
test -e "${module_dir}/opensolaris.ko"
|
||||
test -e "${module_dir}/zfs.ko"
|
||||
test -e "${dirname}/zfs/zpool.cache"
|
||||
|
||||
printf '%s\n' "${prepare_module_dir_cache}"
|
||||
cat << EOF
|
||||
set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${GRUB_DEVICE}
|
||||
kfreebsd_module_elf ${module_dir_rel}/opensolaris.ko
|
||||
kfreebsd_module_elf ${module_dir_rel}/zfs.ko
|
||||
EOF
|
||||
|
||||
printf '%s\n' "${prepare_boot_cache}"
|
||||
cat << EOF
|
||||
kfreebsd_module ${rel_dirname}/zfs/zpool.cache type=/boot/zfs/zpool.cache
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
cat << EOF
|
||||
set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${kfreebsd_device}
|
||||
set kFreeBSD.vfs.root.mountfrom.options=rw
|
||||
}
|
||||
EOF
|
||||
|
@ -100,22 +124,25 @@ while [ "x$list" != "x" ] ; do
|
|||
*) kfreebsd_fs=${GRUB_FS} ;;
|
||||
esac
|
||||
|
||||
case ${GRUB_FS} in
|
||||
zfs) kfreebsd_device=$(grub-probe -t label --device ${GRUB_DEVICE}) ;;
|
||||
*) kfreebsd_device=${GRUB_DEVICE} ;;
|
||||
esac
|
||||
|
||||
version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"`
|
||||
alt_version=`echo $version | sed -e "s,\.old$,,g"`
|
||||
|
||||
acpi_ko=
|
||||
for i in "/lib/modules/${version}/acpi.ko" "/lib/modules/${alt_version}/acpi.ko" \
|
||||
"/boot/kernel/acpi.ko"; do
|
||||
module_dir=
|
||||
for i in "/lib/modules/${version}" "/lib/modules/${alt_version}" \
|
||||
"/boot/kernel"; do
|
||||
if test -e "$i" ; then
|
||||
acpi_ko="$i"
|
||||
module_dir="$i"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "${acpi_ko}" ; then
|
||||
echo "Found ACPI module: ${acpi_ko}" >&2
|
||||
acpi_ko_basename=`basename ${acpi_ko}`
|
||||
acpi_ko_dirname=`dirname ${acpi_ko}`
|
||||
acpi_ko_rel_dirname=`make_system_path_relative_to_its_root $acpi_ko_dirname`
|
||||
if test -n "${module_dir}" ; then
|
||||
echo "Found kernel module directory: ${module_dir}" >&2
|
||||
module_dir_rel=$(make_system_path_relative_to_its_root $module_dir)
|
||||
fi
|
||||
|
||||
kfreebsd_entry "${OS}" "${version}"
|
||||
|
|
|
@ -44,7 +44,8 @@ case ${GRUB_DEVICE} in
|
|||
esac
|
||||
|
||||
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|
||||
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
|
||||
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
|
||||
|| uses_abstraction "${GRUB_DEVICE}" lvm; then
|
||||
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
|
||||
else
|
||||
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
|
||||
|
|
|
@ -212,7 +212,7 @@ fi
|
|||
# this command is allowed to fail (--target=fs already grants us that the
|
||||
# filesystem will be accessible).
|
||||
partmap_module=
|
||||
for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do
|
||||
for x in `$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`; do
|
||||
partmap_module="$partmap_module part_$x";
|
||||
done
|
||||
|
||||
|
|
|
@ -293,7 +293,8 @@ grub_util_init_nls (void)
|
|||
textdomain (PACKAGE);
|
||||
#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GRUB_UTIL */
|
||||
|
||||
int
|
||||
grub_dl_ref (grub_dl_t mod)
|
||||
|
|
Loading…
Reference in a new issue