diff options
Diffstat (limited to 'usr/src/lib/libzfs')
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_dataset.c | 20 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_impl.h | 3 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_iter.c | 16 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 7 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_util.c | 41 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/mapfile-vers | 3 |
7 files changed, 88 insertions, 4 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h index eb550f606f..ddb85646f7 100644 --- a/usr/src/lib/libzfs/common/libzfs.h +++ b/usr/src/lib/libzfs/common/libzfs.h @@ -64,6 +64,7 @@ typedef enum zfs_error { EZFS_PROPTYPE, /* property does not apply to dataset type */ EZFS_PROPNONINHERIT, /* property is not inheritable */ EZFS_PROPSPACE, /* bad quota or reservation */ + EZFS_PROPCACHED, /* prop unavail since cachedprops flag set */ EZFS_BADTYPE, /* dataset is not of appropriate type */ EZFS_BUSY, /* pool or dataset is busy */ EZFS_EXISTS, /* pool or dataset already exists */ @@ -184,6 +185,7 @@ extern libzfs_handle_t *zpool_get_handle(zpool_handle_t *); extern libzfs_handle_t *zfs_get_handle(zfs_handle_t *); extern void libzfs_print_on_error(libzfs_handle_t *, boolean_t); +extern void libzfs_set_cachedprops(libzfs_handle_t *, boolean_t); extern void zfs_save_arguments(int argc, char **, char *, int); extern int zpool_log_history(libzfs_handle_t *, const char *); diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index e491a65c93..f240b6494f 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -329,6 +329,10 @@ get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc) { libzfs_handle_t *hdl = zhp->zfs_hdl; + if (hdl->libzfs_cachedprops && + libzfs_cmd_set_cachedprops(hdl, zc) != 0) + return (-1); + (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name)); while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, zc) != 0) { @@ -1988,6 +1992,11 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, case ZFS_PROP_NORMALIZE: case ZFS_PROP_UTF8ONLY: case ZFS_PROP_CASE: + if (zhp->zfs_hdl->libzfs_cachedprops) { + return (zfs_error(zhp->zfs_hdl, EZFS_PROPCACHED, + "property unavailable since not cached")); + } + if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) || zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) return (-1); @@ -2228,6 +2237,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, char *str; const char *strval; boolean_t received = zfs_is_recvd_props_mode(zhp); + boolean_t printerr; /* * Check to see if this property applies to our object @@ -2238,6 +2248,16 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, if (received && zfs_prop_readonly(prop)) return (-1); + if (zhp->zfs_hdl->libzfs_cachedprops && + zfs_prop_cacheable(prop)) { + printerr = zhp->zfs_hdl->libzfs_printerr; + libzfs_print_on_error(zhp->zfs_hdl, B_FALSE); + (void) zfs_error(zhp->zfs_hdl, EZFS_PROPCACHED, + "property unavailable since not cached"); + libzfs_print_on_error(zhp->zfs_hdl, printerr); + return (-1); + } + if (src) *src = ZPROP_SRC_NONE; diff --git a/usr/src/lib/libzfs/common/libzfs_impl.h b/usr/src/lib/libzfs/common/libzfs_impl.h index ad4142da3f..9d98718dcb 100644 --- a/usr/src/lib/libzfs/common/libzfs_impl.h +++ b/usr/src/lib/libzfs/common/libzfs_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. */ @@ -79,6 +80,7 @@ struct libzfs_handle { libzfs_fru_t **libzfs_fru_hash; libzfs_fru_t *libzfs_fru_list; char libzfs_chassis_id[256]; + boolean_t libzfs_cachedprops; }; #define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */ @@ -149,6 +151,7 @@ int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...); int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***, size_t *); zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *); +int libzfs_cmd_set_cachedprops(libzfs_handle_t *, zfs_cmd_t *); int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t, diff --git a/usr/src/lib/libzfs/common/libzfs_iter.c b/usr/src/lib/libzfs/common/libzfs_iter.c index 5fdfe1d591..01c059fe61 100644 --- a/usr/src/lib/libzfs/common/libzfs_iter.c +++ b/usr/src/lib/libzfs/common/libzfs_iter.c @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <stdio.h> @@ -110,6 +111,10 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data) if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM) return (0); + if (zhp->zfs_hdl->libzfs_cachedprops && + libzfs_cmd_set_cachedprops(zhp->zfs_hdl, &zc) != 0) + return (-1); + if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) return (-1); @@ -120,9 +125,8 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data) * that the pool has since been removed. */ if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl, - &zc)) == NULL) { + &zc)) == NULL) continue; - } if ((ret = func(nzhp, data)) != 0) { zcmd_free_nvlists(&zc); @@ -147,15 +151,19 @@ zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data) zhp->zfs_type == ZFS_TYPE_BOOKMARK) return (0); + if (zhp->zfs_hdl->libzfs_cachedprops && + libzfs_cmd_set_cachedprops(zhp->zfs_hdl, &zc) != 0) + return (-1); + if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) return (-1); + while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT, &zc)) == 0) { if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl, - &zc)) == NULL) { + &zc)) == NULL) continue; - } if ((ret = func(nzhp, data)) != 0) { zcmd_free_nvlists(&zc); diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index 0418091025..0c37c36257 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -270,6 +270,12 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, case PROP_TYPE_NUMBER: intval = zpool_get_prop_int(zhp, prop, &src); + if (literal && prop != ZPOOL_PROP_HEALTH) { + (void) snprintf(buf, len, "%llu", + (u_longlong_t)intval); + break; + } + switch (prop) { case ZPOOL_PROP_SIZE: case ZPOOL_PROP_ALLOCATED: @@ -334,6 +340,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, default: (void) snprintf(buf, len, "%llu", intval); } + break; case PROP_TYPE_INDEX: diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c index 507a72ce02..59b978cf16 100644 --- a/usr/src/lib/libzfs/common/libzfs_util.c +++ b/usr/src/lib/libzfs/common/libzfs_util.c @@ -83,6 +83,9 @@ libzfs_error_description(libzfs_handle_t *hdl) return (dgettext(TEXT_DOMAIN, "property cannot be inherited")); case EZFS_PROPSPACE: return (dgettext(TEXT_DOMAIN, "invalid quota or reservation")); + case EZFS_PROPCACHED: + return (dgettext(TEXT_DOMAIN, "property unavailable since " + "cachedprops flag set")); case EZFS_BADTYPE: return (dgettext(TEXT_DOMAIN, "operation not applicable to " "datasets of this type")); @@ -611,6 +614,42 @@ libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr) hdl->libzfs_printerr = printerr; } +/* + * Set the value of the cachedprops flag. If the cachedprops flag is set, + * operations which get ZFS properties will only retrieve a property if the + * property is cached somewhere in memory. + * + * Consumers of libzfs should take care when setting this flag, as they will + * prevent themselves from listing the full set of ZFS properties. + * + * ZFS properties which always require disk I/O are ZPL properties (utf8only, + * normalization, etc.) and the volsize and volblocksize properties for volumes. + */ +void +libzfs_set_cachedprops(libzfs_handle_t *hdl, boolean_t cachedprops) +{ + hdl->libzfs_cachedprops = cachedprops; +} + +/* + * Adds a src nvlist to a zfs_cmd_t which specifies that only cached (i.e., will + * not require a disk access) properties should be retrieved. + */ +int +libzfs_cmd_set_cachedprops(libzfs_handle_t *hdl, zfs_cmd_t *zc) +{ + nvlist_t *nvl; + int ret; + + if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 || + nvlist_add_boolean_value(nvl, "cachedpropsonly", B_TRUE) != 0) + return (no_memory(hdl)); + + ret = zcmd_write_src_nvlist(hdl, zc, nvl); + nvlist_free(nvl); + return (ret); +} + libzfs_handle_t * libzfs_init(void) { @@ -646,6 +685,8 @@ libzfs_init(void) zpool_feature_init(); libzfs_mnttab_init(hdl); + hdl->libzfs_cachedprops = B_FALSE; + return (hdl); } diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers index c46260717e..9ed5c461c0 100644 --- a/usr/src/lib/libzfs/common/mapfile-vers +++ b/usr/src/lib/libzfs/common/mapfile-vers @@ -21,6 +21,7 @@ # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 2011, 2014 by Delphix. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # MAPFILE HEADER START # @@ -59,6 +60,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { libzfs_init; libzfs_mnttab_cache; libzfs_print_on_error; + libzfs_set_cachedprops; spa_feature_table; zfs_allocatable_devs; zfs_asprintf; @@ -104,6 +106,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zfs_path_to_zhandle; zfs_promote; zfs_prop_align_right; + zfs_prop_cacheable; zfs_prop_column_name; zfs_prop_default_numeric; zfs_prop_default_string; |