diff --git a/ChangeLog.raid b/ChangeLog.raid index 989f0bc09..c546a7632 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,14 @@ +2010-07-18 Colin Watson + + * 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 * disk/mdraid_linux.c (grub_mdraid_detect): Fix calculation of 1.x diff --git a/disk/raid.c b/disk/raid.c index 87e713f30..1dc361e8e 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -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); diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 5b0849a98..2d7469c9d 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -36,6 +36,11 @@ #include #endif +#ifdef __linux__ +# include +# include +#endif + #include #include #include @@ -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 */ diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 8b2f52bb4..524572fad 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -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;