]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2010-09-26 Robert Millan <rmh@gnu.org>
authorRobert Millan <rmh@gnu.org>
Sun, 26 Sep 2010 14:11:33 +0000 (16:11 +0200)
committerRobert Millan <rmh@gnu.org>
Sun, 26 Sep 2010 14:11:33 +0000 (16:11 +0200)
Support degraded ZFS arrays in "grub-probe -t device" resolution.

* grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): When
the pool is an array of devices, iterate through it and return the
first device that passes a stat() test (instead of blindly returning
the first one).

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

index 379549b95b96dbd7be2ccc1f3b3dab2409614d6d..803cd31684d9e10c793fdf7d6214271d1374c12f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-26  Robert Millan  <rmh@gnu.org>
+
+       Support degraded ZFS arrays in "grub-probe -t device" resolution.
+
+       * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): When
+       the pool is an array of devices, iterate through it and return the
+       first device that passes a stat() test (instead of blindly returning
+       the first one).
+
 2010-09-26  Robert Millan  <rmh@gnu.org>
 
        Build fixes for GNU/kFreeBSD.
index 003fe93333733b765dea009da30155293d81153e..0433d49edc8dcfa1d23df6f2ebe9ecfac8ac5ec6 100644 (file)
@@ -189,31 +189,40 @@ find_root_device_from_libzfs (const char *dir)
   {
     zpool_handle_t *zpool;
     libzfs_handle_t *libzfs;
-    nvlist_t *nvlist;
-    nvlist_t **nvlist_array;
+    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);
-    nvlist = zpool_get_config (zpool, NULL);
+    config = zpool_get_config (zpool, NULL);
 
-    if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0)
+    if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
       error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
 
-    if (nvlist_lookup_nvlist_array (nvlist, "children", &nvlist_array, &nvlist_count) != 0)
+    if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
       error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
+    assert (nvlist_count > 0);
 
-    do
+    while (nvlist_lookup_nvlist_array (children[0], "children",
+                                      &children, &nvlist_count) == 0)
+      assert (nvlist_count > 0);
+
+    for (i = 0; i < nvlist_count; i++)
       {
-       assert (nvlist_count > 0);
-      } while (nvlist_lookup_nvlist_array (nvlist_array[0], "children",
-                                          &nvlist_array, &nvlist_count) == 0);
+       if (nvlist_lookup_string (children[i], "path", &device) != 0)
+         error (1, errno, "nvlist_lookup_string (\"path\")");
+
+       struct stat st;
+       if (stat (device, &st) == 0)
+         break;
 
-    if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0)
-      error (1, errno, "nvlist_lookup_string (\"path\")");
+       device = NULL;
+      }
 
     zpool_close (zpool);
   }