diff --git a/external/cddl/osnet/dist/lib/libzfs/common/libzfs_import.c b/external/cddl/osnet/dist/lib/libzfs/common/libzfs_import.c index 308a13c74306..e8d29b86f4b2 100644 --- a/external/cddl/osnet/dist/lib/libzfs/common/libzfs_import.c +++ b/external/cddl/osnet/dist/lib/libzfs/common/libzfs_import.c @@ -1095,8 +1095,16 @@ zpool_open_func(void *arg) } #endif /* __FreeBSD__ */ #ifdef __NetBSD__ + struct dkwedge_list dkwl; off_t size; + /* skip devices with wedges */ + if (native_ioctl(fd, DIOCLWEDGES, &dkwl) == 0 && + dkwl.dkwl_nwedges > 0) { + (void) close(fd); + return; + } + if (native_ioctl(fd, DIOCGMEDIASIZE, &size) < 0 || size < SPA_MINDEVSIZE) { (void) close(fd); @@ -1167,6 +1175,9 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) config_entry_t *ce, *cenext; name_entry_t *ne, *nenext; avl_tree_t slice_cache; +#ifdef __NetBSD__ + avl_tree_t dkwedge_cache; +#endif rdsk_node_t *slice; void *cookie; @@ -1258,6 +1269,8 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) } #endif #ifdef __NetBSD__ + avl_create(&dkwedge_cache, slice_cache_compare, + sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node)); if (strcmp(rdsk, "/dev/") == 0) { static const char mib_name[] = "hw.disknames"; size_t len; @@ -1283,7 +1296,10 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) slice->rn_dfd = dfd; slice->rn_hdl = hdl; slice->rn_nozpool = B_FALSE; - avl_add(&slice_cache, slice); + if (strncmp(name, "dk", 2) == 0) + avl_add(&dkwedge_cache, slice); + else + avl_add(&slice_cache, slice); } free(disknames); @@ -1325,6 +1341,16 @@ skipdir: AVL_AFTER))) (void) tpool_dispatch(t, zpool_open_func, slice); tpool_wait(t); +#ifdef __NetBSD__ + for (slice = avl_first(&dkwedge_cache); slice; + (slice = avl_walk(&dkwedge_cache, slice, + AVL_AFTER))) + (void) tpool_dispatch(t, zpool_open_func, slice); + tpool_wait(t); + while ((slice = avl_destroy_nodes(&dkwedge_cache, + &cookie)) != NULL) + avl_add(&slice_cache, slice); +#endif tpool_destroy(t); cookie = NULL; @@ -1365,6 +1391,9 @@ skipdir: free(slice->rn_name); free(slice); } +#ifdef __NetBSD__ + avl_destroy(&dkwedge_cache); +#endif avl_destroy(&slice_cache); (void) closedir(dirp);