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