]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices,
authorColin Watson <cjwatson@ubuntu.com>
Sun, 18 Jul 2010 14:53:14 +0000 (15:53 +0100)
committerColin Watson <cjwatson@ubuntu.com>
Sun, 18 Jul 2010 14:53:14 +0000 (15:53 +0100)
removing the homehost if present.
* kern/emu/getroot.c (get_mdadm_name) [__linux__]: New function.
(grub_util_get_grub_dev): Use md/%s to name mdadm 1.x devices,
removing the homehost if present.
(grub_util_get_grub_dev) [__linux__]: Get the array name from mdadm
if possible.
* util/i386/pc/grub-setup.c (main): Handle md/* devices.

ChangeLog.raid
disk/raid.c
kern/emu/getroot.c
util/i386/pc/grub-setup.c

index 989f0bc09337b5597d9ea5732888e903c9dc9ce9..c546a7632f357acd2a8395f718ffb22eaf9f62ee 100644 (file)
@@ -1,3 +1,14 @@
+2010-07-18  Colin Watson  <cjwatson@ubuntu.com>
+
+       * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices,
+       removing the homehost if present.
+       * kern/emu/getroot.c (get_mdadm_name) [__linux__]: New function.
+       (grub_util_get_grub_dev): Use md/%s to name mdadm 1.x devices,
+       removing the homehost if present.
+       (grub_util_get_grub_dev) [__linux__]: Get the array name from mdadm
+       if possible.
+       * util/i386/pc/grub-setup.c (main): Handle md/* devices.
+
 2009-12-15  Peter Henn  <peter.henn@web.de>
 
        * disk/mdraid_linux.c (grub_mdraid_detect): Fix calculation of 1.x
index 87e713f305d2f7f1f327e15071b8081a1e7dd559..1dc361e8e3a25b1bf7289331f68f9953e5ed32c8 100644 (file)
@@ -563,7 +563,14 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
       if (! array->name)
        array->name = grub_xasprintf ("md%d", array->number);
       else
-       array->name = grub_xasprintf ("%s", array->name);
+       {
+         /* Strip off the homehost if present.  */
+         char *colon = grub_strchr (array->name, ':');
+         char *new_name = grub_xasprintf ("md/%s",
+                                          colon ? colon + 1 : array->name);
+         grub_free (array->name);
+         array->name = new_name;
+       }
 
       grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
                     scanner_name);
index 5b0849a98263c2b8970aaae4fa1c99b188dfff53..2d7469c9d6f81d4540fd7f77ae43f03714771434 100644 (file)
 #include <sys/mman.h>
 #endif
 
+#ifdef __linux__
+# include <sys/types.h>
+# include <sys/wait.h>
+#endif
+
 #include <grub/mm.h>
 #include <grub/misc.h>
 #include <grub/emu/misc.h>
@@ -516,10 +521,89 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
   return GRUB_DEV_ABSTRACTION_NONE;
 }
 
+#ifdef __linux__
+static char *
+get_mdadm_name (const char *os_dev)
+{
+  int mdadm_pipe[2];
+  pid_t mdadm_pid;
+  char *name = NULL;
+
+  if (pipe (mdadm_pipe) < 0)
+    {
+      grub_util_warn ("Unable to create pipe for mdadm: %s", strerror (errno));
+      return NULL;
+    }
+
+  mdadm_pid = fork ();
+  if (mdadm_pid < 0)
+    grub_util_warn ("Unable to fork mdadm: %s", strerror (errno));
+  else if (mdadm_pid == 0)
+    {
+      /* Child.  */
+      char *argv[5];
+
+      close (mdadm_pipe[0]);
+      dup2 (mdadm_pipe[1], STDOUT_FILENO);
+      close (mdadm_pipe[1]);
+
+      /* execvp has inconvenient types, hence the casts.  None of these
+         strings will actually be modified.  */
+      argv[0] = (char *) "mdadm";
+      argv[1] = (char *) "--detail";
+      argv[2] = (char *) "--export";
+      argv[3] = (char *) os_dev;
+      argv[4] = NULL;
+      execvp ("mdadm", argv);
+      exit (127);
+    }
+  else
+    {
+      /* Parent.  Read mdadm's output.  */
+      FILE *mdadm;
+      char *buf = NULL;
+      size_t len = 0;
+
+      close (mdadm_pipe[1]);
+      mdadm = fdopen (mdadm_pipe[0], "r");
+      if (! mdadm)
+       {
+         grub_util_warn ("Unable to open stream from mdadm: %s",
+                         strerror (errno));
+         goto out;
+       }
+
+      while (getline (&buf, &len, mdadm) > 0)
+       {
+         if (strncmp (buf, "MD_NAME=", sizeof ("MD_NAME=") - 1) == 0)
+           {
+             char *name_start, *colon;
+             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';
+           }
+       }
+
+out:
+      close (mdadm_pipe[0]);
+      waitpid (mdadm_pid, NULL, 0);
+    }
+
+  return name;
+}
+#endif /* __linux__ */
+
 char *
 grub_util_get_grub_dev (const char *os_dev)
 {
-  char *grub_dev;
+  char *grub_dev = NULL;
 
   switch (grub_util_get_dev_abstraction (os_dev))
     {
@@ -611,12 +695,25 @@ grub_util_get_grub_dev (const char *os_dev)
          if (q)
            *q = ',';
 
-         asprintf (&grub_dev, "%s", p);
+         asprintf (&grub_dev, "md/%s", p);
          free (p);
        }
       else
        grub_util_error ("unknown kind of RAID device `%s'", os_dev);
 
+#ifdef __linux__
+      {
+       char *mdadm_name = get_mdadm_name (os_dev);
+
+       if (mdadm_name)
+         {
+           free (grub_dev);
+           asprintf (&grub_dev, "md/%s", mdadm_name);
+           free (mdadm_name);
+         }
+      }
+#endif /* __linux__ */
+
       break;
 
     default:  /* GRUB_DEV_ABSTRACTION_NONE */
index 8b2f52bb4a7d4aad2956fbdf699c98da7bd01693..524572fad747206ef74da1c22cf9f3815b3aa876 100644 (file)
@@ -812,14 +812,14 @@ main (int argc, char *argv[])
     must_embed = 1;
 
   if (root_dev[0] == 'm' && root_dev[1] == 'd'
-      && root_dev[2] >= '0' && root_dev[2] <= '9')
+      && ((root_dev[2] >= '0' && root_dev[2] <= '9') || root_dev[2] == '/'))
     {
       /* FIXME: we can avoid this on RAID1.  */
       must_embed = 1;
     }
 
   if (dest_dev[0] == 'm' && dest_dev[1] == 'd'
-      && dest_dev[2] >= '0' && dest_dev[2] <= '9')
+      && ((dest_dev[2] >= '0' && dest_dev[2] <= '9') || dest_dev[2] == '/'))
     {
       char **devicelist;
       int i;