Am Sonntag, den 05.07.2009, 16:55 +0200 schrieb Felix Zielcke:
> Here's a new one which adds full support for pdc devices.
> > 
> > I think we need a list of possible dmraid names.  There we could go
> > through the list in a loop.  That applies to grub_util_is_dmraid() and
> > other places in the code.
> 
> I don't think it would be that useful, because hostdisk.c
> grub_util_biosdisk_get_grub_dev and device_is_wholedisk just can't use
> this list directly. 

Ah I should have just looked at your mail and not at dmraid's code.
This one should actually work for you and it also adds support for these
intel isw devices.
-- 
Felix Zielcke
2009-07-08  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/hostdisk.c: Include <grub/file.h>.
        (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 <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,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);
   }
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to