diff --git a/ChangeLog b/ChangeLog index a3050ee07..53a664d2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,73 @@ +2010-05-19 BVK Chaitanya + + Fix grub-mkrescue usage unit testing. + + * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. + +2010-05-18 Christian Franke + + * util/grub.d/10_windows.in: Use path names instead of + drive letters to prevent warning from Cygwin 1.7. + Add drivemap command to menuentry if needed. + +2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> + + * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only + gnumach and gnumach.gz. + +2010-05-18 Vladimir Serbinenko + + * include/grub/i18n.h (gettext): Inline instead of using #define. + (grub_gettext): Likewise. + (_): Likewise. + +2010-05-18 Vladimir Serbinenko + + * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with + -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. + * util/grub-mkimage.c (image_targets): Add i386-multiboot. + (main): Add a slash after pkglibdirroot. + +2010-05-18 Vladimir Serbinenko + + * util/grub-install.in: Add missing "in" keyword. + +2010-05-18 Vladimir Serbinenko + + * util/grub-mkrescue.in: Remove -O i386-pc duplication. + Reported by: Seth Goldberg. + +2010-05-18 Vladimir Serbinenko + + * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. + +2010-05-18 Colin Watson + + * configure.ac: Check for Linux device-mapper support. + + * util/hostdisk.c (device_is_mapped): New function. + (find_partition_start): New function, partly broken out from + linux_find_partition and grub_util_biosdisk_get_grub_dev but with + device-mapper support added. + (linux_find_partition): Use find_partition_start. + (convert_system_partition_to_system_disk): Add `st' argument. + Support Linux /dev/mapper/* devices if device-mapper support is + available; only DM-RAID devices are understood at present. + (find_system_device): Add `st' argument. Pass it to + convert_system_partition_to_system_disk. + (grub_util_biosdisk_get_grub_dev): Pass stat result to + find_system_device and convert_system_partition_to_system_disk. Use + find_partition_start. + + * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, + kern/err.c, kern/list.c, kern/misc.c, and kern/emu/mm.c. + * util/deviceiter.c [__linux__]: Define MINOR. + (grub_util_iterate_devices): Add support for DM-RAID disk devices. + * util/mkdevicemap.c (grub_putchar): New function. + (grub_getkey): New function. + (grub_refresh): New function. + (main): Set debug=all if -v -v is used. + 2010-05-18 Colin Watson Fix build with non-GNU libcs. diff --git a/Makefile.in b/Makefile.in index 2e8c011f7..cd22fbdde 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,7 +89,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_PKGLIBROOTDIR=\"$(libdir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ diff --git a/conf/common.rmk b/conf/common.rmk index 4186c61b2..beee25be9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -6,7 +6,8 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/misc.c kern/emu/misc.c + util/misc.c kern/emu/misc.c \ + kern/env.c kern/err.c kern/list.c kern/misc.c kern/emu/mm.c ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c diff --git a/configure.ac b/configure.ac index d8ccccd48..806e3985c 100644 --- a/configure.ac +++ b/configure.ac @@ -764,6 +764,22 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) +AC_ARG_ENABLE([device-mapper], + [AS_HELP_STRING([--enable-device-mapper], + [enable Linux device-mapper support (default=guessed)])]) +if test x"$enable_device_mapper" = xno ; then + device_mapper_excuse="explicitly disabled" +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_task_create], + [LDFLAGS="$LDFLAGS -ldevmapper" + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.])], + [device_mapper_excuse="need devmapper library"]) +fi + AC_SUBST(ASFLAGS) # Output files. diff --git a/include/grub/dl.h b/include/grub/dl.h index fde2e3163..9d5f2af2d 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -101,7 +101,7 @@ grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr, grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); -#if defined (_mips) && ! GRUB_MACHINE_EMU +#if defined (_mips) && (! defined (GRUB_MACHINE_EMU) || ! GRUB_MACHINE_EMU) #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); #endif diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 9e7f52d45..57ca1c45b 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -42,17 +42,33 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # ifdef GRUB_UTIL -# define gettext(Msgid) ((const char *) (Msgid)) +static inline const char * __attribute__ ((always_inline)) +gettext (const char *str) +{ + return str; +} # else -# define grub_gettext(str) ((const char *) (str)) +static inline const char * __attribute__ ((always_inline)) +grub_gettext (const char *str) +{ + return str; +} # endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #ifdef GRUB_UTIL -# define _(str) gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return gettext(str); +} #else -# define _(str) grub_gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return grub_gettext(str); +} #endif /* GRUB_UTIL */ #define N_(str) str diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 983f101ae..0ab25ec7d 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -98,6 +98,10 @@ struct hd_geometry # include #endif +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + #if defined(__NetBSD__) # include # include /* struct disklabel */ @@ -312,6 +316,140 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } +#ifdef HAVE_DEVICE_MAPPER +static int +device_is_mapped (const char *dev) +{ + struct stat st; + + if (stat (dev, &st) < 0) + return 0; + + return dm_is_dm_major (major (st.st_rdev)); +} +#endif /* HAVE_DEVICE_MAPPER */ + +#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) +static grub_disk_addr_t +find_partition_start (const char *dev) +{ + int fd; +# if !defined(__NetBSD__) + struct hd_geometry hdg; +# else /* defined(__NetBSD__) */ + struct disklabel label; + int index; +# endif /* !defined(__NetBSD__) */ + +# ifdef HAVE_DEVICE_MAPPER + if (device_is_mapped (dev)) { + struct dm_task *task = NULL; + grub_uint64_t start, length; + char *target_type, *params, *space; + grub_disk_addr_t partition_start; + + /* If any device-mapper operation fails, we fall back silently to + HDIO_GETGEO. */ + task = dm_task_create (DM_DEVICE_TABLE); + if (! task) + { + grub_dprintf ("hostdisk", "dm_task_create failed\n"); + goto devmapper_fail; + } + + if (! dm_task_set_name (task, dev)) + { + grub_dprintf ("hostdisk", "dm_task_set_name failed\n"); + goto devmapper_fail; + } + + if (! dm_task_run (task)) + { + grub_dprintf ("hostdisk", "dm_task_run failed\n"); + goto devmapper_fail; + } + + dm_get_next_target (task, NULL, &start, &length, &target_type, ¶ms); + if (! target_type) + { + grub_dprintf ("hostdisk", "no dm target\n"); + goto devmapper_fail; + } + if (strcmp (target_type, "linear") != 0) + { + grub_dprintf ("hostdisk", "ignoring dm target %s (not linear)\n", + target_type); + goto devmapper_fail; + } + if (! params) + { + grub_dprintf ("hostdisk", "no dm params\n"); + goto devmapper_fail; + } + + /* The params string for a linear target looks like this: + DEVICE-NAME START-SECTOR + Parse this out. */ + space = strchr (params, ' '); + if (! space) + goto devmapper_fail; + errno = 0; + partition_start = strtoull (space + 1, NULL, 10); + if (errno == 0) + { + grub_dprintf ("hostdisk", "dm %s starts at %llu\n", + dev, (unsigned long long) partition_start); + dm_task_destroy (task); + return partition_start; + } + +devmapper_fail: + if (task) + dm_task_destroy (task); + } +# endif /* HAVE_DEVICE_MAPPER */ + + fd = open (dev, O_RDONLY); + if (fd == -1) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + return 0; + } + +# if !defined(__NetBSD__) + if (ioctl (fd, HDIO_GETGEO, &hdg)) +# else /* defined(__NetBSD__) */ + configure_device_driver (fd); + if (ioctl (fd, DIOCGDINFO, &label) == -1) +# endif /* !defined(__NetBSD__) */ + { + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot get disk geometry of `%s'", dev); + close (fd); + return 0; + } + + close (fd); + +# if !defined(__NetBSD__) + return hdg.start; +# else /* defined(__NetBSD__) */ + /* Since dev and convert_system_partition_to_system_disk (dev) are + * different, we know that dev is of the form /dev/r[wsc]d[0-9]+[a-z] + * and in particular it cannot be a floppy device. */ + index = dev[strlen(dev) - 1] - 'a'; + + if (index >= label.d_npartitions) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "no disk label entry for `%s'", dev); + return 0; + } + return (grub_disk_addr_t) label.d_partitions[index].p_offset; +# endif /* !defined(__NetBSD__) */ +} +#endif /* __linux__ || __CYGWIN__ */ + #ifdef __linux__ /* Cache of partition start sectors for each disk. */ struct linux_partition_cache @@ -365,28 +503,26 @@ linux_find_partition (char *dev, unsigned long sector) for (i = 1; i < 10000; i++) { int fd; - struct hd_geometry hdg; + grub_disk_addr_t start; sprintf (p, format, i); + fd = open (real_dev, O_RDONLY); if (fd == -1) return 0; - - if (ioctl (fd, HDIO_GETGEO, &hdg)) - { - close (fd); - return 0; - } - close (fd); - if (hdg.start == sector) + start = find_partition_start (real_dev); + /* We don't care about errors here. */ + grub_errno = GRUB_ERR_NONE; + + if (start == sector) { struct linux_partition_cache *new_cache_item; new_cache_item = xmalloc (sizeof *new_cache_item); new_cache_item->dev = xstrdup (dev); - new_cache_item->start = hdg.start; + new_cache_item->start = start; new_cache_item->partno = i; grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list), GRUB_AS_LIST (new_cache_item)); @@ -877,7 +1013,7 @@ make_device_name (int drive, int dos_part, int bsd_part) } static char * -convert_system_partition_to_system_disk (const char *os_dev) +convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) { #if defined(__linux__) char *path = xmalloc (PATH_MAX); @@ -995,6 +1131,96 @@ convert_system_partition_to_system_disk (const char *os_dev) p[4] = '\0'; return path; } + +#ifdef HAVE_DEVICE_MAPPER + /* If this is a DM-RAID device. */ + if ((strncmp ("mapper/", p, 7) == 0)) + { + static struct dm_tree *tree = NULL; + uint32_t maj, min; + struct dm_tree_node *node, *child; + void *handle; + const char *node_uuid, *mapper_name, *child_uuid, *child_name; + + if (! tree) + tree = dm_tree_create (); + + if (! tree) + { + grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + return NULL; + } + + maj = major (st->st_rdev); + min = minor (st->st_rdev); + if (! dm_tree_add_dev (tree, maj, min)) + { + grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); + return NULL; + } + + node = dm_tree_find_node (tree, maj, min); + if (! node) + { + grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); + return NULL; + } + node_uuid = dm_tree_node_get_uuid (node); + if (! node_uuid) + { + grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); + return NULL; + } + else if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); + return NULL; + } + + handle = NULL; + mapper_name = NULL; + /* Counter-intuitively, device-mapper refers to the disk-like + device containing a DM-RAID partition device as a "child" of + the partition device. */ + child = dm_tree_next_child (&handle, node, 0); + if (! child) + { + grub_dprintf ("hostdisk", "%s has no DM children\n", path); + goto devmapper_out; + } + child_uuid = dm_tree_node_get_uuid (child); + if (! child_uuid) + { + grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); + goto devmapper_out; + } + else if (strncmp (child_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); + goto devmapper_out; + } + child_name = dm_tree_node_get_name (child); + if (! child_name) + { + grub_dprintf ("hostdisk", "%s child has no DM name\n", path); + goto devmapper_out; + } + mapper_name = child_name; + +devmapper_out: + if (! mapper_name) + { + /* This is a DM-RAID disk, not a partition. */ + mapper_name = dm_tree_node_get_name (node); + if (! mapper_name) + { + grub_dprintf ("hostdisk", "%s has no DM name\n", path); + return NULL; + } + } + return xasprintf ("/dev/mapper/%s", mapper_name); + } +#endif /* HAVE_DEVICE_MAPPER */ } return path; @@ -1091,12 +1317,12 @@ device_is_wholedisk (const char *os_dev) #endif /* defined(__NetBSD__) */ static int -find_system_device (const char *os_dev) +find_system_device (const char *os_dev, struct stat *st) { unsigned int i; char *os_disk; - os_disk = convert_system_partition_to_system_disk (os_dev); + os_disk = convert_system_partition_to_system_disk (os_dev, st); if (! os_disk) return -1; @@ -1130,7 +1356,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - drive = find_system_device (os_dev); + drive = find_system_device (os_dev, &st); if (drive < 0) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, @@ -1138,8 +1364,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev)) - == 0) + if (grub_strcmp (os_dev, + convert_system_partition_to_system_disk (os_dev, &st)) == 0) return make_device_name (drive, -1, -1); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) @@ -1164,15 +1390,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { char *name; grub_disk_t disk; - int fd; -# if !defined(__NetBSD__) - struct hd_geometry hdg; - typeof (hdg.start) p_offset; -# else /* defined(__NetBSD__) */ - struct disklabel label; - int index; - u_int32_t p_offset; -# endif /* !defined(__NetBSD__) */ + grub_disk_addr_t start; int dos_part = -1; int bsd_part = -1; auto int find_partition (grub_disk_t dsk, @@ -1187,7 +1405,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) part_start = grub_partition_get_start (partition); - if (p_offset == part_start) + if (start == part_start) { if (partition->parent) { @@ -1218,46 +1436,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) index = os_dev[strlen(os_dev) - 1] - 'a'; # endif /* !defined(__NetBSD__) */ - fd = open (os_dev, O_RDONLY); - if (fd == -1) + start = find_partition_start (os_dev); + if (grub_errno != GRUB_ERR_NONE) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); free (name); return 0; } -# if !defined(__NetBSD__) - if (ioctl (fd, HDIO_GETGEO, &hdg)) -# else /* defined(__NetBSD__) */ - configure_device_driver (fd); - if (ioctl (fd, DIOCGDINFO, &label) == -1) -# endif /* !defined(__NetBSD__) */ - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk geometry of `%s'", os_dev); - close (fd); - free (name); - return 0; - } + grub_util_info ("%s starts from %lu", os_dev, start); - close (fd); - -# if !defined(__NetBSD__) - p_offset = hdg.start; -# else /* defined(__NetBSD__) */ - if (index >= label.d_npartitions) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "no disk label entry for `%s'", os_dev); - free (name); - return 0; - } - p_offset = label.d_partitions[index].p_offset; -# endif /* !defined(__NetBSD__) */ - - grub_util_info ("%s starts from %lu", os_dev, p_offset); - - if (p_offset == 0 && device_is_wholedisk (os_dev)) + if (start == 0 && device_is_wholedisk (os_dev)) return name; grub_util_info ("opening the device %s", name); diff --git a/po/POTFILES b/po/POTFILES index 0dfc3c041..d2c579edb 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -77,5 +77,5 @@ normal/misc.c term/serial.c -util/grub-mkrawimage.c +util/grub-mkimage.c util/i386/pc/grub-setup.c diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index a41a6f6f4..17da6c8c0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -124,7 +124,8 @@ halt EOF isofile=`mktemp` -grub-mkrescue --output=${isofile} --override-directory=${builddir} \ +grub-mkrescue --grub-mkimage=${builddir}/grub-mkimage --output=${isofile} \ + --override-directory=${builddir} \ /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ >/dev/null 2>&1 diff --git a/util/deviceiter.c b/util/deviceiter.c index b0a9e1388..03813bc7d 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -31,6 +31,8 @@ #include #include +#include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -62,12 +64,23 @@ struct hd_geometry | ((unsigned int) (__dev >> 32) & ~0xfff); \ }) # endif /* ! MAJOR */ +# ifndef MINOR +# define MINOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \ + }) +# endif /* ! MINOR */ # ifndef CDROM_GET_CAPABILITY # define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ # endif /* ! CDROM_GET_CAPABILITY */ # ifndef BLKGETSIZE # define BLKGETSIZE _IO(0x12,96) /* return device size */ # endif /* ! BLKGETSIZE */ + +#ifdef HAVE_DEVICE_MAPPER +# include +#endif #endif /* __linux__ */ /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with @@ -411,6 +424,16 @@ check_device (const char *device) return 1; } +#ifdef __linux__ +# ifdef HAVE_DEVICE_MAPPER +struct dmraid_seen +{ + struct dmraid_seen *next; + const char *name; +}; +# endif /* HAVE_DEVICE_MAPPER */ +#endif /* __linux__ */ + void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), int floppy_disks) @@ -643,6 +666,123 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), return; } } + +# ifdef HAVE_DEVICE_MAPPER +# define dmraid_check(cond, ...) \ + if (! (cond)) \ + { \ + grub_dprintf ("deviceiter", __VA_ARGS__); \ + goto dmraid_end; \ + } + + /* DM-RAID. */ + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; + + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); + + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; + + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } + + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } + + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); + + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + +dmraid_next_child: + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } + +dmraid_end: + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } +# endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } diff --git a/util/grub-install.in b/util/grub-install.in index 8a93ace8c..0db216fd5 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -342,7 +342,7 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi -case "${target_cpu}-${platform}" +case "${target_cpu}-${platform}" in i386-pc) mkimage_target=i386-pc ;; sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index c68482af1..db37f99e6 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -31,6 +31,7 @@ #include #include +#include #include #define _GNU_SOURCE 1 @@ -38,6 +39,24 @@ #include "progname.h" +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + static void make_device_map (const char *device_map, int floppy_disks) { @@ -158,6 +177,9 @@ main (int argc, char *argv[]) } } + if (verbosity > 1) + grub_env_set ("debug", "all"); + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); free (dev_map); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index cc4a225d4..6366a9803 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -99,6 +99,28 @@ struct image_target_desc image_targets[] = .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, + { + .name = "i386-multiboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, { .name = "i386-pc", .voidp_sizeof = 4, @@ -1182,7 +1204,7 @@ Make a bootable image of GRUB.\n\ \n\ Report bugs to <%s>.\n\ "), - program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + program_name, GRUB_PKGLIBROOTDIR, DEFAULT_DIRECTORY, formats, PACKAGE_BUGREPORT); free (formats); @@ -1320,14 +1342,16 @@ main (int argc, char *argv[]) last = strchr (last + 1, '-'); if (!last) last = image_target->name + strlen (image_target->name); - dir = xmalloc (sizeof (GRUB_LIBDIR) + (last - image_target->name)); - memcpy (dir, GRUB_LIBDIR, sizeof (GRUB_LIBDIR) - 1); - memcpy (dir + sizeof (GRUB_LIBDIR) - 1, image_target->name, + dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name) + + 1); + memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); + *(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; + memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->name, last - image_target->name); - *(dir + sizeof (GRUB_LIBDIR) - 1 + (last - image_target->name)) = 0; + *(dir + sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name)) = 0; } - generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, + generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, image_target, note); diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 6018816b3..7e7253006 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -219,7 +219,7 @@ grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${i if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - $grub_mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + $grub_mkimage -O i386-pc -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 8e16e7d9f..e446f10e8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -35,13 +35,13 @@ all_of_them=true # FIXME: add l4 here? kernel= -for i in /boot/gnumach.gz /boot/gnumach ; do +for i in /boot/gnumach* ; do if test -e $i ; then basename=`basename $i` dirname=`dirname $i` rel_dirname=`make_system_path_relative_to_its_root $dirname` echo "Found GNU Mach: $i" >&2 - kernel=${rel_dirname}/${basename} + kernels="${kernels} ${rel_dirname}/${basename}" at_least_one=true fi done @@ -71,17 +71,22 @@ if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else exit 1 fi -cat << EOF -menuentry "${OS}" ${CLASS} { +for kernel in ${kernels} +do + kernel_base="`basename "${kernel}"`" + KERNEL="using ${kernel_base}" + + cat << EOF +menuentry "${OS} ${KERNEL}" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -93,17 +98,17 @@ cat << EOF } EOF -cat << EOF -menuentry "${OS} (recovery mode)" { + cat << EOF +menuentry "${OS} ${KERNEL} (recovery mode)" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -114,3 +119,5 @@ cat << EOF module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' } EOF + +done diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 35dd4a4cc..7d221eac9 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2008 Free Software Foundation, Inc. +# Copyright (C) 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 @@ -28,8 +28,8 @@ esac # Try C: even if current system is on other partition. case "$SYSTEMDRIVE" in - [Cc]:) dirlist="C:" ;; - [D-Zd-z]:) dirlist="C: $SYSTEMDRIVE" ;; + [Cc]:) drives="C:" ;; + [D-Zd-z]:) drives="C: $SYSTEMDRIVE" ;; *) exit 0 ;; esac @@ -51,7 +51,13 @@ get_os_name_from_boot_ini () } -for dir in $dirlist ; do +for drv in $drives ; do + + # Convert to Cygwin path. + dir=`cygpath "$drv"` + test -n "$dir" || continue + + needmap= # Check for Vista bootmgr. if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then @@ -60,6 +66,7 @@ for dir in $dirlist ; do # Check for NTLDR. elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="Windows NT/2000/XP loader" + needmap=t else continue @@ -68,14 +75,16 @@ for dir in $dirlist ; do # Get boot /dev/ice. dev=`${grub_probe} -t device "$dir" 2>/dev/null` || continue - echo "Found $OS on $dir ($dev)" >&2 + echo "Found $OS on $drv ($dev)" >&2 cat << EOF menuentry "$OS" { EOF save_default_entry | sed -e 's,^,\t,' prepare_grub_to_access_device "$dev" | sed 's,^,\t,' - + test -z "$needmap" || cat <