2009-07-26 Felix Zielcke * util/hostdisk.c: Include . (grub_util_biosdisk_get_grub_dev): Use new nested function find_partition_by_uuid in the case that the HD_GETGEO ioctl returns 0 for the sectors count, to get the value of dos_part. diff --git a/util/hostdisk.c b/util/hostdisk.c index 5842698..843bfb4 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -925,7 +926,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) does not count the extended partition and missing primary partitions. Use same method as on Linux here. */ { - char *name; + char *name, *os_dev_uuid; grub_disk_t disk; int fd; struct hd_geometry hdg; @@ -975,7 +976,46 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } + auto int find_partition_by_uuid (const char *name); + int find_partition_by_uuid (const char *name) + { + grub_device_t dev; + + if (name[0] == 'f' && name[1] == 'd' + && name[2] >= '0' && name[2] <= '9') + return 0; + + dev = grub_device_open (name); + if (dev) + { + grub_fs_t fs; + + fs = grub_fs_probe (dev); + + if (fs && fs->uuid) + { + char *uuid, *p; + + (fs->uuid) (dev, &uuid); + if (grub_errno == GRUB_ERR_NONE && uuid) + { + if (grub_strcasecmp (uuid, os_dev_uuid) == 0) + { + p = strchr (name, ','); + dos_part = atoi (p); + if (strchr (p, ',')) + grub_util_error ("BSD partitions not yet supported"); + free (uuid); + return 1; + } + free (uuid); + } + } + grub_device_close (dev); + } + return 0; + } name = make_device_name (drive, -1, -1); if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) @@ -1005,28 +1045,61 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (hdg.start == 0 && device_is_wholedisk (os_dev)) return name; - grub_util_info ("opening the device %s", name); - disk = grub_disk_open (name); - free (name); - - if (! disk) - return 0; - grub_partition_iterate (disk, find_partition); - if (grub_errno != GRUB_ERR_NONE) + if (hdg.sectors == 0) { - grub_disk_close (disk); - return 0; + FILE *fp; + char *free_ptr, *p, *q; + int len = 512; + + p = xmalloc (strlen (os_dev) + strlen ("blkid ") + 1); + strcpy (p, "blkid "); + strcat (p, os_dev); + fp = popen (p, "r"); + free (p); + do { + p = xmalloc (len); + p = fgets (p, len, fp); + if (! p) + return 0; + len *= 2; + } while (! strchr (p, '\n')); + free_ptr = p; + p = strstr (p , "UUID="); + if (! p) + return 0; + p += strlen ("UUID=\""); + q = strchr (p, '\"'); + if (q) + *q = '\0'; + os_dev_uuid = p; + pclose (fp); + grub_device_iterate (find_partition_by_uuid); + free (free_ptr); } + else + { + grub_util_info ("opening the device %s", name); + disk = grub_disk_open (name); + free (name); + if (! disk) + return 0; + grub_partition_iterate (disk, find_partition); + if (grub_errno != GRUB_ERR_NONE) + { + grub_disk_close (disk); + return 0; + } + if (dos_part < 0) + grub_disk_close (disk); + } if (dos_part < 0) { - grub_disk_close (disk); grub_error (GRUB_ERR_BAD_DEVICE, "cannot find the partition of `%s'", os_dev); return 0; } - return make_device_name (drive, dos_part, bsd_part); }