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 | 15 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 8 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_util.c | 40 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/mapfile-vers | 3 |
7 files changed, 87 insertions, 4 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h index 0516845d24..5afdb2a0ba 100644 --- a/usr/src/lib/libzfs/common/libzfs.h +++ b/usr/src/lib/libzfs/common/libzfs.h @@ -65,6 +65,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 */ @@ -215,6 +216,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 49d4283d19..095a940493 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -321,6 +321,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) { @@ -2291,6 +2295,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); @@ -2602,6 +2611,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, const 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 @@ -2612,6 +2622,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 9facac8a93..bec66afc5a 100644 --- a/usr/src/lib/libzfs/common/libzfs_impl.h +++ b/usr/src/lib/libzfs/common/libzfs_impl.h @@ -22,6 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011 Pawel Jakub Dawidek. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2017 by Delphix. All rights reserved. * Copyright 2020 Joyent, Inc. */ @@ -90,6 +91,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; boolean_t libzfs_prop_debug; di_devlink_handle_t libzfs_devlink; regex_t libzfs_urire; @@ -209,6 +211,7 @@ 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 *); zfs_handle_t *make_dataset_simple_handle_zc(zfs_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, nvlist_t *, char **, uint64_t *, const char *); diff --git a/usr/src/lib/libzfs/common/libzfs_iter.c b/usr/src/lib/libzfs/common/libzfs_iter.c index b90293fedd..9e160087b3 100644 --- a/usr/src/lib/libzfs/common/libzfs_iter.c +++ b/usr/src/lib/libzfs/common/libzfs_iter.c @@ -24,6 +24,7 @@ * Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <stdio.h> @@ -112,6 +113,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); @@ -122,9 +127,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); @@ -150,10 +154,17 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func, 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); + zc.zc_simple = simple; + 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) { diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index 6e634a81cb..bb04be87e1 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -383,6 +383,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: @@ -1990,6 +1991,8 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, "corrupted, use '-m' to import the pool " "anyway:\n")); print_vdev_tree(hdl, NULL, missing, 2); + zpool_rewind_exclaim(hdl, newname ? origname : + thename, B_TRUE, nv); (void) printf("\n"); } (void) zpool_standard_error(hdl, error, desc); @@ -2023,8 +2026,9 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, ret = -1; else if (zhp != NULL) zpool_close(zhp); - if (policy.zlp_rewind & - (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) { + if ((policy.zlp_rewind & + (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) || + (flags & ZFS_IMPORT_MISSING_LOG)) { zpool_rewind_exclaim(hdl, newname ? origname : thename, ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), nv); } diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c index 8b5ea59c0e..87ccf2492e 100644 --- a/usr/src/lib/libzfs/common/libzfs_util.c +++ b/usr/src/lib/libzfs/common/libzfs_util.c @@ -87,6 +87,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")); @@ -671,6 +674,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) { @@ -716,6 +755,7 @@ libzfs_init(void) zpool_feature_init(); libzfs_mnttab_init(hdl); + hdl->libzfs_cachedprops = B_FALSE; if (getenv("ZFS_PROP_DEBUG") != NULL) { hdl->libzfs_prop_debug = B_TRUE; } diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers index 196751b44c..456249d9ad 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 (c) 2012, Joyent, Inc. All rights reserved. # Copyright (c) 2011, 2017 by Delphix. All rights reserved. # Copyright 2016 Nexenta Systems, Inc. # Copyright 2020 Joyent, Inc. @@ -69,6 +70,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { libzfs_init; libzfs_mnttab_cache; libzfs_print_on_error; + libzfs_set_cachedprops; spa_feature_table { ASSERT = { TYPE = OBJECT; @@ -131,6 +133,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; |