]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Support install on multi-device filesystems.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Feb 2012 09:35:28 +0000 (10:35 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Feb 2012 09:35:28 +0000 (10:35 +0100)
* include/grub/emu/getroot.h (grub_guess_root_device): Renamed to ...
(grub_guess_root_devices): ...this. Return char **. All users updated.
* include/grub/emu/misc.h (grub_find_root_device_from_mountinfo):
Removed.
* util/getroot.c (find_root_device_from_libzfs): Moved pool logic to ...
(find_root_devices_from_poolname): ... here.
(grub_find_root_devices_from_mountinfo): Return char **. Make static.
Support zfs-fuse.
(grub_guess_root_device): Rename to ...
(grub_guess_root_devices): ... this. Return char **. All users updated.
* util/grub-install.in: Handle multi-device filesystems.
* util/grub-probe.c (probe). Make device_names a char **. Add delim
argument. All users updated.
Handle multi-device filesystems.
Use 'delim' as separator.
Remove device check to allow filesystems on file.
(main): Support -0 argument. Handle multi-device.
* util/grub-setup.c (setup): Remove root argument. Handle multi-device.
Fix a cross-device check while on it.
(arguments): Remove root_dev.
(argp_parser): Remove -r.
(main): Remove root_dev.

ChangeLog
include/grub/emu/getroot.h
include/grub/emu/misc.h
util/getroot.c
util/grub-install.in
util/grub-probe.c
util/grub-setup.c

index cdf079ce9bfc9a8cd83a2d67c289203685f6ea24..0ab39ba8d35d9a66e16052c6bbad93b5cb169a86 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2012-02-03  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Support install on multi-device filesystems.
+
+       * include/grub/emu/getroot.h (grub_guess_root_device): Renamed to ...
+       (grub_guess_root_devices): ...this. Return char **. All users updated.
+       * include/grub/emu/misc.h (grub_find_root_device_from_mountinfo):
+       Removed.
+       * util/getroot.c (find_root_device_from_libzfs): Moved pool logic to ...
+       (find_root_devices_from_poolname): ... here.
+       (grub_find_root_devices_from_mountinfo): Return char **. Make static.
+       Support zfs-fuse.
+       (grub_guess_root_device): Rename to ...
+       (grub_guess_root_devices): ... this. Return char **. All users updated.
+       * util/grub-install.in: Handle multi-device filesystems.
+       * util/grub-probe.c (probe). Make device_names a char **. Add delim
+       argument. All users updated.
+       Handle multi-device filesystems.
+       Use 'delim' as separator.
+       Remove device check to allow filesystems on file.
+       (main): Support -0 argument. Handle multi-device.
+       * util/grub-setup.c (setup): Remove root argument. Handle multi-device.
+       Fix a cross-device check while on it.
+       (arguments): Remove root_dev.
+       (argp_parser): Remove -r.
+       (main): Remove root_dev.
+
 2012-02-01  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/fs/zfs/zfscrypt.c: Add link to documentation.
index 6921e567c75b016d53b80b8fd54cb97ffa76fcf8..83455dddac4bb4175863341c087dc91b16038149 100644 (file)
@@ -30,7 +30,7 @@ enum grub_dev_abstraction_types {
 };
 
 char *grub_find_device (const char *dir, dev_t dev);
-char *grub_guess_root_device (const char *dir);
+char **grub_guess_root_devices (const char *dir);
 int grub_util_get_dev_abstraction (const char *os_dev);
 char *grub_util_get_grub_dev (const char *os_dev);
 char *grub_make_system_path_relative_to_its_root (const char *path);
index a9365f6a1b1d012e256c736c2bd4cd2a8666d06b..7c4652004dd3a48ae235283a86e209619f66528b 100644 (file)
@@ -80,6 +80,4 @@ extern char * canonicalize_file_name (const char *path);
 int grub_device_mapper_supported (void);
 #endif
 
-char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot);
-
 #endif /* GRUB_EMU_MISC_H */
index cae7611ab1c0b63bebf8e5500585ddc861cfe021..12a11b9268b4d589a1ef01e71bfc59e2a09d71c7 100644 (file)
@@ -180,6 +180,149 @@ xgetcwd (void)
   return path;
 }
 
