merge with mainline

This commit is contained in:
BVK Chaitanya 2010-08-10 09:52:16 +05:30
commit 368ba29261
22 changed files with 878 additions and 79 deletions

301
ChangeLog
View file

@ -1,3 +1,304 @@
2010-08-08 Robert Millan <rmh@gnu.org>
Fix path generation for sub-filesystems in ZFS.
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Add
missing slash.
2010-08-08 Robert Millan <rmh@gnu.org>
* util/grub-fstest.c (read_file, cmd_cmp): Improve error message.
2010-08-08 Robert Millan <rmh@gnu.org>
* util/grub.d/10_kfreebsd.in: When files required for ZFS do not
exist, issue a proper error message (rely on `ls' for translated
strings).
2010-08-08 Robert Millan <rmh@gnu.org>
Fix grub-probe invocation.
* util/grub.d/10_kfreebsd.in: s/label/fs_label/g.
2010-08-04 Robert Millan <rmh@gnu.org>
* configure.ac: Remove checks for getfsstat() and getmntany().
Add checks for `<sys/param.h>' and `<sys/mount.h>'.
* kern/emu/misc.c [HAVE_GETMNTANY]: Remove `<sys/mnttab.h>'.
[HAVE_SYS_PARAM_H]: Include `<sys/param.h>'.
[HAVE_SYS_MOUNT_H]: Include `<sys/mount.h>'.
[HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove
function.
(grub_find_zpool_from_dir): Use statfs() instead of indirect matching
via find_mount_point_from_dir() and getfsstat() / getmntany().
2010-08-04 Robert Millan <rmh@gnu.org>
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
(grub_find_zpool_from_mount_point): Merge into ...
(grub_find_zpool_from_dir): ... this.
* kern/emu/misc.c: Likewise.
* kern/emu/misc.c
(grub_make_system_path_relative_to_its_root): Replace
grub_find_mount_point_from_dir() / grub_find_zpool_from_mount_point()
with grub_find_zpool_from_dir().
* kern/emu/getroot.c (find_root_device_from_libzfs): Likewise.
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

View file

@ -246,15 +246,9 @@ else
AC_PATH_PROG(HELP2MAN, help2man)
fi
# Check for functions.
# Check for functions and headers.
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)
AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.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.

View file

@ -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. */
for (p = array_list; p != NULL; p = p->next)
{
if (p->number == array->number)
break;
}
if (! array->name)
{
for (p = array_list; p != NULL; p = p->next)
{
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)

View file

@ -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.

View file

@ -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,16 @@ 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);
void grub_find_zpool_from_dir (const char *dir,
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 +68,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 */

View file

@ -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,

View 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

View 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

View file

@ -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,53 @@ 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;
grub_find_zpool_from_dir (dir, &poolname, &poolfs);
if (! poolname)
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 +513,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);

View file

@ -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>
@ -26,6 +45,22 @@
# include <libdevmapper.h>
#endif
#ifdef HAVE_LIBZFS
# include <grub/util/libzfs.h>
#endif
#ifdef HAVE_LIBNVPAIR
# include <grub/util/libnvpair.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
int verbosity;
void
@ -218,6 +253,54 @@ 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)
/* ZFS has similar problems to those of btrfs (see above). */
void
grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs)
{
struct statfs mnt;
char *slash;
*poolname = *poolfs = NULL;
if (statfs (dir, &mnt) != 0)
return;
*poolname = xstrdup (mnt.f_mntfromname);
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 +308,21 @@ grub_make_system_path_relative_to_its_root (const char *path)
{
struct stat st;
char *p, *buf, *buf2, *buf3;
char *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?). */
grub_find_zpool_from_dir (p, &poolname, &poolfs);
#endif
len = strlen (p) + 1;
buf = xstrdup (p);
free (p);
@ -313,7 +401,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

View file

@ -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;
}

View file

@ -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)
{

View file

@ -272,7 +272,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
struct grub_script_argv argv = { 0, 0 };
/* Lookup the command. */
if (grub_script_arglist_to_argv (cmdline->arglist, &argv))
if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0])
return grub_errno;
cmdname = argv.args[0];

View file

@ -116,7 +116,7 @@ COMMENT #.*$
CHAR [^{}|&$;<> \t\n\'\"\\]
DIGITS [[:digit:]]+
NAME [[:alpha:]_][[:alnum:][:digit:]_]*
NAME [[:alpha:]_][[:alnum:]_]*
ESC \\.
SPECIAL \?|\#|\*|\@

View file

@ -157,7 +157,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
if (sz < 0)
{
grub_util_error ("read error at offset %llu", ofs);
grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg);
break;
}
@ -211,7 +211,7 @@ cmd_cmp (char *src, char *dest)
{
if ((int) fread (buf_1, 1, len, ff) != len)
{
grub_util_error ("read error at offset %llu", ofs);
grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg);
return 1;
}

View file

@ -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

View file

@ -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"))

View file

@ -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

View file

@ -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,35 @@ 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)
for i in "${module_dir}/opensolaris.ko" "${module_dir}/zfs.ko" \
"${dirname}/zfs/zpool.cache" ; do
ls "$i" > /dev/null
done
printf '%s\n' "${prepare_module_dir_cache}"
cat << EOF
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
set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${GRUB_DEVICE}
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 +125,25 @@ while [ "x$list" != "x" ] ; do
*) kfreebsd_fs=${GRUB_FS} ;;
esac
case ${GRUB_FS} in
zfs) kfreebsd_device=$(grub-probe -t fs_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}"

View file

@ -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}

View file

@ -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

View file

@ -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)