From 8e57a6ca44dca7bff5867e0576105b0ba82f2bdf Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 26 Sep 2010 16:11:33 +0200 Subject: [PATCH] 2010-09-26 Robert Millan 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 | 9 +++++++++ grub-core/kern/emu/getroot.c | 31 ++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 379549b95..803cd3168 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-26 Robert Millan + + 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 Build fixes for GNU/kFreeBSD. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 003fe9333..0433d49ed 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -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\")"); - if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0) - error (1, errno, "nvlist_lookup_string (\"path\")"); + struct stat st; + if (stat (device, &st) == 0) + break; + + device = NULL; + } zpool_close (zpool); }