merge mainline into hints
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 23 Dec 2011 17:49:00 +0000 (18:49 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 23 Dec 2011 17:49:00 +0000 (18:49 +0100)
1  2 
Makefile.util.def
grub-core/disk/ieee1275/ofdisk.c
grub-core/kern/emu/hostdisk.c
grub-core/normal/main.c
include/grub/emu/hostdisk.h
util/grub-install.in
util/grub-mkconfig.in
util/grub-mkconfig_lib.in
util/grub-probe.c

@@@ -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)';
Simple merge
Simple merge
Simple merge
@@@ -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 */
Simple merge
Simple merge
@@@ -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
  }
  
  #include <grub/env.h>
  #include <grub/raid.h>
  #include <grub/i18n.h>
 +#include <grub/emu/misc.h>
 +#include <grub/util/ofpath.h>
+ #include <grub/crypto.h>
+ #include <grub/cryptodisk.h>
  
  #include <stdio.h>
  #include <unistd.h>
@@@ -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)
  {
    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;