+static char **
+find_root_devices_from_poolname (char *poolname)
+{
+  char **devices = 0;
+  size_t ndevices = 0;
+  size_t devices_allocated = 0;
+
+#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
+  zpool_handle_t *zpool;
+  libzfs_handle_t *libzfs;
+  nvlist_t *config, *vdev_tree;
+  nvlist_t **children, **path;
+  unsigned int nvlist_count;
+  unsigned int i;
+  char *device = 0;
+
+  libzfs = grub_get_libzfs_handle ();
+  if (! libzfs)
+    return NULL;
+
+  zpool = zpool_open (libzfs, poolname);
+  config = zpool_get_config (zpool, NULL);
+
+  if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
+    error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
+
+  if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
+    error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
+  assert (nvlist_count > 0);
+
+  while (nvlist_lookup_nvlist_array (children[0], "children",
+                                    &children, &nvlist_count) == 0)
+    assert (nvlist_count > 0);
+
+  for (i = 0; i < nvlist_count; i++)
+    {
+      if (nvlist_lookup_string (children[i], "path", &device) != 0)
+       error (1, errno, "nvlist_lookup_string (\"path\")");
+
+      struct stat st;
+      if (stat (device, &st) == 0)
+       {
+#ifdef __sun__
+         if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1)
+             == 0)
+           device = xasprintf ("/dev/rdsk/%s",
+                               device + sizeof ("/dev/dsk/") - 1);
+         else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1)
+                  == 0
+                  && grub_memcmp (device + strlen (device) - 4,
+                                  ",raw", 4) != 0)
+           device = xasprintf ("%s,raw", device);
+         else
+#endif
+           device = xstrdup (device);
+         if (ndevices >= devices_allocated)
+           {
+             devices_allocated = 2 * (devices_allocated + 8);
+             devices = xrealloc (devices, sizeof (devices[0])
+                                 * devices_allocated);
+           }
+         devices[ndevices++] = device;
+       }
+
+      device = NULL;
+    }
+
+  zpool_close (zpool);
+#else
+  char *cmd;
+  FILE *fp;
+  int ret;
+  char *line;
+  size_t len;
+  int st;
+
+  char name[PATH_MAX + 1], state[257], readlen[257], writelen[257];
+  char cksum[257], notes[257];
+  unsigned int dummy;
+
+  cmd = xasprintf ("zpool status %s", poolname);
+  fp = popen (cmd, "r");
+  free (cmd);
+
+  st = 0;
+  while (1)
+    {
+      line = NULL;
+      ret = getline (&line, &len, fp);
+      if (ret == -1)
+       break;
+       
+      if (sscanf (line, " %s %256s %256s %256s %256s %256s",
+                 name, state, readlen, writelen, cksum, notes) >= 5)
+       switch (st)
+         {
+         case 0:
+           if (!strcmp (name, "NAME")
+               && !strcmp (state, "STATE")
+               && !strcmp (readlen, "READ")
+               && !strcmp (writelen, "WRITE")
+               && !strcmp (cksum, "CKSUM"))
+             st++;
+           break;
+         case 1:
+           if (!strcmp (name, poolname))
+             st++;
+           break;
+         case 2:
+           if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy)
+               && !sscanf (name, "raidz%u", &dummy)
+               && !strcmp (state, "ONLINE"))
+             {
+               char *tmp;
+               if (ndevices >= devices_allocated)
+                 {
+                   devices_allocated = 2 * (devices_allocated + 8);
+                   devices = xrealloc (devices, sizeof (devices[0])
+                                       * devices_allocated);
+                 }
+               devices[ndevices++] = xasprintf ("/dev/%s", name);
+             }
+           break;
+         }
+       
+      free (line);
+    }
+
+  pclose (fp);
+#endif
+  if (devices)
+    {
+      if (ndevices >= devices_allocated)
+       {
+         devices_allocated = 2 * (devices_allocated + 8);
+         devices = xrealloc (devices, sizeof (devices[0])
+                             * devices_allocated);
+       }
+      devices[ndevices++] = 0;
+    }
+  return devices;
+}
+
 #ifdef __linux__
 
 #define ESCAPED_PATH_MAX (4 * PATH_MAX)
@@ -219,13 +362,13 @@ unescape (char *str)
   *optr = 0;
 }
 
-char *
-grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
+static char **
+grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
 {
   FILE *fp;
   char *buf = NULL;
   size_t len = 0;
-  char *ret = NULL;
+  char **ret = NULL;
   int entry_len = 0, entry_max = 4;
   struct mountinfo_entry *entries;
   struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
@@ -328,9 +471,33 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
       if (!*entries[i].device)
        continue;
 
-      ret = strdup (entries[i].device);
-      if (relroot)
-       *relroot = strdup (entries[i].enc_root);
+      if (grub_strcmp (entries[i].fstype, "fuse.zfs") == 0)
+       {
+         char *slash;
+         slash = strchr (entries[i].device, '/');
+         if (slash)
+           *slash = 0;
+         ret = find_root_devices_from_poolname (entries[i].device);
+         if (slash)
+           *slash = '/';
+         if (relroot)
+           {
+             if (!slash)
+               *relroot = xasprintf ("/@%s", entries[i].enc_root);
+             else if (strchr (slash + 1, '@'))
+               *relroot = xasprintf ("/%s%s", slash + 1, entries[i].enc_root);
+             else
+               *relroot = xasprintf ("/%s@%s", slash + 1, entries[i].enc_root);
+           }
+       }
+      else
+       {
+         ret = xmalloc (2 * sizeof (ret[0]));
+         ret[0] = strdup (entries[i].device);
+         ret[1] = 0;
+         if (relroot)
+           *relroot = strdup (entries[i].enc_root);
+       }
       break;
     }
 
@@ -342,10 +509,10 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
 
 #endif /* __linux__ */
 
