2009-07-08 Felix Zielcke
* util/getroot.c (grub_util_is_dmraid): New function.
(grub_util_get_dev_abstraction): Use it to not treat dmraid
devices as LVM.
* util/hostdisk.c: Include .
(convert_system_partition_to_system_disk): Add support for
nvidia, pdc and isw dmraid devices.
(device_is_wholedisk): Add support for isw dmraid devices.
(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/getroot.c b/util/getroot.c
index b50979d..a8f1bb6 100644
--- a/util/getroot.c
+++ b/util/getroot.c
@@ -396,13 +396,38 @@ grub_guess_root_device (const char *dir)
return os_dev;
}
+int
+grub_util_is_dmraid (const char *os_dev)
+{
+ if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/isw_", 16))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/via_", 16))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/asr_", 16))
+ return 1;
+ else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
+ return 1;
+ return 0;
+}
int
grub_util_get_dev_abstraction (const char *os_dev UNUSED)
{
#ifdef __linux__
/* Check for LVM. */
- if (!strncmp (os_dev, "/dev/mapper/", 12))
+ if (!strncmp (os_dev, "/dev/mapper/", 12) && ! grub_util_is_dmraid (os_dev))
return GRUB_DEV_ABSTRACTION_LVM;
/* Check for RAID. */
diff --git a/util/hostdisk.c b/util/hostdisk.c
index d84e7f3..eb6be06 100644
--- a/util/hostdisk.c
+++ b/util/hostdisk.c
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
@@ -791,6 +792,22 @@ convert_system_partition_to_system_disk (const char *os_dev)
p[4] = '\0';
return path;
}
+ /* If this is a Nvidia fake raid. */
+ if (strncmp ("mapper/nvidia_", p, 14) == 0 && p[22] >= '0' && p[22] <= '9')
+ {
+ p[sizeof ("mapper/nvidia_abcdefgh") - 1] = '\0';
+ return path;
+ }
+ if (strncmp ("mapper/pdc_", p, 11) == 0 && p[20] >= '0' && p[20] <= '9')
+ {
+ p[sizeof ("mapper/pdc_abcdefghi") -1] = '\0';
+ return path;
+ }
+ if (strncmp ("mapper/isw_", p, 11) == 0 && p[29] >= '0' && p[29] <= '9')
+ {
+ p[sizeof ("mapper/isw_abcdefghij_Volume0")];
+ return path;
+ }
}
return path;
@@ -841,6 +858,8 @@ device_is_wholedisk (const char *os_dev)
if (os_dev[len - 1] < '0' || os_dev[len - 1] > '9')
return 1;
+ if (strncmp ("/dev/mapper/isw_", os_dev, 16) == 0 && os_dev[34] == '\0')
+ return 1;
return 0;
}
#endif
@@ -907,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;
@@ -957,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)
@@ -987,28 +1045,60 @@ 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);
}
-
- if (dos_part < 0)
+ else
{
- grub_disk_close (disk);
- grub_error (GRUB_ERR_BAD_DEVICE,
- "cannot find the partition of `%s'", os_dev);
- return 0;
- }
+ 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);
+ 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);
}