int zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *propbuf, size_t proplen, zfs_source_t *srctype) { uint64_t value; char msg[1024], *strvalue; nvlist_t *nvp; zfs_source_t src = ZFS_SRC_NONE; (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, "cannot get property '%s'"), zpool_prop_to_name(prop)); if (zpool_get_version(zhp) < ZFS_VERSION_BOOTFS) { zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN, "pool must be " "upgraded to support pool properties")); return (zfs_error(zhp->zpool_hdl, EZFS_BADVERSION, msg)); } if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) return (zfs_error(zhp->zpool_hdl, EZFS_POOLPROPS, msg)); /* * the "name" property is special cased */ if (!zfs_prop_valid_for_type(prop, ZFS_TYPE_POOL) && prop != ZFS_PROP_NAME) return (-1); switch (prop) { case ZFS_PROP_NAME: (void) strlcpy(propbuf, zhp->zpool_name, proplen); break; case ZFS_PROP_BOOTFS: if (nvlist_lookup_nvlist(zhp->zpool_props, zpool_prop_to_name(prop), &nvp) != 0) { strvalue = (char *)zfs_prop_default_string(prop); if (strvalue == NULL) strvalue = "-"; src = ZFS_SRC_DEFAULT; } else { VERIFY(nvlist_lookup_uint64(nvp, ZFS_PROP_SOURCE, &value) == 0); src = value; VERIFY(nvlist_lookup_string(nvp, ZFS_PROP_VALUE, &strvalue) == 0); if (strlen(strvalue) >= proplen) return (-1); } (void) strcpy(propbuf, strvalue); break; default: return (-1); } if (srctype) *srctype = src; return (0); }
/** * Create the zpool * @param p_libzfshd: libzfs handle * @param psz_zpool: zpool name * @param pnv_root: the root tree of vdev * @param pnv_props: the tree of properties (can be NULL) * @param pnv_fsprops: the tree of the file system properties (can be NULL) * @param ppsz_error: the error message if any * @return 0 in case of error, the error code overwise */ int libzfs_zpool_create(libzfs_handle_t *p_libzfshd, const char* psz_zpool, nvlist_t *pnv_root, nvlist_t *pnv_props, nvlist_t *pnv_fsprops, const char **ppsz_error) { int i_error; char *psz_altroot; /* Check the zpool name */ if(libzfs_zpool_name_valid(psz_zpool, ppsz_error)) return EINVAL; /** Check the properties TODO: zpool_valid_proplist and zfs_valid_proplist */ if((i_error = spa_create(psz_zpool, pnv_root, pnv_props, "libzfswrap_zpool_create", pnv_fsprops))) { switch(i_error) { case EBUSY: *ppsz_error = "one or more vdevs refer to the same device"; break; case EOVERFLOW: *ppsz_error = "one or more devices is less than the minimum size (64Mo)"; break; case ENOSPC: *ppsz_error = "one or more devices is out of space"; break; case ENOTBLK: *ppsz_error = "cache device must be a disk or disk slice"; break; case EEXIST: *ppsz_error = "the pool already exist"; break; default: *ppsz_error = "unable to create the spa"; } return i_error; } /* If this is an alternate root pool, then automatically set the mountpoint to be '/' */ if(nvlist_lookup_string(pnv_props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &psz_altroot) == 0) { zfs_handle_t *p_zhd; assert((p_zhd = zfs_open(p_libzfshd, psz_zpool, ZFS_TYPE_DATASET)) != NULL); assert(zfs_prop_set(p_zhd, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), "/") == 0); zfs_close(p_zhd); } return 0; }
/* * Target is the dataset whose pool we want to open. */ static void zhack_import(char *target, boolean_t readonly) { nvlist_t *config; nvlist_t *props; int error; kernel_init(readonly ? FREAD : (FREAD | FWRITE)); g_zfs = libzfs_init(); ASSERT(g_zfs != NULL); dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb); g_readonly = readonly; g_importargs.unique = B_TRUE; g_importargs.can_be_active = readonly; g_pool = strdup(target); error = zpool_tryimport(g_zfs, target, &config, &g_importargs); if (error) fatal(NULL, FTAG, "cannot import '%s': %s", target, libzfs_error_description(g_zfs)); props = NULL; if (readonly) { VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_uint64(props, zpool_prop_to_name(ZPOOL_PROP_READONLY), 1) == 0); } zfeature_checks_disable = B_TRUE; error = spa_import(target, config, props, (readonly ? ZFS_IMPORT_SKIP_MMP : ZFS_IMPORT_NORMAL)); zfeature_checks_disable = B_FALSE; if (error == EEXIST) error = 0; if (error) fatal(NULL, FTAG, "can't import '%s': %s", target, strerror(error)); }
/* * Target is the dataset whose pool we want to open. */ static void import_pool(const char *target, boolean_t readonly) { nvlist_t *config; nvlist_t *pools; int error; char *sepp; spa_t *spa; nvpair_t *elem; nvlist_t *props; char *name; kernel_init(readonly ? FREAD : (FREAD | FWRITE)); g_zfs = libzfs_init(); ASSERT(g_zfs != NULL); dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb); g_readonly = readonly; /* * If we only want readonly access, it's OK if we find * a potentially-active (ie, imported into the kernel) pool from the * default cachefile. */ if (readonly && spa_open(target, &spa, FTAG) == 0) { spa_close(spa, FTAG); return; } g_importargs.unique = B_TRUE; g_importargs.can_be_active = readonly; g_pool = strdup(target); if ((sepp = strpbrk(g_pool, "/@")) != NULL) *sepp = '\0'; g_importargs.poolname = g_pool; pools = zpool_search_import(g_zfs, &g_importargs); if (nvlist_empty(pools)) { if (!g_importargs.can_be_active) { g_importargs.can_be_active = B_TRUE; if (zpool_search_import(g_zfs, &g_importargs) != NULL || spa_open(target, &spa, FTAG) == 0) { fatal(spa, FTAG, "cannot import '%s': pool is " "active; run " "\"zpool export %s\" " "first\n", g_pool, g_pool); } } fatal(NULL, FTAG, "cannot import '%s': no such pool " "available\n", g_pool); } elem = nvlist_next_nvpair(pools, NULL); name = nvpair_name(elem); VERIFY(nvpair_value_nvlist(elem, &config) == 0); props = NULL; if (readonly) { VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_uint64(props, zpool_prop_to_name(ZPOOL_PROP_READONLY), 1) == 0); } zfeature_checks_disable = B_TRUE; error = spa_import(name, config, props, ZFS_IMPORT_NORMAL); zfeature_checks_disable = B_FALSE; if (error == EEXIST) error = 0; if (error) fatal(NULL, FTAG, "can't import '%s': %s", name, strerror(error)); }