-static char *
-find_root_device_from_libzfs (const char *dir)
+static char **
+find_root_devices_from_libzfs (const char *dir)
 {
-  char *device = NULL;
+  char **device = NULL;
   char *poolname;
   char *poolfs;
 
@@ -353,119 +520,7 @@ find_root_device_from_libzfs (const char *dir)
   if (! poolname)
     return NULL;
 
-#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
-  {
-    zpool_handle_t *zpool;
-    libzfs_handle_t *libzfs;
-    nvlist_t *config, *vdev_tree;
-    nvlist_t **children, **path;
-    unsigned int nvlist_count;
-    unsigned int i;
-
-    libzfs = grub_get_libzfs_handle ();
-    if (! libzfs)
-      return NULL;
-
-    zpool = zpool_open (libzfs, poolname);
-    config = zpool_get_config (zpool, NULL);
-
-    if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
-      error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
-
-    if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
-      error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
-    assert (nvlist_count > 0);
-
-    while (nvlist_lookup_nvlist_array (children[0], "children",
-                                      &children, &nvlist_count) == 0)
-      assert (nvlist_count > 0);
-
-    for (i = 0; i < nvlist_count; i++)
-      {
-       if (nvlist_lookup_string (children[i], "path", &device) != 0)
-         error (1, errno, "nvlist_lookup_string (\"path\")");
-
-       struct stat st;
-       if (stat (device, &st) == 0)
-         {
-#ifdef __sun__
-           if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1)
-               == 0)
-             device = xasprintf ("/dev/rdsk/%s",
-                                 device + sizeof ("/dev/dsk/") - 1);
-           else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1)
-                    == 0
-                    && grub_memcmp (device + strlen (device) - 4,
-                                    ",raw", 4) != 0)
-             device = xasprintf ("%s,raw", device);
-           else
-#endif
-             device = xstrdup (device);
-           break;
-         }
-
-       device = NULL;
-      }
-
-    zpool_close (zpool);
-  }
-#else
-  {
-    char *cmd;
-    FILE *fp;
-    int ret;
-    char *line;
-    size_t len;
-    int st;
-
-    char name[PATH_MAX + 1], state[257], readlen[257], writelen[257];
-    char cksum[257], notes[257];
-    unsigned int dummy;
-
-    cmd = xasprintf ("zpool status %s", poolname);
-    fp = popen (cmd, "r");
-    free (cmd);
-
-    st = 0;
-    while (st < 3)
-      {
-       line = NULL;
-       ret = getline (&line, &len, fp);
-       if (ret == -1)
-         goto fail;
-       
-       if (sscanf (line, " %s %256s %256s %256s %256s %256s",
-                   name, state, readlen, writelen, cksum, notes) >= 5)
-         switch (st)
-           {
-           case 0:
-             if (!strcmp (name, "NAME")
-                 && !strcmp (state, "STATE")
-                 && !strcmp (readlen, "READ")
-                 && !strcmp (writelen, "WRITE")
-                 && !strcmp (cksum, "CKSUM"))
-               st++;
-             break;
-           case 1:
-             if (!strcmp (name, poolname))
-               st++;
-             break;
-           case 2:
-             if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy)
-                 && !sscanf (name, "raidz%u", &dummy)
-                 && !strcmp (state, "ONLINE"))
-               st++;
-             break;
-           }
-       
-       free (line);
-      }
-    device = xasprintf ("/dev/%s", name);
-
- fail:
-    pclose (fp);
-  }
-#endif
+  device = find_root_devices_from_poolname (poolname);
 
   free (poolname);
   if (poolfs)
@@ -706,10 +761,10 @@ grub_find_device (const char *path, dev_t dev)
 
 #endif /* __CYGWIN__ */
 
-char *
-grub_guess_root_device (const char *dir)
+char **
+grub_guess_root_devices (const char *dir)
 {
-  char *os_dev = NULL;
+  char **os_dev = NULL;
 #ifdef __GNU__
   file_t file;
   mach_port_t *ports;
@@ -743,9 +798,11 @@ grub_guess_root_device (const char *dir)
   if (data[name_len - 1] != '\0')
     grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir);
 
