diff options
-rw-r--r-- | usr/src/cmd/zfs/zfs_main.c | 11 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs.h | 4 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_config.c | 35 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_dataset.c | 11 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/mapfile-vers | 8 | ||||
-rw-r--r-- | usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh | 12 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/timestamp.c | 49 |
7 files changed, 112 insertions, 18 deletions
diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c index 8f38a11ba5..91697fa896 100644 --- a/usr/src/cmd/zfs/zfs_main.c +++ b/usr/src/cmd/zfs/zfs_main.c @@ -25,9 +25,9 @@ * Copyright 2012 Milan Jurik. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>. + * Copyright 2016 Nexenta Systems, Inc. */ #include <assert.h> @@ -6456,6 +6456,15 @@ unshare_unmount(int op, int argc, char **argv) continue; } + /* + * Ignore datasets that are excluded/restricted by + * parent pool name. + */ + if (zpool_skip_pool(zfs_get_pool_name(zhp))) { + zfs_close(zhp); + continue; + } + switch (op) { case OP_SHARE: verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h index b369b18671..81e4cca5f1 100644 --- a/usr/src/lib/libzfs/common/libzfs.h +++ b/usr/src/lib/libzfs/common/libzfs.h @@ -24,8 +24,8 @@ * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Nexenta Systems, Inc. */ #ifndef _LIBZFS_H @@ -220,6 +220,7 @@ extern void zpool_free_handles(libzfs_handle_t *); */ typedef int (*zpool_iter_f)(zpool_handle_t *, void *); extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *); +extern boolean_t zpool_skip_pool(const char *); /* * Functions to create and destroy pools @@ -409,6 +410,7 @@ extern void zfs_close(zfs_handle_t *); extern zfs_type_t zfs_get_type(const zfs_handle_t *); extern const char *zfs_get_name(const zfs_handle_t *); extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *); +extern const char *zfs_get_pool_name(const zfs_handle_t *); /* * Property management functions. Some functions are shared with the kernel, diff --git a/usr/src/lib/libzfs/common/libzfs_config.c b/usr/src/lib/libzfs/common/libzfs_config.c index c3dafd6a77..fe380a24a2 100644 --- a/usr/src/lib/libzfs/common/libzfs_config.c +++ b/usr/src/lib/libzfs/common/libzfs_config.c @@ -27,6 +27,7 @@ /* * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright (c) 2015 by Syneto S.R.L. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. */ /* @@ -339,33 +340,47 @@ zpool_refresh_stats(zpool_handle_t *zhp, boolean_t *missing) } /* - * If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over - * pools it lists. + * The following environment variables are undocumented + * and should be used for testing purposes only: * - * This is an undocumented feature for use during testing only. + * __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists + * __ZFS_POOL_RESTRICT - iterate only over the pools it lists * * This function returns B_TRUE if the pool should be skipped * during iteration. */ -static boolean_t -check_restricted(const char *poolname) +boolean_t +zpool_skip_pool(const char *poolname) { static boolean_t initialized = B_FALSE; - static char *restricted = NULL; + static const char *exclude = NULL; + static const char *restricted = NULL; const char *cur, *end; - int len, namelen; + int len; + int namelen = strlen(poolname); if (!initialized) { initialized = B_TRUE; + exclude = getenv("__ZFS_POOL_EXCLUDE"); restricted = getenv("__ZFS_POOL_RESTRICT"); } + if (exclude != NULL) { + cur = exclude; + do { + end = strchr(cur, ' '); + len = (NULL == end) ? strlen(cur) : (end - cur); + if (len == namelen && 0 == strncmp(cur, poolname, len)) + return (B_TRUE); + cur += (len + 1); + } while (NULL != end); + } + if (NULL == restricted) return (B_FALSE); cur = restricted; - namelen = strlen(poolname); do { end = strchr(cur, ' '); len = (NULL == end) ? strlen(cur) : (end - cur); @@ -403,7 +418,7 @@ zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data) 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)) + if (zpool_skip_pool(cn->cn_name)) continue; if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) { @@ -441,7 +456,7 @@ zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data) 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)) + if (zpool_skip_pool(cn->cn_name)) continue; if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL) diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 034edebb24..2d443e7c71 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -26,8 +26,8 @@ * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2013 Martin Matuska. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Nexenta Systems, Inc. */ #include <ctype.h> @@ -2911,6 +2911,15 @@ zfs_get_name(const zfs_handle_t *zhp) } /* + * Returns the name of the parent pool for the given zfs handle. + */ +const char * +zfs_get_pool_name(const zfs_handle_t *zhp) +{ + return (zhp->zpool_hdl->zpool_name); +} + +/* * Returns the type of the given zfs handle. */ zfs_type_t diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers index f348bf03ab..7c6bcb0fab 100644 --- a/usr/src/lib/libzfs/common/mapfile-vers +++ b/usr/src/lib/libzfs/common/mapfile-vers @@ -18,10 +18,14 @@ # # CDDL HEADER END # + +# # 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. +# Copyright 2016 Nexenta Systems, Inc. +# + # # MAPFILE HEADER START # @@ -80,6 +84,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zfs_get_hole_count; zfs_get_name; zfs_get_pool_handle; + zfs_get_pool_name; zfs_get_user_props; zfs_get_type; zfs_handle_dup; @@ -233,6 +238,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zpool_scan; zpool_search_import; zpool_set_prop; + zpool_skip_pool; zpool_state_to_name; zpool_unmount_datasets; zpool_upgrade; diff --git a/usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh b/usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh index d86faa7afa..1695f5d10a 100644 --- a/usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh +++ b/usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh @@ -14,6 +14,7 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2016 Nexenta Systems, Inc. # export STF_SUITE="/opt/zfs-tests" @@ -115,14 +116,17 @@ else verify_disks || fail "Couldn't verify all the disks in \$DISKS" fi -# Add the rpool to $KEEP according to its contents. It's ok to list it twice. +# Add the root pool to $KEEP according to its contents. +# It's ok to list it twice. if [[ -z $KEEP ]]; then - export KEEP="^$(find_rpool)\$" + KEEP="$(find_rpool)" else - export KEEP="^$(echo $KEEP | sed 's/ /|$/')\$" - KEEP+="|^$(find_rpool)\$" + KEEP+=" $(find_rpool)" fi +export __ZFS_POOL_EXCLUDE="$KEEP" +export KEEP="^$(echo $KEEP | sed 's/ /$|^/g')\$" + [[ -z $runfile ]] && runfile=$(find_runfile) [[ -z $runfile ]] && fail "Couldn't determine distro" diff --git a/usr/src/uts/i86pc/os/timestamp.c b/usr/src/uts/i86pc/os/timestamp.c index 5b97d20e52..c40159018c 100644 --- a/usr/src/uts/i86pc/os/timestamp.c +++ b/usr/src/uts/i86pc/os/timestamp.c @@ -24,6 +24,7 @@ * Use is subject to license terms. * * Copyright 2012 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2014, 2016 by Delphix. All rights reserved. */ #include <sys/types.h> @@ -45,6 +46,7 @@ #include <sys/time.h> #include <sys/panic.h> #include <sys/cpu.h> +#include <sys/sdt.h> /* * Using the Pentium's TSC register for gethrtime() @@ -151,6 +153,14 @@ static hrtime_t tsc_last = 0; static hrtime_t tsc_last_jumped = 0; static hrtime_t tsc_hrtime_base = 0; static int tsc_jumped = 0; +static uint32_t tsc_wayback = 0; +/* + * The cap of 1 second was chosen since it is the frequency at which the + * tsc_tick() function runs which means that when gethrtime() is called it + * should never be more than 1 second since tsc_last was updated. + */ +static hrtime_t tsc_resume_cap; +static hrtime_t tsc_resume_cap_ns = NANOSEC; /* 1s */ static hrtime_t shadow_tsc_hrtime_base; static hrtime_t shadow_tsc_last; @@ -158,6 +168,17 @@ static uint_t shadow_nsec_scale; static uint32_t shadow_hres_lock; int get_tsc_ready(); +static inline +hrtime_t tsc_protect(hrtime_t a) { + if (a > tsc_resume_cap) { + atomic_inc_32(&tsc_wayback); + DTRACE_PROBE3(tsc__wayback, htrime_t, a, hrtime_t, tsc_last, + uint32_t, tsc_wayback); + return (tsc_resume_cap); + } + return (a); +} + hrtime_t tsc_gethrtime(void) { @@ -186,6 +207,20 @@ tsc_gethrtime(void) * delta to be zero. */ tsc = 0; + } else { + /* + * If we reach this else clause we assume that we have + * gone through a suspend/resume cycle and use the + * current tsc value as the delta. + * + * In rare cases we can reach this else clause due to + * a lack of monotonicity in the TSC value. In such + * cases using the current TSC value as the delta would + * cause us to return a value ~2x of what it should + * be. To protect against these cases we cap the + * suspend/resume delta at tsc_resume_cap. + */ + tsc = tsc_protect(tsc); } hrt = tsc_hrtime_base; @@ -226,6 +261,8 @@ tsc_gethrtime_delta(void) tsc -= tsc_last; } else if (tsc >= tsc_last - 2 * tsc_max_delta) { tsc = 0; + } else { + tsc = tsc_protect(tsc); } hrt = tsc_hrtime_base; @@ -285,6 +322,8 @@ dtrace_gethrtime(void) tsc -= tsc_last; else if (tsc >= tsc_last - 2*tsc_max_delta) tsc = 0; + else + tsc = tsc_protect(tsc); hrt = tsc_hrtime_base; @@ -332,6 +371,8 @@ dtrace_gethrtime(void) tsc -= shadow_tsc_last; else if (tsc >= shadow_tsc_last - 2 * tsc_max_delta) tsc = 0; + else + tsc = tsc_protect(tsc); hrt = shadow_tsc_hrtime_base; @@ -598,6 +639,7 @@ tsc_tick(void) * resume (i.e nsec_scale remains the same). */ delta = now; + delta = tsc_protect(delta); tsc_last_jumped += tsc_last; tsc_jumped = 1; } else { @@ -650,6 +692,13 @@ tsc_hrtimeinit(uint64_t cpu_freq_hz) * This structure should be aligned on a multiple of cache line size. */ tscp = kmem_zalloc(PAGESIZE, KM_SLEEP); + + /* + * Convert the TSC resume cap ns value into its unscaled TSC value. + * See tsc_gethrtime(). + */ + if (tsc_resume_cap == 0) + TSC_CONVERT(tsc_resume_cap_ns, tsc_resume_cap, nsec_unscale); } int |