Here's a patch which let grub-probe work with /dev/mapper/nvidia_ dmraid
devices. The other ones that dmraid supports are for now just not
anymore treated as LVM but hostdisk.c doestn't yet support them.

The find_partition_by_uuid is needed, because on my dmraid the
HDIO_GETGEO ioctl returns just zeros for all fields. So there is no way
to get the start of the partition which the normal find_partition needs.
Currently it uses the output of blkid to get the UUID of the device and
then compares it with all grub devices like search --fs-uuid does.

BSD partitions aren't currently supported, but Vladimir wants to change
them so they're numbers instead of letters which would make it easier
for me.
-- 
Felix Zielcke
2009-06-17  Felix Zielcke  <fziel...@z-51.de>

	* util/getroot.c (grub_util_is_dmraid): New function.
	(grub_util_get_dev_abstraction): Use it to not treat dmraid
	devices as LVM.
	* util/hostdisc.c: Include <grub/file.h>.
	(convert_system_partition_to_system_disk): Add support for
	nvidia 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 counti, to get the value of dos_part.

diff --git a/util/getroot.c b/util/getroot.c
index b50979d..0777a67 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; 12
+  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 1844a7e..2629fbf 100644
--- a/util/hostdisk.c
+++ b/util/hostdisk.c
@@ -25,6 +25,7 @@
 #include <grub/util/misc.h>
 #include <grub/util/hostdisk.h>
 #include <grub/misc.h>
+#include <grub/file.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -791,6 +792,12 @@ 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_cediideh") - 1] = '\0';
+	  return path;
+	}
     }
 
   return path;
@@ -905,7 +912,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;
@@ -955,7 +962,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)
@@ -985,20 +1031,53 @@ 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);
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to