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).
This commit is contained in:
Robert Millan 2010-09-26 16:11:33 +02:00
parent f913083640
commit 8e57a6ca44
2 changed files with 29 additions and 11 deletions

View file

@ -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> 2010-09-26 Robert Millan <rmh@gnu.org>
Build fixes for GNU/kFreeBSD. Build fixes for GNU/kFreeBSD.

View file

@ -189,31 +189,40 @@ find_root_device_from_libzfs (const char *dir)
{ {
zpool_handle_t *zpool; zpool_handle_t *zpool;
libzfs_handle_t *libzfs; libzfs_handle_t *libzfs;
nvlist_t *nvlist; nvlist_t *config, *vdev_tree;
nvlist_t **nvlist_array; nvlist_t **children, **path;
unsigned int nvlist_count; unsigned int nvlist_count;
unsigned int i;
libzfs = grub_get_libzfs_handle (); libzfs = grub_get_libzfs_handle ();
if (! libzfs) if (! libzfs)
return NULL; return NULL;
zpool = zpool_open (libzfs, poolname); 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\")"); 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\")"); 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); if (nvlist_lookup_string (children[i], "path", &device) != 0)
} while (nvlist_lookup_nvlist_array (nvlist_array[0], "children", error (1, errno, "nvlist_lookup_string (\"path\")");
&nvlist_array, &nvlist_count) == 0);
if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0) struct stat st;
error (1, errno, "nvlist_lookup_string (\"path\")"); if (stat (device, &st) == 0)
break;
device = NULL;
}
zpool_close (zpool); zpool_close (zpool);
} }