From: Vladimir 'phcoder' Serbinenko Date: Fri, 23 Dec 2011 17:49:00 +0000 (+0100) Subject: merge mainline into hints X-Git-Tag: 2.00~828^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17785932df87183bd30886db65efe5f1c0cdfb7c;p=thirdparty%2Fgrub.git merge mainline into hints --- 17785932df87183bd30886db65efe5f1c0cdfb7c diff --cc Makefile.util.def index 8812a783c,6e026db7e..47aefee32 --- a/Makefile.util.def +++ b/Makefile.util.def @@@ -242,9 -281,13 +281,10 @@@ program = common = util/grub-mkdevicemap.c; common = util/deviceiter.c; - nosparc64 = util/devicemap.c; - - sparc64_ieee1275 = util/ieee1275/ofpath.c; - sparc64_ieee1275 = util/ieee1275/devicemap.c; + common = util/devicemap.c; ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; @@@ -255,9 -298,9 +295,10 @@@ program = installdir = sbin; mansection = 8; common = util/grub-probe.c; + common = util/ieee1275/ofpath.c; ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; diff --cc include/grub/emu/hostdisk.h index b44a573e1,719faa29b..b8c072761 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@@ -28,8 -29,17 +29,19 @@@ char *grub_util_biosdisk_get_grub_dev ( const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); int grub_util_biosdisk_is_present (const char *name); int grub_util_biosdisk_is_floppy (grub_disk_t disk); +const char * +grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk); grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); + void grub_util_pull_device (const char *osname); + grub_err_t + grub_util_fd_seek (int fd, const char *name, grub_uint64_t sector); + ssize_t grub_util_fd_read (int fd, char *buf, size_t len); + grub_err_t + grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat); + void grub_util_cryptodisk_print_uuid (grub_disk_t disk); + #if !defined(__MINGW32__) + grub_uint64_t + grub_util_get_fd_sectors (int fd, unsigned *log_secsize); + #endif #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --cc util/grub-mkconfig_lib.in index 8303edd86,f03fb2b53..13897986b --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@@ -126,16 -138,17 +138,22 @@@ prepare_grub_to_access_device ( echo "insmod ${module}" done + if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then + for uuid in "`"${grub_probe}" --device "${device}" --target=cryptodisk_uuid`"; do + echo "cryptomount -u $uuid" + done + fi + # If there's a filesystem UUID that GRUB is capable of identifying, use it; # otherwise set root as per value in device.map. - echo "set root='`"${grub_probe}" --device "${device}" --target=drive`'" + echo "set root='`"${grub_probe}" --device "${device}" --target=compatibility_hint`'" if fs_uuid="`"${grub_probe}" --device "${device}" --target=fs_uuid 2> /dev/null`" ; then - echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" + hints="`"${grub_probe}" --device "${device}" --target=hints_string 2> /dev/null`" + echo "if [ x$feature_platform_search_hint = xy ]; then" + echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" + echo "else" + echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" + echo "fi" fi } diff --cc util/grub-probe.c index b486a82e5,795a9344e..e33a2ad10 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@@ -34,8 -33,8 +33,10 @@@ #include #include #include +#include +#include + #include + #include #include #include @@@ -56,13 -55,7 +57,14 @@@ enum PRINT_DEVICE, PRINT_PARTMAP, PRINT_ABSTRACTION, - PRINT_CRYPTODISK_UUID ++ PRINT_CRYPTODISK_UUID, + PRINT_HINT_STR, + PRINT_BIOS_HINT, + PRINT_IEEE1275_HINT, + PRINT_BAREMETAL_HINT, + PRINT_EFI_HINT, + PRINT_ARC_HINT, + PRINT_COMPATIBILITY_HINT }; int print = PRINT_FS; @@@ -97,131 -124,42 +133,167 @@@ probe_raid_level (grub_disk_t disk return ((struct grub_raid_array *) disk->data)->level; } +/* Since OF path names can have "," characters in them, and GRUB + internally uses "," to indicate partitions (unlike OF which uses + ":" for this purpose) we escape such commas. */ +static char * +escape_of_path (const char *orig_path) +{ + char *new_path, *d, c; + const char *p; + + if (!strchr (orig_path, ',')) + return (char *) orig_path; + + new_path = xmalloc (strlen (orig_path) * 2 + sizeof ("ieee1275/")); + + p = orig_path; + grub_strcpy (new_path, "ieee1275/"); + d = new_path + sizeof ("ieee1275/") - 1; + while ((c = *p++) != '\0') + { + if (c == ',') + *d++ = '\\'; + *d++ = c; + } + + free ((char *) orig_path); + + return new_path; +} + +static char * +guess_bios_drive (const char *orig_path) +{ + char *canon; + char *ptr; + canon = canonicalize_file_name (orig_path); + if (!canon) + return NULL; + ptr = strrchr (orig_path, '/'); + if (ptr) + ptr++; + else + ptr = canon; + if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("hd%d", num); + } + if (ptr[0] == 'f' && ptr[1] == 'd') + { + int num = atoi (ptr + 2); + free (canon); + return xasprintf ("fd%d", num); + } + free (canon); + return NULL; +} + +static char * +guess_efi_drive (const char *orig_path) +{ + char *canon; + char *ptr; + canon = canonicalize_file_name (orig_path); + if (!canon) + return NULL; + ptr = strrchr (orig_path, '/'); + if (ptr) + ptr++; + else + ptr = canon; + if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("hd%d", num); + } + if (ptr[0] == 'f' && ptr[1] == 'd') + { + int num = atoi (ptr + 2); + free (canon); + return xasprintf ("fd%d", num); + } + free (canon); + return NULL; +} + +static char * +guess_baremetal_drive (const char *orig_path) +{ + char *canon; + char *ptr; + canon = canonicalize_file_name (orig_path); + if (!canon) + return NULL; + ptr = strrchr (orig_path, '/'); + if (ptr) + ptr++; + else + ptr = canon; + if (ptr[0] == 'h' && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("ata%d", num); + } + if (ptr[0] == 's' && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("ahci%d", num); + } + free (canon); + return NULL; +} + +static void +print_full_name (const char *drive, grub_device_t dev) +{ + if (dev->disk->partition) + printf ("%s,%s", drive, grub_partition_get_name (dev->disk->partition)); + else + printf ("%s", drive); +} + + static void + probe_abstraction (grub_disk_t disk) + { + grub_disk_memberlist_t list = NULL, tmp; + int raid_level; + + if (disk->dev->memberlist) + list = disk->dev->memberlist (disk); + while (list) + { + probe_abstraction (list->disk); + + tmp = list->next; + free (list); + list = tmp; + } + + if (disk->dev->id == GRUB_DISK_DEVICE_LVM_ID) + printf ("lvm "); + + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + grub_util_cryptodisk_print_abstraction (disk); + + raid_level = probe_raid_level (disk); + if (raid_level >= 0) + { + printf ("raid "); + if (disk->dev->raidname) + printf ("%s ", disk->dev->raidname (disk)); + } + if (raid_level == 5) + printf ("raid5rec "); + if (raid_level == 6) + printf ("raid6rec "); + } + static void probe (const char *path, char *device_name) { @@@ -266,228 -208,19 +342,186 @@@ grub_util_info ("opening %s", drive_name); dev = grub_device_open (drive_name); if (! dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); + if (print == PRINT_HINT_STR) + { + const char *orig_path = grub_util_devname_to_ofpath (device_name); + char *ofpath = escape_of_path (orig_path); + char *biosname, *bare, *efi; + const char *map; + + printf ("--hint-ieee1275="); + print_full_name (ofpath, dev); + printf (" "); + free (ofpath); + + biosname = guess_bios_drive (device_name); + if (biosname) + { + printf ("--hint-bios="); + print_full_name (biosname, dev); + printf (" "); + } + free (biosname); + + efi = guess_efi_drive (device_name); + if (efi) + { + printf ("--hint-efi="); + print_full_name (efi, dev); + printf (" "); + } + free (efi); + + bare = guess_baremetal_drive (device_name); + if (bare) + { + printf ("--hint-baremetal="); + print_full_name (bare, dev); + printf (" "); + } + free (biosname); + + /* FIXME: Add ARC hint. */ + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + if (map) + { + printf ("--hint="); + print_full_name (map, dev); + printf (" "); + } + printf ("\n"); + + goto end; + } + + if (print == PRINT_COMPATIBILITY_HINT) + { + const char *map; + char *biosname; + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + if (map) + { + printf ("%s\n", map); + goto end; + } + biosname = guess_bios_drive (device_name); + if (biosname) + print_full_name (biosname, dev); + printf ("\n"); + free (biosname); + goto end; + } + + if (print == PRINT_BIOS_HINT) + { + char *biosname; + biosname = guess_bios_drive (device_name); + if (biosname) + print_full_name (biosname, dev); + printf ("\n"); + free (biosname); + goto end; + } + if (print == PRINT_IEEE1275_HINT) + { + const char *orig_path = grub_util_devname_to_ofpath (device_name); + char *ofpath = escape_of_path (orig_path); + const char *map; + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + if (map) + { + printf (" "); + print_full_name (map, dev); + } + + printf (" "); + print_full_name (ofpath, dev); + + printf ("\n"); + free (ofpath); + goto end; + } + if (print == PRINT_EFI_HINT) + { + char *biosname; + char *name; + const char *map; + biosname = guess_efi_drive (device_name); + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + if (map) + { + printf (" "); + print_full_name (map, dev); + } + if (biosname) + { + printf (" "); + print_full_name (biosname, dev); + } + + printf ("\n"); + free (biosname); + goto end; + } + + if (print == PRINT_BAREMETAL_HINT) + { + char *biosname; + char *name; + const char *map; + + biosname = guess_baremetal_drive (device_name); + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + if (map) + { + printf (" "); + print_full_name (map, dev); + } + if (biosname) + { + printf (" "); + print_full_name (biosname, dev); + } + + printf ("\n"); + free (biosname); + goto end; + } + + if (print == PRINT_ARC_HINT) + { + const char *map; + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + if (map) + { + printf (" "); + print_full_name (map, dev); + } + printf ("\n"); + + /* FIXME */ + + goto end; + } + if (print == PRINT_ABSTRACTION) { - grub_disk_memberlist_t list = NULL, tmp; - const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID); - int is_raid = 0; - int is_raid5 = 0; - int is_raid6 = 0; - int raid_level; - grub_disk_t raid_disk; - - raid_level = probe_raid_level (dev->disk); - if (raid_level >= 0) - { - is_raid = 1; - is_raid5 |= (raid_level == 5); - is_raid6 |= (raid_level == 6); - raid_disk = dev->disk; - } - - if ((is_lvm) && (dev->disk->dev->memberlist)) - list = dev->disk->dev->memberlist (dev->disk); - while (list) - { - raid_level = probe_raid_level (list->disk); - if (raid_level >= 0) - { - is_raid = 1; - is_raid5 |= (raid_level == 5); - is_raid6 |= (raid_level == 6); - raid_disk = list->disk; - } - - tmp = list->next; - free (list); - list = tmp; - } - - if (is_raid) - { - printf ("raid "); - if (is_raid5) - printf ("raid5rec "); - if (is_raid6) - printf ("raid6rec "); - if (raid_disk->dev->raidname) - printf ("%s ", raid_disk->dev->raidname (raid_disk)); - } - - if (is_lvm) - printf ("lvm "); - + probe_abstraction (dev->disk); printf ("\n"); + goto end; + } + if (print == PRINT_CRYPTODISK_UUID) + { + probe_cryptodisk_uuid (dev->disk); + printf ("\n"); goto end; } @@@ -649,20 -356,8 +657,22 @@@ main (int argc, char *argv[] print = PRINT_PARTMAP; else if (!strcmp (optarg, "abstraction")) print = PRINT_ABSTRACTION; + else if (!strcmp (optarg, "cryptodisk_uuid")) + print = PRINT_CRYPTODISK_UUID; + else if (!strcmp (optarg, "hints_string")) + print = PRINT_HINT_STR; + else if (!strcmp (optarg, "bios_hints")) + print = PRINT_BIOS_HINT; + else if (!strcmp (optarg, "ieee1275_hints")) + print = PRINT_IEEE1275_HINT; + else if (!strcmp (optarg, "baremetal_hints")) + print = PRINT_BAREMETAL_HINT; + else if (!strcmp (optarg, "efi_hints")) + print = PRINT_EFI_HINT; + else if (!strcmp (optarg, "arc_hints")) + print = PRINT_ARC_HINT; + else if (!strcmp (optarg, "compatibility_hint")) + print = PRINT_COMPATIBILITY_HINT; else usage (1); break;