Am Mittwoch, den 17.06.2009, 18:44 -0400 schrieb Pavel Roskin: 
> On Wed, 2009-06-17 at 16:08 +0200, Felix Zielcke wrote:
> > add support for dmraid devices
> 
> That's good.  I have a system with a PDC RAID, and although I only have
> one drive connected, GRUB2 won't install on it.  I'm looking forward to
> testing your patch on that hardware.
> 
> Unfortunately, your patch doesn't compile as is.  That hanging "12" in
> grub_util_is_dmraid() is not needed.  Also please avoid adding trailing
> whitespace.  STGit warns about it.  "hostdisc" should be spelled
> "hostdisk".

Ah right sorry. Fixed.

> What is "cediideh"?  Actually, on the system I mentioned, root is
> mounted on /dev/mapper/pdc_dieaihahp2.  If "cediideh" is supposed to
> represent all weird names 8 characters long, let's use numbers
> "12345678".

cediideh is how my nvidia dmraid device is called.
I changed it now to abcdefgh.

> Even after fixing the compile error, I'm getting a warning:
> 
> util/hostdisk.c: In function 'grub_util_biosdisk_get_grub_dev':
> util/hostdisk.c:916: warning: 'disk' may be used uninitialized in this
> function
> util/hostdisk.c:916: note: 'disk' was declared here
> 
> Your patch removed the code where 'disk' is initialized:
> disk = grub_disk_open (name);
> 
> Yet grub_disk_close() is still there.  Removing it fixes the warning,
> but I'd like you to recheck the patch.  Apparently the 'disk' variable
> was used for different purposes throughout the function.  While at that,
> it would be great to avoid variable shadowing too and keep variables in
> the innermost possible scope.

I don't get any warning at all with the Debian gcc 4.3.3.
Anyway I fixed it now.

> Finally, the test results, apparently negative:
> 

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. 
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/hostdisk.c: Include <grub/file.h>.
        (convert_system_partition_to_system_disk): Add support for
        nvidia and pdc dmraid devices.
        (device_is_wholedisk): Add support for pdc 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..4be8e74 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,19 @@ 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)
+       {
+         p = strchr (p, '-');
+         if (p)
+           *p = '\0';
+         return path;
+       }
     }
 
   return path;
@@ -841,6 +855,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/pdc_", os_dev, 16) && strchr (os_dev, '-') == NULL)
+    return 1;
   return 0;
 }
 #endif
@@ -907,7 +923,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 +973,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 +1042,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