-  os_dev = xmalloc (strlen ("/dev/") + data_len);
-  memcpy (os_dev, "/dev/", strlen ("/dev/"));
-  memcpy (os_dev + strlen ("/dev/"), data, data_len);
+  os_dev = xmalloc (2 * sizeof (os_dev[0]));
+  os_dev[0] = xmalloc (strlen ("/dev/") + data_len);
+  memcpy (os_dev[0], "/dev/", strlen ("/dev/"));
+  memcpy (os_dev[0] + strlen ("/dev/"), data, data_len);
+  os_dev[1] = 0;
 
   if (ports && num_ports > 0)
     {
@@ -772,48 +829,56 @@ grub_guess_root_device (const char *dir)
 
 #ifdef __linux__
   if (!os_dev)
-    os_dev = grub_find_root_device_from_mountinfo (dir, NULL);
+    os_dev = grub_find_root_devices_from_mountinfo (dir, NULL);
 #endif /* __linux__ */
 
   if (!os_dev)
-    os_dev = find_root_device_from_libzfs (dir);
+    os_dev = find_root_devices_from_libzfs (dir);
 
   if (os_dev)
     {
-      char *tmp = os_dev;
-      os_dev = canonicalize_file_name (os_dev);
-      free (tmp);
-    }
-
-  if (os_dev)
-    {
-      int dm = (strncmp (os_dev, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0);
-      int root = (strcmp (os_dev, "/dev/root") == 0);
-      if (!dm && !root)
-       return os_dev;
-      if (stat (os_dev, &st) >= 0)
+      char **cur;
+      for (cur = os_dev; *cur; cur++)
        {
-         free (os_dev);
+         char *tmp = *cur;
+         int root, dm;
+         *cur = canonicalize_file_name (*cur);
+         free (tmp);
+         root = (strcmp (*cur, "/dev/root") == 0);
+         dm = (strncmp (*cur, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0);
+         if (!dm && !root)
+           continue;
+         if (stat (*cur, &st) < 0)
+           break;
+         free (*cur);
          dev = st.st_rdev;
-         return grub_find_device (dm ? "/dev/mapper" : "/dev", dev);
+         *cur = grub_find_device (dm ? "/dev/mapper" : "/dev", dev);
        }
+      if (!*cur)
+       return os_dev;
+      for (cur = os_dev; *cur; cur++)
+       free (*cur);
       free (os_dev);
+      os_dev = 0;
     }
 
   if (stat (dir, &st) < 0)
     grub_util_error (_("cannot stat `%s'"), dir);
 
   dev = st.st_dev;
+
+  os_dev = xmalloc (2 * sizeof (os_dev[0]));
   
 #ifdef __CYGWIN__
   /* Cygwin specific function.  */
-  os_dev = grub_find_device (dir, dev);
+  os_dev[0] = grub_find_device (dir, dev);
 
 #else
 
   /* This might be truly slow, but is there any better way?  */
-  os_dev = grub_find_device ("/dev", dev);
+  os_dev[0] = grub_find_device ("/dev", dev);
 #endif
+  os_dev[1] = 0;
 #endif /* !__GNU__ */
 
   return os_dev;
@@ -2412,7 +2477,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
 #ifdef __linux__
              {
                char *bind;
-               grub_free (grub_find_root_device_from_mountinfo (buf2, &bind));
+               grub_free (grub_find_root_devices_from_mountinfo (buf2, &bind));
                if (bind && bind[0] && bind[1])
                  {
                    buf3 = bind;
@@ -2445,7 +2510,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
 #ifdef __linux__
   {
     char *bind;
-    grub_free (grub_find_root_device_from_mountinfo (buf2, &bind));
+    grub_free (grub_find_root_devices_from_mountinfo (buf2, &bind));
     if (bind && bind[0] && bind[1])
       {
        char *temp = buf3;
index 7e4bf1512e1b5f771b2b75a6b9450973c78f2b53..9d219bb9371b3b209ec42715a3801874ef06db1b 100644 (file)
@@ -473,7 +473,7 @@ if ! test -f "${grubdir}"/grubenv; then
 fi
 
 # Create the core image. First, auto-detect the filesystem module.
-fs_module="`"$grub_probe" --device-map="${device_map}" --target=fs --device "${grub_device}"`"
+fs_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs --device `"
 if test "x$fs_module" = x ; then
     echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2
     echo "Try with --recheck." 1>&2
@@ -485,7 +485,7 @@ fi
 # this command is allowed to fail (--target=fs already grants us that the
 # filesystem will be accessible).
 partmap_module=
-for x in `"$grub_probe" --device-map="${device_map}" --target=partmap --device "${grub_device}" 2> /dev/null`; do
+for x in `echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=partmap --device 2> /dev/null`; do
    case "$x" in
        netbsd | openbsd) 
           partmap_module="$partmap_module part_bsd";;
@@ -496,7 +496,7 @@ for x in `"$grub_probe" --device-map="${device_map}" --target=partmap --device "
 done
 
 # Device abstraction module, if any (lvm, raid).
-devabstraction_module="`"$grub_probe" --device-map="${device_map}" --target=abstraction --device "${grub_device}"`"
+devabstraction_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=abstraction --device`"
 
 if [ "x$disk_module" = xata ]; then
     disk_module=pata
@@ -538,14 +538,14 @@ if [ "x${devabstraction_module}" = "x" ] ; then
       fi
       install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
     fi
-    grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1
+    grub_drive="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=drive --device`" || exit 1
 
     # Strip partition number
     grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
     grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
     if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then
         # generic method (used on coreboot and ata mod)
-        uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`"
+        uuid="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs_uuid --device`"
         if [ "x${uuid}" = "x" ] ; then
           if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then
              echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
@@ -559,15 +559,15 @@ if [ "x${devabstraction_module}" = "x" ] ; then
         fi
 
        if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
        elif [ x"$platform" = xpc ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=bios_hints --device "${grub_device}"`"
+            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=bios_hints --device`"
        elif [ x"$platform" = xefi ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=efi_hints --device "${grub_device}"`"
+            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=efi_hints --device`"
        elif [ x"$platform" = xieee1275 ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device "${grub_device}"`"
+            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device`"
        elif [ x"$platform" = xloongson ] || [ x"$platform" = xqemu ] || [ x"$platform" = xcoreboot ] || [ x"$platform" = xmultiboot ] || [ x"$platform" = xqemu-mips ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
        else
             echo "No hints available for your platform. Expect reduced performance"
            hints=
@@ -587,7 +587,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then
     fi
 else
     if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
-       for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do
+       for uuid in "`echo "${grub_device}" | xargs "${grub_probe}"  --target=cryptodisk_uuid --device`"; do
            echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg"
        done
        config_opt="-c ${grubdir}/load.cfg "
index 17edff6ce9c5c47dac0254fd111f385a3a1c0025..1d1a82230b3856ed2562d2379fadb3300b7d3492 100644 (file)
@@ -313,307 +313,342 @@ probe_abstraction (grub_disk_t disk)
 }
 
 static void
-probe (const char *path, char *device_name)
+probe (const char *path, char **device_names, char delim)
 {
-  char *drive_name = NULL;
+  char **drives_names = NULL;
+  char **curdev, **curdrive;
   char *grub_path = NULL;
-  char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
-  grub_device_t dev = NULL;
-  grub_fs_t fs;
+  int ndev = 0;
 
-  if (path == NULL)
-    {
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__sun__)
-      if (! grub_util_check_char_device (device_name))
-        grub_util_error (_("%s is not a character device"), device_name);
-#else
-      if (! grub_util_check_block_device (device_name))
-        grub_util_error (_("%s is not a block device"), device_name);
-#endif
-    }
-  else
+  if (path != NULL)
     {
       grub_path = canonicalize_file_name (path);
-      device_name = grub_guess_root_device (grub_path);
+      device_names = grub_guess_root_devices (grub_path);
+      free (grub_path);
     }
 
-  if (! device_name)
+  if (! device_names)
     grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
 
   if (print == PRINT_DEVICE)
     {
-      printf ("%s\n", device_name);
-      goto end;
+      for (curdev = device_names; *curdev; curdev++)
+       {
+         printf ("%s", *curdev);
+         putchar (delim);
+       }
+      return;
     }
 
-  drive_name = grub_util_get_grub_dev (device_name);
-  if (! drive_name)
-    grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
-                    device_name);
-
-  if (print == PRINT_DRIVE)
+  for (curdev = device_names; *curdev; curdev++)
     {
-      printf ("(%s)\n", drive_name);
-      goto end;
+      grub_util_pull_device (*curdev);
+      ndev++;
     }
+  
+  drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); 
 
-  grub_util_info ("opening %s", drive_name);
-  dev = grub_device_open (drive_name);
-  if (! dev)
-    grub_util_error ("%s", _(grub_errmsg));
+  for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
+       curdrive++)
+    {
+      *curdrive = grub_util_get_grub_dev (*curdev);
+      if (! *curdrive)
+       grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
+                        *curdev);
+    }
+  *curdrive = 0;
 
-  if (print == PRINT_HINT_STR)
+  if (print == PRINT_FS || print == PRINT_FS_UUID
+      || print == PRINT_FS_LABEL)
     {
-      const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
-      const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
-      char *biosname, *bare, *efi;
-      const char *map;
+      grub_device_t dev = NULL;
+      grub_fs_t fs;
 
-      if (ofpath)
-       {
-         printf ("--hint-ieee1275='");
-         print_full_name (ofpath, dev);
-         printf ("' ");
-       }
+      grub_util_info ("opening %s", drives_names[0]);
+      dev = grub_device_open (drives_names[0]);
+      if (! dev)
+       grub_util_error ("%s", _(grub_errmsg));
+      
+      fs = grub_fs_probe (dev);
+      if (! fs)
+       grub_util_error ("%s", _(grub_errmsg));
 
-      biosname = guess_bios_drive (device_name);
-      if (biosname)
+      if (print == PRINT_FS)
        {
-         printf ("--hint-bios=");
-         print_full_name (biosname, dev);
-         printf (" ");
+         printf ("%s", fs->name);
+         putchar (delim);
        }
-      free (biosname);
-
-      efi = guess_efi_drive (device_name);
-      if (efi)
+      else if (print == PRINT_FS_UUID)
        {
-         printf ("--hint-efi=");
-         print_full_name (efi, dev);
-         printf (" ");
-       }
-      free (efi);
+         char *uuid;
+         if (! fs->uuid)
+           grub_util_error (_("%s does not support UUIDs"), fs->name);
 
-      bare = guess_baremetal_drive (device_name);
-      if (bare)
-       {
-         printf ("--hint-baremetal=");
-         print_full_name (bare, dev);
-         printf (" ");
+         if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
+           grub_util_error ("%s", grub_errmsg);
+
+         printf ("%s", uuid);
+         putchar (delim);
        }
-      free (bare);
+      else if (print == PRINT_FS_LABEL)
+       {
+         char *label;
+         if (! fs->label)
+           grub_util_error (_("%s does not support labels"), fs->name);
 
-      /* FIXME: Add ARC hint.  */
+         if (fs->label (dev, &label) != GRUB_ERR_NONE)
+           grub_util_error ("%s", _(grub_errmsg));
 
-      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
-      if (map)
-       {
-         printf ("--hint='");
-         print_full_name (map, dev);
-         printf ("' ");
+         printf ("%s", label);
+         putchar (delim);
        }
-      printf ("\n");
-
       goto end;
     }
 
-  if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
-       || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
-       || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
-      && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
+  for (curdrive = drives_names, curdev = device_names; *curdrive;
+       curdrive++, curdev++)
     {
-      print_full_name (dev->disk->name, dev);
-      printf ("\n");
-      goto end;
-    }
+      grub_device_t dev = NULL;
 
-  if (print == PRINT_COMPATIBILITY_HINT)
-    {
-      const char *map;
-      char *biosname;
-      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
-      if (map)
+      grub_util_info ("opening %s", *curdrive);
+      dev = grub_device_open (*curdrive);
+      if (! dev)
+       grub_util_error ("%s", _(grub_errmsg));
+
+      if (print == PRINT_HINT_STR)
        {
-         print_full_name (map, dev);
+         const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
+         const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
+         char *biosname, *bare, *efi;
+         const char *map;
+
+         if (ofpath)
+           {
+             printf ("--hint-ieee1275='");
+             print_full_name (ofpath, dev);
+             printf ("' ");
+           }
+
+         biosname = guess_bios_drive (*curdev);
+         if (biosname)
+           {
+             printf ("--hint-bios=");
+             print_full_name (biosname, dev);
+             printf (" ");
+           }
+         free (biosname);
+
+         efi = guess_efi_drive (*curdev);
+         if (efi)
+           {
+             printf ("--hint-efi=");
+             print_full_name (efi, dev);
+             printf (" ");
+           }
+         free (efi);
+
+         bare = guess_baremetal_drive (*curdev);
+         if (bare)
+           {
+             printf ("--hint-baremetal=");
+             print_full_name (bare, dev);
+             printf (" ");
+           }
+         free (bare);
+
+         /* FIXME: Add ARC hint.  */
+
+         map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+         if (map)
+           {
+             printf ("--hint='");
+             print_full_name (map, dev);
+             printf ("' ");
+           }
          printf ("\n");
-         goto end;
-       }
-      biosname = guess_bios_drive (device_name);
-      if (biosname)
-       print_full_name (biosname, dev);
-      printf ("\n");
-      free (biosname);
-      goto end;
-    }
-
-  if (print == PRINT_BIOS_HINT)
-    {
-      char *biosname;
-      biosname = guess_bios_drive (device_name);
-      if (biosname)
-       print_full_name (biosname, dev);
-      printf ("\n");
-      free (biosname);
-      goto end;
-    }
-  if (print == PRINT_IEEE1275_HINT)
-    {
-      const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
-      const char *ofpath = grub_util_devname_to_ofpath (osdev);
-      const char *map;
 
-      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
-      if (map)
+         grub_device_close (dev);
+         continue;
+       }
+      
+      if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
+          || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
+          || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
+         && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
        {
-         printf (" ");
-         print_full_name (map, dev);
+         print_full_name (dev->disk->name, dev);
+         putchar (delim);
+         continue;
        }
 
-      if (ofpath)
+      if (print == PRINT_COMPATIBILITY_HINT)
        {
-         printf (" ");
-         print_full_name (ofpath, dev);
+         const char *map;
+         char *biosname;
+         map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+         if (map)
+           {
+             print_full_name (map, dev);
+             putchar (delim);
+             grub_device_close (dev);
+             /* Compatibility hint is one device only.  */
+             break;
+           }
+         biosname = guess_bios_drive (*curdev);
+         if (biosname)
+           {
+             print_full_name (biosname, dev);
+             putchar (delim);
+           }
+         free (biosname);
+         grub_device_close (dev);
+         /* Compatibility hint is one device only.  */
+         if (biosname)
+           break;
+         continue;
        }
 
-      printf ("\n");
-      goto end;
-    }
-  if (print == PRINT_EFI_HINT)
-    {
-      char *biosname;
-      char *name;
-      const char *map;
-      biosname = guess_efi_drive (device_name);
-
-      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
-      if (map)
+      if (print == PRINT_BIOS_HINT)
        {
-         printf (" ");
-         print_full_name (map, dev);
+         char *biosname;
+         biosname = guess_bios_drive (*curdev);
+         if (biosname)
+           {
+             print_full_name (biosname, dev);
+             putchar (delim);
+           }
+         free (biosname);
+         grub_device_close (dev);
+         continue;
        }
-      if (biosname)
+      if (print == PRINT_IEEE1275_HINT)
        {
-         printf (" ");
-         print_full_name (biosname, dev);
+         const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
+         const char *ofpath = grub_util_devname_to_ofpath (osdev);
+         const char *map;
+
+         map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+         if (map)
+           {
+             print_full_name (map, dev);
+             putchar (delim);
+           }
+
+         if (ofpath)
+           {
+             print_full_name (ofpath, dev);
+             putchar (delim);
+           }
+
+         grub_device_close (dev);
+         continue;
        }
-
-      printf ("\n");
-      free (biosname);
-      goto end;
-    }
-
-  if (print == PRINT_BAREMETAL_HINT)
-    {
-      char *biosname;
-      char *name;
-      const char *map;
-
-      biosname = guess_baremetal_drive (device_name);
-
-      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
-      if (map)
+      if (print == PRINT_EFI_HINT)
        {
-         printf (" ");
-         print_full_name (map, dev);
+         char *biosname;
+         char *name;
+         const char *map;
+         biosname = guess_efi_drive (*curdev);
+
+         map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+         if (map)
+           {
+             print_full_name (map, dev);
+             putchar (delim);
+           }
+         if (biosname)
+           {
+             print_full_name (biosname, dev);
+             putchar (delim);
+           }
+
+         free (biosname);
+         grub_device_close (dev);
+         continue;
        }
-      if (biosname)
+
+      if (print == PRINT_BAREMETAL_HINT)
        {
-         printf (" ");
-         print_full_name (biosname, dev);
+         char *biosname;
+         char *name;
+         const char *map;
+
+         biosname = guess_baremetal_drive (*curdev);
+
+         map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+         if (map)
+           {
+             print_full_name (map, dev);
+             putchar (delim);
+           }
+         if (biosname)
+           {
+             print_full_name (biosname, dev);
+             putchar (delim);
+           }
+
+         free (biosname);
+         grub_device_close (dev);
+         continue;
        }
 
-      printf ("\n");
-      free (biosname);
-      goto end;
-    }
-
-  if (print == PRINT_ARC_HINT)
-    {
-      const char *map;
-
-      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
-      if (map)
+      if (print == PRINT_ARC_HINT)
        {
-         printf (" ");
-         print_full_name (map, dev);
+         const char *map;
+
+         map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+         if (map)
+           {
+             print_full_name (map, dev);
+             putchar (delim);
+           }
+
+         /* FIXME */
+         grub_device_close (dev);
+         continue;
        }
-      printf ("\n");
-
-      /* FIXME */
-
-      goto end;
-    }
-
-  if (print == PRINT_ABSTRACTION)
-    {
-      probe_abstraction (dev->disk);
-      printf ("\n");
-      goto end;
-    }
-
-  if (print == PRINT_CRYPTODISK_UUID)
-    {
-      probe_cryptodisk_uuid (dev->disk);
-      printf ("\n");
-      goto end;
-    }
-
-  if (print == PRINT_PARTMAP)
-    {
-      /* Check if dev->disk itself is contained in a partmap.  */
-      probe_partmap (dev->disk);
-      printf ("\n");
-      goto end;
-    }
 
-  if (print == PRINT_MSDOS_PARTTYPE)
-    {
-      if (dev->disk->partition
-         && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
-        printf ("%02x", dev->disk->partition->msdostype);
-
-      printf ("\n");
-      goto end;
-    }
-
-  fs = grub_fs_probe (dev);
-  if (! fs)
-    grub_util_error ("%s", _(grub_errmsg));
-
-  if (print == PRINT_FS)
-    {
-      printf ("%s\n", fs->name);
-    }
-  else if (print == PRINT_FS_UUID)
-    {
-      char *uuid;
-      if (! fs->uuid)
-       grub_util_error (_("%s does not support UUIDs"), fs->name);
+      if (print == PRINT_ABSTRACTION)
+       {
+         probe_abstraction (dev->disk);
+         putchar (delim);
+         grub_device_close (dev);
+         continue;
+       }
 
-      if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
-       grub_util_error ("%s", grub_errmsg);
+      if (print == PRINT_CRYPTODISK_UUID)
+       {
+         probe_cryptodisk_uuid (dev->disk);
+         putchar (delim);
+         grub_device_close (dev);
+         continue;
+       }
 
-      printf ("%s\n", uuid);
-    }
-  else if (print == PRINT_FS_LABEL)
-    {
-      char *label;
-      if (! fs->label)
-       grub_util_error (_("%s does not support labels"), fs->name);
+      if (print == PRINT_PARTMAP)
+       {
+         /* Check if dev->disk itself is contained in a partmap.  */
+         probe_partmap (dev->disk);
+         putchar (delim);
+         grub_device_close (dev);
+         continue;
+       }
 
-      if (fs->label (dev, &label) != GRUB_ERR_NONE)
-       grub_util_error ("%s", _(grub_errmsg));
+      if (print == PRINT_MSDOS_PARTTYPE)
+       {
+         if (dev->disk->partition
+             && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
+           printf ("%02x", dev->disk->partition->msdostype);
 
-      printf ("%s\n", label);
+         putchar (delim);
+         grub_device_close (dev);
+         continue;
+       }
     }
 
  end:
-  if (dev)
-    grub_device_close (dev);
-  free (grub_path);
-  free (filebuf_via_grub);
-  free (filebuf_via_sys);
-  free (drive_name);
+  for (curdrive = drives_names; *curdrive; curdrive++)
+    free (*curdrive);
+  free (drives_names);
 }
 
 static struct option options[] =
@@ -658,7 +693,8 @@ int
 main (int argc, char *argv[])
 {
   char *dev_map = 0;
-  char *argument;
+  int zero_delim = 0;
+  char delim;
 
   set_program_name (argv[0]);
 
@@ -667,7 +703,7 @@ main (int argc, char *argv[])
   /* Check for options.  */
   while (1)
     {
-      int c = getopt_long (argc, argv, "dm:t:hVv", options, 0);
+      int c = getopt_long (argc, argv, "dm:t:hVv0", options, 0);
 
       if (c == -1)
        break;
@@ -726,6 +762,10 @@ main (int argc, char *argv[])
            usage (0);
            break;
 
+         case '0':
+           zero_delim = 1;
+           break;
+
          case 'V':
            printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
            return 0;
@@ -750,14 +790,12 @@ main (int argc, char *argv[])
       usage (1);
     }
 
-  if (optind + 1 != argc)
+  if (optind + 1 != argc && !argument_is_device)
     {
       fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
       usage (1);
     }
 
-  argument = argv[optind];
-
   /* Initialize the emulated biosdisk driver.  */
   grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
 
@@ -774,11 +812,28 @@ main (int argc, char *argv[])
   grub_mdraid1x_init ();
   grub_lvm_init ();
 
+  if (print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
+      || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
+      || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
+    delim = ' ';
+  else
+    delim = '\n';
+
+  if (zero_delim)
+    delim = '\0';
+
   /* Do it.  */
   if (argument_is_device)
-    probe (NULL, argument);
+    probe (NULL, argv + optind, delim);
   else
-    probe (argument, NULL);
+    probe (argv[optind], NULL, delim);
+
+  if (!zero_delim && (print == PRINT_COMPATIBILITY_HINT
+                     || print == PRINT_BIOS_HINT
+                     || print == PRINT_IEEE1275_HINT
+                     || print == PRINT_BAREMETAL_HINT
+                     || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT))
+    putchar ('\n');
 
   /* Free resources.  */
   grub_gcry_fini_all ();
index 3db3d1f969a0ad8ed93a5ed57dcbaf25c5990ebf..a50b0efedcb7982fa252804c96b1fa60cefad1c4 100644 (file)
@@ -133,15 +133,16 @@ write_rootdev (char *core_img, grub_device_t root_dev,
 static void
 setup (const char *dir,
        const char *boot_file, const char *core_file,
-       const char *root, const char *dest, int force,
+       const char *dest, int force,
        int fs_probe, int allow_floppy)
 {
   char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
   char *boot_img, *core_img;
+  char *root = 0;
   size_t boot_size, core_size;
   grub_uint16_t core_sectors;
-  grub_device_t root_dev, dest_dev;
-  struct grub_boot_blocklist *first_block, *block;
+  grub_device_t root_dev = 0, dest_dev;
+  struct grub_boot_blocklist *first_block, *block, *last_block;
   char *tmp_img;
   int i;
   grub_disk_addr_t first_sector;
@@ -235,17 +236,56 @@ setup (const char *dir,
                                                - sizeof (*block));
   grub_util_info ("root is `%s', dest is `%s'", root, dest);
 
-  /* Open the root device and the destination device.  */
-  grub_util_info ("Opening root");
-  root_dev = grub_device_open (root);
-  if (! root_dev)
-    grub_util_error ("%s", _(grub_errmsg));
-
   grub_util_info ("Opening dest");
   dest_dev = grub_device_open (dest);
   if (! dest_dev)
     grub_util_error ("%s", _(grub_errmsg));
 
+  {
+    char **root_devices = grub_guess_root_devices (dir);
+    char **cur;
+    int found = 0;
+
+    for (cur = root_devices; *cur; cur++)
+      {
+       char *drive;
+       grub_device_t try_dev;
+
+       drive = grub_util_get_grub_dev (*cur);
+       if (!drive)
+         continue;
+       try_dev = grub_device_open (drive);
+       if (! try_dev)
+         continue;
+       if (!found && try_dev->disk->id == dest_dev->disk->id
+           && try_dev->disk->dev->id == dest_dev->disk->dev->id)
+         {
+           if (root_dev)
+             grub_device_close (root_dev);
+           free (root);
+           root_dev = try_dev;
+           root = drive;
+           found = 1;
+           continue;
+         }
+       if (!root_dev)
+         {
+           root_dev = try_dev;
+           root = drive;
+           continue;
+         }
+       grub_device_close (try_dev);    
+       free (drive);
+      }
+    if (!root_dev)
+      {
+       grub_util_error ("guessing the root device failed, because of `%s'",
+                        grub_errmsg);
+      }
+    grub_util_info ("guessed root_dev `%s' from "
+                   "dir `%s'", root_dev->disk->name, dir);
+  }
+
   grub_util_info ("setting the root device to `%s'", root);
   if (grub_env_set ("root", root) != GRUB_ERR_NONE)
     grub_util_error ("%s", _(grub_errmsg));
@@ -636,11 +676,12 @@ unable_to_embed:
     boot_devpath = (char *) (boot_img
                             + GRUB_BOOT_AOUT_HEADER_SIZE
                             + GRUB_BOOT_MACHINE_BOOT_DEVPATH);
-    if (file->device->disk->id != dest_dev->disk->id)
+    if (dest_dev->disk->id != root_dev->disk->id
+       || dest_dev->disk->dev->id != root_dev->disk->dev->id)
       {
        const char *dest_ofpath;
        dest_ofpath
-         = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (file->device->disk));
+         = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (root_dev->disk));
        grub_util_info ("dest_ofpath is `%s'", dest_ofpath);
        strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END
                 - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1);
@@ -741,7 +782,6 @@ struct arguments
   char *core_file;
   char *dir;
   char *dev_map;
-  char *root_dev;
   int  force;
   int  fs_probe;
   int allow_floppy;
@@ -802,13 +842,6 @@ argp_parser (int key, char *arg, struct argp_state *state)
         arguments->dev_map = xstrdup (arg);
         break;
 
-      case 'r':
-        if (arguments->root_dev)
-          free (arguments->root_dev);
-
-        arguments->root_dev = xstrdup (arg);
-        break;
-
       case 'f':
         arguments->force = 1;
         break;
@@ -935,38 +968,11 @@ main (int argc, char *argv[])
       grub_util_info ("Using `%s' as GRUB device", dest_dev);
     }
 
-  if (arguments.root_dev)
-    {
-      root_dev = get_device_name (arguments.root_dev);
-
-      if (! root_dev)
-        grub_util_error (_("invalid root device `%s'"), arguments.root_dev);
-
-      root_dev = xstrdup (root_dev);
-    }
-  else
-    {
-      char *root_device =
-        grub_guess_root_device (arguments.dir ? : DEFAULT_DIRECTORY);
-
-      root_dev = grub_util_get_grub_dev (root_device);
-      if (! root_dev)
-       {
-         grub_util_info ("guessing the root device failed, because of `%s'",
-                         grub_errmsg);
-          grub_util_error (_("cannot guess the root device. Specify the option "
-                             "`--root-device'"));
-       }
-      grub_util_info ("guessed root device `%s' and root_dev `%s' from "
-                      "dir `%s'", root_device, root_dev,
-                      arguments.dir ? : DEFAULT_DIRECTORY);
-    }
-
   /* Do the real work.  */
   setup (arguments.dir ? : DEFAULT_DIRECTORY,
         arguments.boot_file ? : DEFAULT_BOOT_FILE,
         arguments.core_file ? : DEFAULT_CORE_FILE,
-        root_dev, dest_dev, arguments.force,
+        dest_dev, arguments.force,
         arguments.fs_probe, arguments.allow_floppy);
 
   /* Free resources.  */
@@ -976,7 +982,6 @@ main (int argc, char *argv[])
   free (arguments.boot_file);
   free (arguments.core_file);
   free (arguments.dir);
-  free (arguments.root_dev);
   free (arguments.dev_map);
   free (arguments.device);
   free (root_dev);