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