summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2016-02-23 13:25:43 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2016-02-23 13:25:43 +0000
commitd3d31ab6f2a28d67593b8dcad42c0f03964ab6c0 (patch)
tree9f6711836b72b99b8d94d2300e585e659d35b984 /usr/src
parent3f9daf6d27ccf52cc878e4bee17bf6f657f6f50d (diff)
parente014e7f89c5273294b22953615734b04c11b1b4f (diff)
downloadillumos-joyent-d3d31ab6f2a28d67593b8dcad42c0f03964ab6c0.tar.gz
[illumos-gate merge]
commit e014e7f89c5273294b22953615734b04c11b1b4f 6641 deadman fires spuriously when running on VMware commit 8808ac5dae118369991f158b6ab736cb2691ecde 4521 zfstest is trying to execute evil "zfs unmount -a"
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/zfs/zfs_main.c11
-rw-r--r--usr/src/lib/libzfs/common/libzfs.h4
-rw-r--r--usr/src/lib/libzfs/common/libzfs_config.c35
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c11
-rw-r--r--usr/src/lib/libzfs/common/mapfile-vers8
-rw-r--r--usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh12
-rw-r--r--usr/src/uts/i86pc/os/timestamp.c49
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