+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
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);
#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>
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))
{
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 */