]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Identify RAID by its UUID rather than (guessed) name.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 16 Apr 2011 13:27:35 +0000 (15:27 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 16 Apr 2011 13:27:35 +0000 (15:27 +0200)
* grub-core/disk/raid.c (ascii2hex): New function.
(grub_raid_open): Accept mduuid/%s specification.
* grub-core/kern/emu/getroot.c (get_mdadm_name): Revamped into ...
(get_mdadm_uuid): ... this.
(grub_util_get_grub_dev): Use mduuid/%s if UUID is available.

ChangeLog
grub-core/disk/raid.c
grub-core/kern/emu/getroot.c

index 572d49a136d94601686c91d964677b1f635b9c96..84840a9a7949f7e83b60cefb17c227d1411d083c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-04-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Identify RAID by its UUID rather than (guessed) name.
+
+       * grub-core/disk/raid.c (ascii2hex): New function.
+       (grub_raid_open): Accept mduuid/%s specification.
+       * grub-core/kern/emu/getroot.c (get_mdadm_name): Revamped into ...
+       (get_mdadm_uuid): ... this.
+       (grub_util_get_grub_dev): Use mduuid/%s if UUID is available.
+
 2011-04-16  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/gfxmenu/gui_image.c (rescale_image): Don't attempt to scale
index 3c74bba99d645dd7172031120b51b526117f89e1..946e6d2c2a1510aa6d96a3691c047f79e9217933 100644 (file)
@@ -122,18 +122,49 @@ grub_raid_getname (struct grub_disk *disk)
 }
 #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",
index 17da9070fe1da8a2f0475fac5b3e78af66dd2494..f836a66257be91a43f06c815b358c2d60c7c4b67 100644 (file)
@@ -690,7 +690,7 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
 
 #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;
@@ -742,19 +742,21 @@ get_mdadm_name (const char *os_dev)
 
       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;
            }
        }
 
@@ -870,37 +872,26 @@ grub_util_get_grub_dev (const char *os_dev)
 
 #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
                   && grub_isdigit (*q); q--);
 
            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);
          }
       }