/* * Iterate over all pools in the system. */ int zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data) { config_node_t *cn; zpool_handle_t *zhp; int ret; /* * 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 (check_restricted(cn->cn_name)) continue; 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) { hdl->libzfs_pool_iter--; return (ret); } } hdl->libzfs_pool_iter--; return (0); }
/* * Returns true if the named pool matches the given GUID. */ static int pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid, boolean_t *isactive) { zpool_handle_t *zhp; uint64_t theguid; if (zpool_open_silent(hdl, name, &zhp) != 0) return (-1); if (zhp == NULL) { *isactive = B_FALSE; return (0); } verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID, &theguid) == 0); zpool_close(zhp); *isactive = (theguid == guid); return (0); }
/* * Import the given pool using the known configuration. The configuration * should have come from zpool_find_import(). The 'newname' and 'altroot' * parameters control whether the pool is imported with a different name or with * an alternate root, respectively. */ int zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, const char *altroot) { zfs_cmd_t zc; char *packed; size_t len; char *thename; char *origname; int ret; verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &origname) == 0); if (newname != NULL) { if (!zpool_name_valid(hdl, B_FALSE, newname)) return (zfs_error(hdl, EZFS_INVALIDNAME, dgettext(TEXT_DOMAIN, "cannot import '%s'"), newname)); thename = (char *)newname; } else { thename = origname; } if (altroot != NULL && altroot[0] != '/') return (zfs_error(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), altroot)); (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name)); if (altroot != NULL) (void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root)); else zc.zc_root[0] = '\0'; verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &zc.zc_guid) == 0); verify(nvlist_size(config, &len, NV_ENCODE_NATIVE) == 0); if ((packed = zfs_alloc(hdl, len)) == NULL) return (-1); verify(nvlist_pack(config, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); zc.zc_config_src = (uint64_t)(uintptr_t)packed; zc.zc_config_src_size = len; ret = 0; if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) { char desc[1024]; if (newname == NULL) (void) snprintf(desc, sizeof (desc), dgettext(TEXT_DOMAIN, "cannot import '%s'"), thename); else (void) snprintf(desc, sizeof (desc), dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"), origname, thename); switch (errno) { case ENOTSUP: /* * Unsupported version. */ (void) zfs_error(hdl, EZFS_BADVERSION, desc); break; case EINVAL: (void) zfs_error(hdl, EZFS_INVALCONFIG, desc); break; default: (void) zpool_standard_error(hdl, errno, desc); } ret = -1; } else { zpool_handle_t *zhp; /* * This should never fail, but play it safe anyway. */ if (zpool_open_silent(hdl, thename, &zhp) != 0) { ret = -1; } else if (zhp != NULL) { ret = zpool_create_zvol_links(zhp); zpool_close(zhp); } } free(packed); return (ret); }