=== modified file 'grub-core/disk/raid.c' --- a/grub-core/disk/raid.c 2011-04-12 18:53:25 +0000 +++ b/grub-core/disk/raid.c 2011-04-13 18:39:15 +0000 @@ -122,18 +122,49 @@ } #endif +static inline int +ascii2hex (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; +} + static grub_err_t grub_raid_open (const char *name, grub_disk_t disk) { struct grub_raid_array *array; unsigned n; - for (array = array_list; array != NULL; array = array->next) + if (grub_memcmp (name, "mduuid/", sizeof ("mduuid/") - 1) == 0) { - if (!grub_strcmp (array->name, name)) - if (grub_is_array_readable (array)) - break; + const char *uuidstr = name + sizeof ("mduuid/") - 1; + grub_size_t uuid_len = grub_strlen (uuidstr) / 2; + grub_uint8_t uuidbin[uuid_len]; + unsigned i; + for (i = 0; i < uuid_len; i++) + uuidbin[i] = ascii2hex (uuidstr[2 * i + 1]) + | (ascii2hex (uuidstr[2 * i]) << 4); + + for (array = array_list; array != NULL; array = array->next) + { + if (uuid_len == (unsigned) array->uuid_len + && grub_memcmp (uuidbin, array->uuid, uuid_len) == 0) + if (grub_is_array_readable (array)) + break; + } } + else + for (array = array_list; array != NULL; array = array->next) + { + if (!grub_strcmp (array->name, name)) + if (grub_is_array_readable (array)) + break; + } if (!array) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", === modified file 'grub-core/kern/emu/getroot.c' --- a/grub-core/kern/emu/getroot.c 2011-04-12 18:53:25 +0000 +++ b/grub-core/kern/emu/getroot.c 2011-04-13 18:39:15 +0000 @@ -628,7 +628,7 @@ #ifdef __linux__ static char * -get_mdadm_name (const char *os_dev) +get_mdadm_uuid (const char *os_dev) { int mdadm_pipe[2]; pid_t mdadm_pid; @@ -680,19 +680,21 @@ while (getline (&buf, &len, mdadm) > 0) { - if (strncmp (buf, "MD_NAME=", sizeof ("MD_NAME=") - 1) == 0) + if (strncmp (buf, "MD_UUID=", sizeof ("MD_UUID=") - 1) == 0) { - char *name_start, *colon; + char *name_start, *ptri, *ptro; size_t name_len; free (name); - name_start = buf + sizeof ("MD_NAME=") - 1; - /* Strip off the homehost if present. */ - colon = strchr (name_start, ':'); - name = strdup (colon ? colon + 1 : name_start); - name_len = strlen (name); - if (name[name_len - 1] == '\n') - name[name_len - 1] = '\0'; + name_start = buf + sizeof ("MD_UUID=") - 1; + ptro = name = xmalloc (strlen (name_start) + 1); + for (ptri = name_start; *ptri && *ptri != '\n' && *ptri != '\r'; + ptri++) + if ((*ptri >= '0' && *ptri <= '9') + || (*ptri >= 'a' && *ptri <= 'f') + || (*ptri >= 'A' && *ptri <= 'F')) + *ptro++ = *ptri; + *ptro = 0; } } @@ -808,12 +810,11 @@ #ifdef __linux__ { - char *mdadm_name = get_mdadm_name (os_dev); + char *mdadm_name = get_mdadm_uuid (os_dev); struct stat st; if (mdadm_name) { - char *newname; const char *q; for (q = os_dev + strlen (os_dev) - 1; q >= os_dev @@ -821,24 +822,14 @@ if (q >= os_dev && *q == 'p') { - newname = xasprintf ("/dev/md/%sp%s", mdadm_name, q + 1); - if (stat (newname, &st) == 0) - { - free (grub_dev); - grub_dev = xasprintf ("md/%s,%s", mdadm_name, q + 1); - goto done; - } - free (newname); - } - newname = xasprintf ("/dev/md/%s", mdadm_name); - if (stat (newname, &st) == 0) - { free (grub_dev); - grub_dev = xasprintf ("md/%s", mdadm_name); + grub_dev = xasprintf ("mduuid/%s,%s", mdadm_name, q + 1); + goto done; } + free (grub_dev); + grub_dev = xasprintf ("mduuid/%s", mdadm_name); done: - free (newname); free (mdadm_name); } }