diff options
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c index 94640d1..dc27238 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * The pool configuration repository is stored in /etc/zfs/zpool.cache as a * single packed nvlist. While it would be nice to just read in this @@ -313,21 +311,33 @@ zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data) zpool_handle_t *zhp; int ret; - if (namespace_reload(hdl) != 0) + /* + * If someone makes a recursive call to zpool_iter(), we want to avoid + * refreshing the namespace because that will invalidate the parent + * context. We allow recursive calls, but simply re-use the same + * namespace AVL tree. + */ + if (!hdl->libzfs_pool_iter && namespace_reload(hdl) != 0) return (-1); + hdl->libzfs_pool_iter++; for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL; cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) { - if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) + if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) { + hdl->libzfs_pool_iter--; return (-1); + } if (zhp == NULL) continue; - if ((ret = func(zhp, data)) != 0) + if ((ret = func(zhp, data)) != 0) { + hdl->libzfs_pool_iter--; return (ret); + } } + hdl->libzfs_pool_iter--; return (0); } |