aboutsummaryrefslogtreecommitdiff
path: root/cddl
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
commit69e6d7b75e96c406d072cb83ffc9b26fbf1a86fb (patch)
tree54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /cddl
parent51048477bcc79bcc8753121ec91c150648df3d1b (diff)
parent8818042ff2ecd155adb5c248a22de2dbe5d9c2a9 (diff)
downloadsrc-69e6d7b75e96c406d072cb83ffc9b26fbf1a86fb.tar.gz
src-69e6d7b75e96c406d072cb83ffc9b26fbf1a86fb.zip
sync from head
Notes
Notes: svn path=/projects/bmake/; revision=249429
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.c13
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst6
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d.out10
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d36
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d.out10
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d17
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d28
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d (renamed from cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d)77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out302
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d (renamed from cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d)59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast1.d28
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast2.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal.ksh106
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal2.ksh102
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal3.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh197
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out23
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.dyn.d28
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out12
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d14
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.dyn.d28
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d (renamed from cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toomany.d)28
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out1313
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh.out14
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh.out14
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh128
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh124
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh115
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.c223
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs.8327
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c217
-rw-r--r--cddl/contrib/opensolaris/cmd/zhack/zhack.c34
-rw-r--r--cddl/contrib/opensolaris/cmd/zinject/translate.c15
-rw-r--r--cddl/contrib/opensolaris/cmd/zinject/zinject.c32
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool-features.746
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool.87
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c176
-rw-r--r--cddl/contrib/opensolaris/cmd/ztest/ztest.c217
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c30
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c78
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c345
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c542
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c23
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c14
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c6
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h12
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h21
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c172
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c40
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c63
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c110
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c161
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.h51
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c30
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c648
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c5
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c68
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h10
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c2
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c37
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h8
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c5
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h13
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c7
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h31
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c105
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h44
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c560
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h52
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c8
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c8
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c64
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c25
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c26
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c618
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h67
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c189
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h47
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/kernel.c40
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h99
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/zfs.d36
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/input.c7
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/output.c4
-rw-r--r--cddl/lib/Makefile2
-rw-r--r--cddl/lib/libdtrace/Makefile2
-rw-r--r--cddl/lib/libzfs/Makefile7
-rw-r--r--cddl/lib/libzfs_core/Makefile37
-rw-r--r--cddl/sbin/zfs/Makefile5
-rw-r--r--cddl/sbin/zpool/Makefile4
-rw-r--r--cddl/usr.bin/zinject/Makefile4
-rw-r--r--cddl/usr.bin/ztest/Makefile5
-rw-r--r--cddl/usr.sbin/zdb/Makefile4
-rw-r--r--cddl/usr.sbin/zhack/Makefile4
129 files changed, 8346 insertions, 1577 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
index a2766593607b..a745ceb71732 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
@@ -23,8 +23,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/stat.h>
@@ -195,6 +196,13 @@ fatal(const char *fmt, ...)
verror(fmt, ap);
va_end(ap);
+ /*
+ * Close the DTrace handle to ensure that any controlled processes are
+ * correctly restored and continued.
+ */
+ if (g_dtp)
+ dtrace_close(g_dtp);
+
exit(E_ERROR);
}
@@ -1402,6 +1410,7 @@ main(int argc, char *argv[])
(void) dtrace_setopt(g_dtp, "bufsize", "4m");
(void) dtrace_setopt(g_dtp, "aggsize", "4m");
#endif
+ (void) dtrace_setopt(g_dtp, "temporal", "yes");
/*
* If -G is specified, enable -xlink=dynamic and -xunodefs to permit
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
index 261f8707c18f..19fc3aca51c2 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
@@ -23,7 +23,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
# Exception list: names tests that are bypassed when running in Java
# mode (relative to /opt/SUNWdtrt/tst)
@@ -52,14 +51,17 @@ common/usdt/tst.enabled.ksh
common/usdt/tst.enabled2.ksh
common/usdt/tst.entryreturn.ksh
common/usdt/tst.fork.ksh
-common/usdt/tst.header.ksh
common/usdt/tst.guess32.ksh
common/usdt/tst.guess64.ksh
+common/usdt/tst.header.ksh
common/usdt/tst.linkpriv.ksh
common/usdt/tst.linkunpriv.ksh
common/usdt/tst.multiple.ksh
common/usdt/tst.nodtrace.ksh
+common/usdt/tst.noreap.ksh
+common/usdt/tst.noreapring.ksh
common/usdt/tst.onlyenabled.ksh
+common/usdt/tst.reap.ksh
common/usdt/tst.reeval.ksh
common/usdt/tst.static.ksh
common/usdt/tst.static2.ksh
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl
index 7b47580ddf62..db157415b62b 100755
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl
@@ -583,6 +583,8 @@ if ($opt_x) {
die "$PNAME: failed to open $PNAME.$$.log: $!\n"
unless (!$opt_l || open(LOG, ">$PNAME.$$.log"));
+$ENV{'DTRACE_DEBUG_REGSET'} = 'true';
+
if ($opt_g) {
$ENV{'UMEM_DEBUG'} = 'default,verbose';
$ENV{'UMEM_LOGGING'} = 'fail,contents';
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d
new file mode 100644
index 000000000000..bb3ed4789bf5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+/*
+ * Make sure the sizes of compatible keys doesn't affect the sort order.
+ */
+
+BEGIN
+{
+ @[(int)1, 0] = sum(10);
+ @[(uint64_t)2, 0] = sum(20);
+ @[(int)3, 0] = sum(30);
+ @[(uint64_t)4, 0] = sum(40);
+ printa(@);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d.out
new file mode 100644
index 000000000000..83252ade53ae
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sizedkeys.d.out
@@ -0,0 +1,6 @@
+
+ 1 0 10
+ 2 0 20
+ 3 0 30
+ 4 0 40
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d.out
new file mode 100644
index 000000000000..d3b6af813101
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d.out
@@ -0,0 +1,8 @@
+The value of i is 6
+The value of i is 18
+The value of i is 72
+The value of i is 25920
+The value of i is 935761216
+The value of i is -91738734
+The value of i is -91738729
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d
new file mode 100644
index 000000000000..714fbe373b2c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Test compile-time casting between integer types of different size.
+ */
+
+#pragma D option quiet
+
+int64_t x;
+
+BEGIN
+{
+ x = (int32_t)(int16_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (int32_t)(uint16_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint32_t)(int16_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint32_t)(uint16_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ printf("\n");
+
+ x = (int16_t)(int32_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (int16_t)(uint32_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint16_t)(int32_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint16_t)(uint32_t)0xfff0;
+ printf("%16x %20d %20u\n", x, x, x);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d.out
new file mode 100644
index 000000000000..d43df27d5d5c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compcast.d.out
@@ -0,0 +1,10 @@
+fffffffffffffff0 -16 18446744073709551600
+ fff0 65520 65520
+ fffffff0 4294967280 4294967280
+ fff0 65520 65520
+
+fffffffffffffff0 -16 18446744073709551600
+fffffffffffffff0 -16 18446744073709551600
+ fff0 65520 65520
+ fff0 65520 65520
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d
new file mode 100644
index 000000000000..0589b721b421
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Test narrowing at assignment.
+ */
+
+#pragma D option quiet
+
+uint16_t x;
+uint32_t y;
+
+BEGIN
+{
+ x = 0xbeefcafe;
+ y = x;
+ printf("%x", y); /* where's the beef? */
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d.out
new file mode 100644
index 000000000000..ea17b160d298
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.compnarrowassign.d.out
@@ -0,0 +1 @@
+cafe
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d
new file mode 100644
index 000000000000..a7017bfee5e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Test execution-time casting between integer types of different size.
+ */
+
+#pragma D option quiet
+
+int64_t x;
+
+BEGIN
+{
+ z = 0xfff0;
+
+ x = (int32_t)(int16_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (int32_t)(uint16_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint32_t)(int16_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint32_t)(uint16_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ printf("\n");
+
+ x = (int16_t)(int32_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (int16_t)(uint32_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint16_t)(int32_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+ x = (uint16_t)(uint32_t)z;
+ printf("%16x %20d %20u\n", x, x, x);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d.out
new file mode 100644
index 000000000000..d43df27d5d5c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.execcast.d.out
@@ -0,0 +1,10 @@
+fffffffffffffff0 -16 18446744073709551600
+ fff0 65520 65520
+ fffffff0 4294967280 4294967280
+ fff0 65520 65520
+
+fffffffffffffff0 -16 18446744073709551600
+fffffffffffffff0 -16 18446744073709551600
+ fff0 65520 65520
+ fff0 65520 65520
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d
index 143ed641f9e7..fffc7e3d550c 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d
@@ -23,26 +23,29 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
/*
* ASSERTION:
* Positive test for fill buffer policy.
*
* SECTION: Buffers and Buffering/fill Policy;
- * Buffers and Buffering/Buffer Sizes;
+ * Buffers and Buffering/Buffer Sizes;
* Options and Tunables/bufsize;
* Options and Tunables/bufpolicy;
* Options and Tunables/statusrate
*/
/*
- * This is a brute-force way of testing fill buffers. We assume that each
- * printf() stores 8 bytes. Because each fill buffer is per-CPU, we must
- * fill up our buffer in one series of enablings on a single CPU.
+ * This is a brute-force way of testing fill buffers. We assume that
+ * each printf() stores 16 bytes (4x 32-bit words for EPID, timestamp
+ * lo, timestamp hi, and the variable i). Because each fill buffer is
+ * per-CPU, we must fill up our buffer in one series of enablings on a
+ * single CPU.
*/
#pragma D option bufpolicy=fill
-#pragma D option bufsize=64
+#pragma D option bufsize=128
#pragma D option statusrate=10ms
#pragma D option quiet
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d
index 68e35889eca0..ea746948e5ef 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d
@@ -23,8 +23,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
/*
* ASSERTION:
@@ -37,19 +38,20 @@
*/
/*
- * We make some regrettable assumptions about the implementation in this test.
- * First, we assume that each entry for the printf() of an int takes _exactly_
- * eight bytes (four bytes for the EPID, four bytes for the payload). Second,
- * we assume that by allocating storage for n + 1 records, we will get exactly
- * n. Here is why: the final predicate that evaluates to false will reserve
- * space that it won't use. This act of reservation will advance the wrapped
- * offset. That record won't be subsequently used, but the wrapped offset has
- * advanced. (And in this case, that old record is clobbered by the exit()
- * anyway.) Thirdly: we rely on t_cpu/cpu_id. Finally: we rely on being
- * able to run on the CPU that we first ran on.
+ * We make some regrettable assumptions about the implementation in this
+ * test. First, we assume that each entry for the printf() of an int
+ * takes _exactly_ 16 bytes (4 bytes for the EPID, 8 bytes for the
+ * timestamp, 4 bytes for the payload). Second, we assume that by
+ * allocating storage for n + 1 records, we will get exactly n. Here is
+ * why: the final predicate that evaluates to false will reserve space
+ * that it won't use. This act of reservation will advance the wrapped
+ * offset. That record won't be subsequently used, but the wrapped
+ * offset has advanced. (And in this case, that old record is clobbered
+ * by the exit() anyway.) Thirdly: we rely on t_cpu/cpu_id. Finally:
+ * we rely on being able to run on the CPU that we first ran on.
*/
#pragma D option bufpolicy=ring
-#pragma D option bufsize=40
+#pragma D option bufsize=80
#pragma D option quiet
int n;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d
new file mode 100644
index 000000000000..636e5686433d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Compile some code that requires exactly 9 registers. This should run out
+ * of registers.
+ *
+ * Changes to the code generator might cause this test to succeeed in which
+ * case the code should be changed to another sequence that exhausts the
+ * available internal registers.
+ *
+ * Note that this and err.baddif.d should be kept in sync.
+ */
+
+BEGIN
+{
+ a = 4;
+ trace((a + a) * ((a + a) * ((a + a) * ((a + a) * ((a + a) *
+ ((a + a) * (a + a)))))));
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d
new file mode 100644
index 000000000000..d84934823354
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Compile some code that requires exactly 9 registers. This should generate
+ * invalid DIF because the kernel will flag the fact that we're using more
+ * registers than are available internally.
+ *
+ * Changes to the code generator might cause this test to succeeed in which
+ * case the code should be changed to another sequence that exhausts the
+ * available internal registers.
+ *
+ * Note that this and err.D_NOREG.noreg.d should be kept in sync.
+ */
+
+#pragma D option iregs=9
+
+BEGIN
+{
+ a = 4;
+ trace((a + a) * ((a + a) * ((a + a) * ((a + a) * ((a + a) *
+ ((a + a) * (a + a)))))));
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d
new file mode 100644
index 000000000000..9d4e40b4dbde
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower(2152006));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d
new file mode 100644
index 000000000000..2c1389bdeb48
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(toupper(timestamp));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d
new file mode 100644
index 000000000000..7d9c27f902d9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower());
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d
new file mode 100644
index 000000000000..afaa7f976ed6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower("dory", "eel", "roughy"));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d
new file mode 100644
index 000000000000..9658f6a75441
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(toupper());
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d
new file mode 100644
index 000000000000..bee8697fb2c4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower("haino", "tylo"));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d
index 2db1b6350b94..1afe37dc689d 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d
@@ -20,38 +20,61 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * ASSERTION:
- * Complex expressions.
- * Call complex expressions and make sure test succeeds.
- * Match expected output in tst.complex.d.out
- *
- * SECTION: Types, Operators, and Expressions/Arithmetic Operators
- *
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
#pragma D option quiet
+int64_t val[int];
+
BEGIN
{
+ base = -2;
+ i = 0;
+ val[i++] = -10;
+ val[i++] = -1;
+ val[i++] = 0;
+ val[i++] = 10;
+ val[i++] = 100;
+ val[i++] = 1000;
+ val[i++] = (1LL << 62);
+ maxval = i;
+ i = 0;
+}
+
+tick-1ms
+/i < maxval/
+{
+ printf("base %2d of %20d: ", base, val[i]);
+}
+
+tick-1ms
+/i < maxval/
+{
+ printf(" %s\n", lltostr(val[i], base));
+}
+
+ERROR
+{
+ printf(" <error>\n");
+}
+
+tick-1ms
+/i < maxval/
+{
+ i++;
+}
+
+tick-1ms
+/i == maxval/
+{
i = 0;
- i = i++ + ++i;
- printf("The value of i is %d\n", i);
- i = i-- - --i;
- printf("The value of i is %d\n", i);
- i = i-- + ++i;
- printf("The value of i is %d\n", i);
- i += i++ + -- i + ++i - ++i * i ;
- printf("The value of i is %d\n", i);
- i -= i++ * 3;
- printf("The value of i is %d\n", i);
- i = i++/i--+i++-++i-++i;
- printf("The value of i is %d\n", i);
- exit (0);
+ base++;
}
+
+tick-1ms
+/base > 40/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out
new file mode 100644
index 000000000000..94e22577123a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out
@@ -0,0 +1,302 @@
+base -2 of -10: <error>
+base -2 of -1: <error>
+base -2 of 0: <error>
+base -2 of 10: <error>
+base -2 of 100: <error>
+base -2 of 1000: <error>
+base -2 of 4611686018427387904: <error>
+base -1 of -10: <error>
+base -1 of -1: <error>
+base -1 of 0: <error>
+base -1 of 10: <error>
+base -1 of 100: <error>
+base -1 of 1000: <error>
+base -1 of 4611686018427387904: <error>
+base 0 of -10: <error>
+base 0 of -1: <error>
+base 0 of 0: <error>
+base 0 of 10: <error>
+base 0 of 100: <error>
+base 0 of 1000: <error>
+base 0 of 4611686018427387904: <error>
+base 1 of -10: <error>
+base 1 of -1: <error>
+base 1 of 0: <error>
+base 1 of 10: <error>
+base 1 of 100: <error>
+base 1 of 1000: <error>
+base 1 of 4611686018427387904: <error>
+base 2 of -10: 1111111111111111111111111111111111111111111111111111111111110110
+base 2 of -1: 1111111111111111111111111111111111111111111111111111111111111111
+base 2 of 0: 0
+base 2 of 10: 1010
+base 2 of 100: 1100100
+base 2 of 1000: 1111101000
+base 2 of 4611686018427387904: 100000000000000000000000000000000000000000000000000000000000000
+base 3 of -10: 11112220022122120101211020120210210211120
+base 3 of -1: 11112220022122120101211020120210210211220
+base 3 of 0: 0
+base 3 of 10: 101
+base 3 of 100: 10201
+base 3 of 1000: 1101001
+base 3 of 4611686018427387904: 1010201120122220002201001122110012110111
+base 4 of -10: 33333333333333333333333333333312
+base 4 of -1: 33333333333333333333333333333333
+base 4 of 0: 0
+base 4 of 10: 22
+base 4 of 100: 1210
+base 4 of 1000: 33220
+base 4 of 4611686018427387904: 10000000000000000000000000000000
+base 5 of -10: 2214220303114400424121122411
+base 5 of -1: 2214220303114400424121122430
+base 5 of 0: 0
+base 5 of 10: 20
+base 5 of 100: 400
+base 5 of 1000: 13000
+base 5 of 4611686018427387904: 302141200402211214402403104
+base 6 of -10: 3520522010102100444244410
+base 6 of -1: 3520522010102100444244423
+base 6 of 0: 0
+base 6 of 10: 14
+base 6 of 100: 244
+base 6 of 1000: 4344
+base 6 of 4611686018427387904: 550120301313313111041104
+base 7 of -10: 45012021522523134134556
+base 7 of -1: 45012021522523134134601
+base 7 of 0: 0
+base 7 of 10: 13
+base 7 of 100: 202
+base 7 of 1000: 2626
+base 7 of 4611686018427387904: 11154003640456024361134
+base 8 of -10: 01777777777777777777766
+base 8 of -1: 01777777777777777777777
+base 8 of 0: 0
+base 8 of 10: 012
+base 8 of 100: 0144
+base 8 of 1000: 01750
+base 8 of 4611686018427387904: 0400000000000000000000
+base 9 of -10: 145808576354216723746
+base 9 of -1: 145808576354216723756
+base 9 of 0: 0
+base 9 of 10: 11
+base 9 of 100: 121
+base 9 of 1000: 1331
+base 9 of 4611686018427387904: 33646586081048405414
+base 10 of -10: -10
+base 10 of -1: -1
+base 10 of 0: 0
+base 10 of 10: 10
+base 10 of 100: 100
+base 10 of 1000: 1000
+base 10 of 4611686018427387904: 4611686018427387904
+base 11 of -10: 335500516a429071276
+base 11 of -1: 335500516a429071284
+base 11 of 0: 0
+base 11 of 10: a
+base 11 of 100: 91
+base 11 of 1000: 82a
+base 11 of 4611686018427387904: 9140013181078458a4
+base 12 of -10: 839365134a2a240706
+base 12 of -1: 839365134a2a240713
+base 12 of 0: 0
+base 12 of 10: a
+base 12 of 100: 84
+base 12 of 1000: 6b4
+base 12 of 4611686018427387904: 20b3a733a268670194
+base 13 of -10: 219505a9511a867b66
+base 13 of -1: 219505a9511a867b72
+base 13 of 0: 0
+base 13 of 10: a
+base 13 of 100: 79
+base 13 of 1000: 5bc
+base 13 of 4611686018427387904: 6c1349246a2881c84
+base 14 of -10: 8681049adb03db166
+base 14 of -1: 8681049adb03db171
+base 14 of 0: 0
+base 14 of 10: a
+base 14 of 100: 72
+base 14 of 1000: 516
+base 14 of 4611686018427387904: 219038263637dd3c4
+base 15 of -10: 2c1d56b648c6cd106
+base 15 of -1: 2c1d56b648c6cd110
+base 15 of 0: 0
+base 15 of 10: a
+base 15 of 100: 6a
+base 15 of 1000: 46a
+base 15 of 4611686018427387904: a7e8ce189a933404
+base 16 of -10: 0xfffffffffffffff6
+base 16 of -1: 0xffffffffffffffff
+base 16 of 0: 0x0
+base 16 of 10: 0xa
+base 16 of 100: 0x64
+base 16 of 1000: 0x3e8
+base 16 of 4611686018427387904: 0x4000000000000000
+base 17 of -10: 67979g60f5428008
+base 17 of -1: 67979g60f5428010
+base 17 of 0: 0
+base 17 of 10: a
+base 17 of 100: 5f
+base 17 of 1000: 37e
+base 17 of 4611686018427387904: 1a6a6ca03e10a88d
+base 18 of -10: 2d3fgb0b9cg4bd26
+base 18 of -1: 2d3fgb0b9cg4bd2f
+base 18 of 0: 0
+base 18 of 10: a
+base 18 of 100: 5a
+base 18 of 1000: 31a
+base 18 of 4611686018427387904: c588bdbfgd12ge4
+base 19 of -10: 141c8786h1ccaag7
+base 19 of -1: 141c8786h1ccaagg
+base 19 of 0: 0
+base 19 of 10: a
+base 19 of 100: 55
+base 19 of 1000: 2ec
+base 19 of 4611686018427387904: 5ecbb6fi9h7ggi9
+base 20 of -10: b53bjh07be4dj06
+base 20 of -1: b53bjh07be4dj0f
+base 20 of 0: 0
+base 20 of 10: a
+base 20 of 100: 50
+base 20 of 1000: 2a0
+base 20 of 4611686018427387904: 2g5hjj51hib39f4
+base 21 of -10: 5e8g4ggg7g56di6
+base 21 of -1: 5e8g4ggg7g56dif
+base 21 of 0: 0
+base 21 of 10: a
+base 21 of 100: 4g
+base 21 of 1000: 25d
+base 21 of 4611686018427387904: 18hjgjjjhebh8f4
+base 22 of -10: 2l4lf104353j8k6
+base 22 of -1: 2l4lf104353j8kf
+base 22 of 0: 0
+base 22 of 10: a
+base 22 of 100: 4c
+base 22 of 1000: 21a
+base 22 of 4611686018427387904: g6g95gc0hha7g4
+base 23 of -10: 1ddh88h2782i50j
+base 23 of -1: 1ddh88h2782i515
+base 23 of 0: 0
+base 23 of 10: a
+base 23 of 100: 48
+base 23 of 1000: 1kb
+base 23 of 4611686018427387904: 93a22467dc4chd
+base 24 of -10: l12ee5fn0ji1i6
+base 24 of -1: l12ee5fn0ji1if
+base 24 of 0: 0
+base 24 of 10: a
+base 24 of 100: 44
+base 24 of 1000: 1hg
+base 24 of 4611686018427387904: 566ffd9ni4mcag
+base 25 of -10: c9c336o0mlb7e6
+base 25 of -1: c9c336o0mlb7ef
+base 25 of 0: 0
+base 25 of 10: a
+base 25 of 100: 40
+base 25 of 1000: 1f0
+base 25 of 4611686018427387904: 32970kc6bo2kg4
+base 26 of -10: 7b7n2pcniokcg6
+base 26 of -1: 7b7n2pcniokcgf
+base 26 of 0: 0
+base 26 of 10: a
+base 26 of 100: 3m
+base 26 of 1000: 1cc
+base 26 of 4611686018427387904: 1m8c769io65344
+base 27 of -10: 4eo8hfam6fllmf
+base 27 of -1: 4eo8hfam6fllmo
+base 27 of 0: 0
+base 27 of 10: a
+base 27 of 100: 3j
+base 27 of 1000: 1a1
+base 27 of 4611686018427387904: 13jfho2j1hc5cd
+base 28 of -10: 2nc6j26l66rho6
+base 28 of -1: 2nc6j26l66rhof
+base 28 of 0: 0
+base 28 of 10: a
+base 28 of 100: 3g
+base 28 of 1000: 17k
+base 28 of 4611686018427387904: jo1ilfj8fkpd4
+base 29 of -10: 1n3rsh11f098re
+base 29 of -1: 1n3rsh11f098rn
+base 29 of 0: 0
+base 29 of 10: a
+base 29 of 100: 3d
+base 29 of 1000: 15e
+base 29 of 4611686018427387904: d0slim0b029e6
+base 30 of -10: 14l9lkmo30o406
+base 30 of -1: 14l9lkmo30o40f
+base 30 of 0: 0
+base 30 of 10: a
+base 30 of 100: 3a
+base 30 of 1000: 13a
+base 30 of 4611686018427387904: 8k9rrkl0ml104
+base 31 of -10: nd075ib45k866
+base 31 of -1: nd075ib45k86f
+base 31 of 0: 0
+base 31 of 10: a
+base 31 of 100: 37
+base 31 of 1000: 118
+base 31 of 4611686018427387904: 5qfh94i8okhh4
+base 32 of -10: fvvvvvvvvvvvm
+base 32 of -1: fvvvvvvvvvvvv
+base 32 of 0: 0
+base 32 of 10: a
+base 32 of 100: 34
+base 32 of 1000: v8
+base 32 of 4611686018427387904: 4000000000000
+base 33 of -10: b1w8p7j5q9r66
+base 33 of -1: b1w8p7j5q9r6f
+base 33 of 0: 0
+base 33 of 10: a
+base 33 of 100: 31
+base 33 of 1000: ua
+base 33 of 4611686018427387904: 2p826a4q6ivi4
+base 34 of -10: 7orp63sh4dph8
+base 34 of -1: 7orp63sh4dphh
+base 34 of 0: 0
+base 34 of 10: a
+base 34 of 100: 2w
+base 34 of 1000: te
+base 34 of 4611686018427387904: 1vnvr0wl9ketu
+base 35 of -10: 5g24a25twkwf6
+base 35 of -1: 5g24a25twkwff
+base 35 of 0: 0
+base 35 of 10: a
+base 35 of 100: 2u
+base 35 of 1000: sk
+base 35 of 4611686018427387904: 1cqrb9a7gvgu4
+base 36 of -10: 3w5e11264sgs6
+base 36 of -1: 3w5e11264sgsf
+base 36 of 0: 0
+base 36 of 10: a
+base 36 of 100: 2s
+base 36 of 1000: rs
+base 36 of 4611686018427387904: z1ci99jj7474
+base 37 of -10: <error>
+base 37 of -1: <error>
+base 37 of 0: <error>
+base 37 of 10: <error>
+base 37 of 100: <error>
+base 37 of 1000: <error>
+base 37 of 4611686018427387904: <error>
+base 38 of -10: <error>
+base 38 of -1: <error>
+base 38 of 0: <error>
+base 38 of 10: <error>
+base 38 of 100: <error>
+base 38 of 1000: <error>
+base 38 of 4611686018427387904: <error>
+base 39 of -10: <error>
+base 39 of -1: <error>
+base 39 of 0: <error>
+base 39 of 10: <error>
+base 39 of 100: <error>
+base 39 of 1000: <error>
+base 39 of 4611686018427387904: <error>
+base 40 of -10: <error>
+base 40 of -1: <error>
+base 40 of 0: <error>
+base 40 of 10: <error>
+base 40 of 100: <error>
+base 40 of 1000: <error>
+base 40 of 4611686018427387904: <error>
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d
index c664188f13a3..2539630e9d66 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d
@@ -20,42 +20,47 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma D option quiet
-/*
- * ASSERTION:
- * The D inline translation mechanism can be used to facilitate stable
- * translations.
- *
- * SECTION: Translators/ Translator Declarations
- * SECTION: Translators/ Translate Operator
- * SECTION: Translators/Stable Translations
- *
- * NOTES: Uncomment the pragma that explicitly resets the attributes of
- * myinfo identifier to Stable/Stable/Common from Private/Private/Unknown.
- * Run the program with and without the comments as:
- * /usr/sbin/dtrace -vs man.TestTransStability.d
- */
+BEGIN
+{
+ i = 0;
-#pragma D option quiet
+ input[i] = "ahi";
+ expected[i++] = "ahi";
-inline lwpsinfo_t *myinfo = xlate < lwpsinfo_t *> (curthread);
+ input[i] = "MaHi!";
+ expected[i++] = "mahi!";
-/*
-#pragma D attributes Stable/Stable/Common myinfo
-*/
+ input[i] = " Nase-5";
+ expected[i++] = " nase-5";
-BEGIN
-{
- trace(myinfo->pr_flag);
- exit(0);
+ input[i] = "!@#$%";
+ expected[i++] = "!@#$%";
+
+ i = 0;
}
-ERROR
+tick-1ms
+/input[i] != NULL && (this->out = tolower(input[i])) != expected[i]/
{
+ printf("expected tolower(\"%s\") to be \"%s\"; found \"%s\"\n",
+ input[i], expected[i], this->out);
exit(1);
}
+
+tick-1ms
+/input[i] != NULL/
+{
+ printf("tolower(\"%s\") is \"%s\", as expected\n",
+ input[i], expected[i]);
+}
+
+tick-1ms
+/input[i++] == NULL/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d
new file mode 100644
index 000000000000..fd803f2ef0af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+
+ input[i] = "ahi";
+ expected[i++] = "AHI";
+
+ input[i] = "MaHi!";
+ expected[i++] = "MAHI!";
+
+ input[i] = " dace-9";
+ expected[i++] = " DACE-9";
+
+ input[i] = "!@#$%";
+ expected[i++] = "!@#$%";
+
+ i = 0;
+}
+
+tick-1ms
+/input[i] != NULL && (this->out = toupper(input[i])) != expected[i]/
+{
+ printf("expected toupper(\"%s\") to be \"%s\"; found \"%s\"\n",
+ input[i], expected[i], this->out);
+ exit(1);
+}
+
+tick-1ms
+/input[i] != NULL/
+{
+ printf("toupper(\"%s\") is \"%s\", as expected\n",
+ input[i], expected[i]);
+}
+
+tick-1ms
+/input[i++] == NULL/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh
index 35f0391ba87d..25ae061ec074 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh
@@ -24,7 +24,9 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
#
if [ $# != 1 ]; then
@@ -49,13 +51,13 @@ tick-1s
tick-1s
/(i % 2) == 0/
{
- system("dtrace -c date -ln 'pid\$target::main:entry' >/dev/null");
+ system("dtrace -c date -n 'pid\$target::main:entry' >/dev/null");
}
tick-1s
/(i % 2) == 1/
{
- system("dtrace -c date -ln 'pid\$target::main:return' >/dev/null");
+ system("dtrace -c date -n 'pid\$target::main:return' >/dev/null");
}
EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d
index 64b77289481f..c4d35e9e3f56 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
/*
* ASSERTION:
@@ -32,44 +34,51 @@
* a runtime error.
*
* SECTION: Pointers and Arrays/Generic Pointers
- *
- * NOTES:
- * This test doesn't apply to x86; for the time being, we're working
- * around this with the preprocessor.
*/
#pragma D option quiet
-int array[3];
-uintptr_t uptr;
+#if defined(__i386) || defined(__amd64)
+#define __x86 1
+#endif
+
+int array[2];
+char *ptr;
int *p;
int *q;
int *r;
BEGIN
{
-#ifdef __i386
- exit(1);
-#else
- array[0] = 20;
- array[1] = 40;
- array[2] = 80;
+ array[0] = 0x12345678;
+ array[1] = 0xabcdefff;
- uptr = (uintptr_t) &array[0];
+ ptr = (char *) &array[0];
- p = (int *) (uptr);
- q = (int *) (uptr + 2);
- r = (int *) (uptr + 3);
+ p = (int *) (ptr);
+ q = (int *) (ptr + 2);
+ r = (int *) (ptr + 3);
- printf("array[0]: %d\t*p: %d\n", array[0], *p);
- printf("array[1]: %d\t*q: %d\n", array[1], *q);
- printf("array[2]: %d\t*r: %d\n", array[2], *r);
+ printf("*p: 0x%x\n", *p);
+ printf("*q: 0x%x\n", *q);
+ printf("*r: 0x%x\n", *r);
+ /*
+ * On x86, the above unaligned memory accesses are allowed and should
+ * not result in the ERROR probe firing.
+ */
+#ifdef __x86
+ exit(1);
+#else
exit(0);
#endif
}
ERROR
{
+#ifdef __x86
+ exit(0);
+#else
exit(1);
+#endif
}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast1.d
new file mode 100644
index 000000000000..0567123f3a8b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast1.d
@@ -0,0 +1,28 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ *((int *)alloca(4)) = 1;
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast2.d
new file mode 100644
index 000000000000..6282e7ae15a3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast2.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ this->a = alloca(4);
+ *((int *)this->a) = 1;
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal.ksh
new file mode 100644
index 000000000000..9a0aed0678cf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal.ksh
@@ -0,0 +1,106 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+############################################################################
+# ASSERTION:
+# temporal option causes output to be sorted
+#
+# SECTION: Pragma
+#
+# NOTES: The temporal option has no effect on a single-CPU system, so
+# this needs to be run on a multi-CPU system to effectively test the
+# temporal option.
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+file=/tmp/out.$$
+
+rm -f $file
+
+$dtrace -o $file -c 'sleep 3' -s /dev/stdin <<EOF
+ #pragma D option quiet
+ #pragma D option temporal
+
+ BEGIN
+ {
+ @lines = count();
+ printf("0 begin\n");
+ }
+
+ END
+ {
+ /* Bump @lines every time we print a line. */
+ @lines = count();
+ printf("%u end\n", timestamp);
+ @lines = count();
+ printa("99999999999999999 lines %@u\n", @lines);
+ }
+
+ profile-97hz
+ {
+ @lines = count();
+ printf("%u\n", timestamp);
+ }
+EOF
+
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+# dtrace outputs a blank line at the end, which will sort to the beginning,
+# so use head to remove the blank line.
+head -n -1 $file > $file.2
+
+sort -n $file.2 | diff $file.2 -
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: output is not sorted
+ exit $status
+fi
+
+head -n 1 $file.2 | grep begin >/dev/null
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: begin probe did not fire
+ exit $status
+fi
+
+tail -n 2 $file.2 | grep end >/dev/null
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: end probe did not fire
+ exit $status
+fi
+
+if [ $(tail -n 1 $file.2 | cut -f3 -d ' ') -ne \
+ $(wc -l $file.2) ]; then
+ echo $tst: incorrect number of lines output
+ exit 1
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal2.ksh
new file mode 100644
index 000000000000..4e8d592d81d6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal2.ksh
@@ -0,0 +1,102 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+############################################################################
+# ASSERTION:
+# temporal option causes output to be sorted, even when some
+# buffers are empty
+#
+# SECTION: Pragma
+#
+# NOTES: The temporal option has no effect on a single-CPU system, so
+# this needs to be run on a multi-CPU system to effectively test the
+# temporal option.
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+file=/tmp/out.$$
+
+rm -f $file
+
+$dtrace -o $file -s /dev/stdin <<EOF
+ #pragma D option quiet
+ #pragma D option destructive
+ #pragma D option temporal
+ #pragma D option switchrate=1000hz
+
+ /*
+ * Use two enablings of the same probe, so that cpu 0 will always
+ * record its data just a little bit before the other cpus.
+ * We don't want to use the chill() action in the same enabling
+ * that we record the timestamp, because chill() causes the
+ * timestamp to be re-read, and thus not match the timestamp
+ * which libdtrace uses to sort the records.
+ */
+
+ profile-401
+ /cpu == 0/
+ {
+ printf("%d\n", timestamp);
+ }
+
+ profile-401
+ /cpu != 0/
+ {
+ chill(1000); /* one microsecond */
+ }
+
+ profile-401
+ /cpu != 0/
+ {
+ printf("%d\n", timestamp);
+ }
+
+ tick-1s
+ /k++ == 10/
+ {
+ printf("%d\n", timestamp);
+ exit(0);
+ }
+EOF
+
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+# dtrace outputs a blank line at the end, which will sort to the beginning,
+# so use grep to remove the blank line.
+head -n -1 $file > $file.2
+
+sort -n $file.2 | diff $file.2 -
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: output is not sorted
+ exit $status
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal3.d
new file mode 100644
index 000000000000..b4c0e557bea1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal3.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * This test excercises the "remnant" handling of the temporal option.
+ * At the end of one pass of retrieving and printing data from all CPUs,
+ * some unprocessed data will remain, because its timestamp is after the
+ * time covered by all CPUs' buffers. This unprocessed data is
+ * rearranged in a more space-efficient manner. If this is done
+ * incorrectly, an alignment error may occur. To test this, we use a
+ * high-frequency probe so that data will be recorded in subsequent
+ * CPU's buffers after the first CPU's buffer is obtained. The
+ * combination of data traced here (a 8-byte value and a 4-byte value)
+ * is effective to cause alignment problems with an incorrect
+ * implementation.
+ *
+ * This test needs to be run on a multi-CPU system to be effective.
+ */
+
+#pragma D option quiet
+#pragma D option temporal
+
+profile-4997
+{
+ printf("%u %u", 1ULL, 2);
+}
+
+tick-1
+/i++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh
deleted file mode 100644
index f06edcb5a4ec..000000000000
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh
+++ /dev/null
@@ -1,197 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-unload()
-{
- #
- # Get the list of services whose processes have USDT probes. Ideally
- # it would be possible to unload the fasttrap provider while USDT
- # probes exist -- once that fix is integrated, this hack can go away
- # We create two lists -- one of regular SMF services and one of legacy
- # services -- since each must be enabled and disabled using a specific
- # mechanism.
- #
- pids=$(dtrace -l | \
- perl -ne 'print "$1\n" if (/^\s*\S+\s+\S*\D(\d+)\s+/);' | \
- sort | uniq | tr '\n' ',')
-
- ctids=$(ps -p $pids -o ctid | tail +2 | sort | uniq)
- svcs=
- lrcs=
-
- for ct in $ctids
- do
- line=$(svcs -o fmri,ctid | grep " $ct\$")
- svc=$(echo $line | cut -d' ' -f1)
-
- if [[ $(svcs -Ho STA $svc) == "LRC" ]]; then
- lrc=$(svcs -Ho SVC $svc | tr _ '?')
- lrcs="$lrcs $lrc"
- else
- svcs="$svcs $svc"
- fi
- done
-
- for svc in $svcs
- do
- svcadm disable -ts $svc
- done
-
- for lrc in $lrcs
- do
- #
- # Does it seem a little paternalistic that lsvcrun requires
- # this environment variable to be set? I'd say so...
- #
- SMF_RESTARTER=svc:/system/svc/restarter:default \
- /lib/svc/bin/lsvcrun $lrc stop
- done
-
- modunload -i 0
- modunload -i 0
- modunload -i 0
- modinfo | grep dtrace
- success=$?
-
- for svc in $svcs
- do
- svcadm enable -ts $svc
- done
-
- for lrc in $lrcs
- do
- SMF_RESTARTER=svc:/system/svc/restarter:default \
- /lib/svc/bin/lsvcrun $lrc start
- done
-
- if [ ! $success ]; then
- echo $tst: could not unload dtrace
- exit 1
- fi
-}
-
-script1()
-{
- $dtrace -s /dev/stdin <<EOF
- syscall:::entry
- /pid != $ppid/
- {
- @a[probefunc] = count();
- }
-
- tick-1sec
- /i++ == 5/
- {
- exit(0);
- }
-EOF
-}
-
-script2()
-{
- $dtrace -s /dev/stdin <<EOF
-
- #pragma D option statusrate=1ms
-
- syscall:::entry
- /pid == $ppid/
- {
- ttl++;
- }
-
- tick-1sec
- /i++ == 5/
- {
- exit(2);
- }
-
- END
- /ttl/
- {
- printf("success; ttl is %d", ttl);
- exit(0);
- }
-
- END
- /ttl == 0/
- {
- printf("error -- total should be non-zero");
- exit(1);
- }
-EOF
-}
-
-if [ $# != 1 ]; then
- echo expected one argument: '<'dtrace-path'>'
- exit 2
-fi
-
-ppid=$$
-dtrace=$1
-
-unload
-script1 &
-child=$!
-
-let waited=0
-
-while [ "$waited" -lt 5 ]; do
- seconds=`date +%S`
-
- if [ "$seconds" -ne "$last" ]; then
- last=$seconds
- let waited=waited+1
- fi
-done
-
-wait $child
-status=$?
-
-if [ "$status" -ne 0 ]; then
- echo $tst: first dtrace failed
- exit $status
-fi
-
-unload
-script2 &
-child=$!
-
-let waited=0
-
-while [ "$waited" -lt 10 ]; do
- seconds=`date +%S`
-
- if [ "$seconds" -ne "$last" ]; then
- last=$seconds
- let waited=waited+1
- fi
-done
-
-wait $child
-status=$?
-
-exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d
new file mode 100644
index 000000000000..902f07272dd0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ print((void)`p0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d
new file mode 100644
index 000000000000..a1d3be1f62d3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ print();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d
new file mode 100644
index 000000000000..9650bf7c0f5e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct bar {
+ int alpha;
+} bar_t;
+
+typedef struct foo {
+ int a[3];
+ char b[30];
+ bar_t c[2];
+ char d[3];
+} foo_t;
+
+BEGIN
+{
+ this->f = (foo_t *)alloca(sizeof (foo_t));
+
+ this->f->a[0] = 1;
+ this->f->a[1] = 2;
+ this->f->a[2] = 3;
+ this->f->b[0] = 'a';
+ this->f->b[1] = 'b';
+ this->f->b[2] = 0;
+ this->f->c[0].alpha = 5;
+ this->f->c[1].alpha = 6;
+ this->f->c[2].alpha = 7;
+ this->f->d[0] = 4;
+ this->f->d[1] = 0;
+ this->f->d[2] = 0;
+
+ print(this->f->a);
+ print(this->f->b);
+ print(this->f->c);
+ print(*this->f);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out
new file mode 100644
index 000000000000..0702d4bb5a80
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out
@@ -0,0 +1,23 @@
+int [3] [ 0x1, 0x2, 0x3 ]
+char [30] "ab"
+bar_t [2] [
+ bar_t {
+ int alpha = 0x5
+ },
+ bar_t {
+ int alpha = 0x6
+ }
+]
+foo_t {
+ int [3] a = [ 0x1, 0x2, 0x3 ]
+ char [30] b = [ "ab" ]
+ bar_t [2] c = [
+ bar_t {
+ int alpha = 0x5
+ },
+ bar_t {
+ int alpha = 0x6
+ }
+ ]
+ char [3] d = [ '\004', '\0', '\0' ]
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d
new file mode 100644
index 000000000000..ff77bb0ec74d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct forward forward_t;
+
+typedef struct foo {
+ int a:4;
+ int b:7;
+ int c:1;
+ int d:2;
+} foo_t;
+
+BEGIN
+{
+ this->s = (foo_t *)alloca(sizeof (foo_t));
+
+ this->s->a = 1;
+ this->s->b = 5;
+ this->s->c = 0;
+ this->s->d = 2;
+
+ print(*this->s);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out
new file mode 100644
index 000000000000..309444d5c8d4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out
@@ -0,0 +1,6 @@
+foo_t {
+ int a :4 = 0x1
+ int b :7 = 0x5
+ int c :1 = 0
+ int d :2 = 0x2
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.dyn.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.dyn.d
new file mode 100644
index 000000000000..f17551facb4e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.dyn.d
@@ -0,0 +1,28 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ print(*curpsinfo);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d
new file mode 100644
index 000000000000..559dab1840c7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = (int)'a';
+
+ printf("\n");
+
+ print((char)'a');
+ print((int)-1);
+ print((unsigned int)23);
+ print((short)456);
+ print((unsigned short)789);
+ print((long)1234);
+ print((ulong_t)56789);
+ print((void *)0x1234);
+ print("hello");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out
new file mode 100644
index 000000000000..f7e4076726ae
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out
@@ -0,0 +1,11 @@
+
+char 'a'
+int 0xffffffff
+unsigned int 0x17
+short 0x1c8
+unsigned short 0x315
+long 0x4d2
+ulong_t 0xddd5
+void * 0x1234
+string "hello"
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d
new file mode 100644
index 000000000000..2fb1c41401e5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct forward forward_t;
+
+typedef struct foo {
+ int a;
+ void *b;
+ struct {
+ uint64_t alpha;
+ uint64_t beta;
+ } c;
+ ushort_t d;
+ int e;
+ forward_t *f;
+ void (*g)();
+} foo_t;
+
+BEGIN
+{
+ this->s = (foo_t *)alloca(sizeof (foo_t));
+
+ this->s->a = 1;
+ this->s->b = (void *)2;
+ this->s->c.alpha = 3;
+ this->s->c.beta = 4;
+ this->s->d = 5;
+ this->s->e = 6;
+ this->s->f = (void *)7;
+ this->s->g = (void *)8;
+
+ print(*this->s);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out
new file mode 100644
index 000000000000..b7b210837552
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out
@@ -0,0 +1,12 @@
+foo_t {
+ int a = 0x1
+ void *b = 0x2
+ struct c = {
+ uint64_t alpha = 0x3
+ uint64_t beta = 0x4
+ }
+ ushort_t d = 0x5
+ int e = 0x6
+ forward_t *f = 0x7
+ int (*)() g = 0x8
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d
new file mode 100644
index 000000000000..e8125d4f5cba
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct pancakes {
+ int i;
+ string s;
+ timespec_t t;
+} pancakes_t;
+
+translator pancakes_t < void *V > {
+ i = 2 * 10;
+ s = strjoin("I like ", "pancakes");
+ t = *(timespec_t *)`dtrace_zero;
+};
+
+BEGIN
+{
+ print(*(xlate < pancakes_t * > ((void *)NULL)));
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d.out
new file mode 100644
index 000000000000..9b01402af34b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.xlate.d.out
@@ -0,0 +1,8 @@
+pancakes_t {
+ int i = 0x14
+ string s = [ "I like pancakes" ]
+ timespec_t t = {
+ time_t tv_sec = 0
+ long tv_nsec = 0
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out
index 4d2bb11207e1..bc7eaed0ec9a 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out
@@ -1,6 +1,6 @@
-239
-52719
+-17
+-12817
-1867788817
1311768467294899695
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d
new file mode 100644
index 000000000000..64e565e267b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Check %d v. %i v. %u.
+ */
+
+#pragma D option quiet
+
+uint16_t x;
+int16_t y;
+
+BEGIN
+{
+ x = 0xffffffff;
+ y = 0xffffffff;
+
+ printf("%d %i %u\n", x, x, x);
+ printf("%d %i %u\n", y, y, y);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d.out
new file mode 100644
index 000000000000..169ac59b9554
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.signs.d.out
@@ -0,0 +1,3 @@
+65535 -1 65535
+-1 -1 65535
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d
index e97506e1108f..c59ea3bee57d 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d
@@ -24,7 +24,10 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
/*
* ASSERTION:
@@ -35,17 +38,10 @@
*
* NOTES: This test behaves differently depending on the values
* assigned to bufsize.
- * 1. 0 > bufsize.
- * 2. 0 == bufsize.
- * 3. 0 < bufsize <= 7
- * 4. 8 <= bufsize <= 31
- * 5. 32 <= bufsize <= 47
- * 6. 48 <= bufsize <= 71
- * 7. 72 <= bufsize
*/
#pragma D option quiet
-#pragma D option bufsize=41
+#pragma D option bufsize=49
BEGIN
{
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d
index 6b91efd9114b..99539f903eb6 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d
@@ -24,7 +24,10 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
/*
* ASSERTION:
* Verify the behavior of speculations with changes in specsize.
@@ -35,7 +38,7 @@
*/
#pragma D option quiet
-#pragma D option specsize=40
+#pragma D option specsize=48
BEGIN
{
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.dyn.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.dyn.d
new file mode 100644
index 000000000000..24ad80fb469c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.dyn.d
@@ -0,0 +1,28 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(*curpsinfo);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d
new file mode 100644
index 000000000000..1eb96be529cc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ tracemem(`dtrace_zero, 256, 0, "fishpong");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d
new file mode 100644
index 000000000000..554bb7dfb4df
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ tracemem(`dtrace_zero, 256, "fishpong");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d
index dfe8e4d229fc..de530e811cb1 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toomany.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d
@@ -20,20 +20,26 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * ASSERTION:
- * Test tracemem() with too many arguments.
- *
- * SECTION: Actions and Subroutines/tracemem()
- */
+#pragma D option quiet
BEGIN
{
- tracemem(123, 456, 789);
+ i = -10;
+}
+
+tick-10ms
+/i++ < 150/
+{
+ printf("%d:", i);
+ tracemem(`dtrace_zero, 128, i);
+ printf("\n");
+}
+
+tick-10ms
+/i >= 150/
+{
+ exit(0);
}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out
new file mode 100644
index 000000000000..6415893b8db1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out
@@ -0,0 +1,1313 @@
+-9:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-8:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-7:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-6:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-5:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-4:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-3:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-2:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-1:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+0:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+1:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 .
+
+2:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 ..
+
+3:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 ...
+
+4:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 ....
+
+5:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 .....
+
+6:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 ......
+
+7:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 .......
+
+8:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 ........
+
+9:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 .........
+
+10:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 ..........
+
+11:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+12:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+13:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+14:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+15:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+16:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+17:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 .
+
+18:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 ..
+
+19:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 ...
+
+20:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 ....
+
+21:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 .....
+
+22:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 ......
+
+23:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 .......
+
+24:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 ........
+
+25:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 .........
+
+26:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 ..........
+
+27:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+28:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+29:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+30:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+31:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+32:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+33:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 .
+
+34:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 ..
+
+35:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 ...
+
+36:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 ....
+
+37:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 .....
+
+38:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 ......
+
+39:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 .......
+
+40:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 ........
+
+41:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 .........
+
+42:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 ..........
+
+43:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+44:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+45:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+46:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+47:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+48:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+49:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 .
+
+50:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 ..
+
+51:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 ...
+
+52:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 ....
+
+53:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 .....
+
+54:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 ......
+
+55:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 .......
+
+56:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 ........
+
+57:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 .........
+
+58:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 ..........
+
+59:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+60:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+61:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+62:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+63:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+64:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+65:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 .
+
+66:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 ..
+
+67:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 ...
+
+68:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 ....
+
+69:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 .....
+
+70:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 ......
+
+71:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 .......
+
+72:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 ........
+
+73:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 .........
+
+74:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 ..........
+
+75:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+76:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+77:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+78:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+79:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+80:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+81:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 .
+
+82:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 ..
+
+83:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 ...
+
+84:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 ....
+
+85:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 .....
+
+86:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 ......
+
+87:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 .......
+
+88:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 ........
+
+89:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 .........
+
+90:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 ..........
+
+91:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+92:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+93:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+94:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+95:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+96:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+97:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 .
+
+98:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 ..
+
+99:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 ...
+
+100:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 ....
+
+101:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 .....
+
+102:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 ......
+
+103:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 .......
+
+104:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 ........
+
+105:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 .........
+
+106:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 ..........
+
+107:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+108:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+109:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+110:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+111:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+112:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+113:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 .
+
+114:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 ..
+
+115:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 ...
+
+116:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 ....
+
+117:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 .....
+
+118:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 ......
+
+119:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 .......
+
+120:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 ........
+
+121:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 .........
+
+122:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 ..........
+
+123:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+124:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+125:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+126:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+127:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+128:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+129:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+130:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+131:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+132:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+133:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+134:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+135:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+136:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+137:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+138:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+139:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+140:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+141:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+142:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+143:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+144:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+145:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+146:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+147:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+148:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+149:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+150:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh
new file mode 100644
index 000000000000..16eeda32916b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+#
+# Test the output for stable translations.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -v -s /dev/stdin <<EOF
+
+#pragma D option quiet
+
+inline lwpsinfo_t *myinfo = xlate < lwpsinfo_t *> (curthread);
+
+#pragma D attributes Stable/Stable/Common myinfo
+
+BEGIN
+{
+ this->a = myinfo->pr_flag;
+ exit(0);
+}
+
+BEGIN
+{
+ exit(1);
+}
+EOF
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh.out
new file mode 100644
index 000000000000..43c1adb1a54f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability1.ksh.out
@@ -0,0 +1,14 @@
+
+Stability attributes for script /dev/stdin:
+
+ Minimum Probe Description Attributes
+ Identifier Names: Unstable
+ Data Semantics: Unstable
+ Dependency Class: Common
+
+ Minimum Statement Attributes
+ Identifier Names: Stable
+ Data Semantics: Stable
+ Dependency Class: Common
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh
new file mode 100644
index 000000000000..82070cde9237
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+#
+# Test the output of unstable translations.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -v -s /dev/stdin <<EOF
+
+#pragma D option quiet
+
+inline lwpsinfo_t *myinfo = xlate < lwpsinfo_t *> (curthread);
+
+BEGIN
+{
+ this->a = myinfo->pr_flag;
+ exit(0);
+}
+
+BEGIN
+{
+ exit(1);
+}
+EOF
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh.out
new file mode 100644
index 000000000000..f4b70f9573db
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TestTransStability2.ksh.out
@@ -0,0 +1,14 @@
+
+Stability attributes for script /dev/stdin:
+
+ Minimum Probe Description Attributes
+ Identifier Names: Unstable
+ Data Semantics: Unstable
+ Dependency Class: Common
+
+ Minimum Statement Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh
new file mode 100644
index 000000000000..338dcdf03e6f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh
@@ -0,0 +1,128 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, probe1);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe probe1();
+};
+EOF
+
+gcc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+gcc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -Zwqs /dev/stdin <<EOF
+
+ BEGIN
+ {
+ spec = speculation();
+ speculate(spec);
+ printf("this is speculative!\n");
+ }
+
+ test_prov*:::
+ {
+ probeid = id;
+ }
+
+ tick-1sec
+ /probeid == 0/
+ {
+ printf("launching test\n");
+ system("./test");
+ }
+
+ tick-1sec
+ /probeid != 0/
+ {
+ printf("attempting re-enabling\n");
+ system("dtrace -e -x errtags -i %d", probeid);
+ attempts++;
+ }
+
+ tick-1sec
+ /attempts > 10/
+ {
+ exit(0);
+ }
+EOF
+}
+
+script 2>&1 | tee test.out
+
+#
+# It should be true that our probe was not reaped after the provider was made
+# defunct: the speculative tracing action prevents reaping of any ECB in the
+# enabling.
+#
+status=0
+
+if grep D_PDESC_INVAL test.out 2> /dev/null 1>&2 ; then
+ status=1
+else
+ grep D_PROC_GRAB test.out 2> /dev/null 1>&2
+ status=$?
+fi
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh
new file mode 100644
index 000000000000..a2e5edee3814
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh
@@ -0,0 +1,124 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, probe1);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe probe1();
+};
+EOF
+
+gcc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+gcc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -Zwqs /dev/stdin <<EOF
+ test_prov*:::
+ {
+ probeid = id;
+ }
+
+ tick-1sec
+ /probeid == 0/
+ {
+ printf("launching test\n");
+ system("./test");
+ }
+
+ tick-1sec
+ /probeid != 0/
+ {
+ printf("attempting re-enabling\n");
+ system("dtrace -e -x errtags -i %d", probeid);
+ attempts++;
+ }
+
+ tick-1sec
+ /attempts > 10/
+ {
+ exit(0);
+ }
+EOF
+}
+
+$dtrace -x bufpolicy=ring -ZwqP test_prov\* > /dev/null 2>&1 &
+background=$!
+echo launched ring buffered enabling as pid $background
+script 2>&1 | tee test.out
+
+#
+# It should be true that our probe was not reaped after the provider was made
+# defunct: the active ring buffer in the earlier enabling prevents reaping of
+# any of the earlier enabling's ECBs.
+#
+status=0
+
+if grep D_PDESC_INVAL test.out 2> /dev/null 1>&2 ; then
+ status=1
+else
+ grep D_PROC_GRAB test.out 2> /dev/null 1>&2
+ status=$?
+fi
+
+kill $background
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh
new file mode 100644
index 000000000000..f18c585ef6c8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh
@@ -0,0 +1,115 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, probe1);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe probe1();
+};
+EOF
+
+gcc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+gcc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -Zwqs /dev/stdin <<EOF
+ test_prov*:::
+ {
+ probeid = id;
+ }
+
+ tick-1sec
+ /probeid == 0/
+ {
+ printf("launching test\n");
+ system("./test");
+ }
+
+ tick-1sec
+ /probeid != 0/
+ {
+ printf("attempting re-enabling\n");
+ system("dtrace -e -x errtags -i %d", probeid);
+ attempts++;
+ }
+
+ tick-1sec
+ /attempts > 10/
+ {
+ exit(0);
+ }
+EOF
+}
+
+script 2>&1 | tee test.out
+
+#
+# It should be true that our probe was reaped over the course of the enabling,
+# causing the embedded DTrace invocation to fail on an invalid probe (that is,
+# D_PDESC_INVAL) instead of an inability to grab the underlying process
+# (D_PROC_GRAB).
+#
+grep D_PDESC_INVAL test.out 2> /dev/null 1>&2
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
index 82941af4e93a..c265c99b4bee 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
@@ -21,10 +21,11 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <stdio.h>
+#include <unistd.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <ctype.h>
@@ -57,6 +58,7 @@
#include <sys/arc.h>
#include <sys/ddt.h>
#include <sys/zfeature.h>
+#include <zfs_comutil.h>
#undef ZFS_MAXNAMELEN
#undef verify
#include <libzfs.h>
@@ -206,6 +208,27 @@ dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
nvlist_free(nv);
}
+/* ARGSUSED */
+static void
+dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ spa_history_phys_t *shp = data;
+
+ if (shp == NULL)
+ return;
+
+ (void) printf("\t\tpool_create_len = %llu\n",
+ (u_longlong_t)shp->sh_pool_create_len);
+ (void) printf("\t\tphys_max_off = %llu\n",
+ (u_longlong_t)shp->sh_phys_max_off);
+ (void) printf("\t\tbof = %llu\n",
+ (u_longlong_t)shp->sh_bof);
+ (void) printf("\t\teof = %llu\n",
+ (u_longlong_t)shp->sh_eof);
+ (void) printf("\t\trecords_lost = %llu\n",
+ (u_longlong_t)shp->sh_records_lost);
+}
+
static void
zdb_nicenum(uint64_t num, char *buf)
{
@@ -215,18 +238,18 @@ zdb_nicenum(uint64_t num, char *buf)
nicenum(num, buf);
}
-const char dump_zap_stars[] = "****************************************";
-const int dump_zap_width = sizeof (dump_zap_stars) - 1;
+const char histo_stars[] = "****************************************";
+const int histo_width = sizeof (histo_stars) - 1;
static void
-dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
+dump_histogram(const uint64_t *histo, int size)
{
int i;
- int minidx = ZAP_HISTOGRAM_SIZE - 1;
+ int minidx = size - 1;
int maxidx = 0;
uint64_t max = 0;
- for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
+ for (i = 0; i < size; i++) {
if (histo[i] > max)
max = histo[i];
if (histo[i] > 0 && i > maxidx)
@@ -235,12 +258,14 @@ dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
minidx = i;
}
- if (max < dump_zap_width)
- max = dump_zap_width;
+ if (max < histo_width)
+ max = histo_width;
- for (i = minidx; i <= maxidx; i++)
- (void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i],
- &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]);
+ for (i = minidx; i <= maxidx; i++) {
+ (void) printf("\t\t\t%3u: %6llu %s\n",
+ i, (u_longlong_t)histo[i],
+ &histo_stars[(max - histo[i]) * histo_width / max]);
+ }
}
static void
@@ -291,19 +316,19 @@ dump_zap_stats(objset_t *os, uint64_t object)
(u_longlong_t)zs.zs_salt);
(void) printf("\t\tLeafs with 2^n pointers:\n");
- dump_zap_histogram(zs.zs_leafs_with_2n_pointers);
+ dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE);
(void) printf("\t\tBlocks with n*5 entries:\n");
- dump_zap_histogram(zs.zs_blocks_with_n5_entries);
+ dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE);
(void) printf("\t\tBlocks n/10 full:\n");
- dump_zap_histogram(zs.zs_blocks_n_tenths_full);
+ dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE);
(void) printf("\t\tEntries with n chunks:\n");
- dump_zap_histogram(zs.zs_entries_using_n_chunks);
+ dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE);
(void) printf("\t\tBuckets with n entries:\n");
- dump_zap_histogram(zs.zs_buckets_with_n_entries);
+ dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE);
}
/*ARGSUSED*/
@@ -545,7 +570,7 @@ static void
dump_metaslab_stats(metaslab_t *msp)
{
char maxbuf[32];
- space_map_t *sm = &msp->ms_map;
+ space_map_t *sm = msp->ms_map;
avl_tree_t *t = sm->sm_pp_root;
int free_pct = sm->sm_space * 100 / sm->sm_size;
@@ -561,7 +586,7 @@ dump_metaslab(metaslab_t *msp)
{
vdev_t *vd = msp->ms_group->mg_vd;
spa_t *spa = vd->vdev_spa;
- space_map_t *sm = &msp->ms_map;
+ space_map_t *sm = msp->ms_map;
space_map_obj_t *smo = &msp->ms_smo;
char freebuf[32];
@@ -857,21 +882,22 @@ dump_history(spa_t *spa)
for (int i = 0; i < num; i++) {
uint64_t time, txg, ievent;
char *cmd, *intstr;
+ boolean_t printed = B_FALSE;
if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME,
&time) != 0)
- continue;
+ goto next;
if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD,
&cmd) != 0) {
if (nvlist_lookup_uint64(events[i],
ZPOOL_HIST_INT_EVENT, &ievent) != 0)
- continue;
+ goto next;
verify(nvlist_lookup_uint64(events[i],
ZPOOL_HIST_TXG, &txg) == 0);
verify(nvlist_lookup_string(events[i],
ZPOOL_HIST_INT_STR, &intstr) == 0);
- if (ievent >= LOG_END)
- continue;
+ if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS)
+ goto next;
(void) snprintf(internalstr,
sizeof (internalstr),
@@ -884,6 +910,14 @@ dump_history(spa_t *spa)
(void) localtime_r(&tsec, &t);
(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
(void) printf("%s %s\n", tbuf, cmd);
+ printed = B_TRUE;
+
+next:
+ if (dump_opt['h'] > 1) {
+ if (!printed)
+ (void) printf("unrecognized record:\n");
+ dump_nvlist(events[i], 2);
+ }
}
}
@@ -916,7 +950,7 @@ sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp)
const dva_t *dva = bp->blk_dva;
int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
- if (dump_opt['b'] >= 5) {
+ if (dump_opt['b'] >= 6) {
sprintf_blkptr(blkbuf, bp);
return;
}
@@ -983,7 +1017,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
arc_buf_t *buf;
uint64_t fill = 0;
- err = arc_read_nolock(NULL, spa, bp, arc_getbuf_func, &buf,
+ err = arc_read(NULL, spa, bp, arc_getbuf_func, &buf,
ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
if (err)
return (err);
@@ -1189,7 +1223,7 @@ dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
}
static void
-dump_bpobj(bpobj_t *bpo, char *name)
+dump_bpobj(bpobj_t *bpo, char *name, int indent)
{
char bytes[32];
char comp[32];
@@ -1199,31 +1233,57 @@ dump_bpobj(bpobj_t *bpo, char *name)
return;
zdb_nicenum(bpo->bpo_phys->bpo_bytes, bytes);
- if (bpo->bpo_havesubobj) {
+ if (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_subobjs != 0) {
zdb_nicenum(bpo->bpo_phys->bpo_comp, comp);
zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp);
- (void) printf("\n %s: %llu local blkptrs, %llu subobjs, "
- "%s (%s/%s comp)\n",
- name, (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
+ (void) printf(" %*s: object %llu, %llu local blkptrs, "
+ "%llu subobjs, %s (%s/%s comp)\n",
+ indent * 8, name,
+ (u_longlong_t)bpo->bpo_object,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
(u_longlong_t)bpo->bpo_phys->bpo_num_subobjs,
bytes, comp, uncomp);
+
+ for (uint64_t i = 0; i < bpo->bpo_phys->bpo_num_subobjs; i++) {
+ uint64_t subobj;
+ bpobj_t subbpo;
+ int error;
+ VERIFY0(dmu_read(bpo->bpo_os,
+ bpo->bpo_phys->bpo_subobjs,
+ i * sizeof (subobj), sizeof (subobj), &subobj, 0));
+ error = bpobj_open(&subbpo, bpo->bpo_os, subobj);
+ if (error != 0) {
+ (void) printf("ERROR %u while trying to open "
+ "subobj id %llu\n",
+ error, (u_longlong_t)subobj);
+ continue;
+ }
+ dump_bpobj(&subbpo, "subobj", indent + 1);
+ bpobj_close(&subbpo);
+ }
} else {
- (void) printf("\n %s: %llu blkptrs, %s\n",
- name, (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs, bytes);
+ (void) printf(" %*s: object %llu, %llu blkptrs, %s\n",
+ indent * 8, name,
+ (u_longlong_t)bpo->bpo_object,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
+ bytes);
}
if (dump_opt['d'] < 5)
return;
- (void) printf("\n");
- (void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
+ if (indent == 0) {
+ (void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
+ (void) printf("\n");
+ }
}
static void
dump_deadlist(dsl_deadlist_t *dl)
{
dsl_deadlist_entry_t *dle;
+ uint64_t unused;
char bytes[32];
char comp[32];
char uncomp[32];
@@ -1242,14 +1302,24 @@ dump_deadlist(dsl_deadlist_t *dl)
(void) printf("\n");
+ /* force the tree to be loaded */
+ dsl_deadlist_space_range(dl, 0, UINT64_MAX, &unused, &unused, &unused);
+
for (dle = avl_first(&dl->dl_tree); dle;
dle = AVL_NEXT(&dl->dl_tree, dle)) {
- (void) printf(" mintxg %llu -> obj %llu\n",
- (longlong_t)dle->dle_mintxg,
- (longlong_t)dle->dle_bpobj.bpo_object);
+ if (dump_opt['d'] >= 5) {
+ char buf[128];
+ (void) snprintf(buf, sizeof (buf), "mintxg %llu -> ",
+ (longlong_t)dle->dle_mintxg,
+ (longlong_t)dle->dle_bpobj.bpo_object);
- if (dump_opt['d'] >= 5)
- dump_bpobj(&dle->dle_bpobj, "");
+ dump_bpobj(&dle->dle_bpobj, buf, 0);
+ } else {
+ (void) printf("mintxg %llu -> obj %llu\n",
+ (longlong_t)dle->dle_mintxg,
+ (longlong_t)dle->dle_bpobj.bpo_object);
+
+ }
}
}
@@ -1272,7 +1342,7 @@ fuid_table_destroy()
* print uid or gid information.
* For normal POSIX id just the id is printed in decimal format.
* For CIFS files with FUID the fuid is printed in hex followed by
- * the doman-rid string.
+ * the domain-rid string.
*/
static void
print_idstr(uint64_t id, const char *id_type)
@@ -1460,7 +1530,7 @@ static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
dump_zap, /* other ZAP */
dump_zap, /* persistent error log */
dump_uint8, /* SPA history */
- dump_uint64, /* SPA history offsets */
+ dump_history_offsets, /* SPA history offsets */
dump_zap, /* Pool properties */
dump_zap, /* DSL permissions */
dump_acl, /* ZFS ACL */
@@ -1625,7 +1695,9 @@ dump_dir(objset_t *os)
int print_header = 1;
int i, error;
+ dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
dmu_objset_fast_stat(os, &dds);
+ dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
if (dds.dds_type < DMU_OST_NUMTYPES)
type = objset_types[dds.dds_type];
@@ -1917,11 +1989,13 @@ dump_one_dir(const char *dsname, void *arg)
/*
* Block statistics.
*/
+#define PSIZE_HISTO_SIZE (SPA_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1)
typedef struct zdb_blkstats {
- uint64_t zb_asize;
- uint64_t zb_lsize;
- uint64_t zb_psize;
- uint64_t zb_count;
+ uint64_t zb_asize;
+ uint64_t zb_lsize;
+ uint64_t zb_psize;
+ uint64_t zb_count;
+ uint64_t zb_psize_histogram[PSIZE_HISTO_SIZE];
} zdb_blkstats_t;
/*
@@ -1945,6 +2019,9 @@ typedef struct zdb_cb {
zdb_blkstats_t zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1];
uint64_t zcb_dedup_asize;
uint64_t zcb_dedup_blocks;
+ uint64_t zcb_start;
+ uint64_t zcb_lastprint;
+ uint64_t zcb_totalasize;
uint64_t zcb_errors[256];
int zcb_readfails;
int zcb_haderrors;
@@ -1971,6 +2048,7 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
zb->zb_lsize += BP_GET_LSIZE(bp);
zb->zb_psize += BP_GET_PSIZE(bp);
zb->zb_count++;
+ zb->zb_psize_histogram[BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT]++;
}
if (dump_opt['L'])
@@ -2001,9 +2079,8 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0);
}
-/* ARGSUSED */
static int
-zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
+zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
{
zdb_cb_t *zcb = arg;
@@ -2035,7 +2112,6 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb));
free(data);
-
if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) {
zcb->zcb_haderrors = 1;
zcb->zcb_errors[ioerr]++;
@@ -2059,7 +2135,7 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
zcb->zcb_readfails = 0;
- if (dump_opt['b'] >= 4) {
+ if (dump_opt['b'] >= 5) {
sprintf_blkptr(blkbuf, bp);
(void) printf("objset %llu object %llu "
"level %lld offset 0x%llx %s\n",
@@ -2070,6 +2146,28 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
blkbuf);
}
+ if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) &&
+ gethrtime() > zcb->zcb_lastprint + NANOSEC) {
+ uint64_t now = gethrtime();
+ char buf[10];
+ uint64_t bytes = zcb->zcb_type[ZB_TOTAL][ZDB_OT_TOTAL].zb_asize;
+ int kb_per_sec =
+ 1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000));
+ int sec_remaining =
+ (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec;
+
+ zfs_nicenum(bytes, buf, sizeof (buf));
+ (void) fprintf(stderr,
+ "\r%5s completed (%4dMB/s) "
+ "estimated time remaining: %uhr %02umin %02usec ",
+ buf, kb_per_sec / 1024,
+ sec_remaining / 60 / 60,
+ sec_remaining / 60 % 60,
+ sec_remaining % 60);
+
+ zcb->zcb_lastprint = now;
+ }
+
return (0);
}
@@ -2161,11 +2259,11 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
for (int m = 0; m < vd->vdev_ms_count; m++) {
metaslab_t *msp = vd->vdev_ms[m];
mutex_enter(&msp->ms_lock);
- space_map_unload(&msp->ms_map);
- VERIFY(space_map_load(&msp->ms_map,
+ space_map_unload(msp->ms_map);
+ VERIFY(space_map_load(msp->ms_map,
&zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
spa->spa_meta_objset) == 0);
- msp->ms_map.sm_ppd = vd;
+ msp->ms_map->sm_ppd = vd;
mutex_exit(&msp->ms_lock);
}
}
@@ -2188,7 +2286,7 @@ zdb_leak_fini(spa_t *spa)
for (int m = 0; m < vd->vdev_ms_count; m++) {
metaslab_t *msp = vd->vdev_ms[m];
mutex_enter(&msp->ms_lock);
- space_map_unload(&msp->ms_map);
+ space_map_unload(msp->ms_map);
mutex_exit(&msp->ms_lock);
}
}
@@ -2201,7 +2299,7 @@ count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
{
zdb_cb_t *zcb = arg;
- if (dump_opt['b'] >= 4) {
+ if (dump_opt['b'] >= 5) {
char blkbuf[BP_SPRINTF_LEN];
sprintf_blkptr(blkbuf, bp);
(void) printf("[%s] %s\n",
@@ -2220,7 +2318,7 @@ dump_block_stats(spa_t *spa)
int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
int leaks = 0;
- (void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
+ (void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n",
(dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
(dump_opt['c'] == 1) ? "metadata " : "",
dump_opt['c'] ? "checksums " : "",
@@ -2256,6 +2354,8 @@ dump_block_stats(spa_t *spa)
if (dump_opt['c'] > 1)
flags |= TRAVERSE_PREFETCH_DATA;
+ zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
+ zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
if (zcb.zcb_haderrors) {
@@ -2383,6 +2483,14 @@ dump_block_stats(spa_t *spa)
else
(void) printf(" L%d %s\n",
level, typename);
+
+ if (dump_opt['b'] >= 4) {
+ (void) printf("psize "
+ "(in 512-byte sectors): "
+ "number of blocks\n");
+ dump_histogram(zb->zb_psize_histogram,
+ PSIZE_HISTO_SIZE);
+ }
}
}
}
@@ -2410,7 +2518,7 @@ typedef struct zdb_ddt_entry {
/* ARGSUSED */
static int
zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
- arc_buf_t *pbuf, const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
+ const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
{
avl_tree_t *t = arg;
avl_index_t where;
@@ -2530,10 +2638,11 @@ dump_zpool(spa_t *spa)
if (dump_opt['d'] || dump_opt['i']) {
dump_dir(dp->dp_meta_objset);
if (dump_opt['d'] >= 3) {
- dump_bpobj(&spa->spa_deferred_bpobj, "Deferred frees");
+ dump_bpobj(&spa->spa_deferred_bpobj,
+ "Deferred frees", 0);
if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
- "Pool snapshot frees");
+ "Pool snapshot frees", 0);
}
if (spa_feature_is_active(spa,
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
index 3a7568177fa5..a7a51c971012 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -1,5 +1,5 @@
'\" te
-.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
+.\" Copyright (c) 2013, Martin Matuska <mm@FreeBSD.org>.
.\" All Rights Reserved.
.\"
.\" The contents of this file are subject to the terms of the
@@ -19,15 +19,16 @@
.\"
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright (c) 2012 by Delphix. All rights reserved.
-.\" Copyright (c) 2012 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2012, Joyent, Inc. All rights reserved.
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
+.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+.\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved.
.\"
.\" $FreeBSD$
.\"
-.Dd November 26, 2012
+.Dd March 21, 2013
.Dt ZFS 8
.Os
.Sh NAME
@@ -39,14 +40,12 @@
.Nm
.Cm create
.Op Fl pu
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ... filesystem
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... Ar filesystem
.Nm
.Cm create
.Op Fl ps
.Op Fl b Ar blocksize
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ...
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Fl V
.Ar size volume
.Nm
@@ -59,13 +58,14 @@
.Sm off
.Ar snapshot
.Op % Ns Ar snapname
-.Op , Ns Ar ...
+.Op , Ns ...
.Sm on
.Nm
.Cm snapshot
.Op Fl r
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ... filesystem@snapname Ns | Ns Ar volume@snapname
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar filesystem@snapname Ns | Ns Ar volume@snapname
+.Ar filesystem@snapname Ns | Ns Ar volume@snapname Ns ...
.Nm
.Cm rollback
.Op Fl rRf
@@ -73,8 +73,8 @@
.Nm
.Cm clone
.Op Fl p
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ... snapshot filesystem Ns | Ns Ar volume
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar snapshot filesystem Ns | Ns Ar volume
.Nm
.Cm promote
.Ar clone-filesystem
@@ -102,31 +102,29 @@
.Cm list
.Op Fl r Ns | Ns Fl d Ar depth
.Op Fl H
-.Op Fl o Ar property Ns Op , Ns Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
-.Op Fl s Ar property
-.Ar ...
-.Op Fl S Ar property
-.Ar ...
+.Op Fl o Ar property Ns Oo , Ns property Ns Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns type Ns Oc Ns ...
+.Oo Fl s Ar property Oc Ns ...
+.Oo Fl S Ar property Oc Ns ...
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
.Cm set
.Ar property Ns = Ns Ar value
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
.Nm
.Cm get
.Op Fl r Ns | Ns Fl d Ar depth
.Op Fl Hp
-.Op Fl o Ar all | field Ns Op , Ns Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
-.Op Fl s Ar source Ns Op , Ns Ar ...
-.Ar all | property Ns Op , Ns Ar ...
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Op Fl o Ar all | field Ns Oo , Ns Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo Ns , Ar type Oc Ns ...
+.Op Fl s Ar source Ns Oo Ns , Ns Ar source Oc Ns ...
+.Ar all | property Ns Oo Ns , Ns Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
.Nm
.Cm inherit
.Op Fl rS
.Ar property
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
.Nm
.Cm upgrade
.Op Fl v
@@ -138,29 +136,25 @@
.Nm
.Cm userspace
.Op Fl Hinp
-.Op Fl o Ar field Ns Op , Ns Ar ...
-.Op Fl s Ar field
-.Ar ...
-.Op Fl S Ar field
-.Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
+.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo Ns , Ns Ar type Oc Ns ...
.Ar filesystem Ns | Ns Ar snapshot
.Nm
.Cm groupspace
.Op Fl Hinp
-.Op Fl o Ar field Ns Op , Ns Ar ...
-.Op Fl s Ar field
-.Ar ...
-.Op Fl S Ar field
-.Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
+.Op Fl o Ar field Ns Oo , Ns field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo Ns , Ns Ar type Oc Ns ...
.Ar filesystem Ns | Ns Ar snapshot
.Nm
.Cm mount
.Nm
.Cm mount
.Op Fl vO
-.Op Fl o Ar property Ns Op , Ns Ar ...
+.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
.Fl a | Ar filesystem
.Nm
.Cm unmount
@@ -192,63 +186,71 @@
.Nm
.Cm allow
.Op Fl ldug
-.Cm everyone Ns | Ns Ar user Ns | Ns Ar group Ns Op , Ns Ar ...
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Ar perm Ns | Ns Ar @setname Ns
+.Oo Ns , Ns Ar perm Ns | Ns Ar @setname Oc Ns ...
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm allow
.Op Fl ld
-.Fl e
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Fl e Ns | Ns Cm everyone
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm allow
.Fl c
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm allow
.Fl s
.Ar @setname
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm unallow
.Op Fl rldug
-.Cm everyone Ns | Ns Ar user Ns | Ns Ar group Ns Op , Ns Ar ...
-.Op Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm unallow
.Op Fl rld
-.Fl e
-.Op Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Fl e Ns | Ns Cm everyone
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm unallow
.Op Fl r
.Fl c
-.Op Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm unallow
.Op Fl r
.Fl s
.Ar @setname
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm hold
.Op Fl r
-.Ar tag snapshot ...
+.Ar tag snapshot Ns ...
.Nm
.Cm holds
.Op Fl r
-.Ar snapshot ...
+.Ar snapshot Ns ...
.Nm
.Cm release
.Op Fl r
-.Ar tag snapshot ...
+.Ar tag snapshot Ns ...
.Nm
.Cm diff
.Op Fl FHt
@@ -525,6 +527,39 @@ if the snapshot has been marked for deferred destroy by using the
.Qq Nm Cm destroy -d
command. Otherwise, the property is
.Cm off .
+.It Sy logicalreferenced
+The amount of space that is
+.Qq logically
+accessible by this dataset.
+See the
+.Sy referenced
+property.
+The logical space ignores the effect of the
+.Sy compression
+and
+.Sy copies
+properties, giving a quantity closer to the amount of data that applications
+see.
+However, it does include space consumed by metadata.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy lrefer .
+.It Sy logicalused
+The amount of space that is
+.Qq logically
+consumed by this dataset and all its descendents.
+See the
+.Sy used
+property.
+The logical space ignores the effect of the
+.Sy compression
+and
+.Sy copies
+properties, giving a quantity closer to the amount of data that applications
+see.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy lused .
.It Sy mounted
For file systems, indicates whether the file system is currently mounted. This
property can be either
@@ -866,7 +901,7 @@ but this may change in future releases). The value
disables integrity checking on user data. Disabling checksums is
.Em NOT
a recommended practice.
-.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | Cm zle
+.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | zle | Cm lz4
Controls the compression algorithm used for this dataset. The
.Cm lzjb
compression algorithm is optimized for performance while providing decent data
@@ -894,6 +929,26 @@ The
.Cm zle
compression algorithm compresses runs of zeros.
.Pp
+The
+.Sy lz4
+compression algorithm is a high-performance replacement
+for the
+.Sy lzjb
+algorithm. It features significantly faster
+compression and decompression, as well as a moderately higher
+compression ratio than
+.Sy lzjb ,
+but can only be used on pools with
+the
+.Sy lz4_compress
+feature set to
+.Sy enabled .
+See
+.Xr zpool-features 7
+for details on ZFS feature flags and the
+.Sy lz4_compress
+feature.
+.Pp
This property can also be referred to by its shortened column name
.Cm compress .
Changing this property affects only newly-written data.
@@ -1144,7 +1199,7 @@ When the
.Sy sharenfs
property is changed for a dataset, the
.Xr mountd 8
-dameon is reloaded.
+daemon is reloaded.
.It Sy logbias Ns = Ns Cm latency | throughput
Provide a hint to
.Tn ZFS
@@ -1390,8 +1445,8 @@ Displays a help message.
.Nm
.Cm create
.Op Fl pu
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ... filesystem
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar filesystem
.Xc
.Pp
Creates a new
@@ -1428,8 +1483,7 @@ options.
.Cm create
.Op Fl ps
.Op Fl b Ar blocksize
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ...
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Fl V
.Ar size volume
.Xc
@@ -1529,7 +1583,7 @@ behavior for mounted file systems in use.
.Sm off
.Ar snapshot
.Op % Ns Ar snapname
-.Op , Ns Ar ...
+.Op , Ns ...
.Sm on
.Xc
.Pp
@@ -1564,7 +1618,11 @@ multiple snapshots.
Destroy (or mark for deferred deletion) all snapshots with this name in
descendent file systems.
.It Fl R
-Recursively destroy all dependents.
+Recursively destroy all clones of these snapshots, including the clones,
+snapshots, and children.
+If this flag is specified, the
+.Op fl d
+flag will have no effect.
.It Fl n
Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
conjunction with the
@@ -1590,20 +1648,20 @@ behavior for mounted file systems in use.
.Nm
.Cm snapshot
.Op Fl r
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ...
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Ar filesystem@snapname Ns | Ns volume@snapname
+.Ar filesystem@snapname Ns | Ns volume@snapname Ns ...
.Xc
.Pp
-Creates a snapshot with the given name. All previous modifications by
-successful system calls to the file system are part of the snapshot. See the
+Creates snapshots with the given names. All previous modifications by
+successful system calls to the file system are part of the snapshots.
+Snapshots are taken atomically, so that all snapshots correspond to the same
+moment in time. See the
.Qq Sx Snapshots
section for details.
.Bl -tag -width indent
.It Fl r
-Recursively create snapshots of all descendent datasets. Snapshots are taken
-atomically, so that all recursive snapshots correspond to the same moment in
-time.
+Recursively create snapshots of all descendent datasets
.It Fl o Ar property Ns = Ns Ar value
Sets the specified property; see
.Qq Nm Cm create
@@ -1638,8 +1696,8 @@ option to force an unmount of any clone file systems that are to be destroyed.
.Nm
.Cm clone
.Op Fl p
-.Op Fl o Ar property Ns = Ns Ar value
-.Ar ... snapshot filesystem Ns | Ns Ar volume
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar snapshot filesystem Ns | Ns Ar volume
.Xc
.Pp
Creates a clone of the given snapshot. See the
@@ -1742,13 +1800,11 @@ only dataset that can be renamed recursively.
.Cm list
.Op Fl r Ns | Ns Fl d Ar depth
.Op Fl H
-.Op Fl o Ar property Ns Op , Ns Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
-.Op Fl s Ar property
-.Ar ...
-.Op Fl S Ar property
-.Ar ...
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+.Oo Fl s Ar property Oc Ns ...
+.Oo Fl S Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
.Xc
.Pp
Lists the property information for the given datasets in tabular form. If
@@ -1774,7 +1830,7 @@ will display only the dataset and its direct children.
.It Fl H
Used for scripting mode. Do not print headers and separate fields by a single
tab instead of arbitrary white space.
-.It Fl o Ar property Ns Op , Ns Ar ...
+.It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
A comma-separated list of properties to display. The property must be:
.Bl -bullet -offset 2n
.It
@@ -1798,7 +1854,7 @@ shortcut for specifying
.Sy filesystem,volume
syntax.
.El
-.It Fl t Ar type Ns Op , Ns Ar ...
+.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
A comma-separated list of types to display, where
.Ar type
is one of
@@ -1861,11 +1917,11 @@ section.
.Cm get
.Op Fl r Ns | Ns Fl d Ar depth
.Op Fl Hp
-.Op Fl o Ar all | field Ns Op , Ns Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
-.Op Fl s Ar source Ns Op , Ns Ar ...
-.Ar all | property Ns Op , Ns Ar ...
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Op Fl o Ar all | field Ns Oo , Ns Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+.Op Fl s Ar source Ns Oo , Ns Ar source Oc Ns ...
+.Ar all | property Ns Oo , Ns Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
.Xc
.Pp
Displays properties for the given datasets. If no datasets are specified, then
@@ -1915,7 +1971,7 @@ omitted, and fields are explicitly separated by a single tab instead of an
arbitrary amount of space.
.It Fl p
Display numbers in parseable (exact) values.
-.It Fl o Cm all | Ar field Ns Op , Ns Ar ...
+.It Fl o Cm all | Ar field Ns Oo , Ns Ar field Oc Ns ...
A comma-separated list of columns to display. Supported values are
.Sy name,property,value,received,source .
Default values are
@@ -1923,7 +1979,7 @@ Default values are
The keyword
.Cm all
specifies all columns.
-.It Fl t Ar type Ns Op , Ns Ar ...
+.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
A comma-separated list of types to display, where
.Ar type
is one of
@@ -1931,7 +1987,7 @@ is one of
For example, specifying
.Fl t Cm snapshot
displays only snapshots.
-.It Fl s Ar source Ns Op , Ns Ar ...
+.It Fl s Ar source Ns Oo , Ns Ar source Oc Ns ...
A comma-separated list of sources to display. Those properties coming from a
source other than those in this list are ignored. Each source must be one of
the following:
@@ -1943,7 +1999,7 @@ The default value is all sources.
.Cm inherit
.Op Fl rS
.Ar property
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
.Xc
.Pp
Clears the specified property, causing it to be inherited from an ancestor. If
@@ -2018,12 +2074,10 @@ Upgrade the specified file system.
.Nm
.Cm userspace
.Op Fl Hinp
-.Op Fl o Ar field Ns Op , Ns Ar ...
-.Op Fl s Ar field
-.Ar ...
-.Op Fl S Ar field
-.Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
+.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
.Ar filesystem Ns | Ns Ar snapshot
.Xc
.Pp
@@ -2040,7 +2094,7 @@ Print numeric ID instead of user/group name.
Do not print headers, use tab-delimited output.
.It Fl p
Use exact (parsable) numeric output.
-.It Fl o Ar field Ns Op , Ns Ar ...
+.It Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
Display only the specified fields from the following set:
.Sy type,name,used,quota .
The default is to display all fields.
@@ -2055,7 +2109,7 @@ another. The default is
.It Fl S Ar field
Sort by this field in reverse order. See
.Fl s .
-.It Fl t Ar type Ns Op , Ns Ar ...
+.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
Print only the specified types from the following set:
.Sy all,posixuser,smbuser,posixgroup,smbgroup .
.Pp
@@ -2071,12 +2125,10 @@ Translate SID to POSIX ID. This flag currently has no effect on
.Nm
.Cm groupspace
.Op Fl Hinp
-.Op Fl o Ar field Ns Op , Ns Ar ...
-.Op Fl s Ar field
-.Ar ...
-.Op Fl S Ar field
-.Ar ...
-.Op Fl t Ar type Ns Op , Ns Ar ...
+.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
.Ar filesystem Ns | Ns Ar snapshot
.Xc
.Pp
@@ -2100,7 +2152,7 @@ file systems currently mounted.
.Nm
.Cm mount
.Op Fl vO
-.Op Fl o Ar property Ns Op , Ns Ar ...
+.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
.Fl a | Ar filesystem
.Xc
.Pp
@@ -2113,7 +2165,7 @@ Report mount progress.
.It Fl O
Perform an overlay mount. Overlay mounts are not supported on
.Fx .
-.It Fl o Ar property Ns Op , Ns Ar ...
+.It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
An optional, comma-separated list of mount options to use temporarily for the
duration of the mount. See the
.Qq Sx Temporary Mount Point Properties
@@ -2432,16 +2484,18 @@ for more information.
.Nm
.Cm allow
.Op Fl ldug
-.Cm everyone Ns | Ns Ar user Ns | Ns Ar group Ns Op , Ns Ar ...
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Ar perm Ns | Ns Ar @setname Ns
+.Oo Ns , Ns Ar perm Ns | Ns Ar @setname Oc Ns ...
.Ar filesystem Ns | Ns Ar volume
.Xc
.It Xo
.Nm
.Cm allow
.Op Fl ld
-.Fl e
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Fl e Ns | Ns Cm everyone
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
.Ar filesystem Ns | Ns Ar volume
.Xc
.Pp
@@ -2451,26 +2505,31 @@ administration permission for the file systems to non-privileged users.
.Bl -tag -width indent
.It Xo
.Op Fl ug
-.Cm everyone Ns | Ns Ar user Ns | Ns Ar group Ns Op , Ns Ar ...
+.Ar user Ns | Ns Ar group Ns Oo , Ar user Ns | Ns Ar group Oc Ns ...
.Xc
Specifies to whom the permissions are delegated. Multiple entities can be
specified as a comma-separated list. If neither of the
.Fl ug
options are specified, then the argument is interpreted preferentially as the
-keyword "everyone", then as a user name, and lastly as a group name. To specify
-a user or group named "everyone", use the
+keyword
+.Cm everyone ,
+then as a user name, and lastly as a group name. To specify
+a user or group named
+.Qq everyone ,
+use the
.Fl u
or
.Fl g
options. To specify a group with the same name as a user, use the
.Fl g
option.
+.It Op Fl e Ns | Ns Cm everyone
+Specifies that the permissions be delegated to
+.Qq everyone .
.It Xo
-.Op Fl e
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar perm Ns | Ns Ar @setname Ns Oo , Ns Ar perm Ns | Ns Ar @setname Oc Ns ...
.Xc
-Specifies that the permissions be delegated to "everyone".
-Multiple permissions
+The permissions to delegate. Multiple permissions
may be specified as a comma-separated list. Permission names are the same as
.Tn ZFS
subcommand and property names. See the property list below. Property set names,
@@ -2577,7 +2636,8 @@ protocol
.Nm
.Cm allow
.Fl c
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
.Ar filesystem Ns | Ns Ar volume
.Xc
.Pp
@@ -2588,7 +2648,8 @@ creator of any newly-created descendent file system.
.Cm allow
.Fl s
.Ar @setname
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
.Ar filesystem Ns | Ns Ar volume
.Xc
.Pp
@@ -2604,16 +2665,18 @@ and can be no more than 64 characters long.
.Nm
.Cm unallow
.Op Fl rldug
-.Cm everyone Ns | Ns Ar user Ns | Ns Ar group Ns Op , Ns Ar ...
-.Op Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Xc
.It Xo
.Nm
.Cm unallow
.Op Fl rld
-.Fl e
-.Op Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Fl e Ns | Ns Cm everyone
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Xc
.It Xo
@@ -2621,7 +2684,8 @@ and can be no more than 64 characters long.
.Cm unallow
.Op Fl r
.Fl c
-.Op Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Xc
.Pp
@@ -2630,10 +2694,12 @@ Removes permissions that were granted with the
command. No permissions are explicitly denied, so other permissions granted are
still in effect. For example, if the permission is granted by an ancestor. If
no permissions are specified, then all permissions for the specified
-.Ar user , group , No or Ar everyone
-are removed. Specifying "everyone" (or using the
-.Fl e
-option) only removes the permissions that were granted to "everyone",
+.Ar user , group , No or everyone
+are removed. Specifying
+.Cm everyone
+.Po or using the Fl e
+option
+.Pc only removes the permissions that were granted to everyone ,
not all permissions for every user and group. See the
.Qq Nm Cm allow
command for a description of the
@@ -2649,7 +2715,8 @@ Recursively remove the permissions from this file system and all descendents.
.Op Fl r
.Fl s
.Ar @setname
-.Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
.Ar filesystem Ns | Ns Ar volume
.Xc
.Pp
@@ -2659,7 +2726,7 @@ then all permissions are removed, thus removing the set entirely.
.Nm
.Cm hold
.Op Fl r
-.Ar tag snapshot ...
+.Ar tag snapshot Ns ...
.Xc
.Pp
Adds a single reference, named with the
@@ -2680,7 +2747,7 @@ snapshots of all descendent file systems.
.Nm
.Cm holds
.Op Fl r
-.Ar snapshot ...
+.Ar snapshot Ns ...
.Xc
.Pp
Lists all existing user references for the given snapshot or snapshots.
@@ -2693,7 +2760,7 @@ listing the holds on the named snapshot.
.Nm
.Cm release
.Op Fl r
-.Ar tag snapshot ...
+.Ar tag snapshot Ns ...
.Xc
.Pp
Removes a single reference, named with the
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index 1dfc82d44e78..611740c756e8 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -58,6 +58,7 @@
#include <time.h>
#include <libzfs.h>
+#include <libzfs_core.h>
#include <zfs_prop.h>
#include <zfs_deleg.h>
#include <libuutil.h>
@@ -74,6 +75,7 @@ libzfs_handle_t *g_zfs;
static FILE *mnttab_file;
static char history_str[HIS_MAX_RECORD_LEN];
+static boolean_t log_history = B_TRUE;
static int zfs_do_clone(int argc, char **argv);
static int zfs_do_create(int argc, char **argv);
@@ -276,7 +278,7 @@ get_usage(zfs_help_t idx)
return (gettext("\tshare <-a | filesystem>\n"));
case HELP_SNAPSHOT:
return (gettext("\tsnapshot [-r] [-o property=value] ... "
- "<filesystem@snapname|volume@snapname>\n"));
+ "<filesystem@snapname|volume@snapname> ...\n"));
case HELP_UNMOUNT:
return (gettext("\tunmount [-f] "
"<-a | filesystem|mountpoint>\n"));
@@ -914,11 +916,12 @@ typedef struct destroy_cbdata {
boolean_t cb_parsable;
boolean_t cb_dryrun;
nvlist_t *cb_nvl;
+ nvlist_t *cb_batchedsnaps;
/* first snap in contiguous run */
- zfs_handle_t *cb_firstsnap;
+ char *cb_firstsnap;
/* previous snap in contiguous run */
- zfs_handle_t *cb_prevsnap;
+ char *cb_prevsnap;
int64_t cb_snapused;
char *cb_snapspec;
} destroy_cbdata_t;
@@ -1010,9 +1013,27 @@ destroy_callback(zfs_handle_t *zhp, void *data)
zfs_close(zhp);
return (0);
}
+ if (cb->cb_dryrun) {
+ zfs_close(zhp);
+ return (0);
+ }
- if (!cb->cb_dryrun) {
- if (zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
+ /*
+ * We batch up all contiguous snapshots (even of different
+ * filesystems) and destroy them with one ioctl. We can't
+ * simply do all snap deletions and then all fs deletions,
+ * because we must delete a clone before its origin.
+ */
+ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
+ fnvlist_add_boolean(cb->cb_batchedsnaps, name);
+ } else {
+ int error = zfs_destroy_snaps_nvl(g_zfs,
+ cb->cb_batchedsnaps, B_FALSE);
+ fnvlist_free(cb->cb_batchedsnaps);
+ cb->cb_batchedsnaps = fnvlist_alloc();
+
+ if (error != 0 ||
+ zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
zfs_close(zhp);
return (-1);
@@ -1032,11 +1053,13 @@ destroy_print_cb(zfs_handle_t *zhp, void *arg)
if (nvlist_exists(cb->cb_nvl, name)) {
if (cb->cb_firstsnap == NULL)
- cb->cb_firstsnap = zfs_handle_dup(zhp);
+ cb->cb_firstsnap = strdup(name);
if (cb->cb_prevsnap != NULL)
- zfs_close(cb->cb_prevsnap);
+ free(cb->cb_prevsnap);
/* this snap continues the current range */
- cb->cb_prevsnap = zfs_handle_dup(zhp);
+ cb->cb_prevsnap = strdup(name);
+ if (cb->cb_firstsnap == NULL || cb->cb_prevsnap == NULL)
+ nomem();
if (cb->cb_verbose) {
if (cb->cb_parsable) {
(void) printf("destroy\t%s\n", name);
@@ -1051,12 +1074,12 @@ destroy_print_cb(zfs_handle_t *zhp, void *arg)
} else if (cb->cb_firstsnap != NULL) {
/* end of this range */
uint64_t used = 0;
- err = zfs_get_snapused_int(cb->cb_firstsnap,
+ err = lzc_snaprange_space(cb->cb_firstsnap,
cb->cb_prevsnap, &used);
cb->cb_snapused += used;
- zfs_close(cb->cb_firstsnap);
+ free(cb->cb_firstsnap);
cb->cb_firstsnap = NULL;
- zfs_close(cb->cb_prevsnap);
+ free(cb->cb_prevsnap);
cb->cb_prevsnap = NULL;
}
zfs_close(zhp);
@@ -1073,13 +1096,13 @@ destroy_print_snapshots(zfs_handle_t *fs_zhp, destroy_cbdata_t *cb)
if (cb->cb_firstsnap != NULL) {
uint64_t used = 0;
if (err == 0) {
- err = zfs_get_snapused_int(cb->cb_firstsnap,
+ err = lzc_snaprange_space(cb->cb_firstsnap,
cb->cb_prevsnap, &used);
}
cb->cb_snapused += used;
- zfs_close(cb->cb_firstsnap);
+ free(cb->cb_firstsnap);
cb->cb_firstsnap = NULL;
- zfs_close(cb->cb_prevsnap);
+ free(cb->cb_prevsnap);
cb->cb_prevsnap = NULL;
}
return (err);
@@ -1166,8 +1189,10 @@ static int
zfs_do_destroy(int argc, char **argv)
{
destroy_cbdata_t cb = { 0 };
+ int rv = 0;
+ int err = 0;
int c;
- zfs_handle_t *zhp;
+ zfs_handle_t *zhp = NULL;
char *at;
zfs_type_t type = ZFS_TYPE_DATASET;
@@ -1221,11 +1246,9 @@ zfs_do_destroy(int argc, char **argv)
at = strchr(argv[0], '@');
if (at != NULL) {
- int err = 0;
/* Build the list of snaps to destroy in cb_nvl. */
- if (nvlist_alloc(&cb.cb_nvl, NV_UNIQUE_NAME, 0) != 0)
- nomem();
+ cb.cb_nvl = fnvlist_alloc();
*at = '\0';
zhp = zfs_open(g_zfs, argv[0],
@@ -1236,17 +1259,15 @@ zfs_do_destroy(int argc, char **argv)
cb.cb_snapspec = at + 1;
if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 ||
cb.cb_error) {
- zfs_close(zhp);
- nvlist_free(cb.cb_nvl);
- return (1);
+ rv = 1;
+ goto out;
}
if (nvlist_empty(cb.cb_nvl)) {
(void) fprintf(stderr, gettext("could not find any "
"snapshots to destroy; check snapshot names.\n"));
- zfs_close(zhp);
- nvlist_free(cb.cb_nvl);
- return (1);
+ rv = 1;
+ goto out;
}
if (cb.cb_verbose) {
@@ -1265,18 +1286,26 @@ zfs_do_destroy(int argc, char **argv)
}
if (!cb.cb_dryrun) {
- if (cb.cb_doclones)
+ if (cb.cb_doclones) {
+ cb.cb_batchedsnaps = fnvlist_alloc();
err = destroy_clones(&cb);
+ if (err == 0) {
+ err = zfs_destroy_snaps_nvl(g_zfs,
+ cb.cb_batchedsnaps, B_FALSE);
+ }
+ if (err != 0) {
+ rv = 1;
+ goto out;
+ }
+ }
if (err == 0) {
- err = zfs_destroy_snaps_nvl(zhp, cb.cb_nvl,
+ err = zfs_destroy_snaps_nvl(g_zfs, cb.cb_nvl,
cb.cb_defer_destroy);
}
}
- zfs_close(zhp);
- nvlist_free(cb.cb_nvl);
if (err != 0)
- return (1);
+ rv = 1;
} else {
/* Open the given dataset */
if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
@@ -1297,8 +1326,8 @@ zfs_do_destroy(int argc, char **argv)
zfs_get_name(zhp));
(void) fprintf(stderr, gettext("use 'zpool destroy %s' "
"to destroy the pool itself\n"), zfs_get_name(zhp));
- zfs_close(zhp);
- return (1);
+ rv = 1;
+ goto out;
}
/*
@@ -1308,30 +1337,42 @@ zfs_do_destroy(int argc, char **argv)
if (!cb.cb_doclones &&
zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
&cb) != 0) {
- zfs_close(zhp);
- return (1);
+ rv = 1;
+ goto out;
}
if (cb.cb_error) {
- zfs_close(zhp);
- return (1);
+ rv = 1;
+ goto out;
}
+ cb.cb_batchedsnaps = fnvlist_alloc();
if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
&cb) != 0) {
- zfs_close(zhp);
- return (1);
+ rv = 1;
+ goto out;
}
/*
* Do the real thing. The callback will close the
* handle regardless of whether it succeeds or not.
*/
- if (destroy_callback(zhp, &cb) != 0)
- return (1);
+ err = destroy_callback(zhp, &cb);
+ zhp = NULL;
+ if (err == 0) {
+ err = zfs_destroy_snaps_nvl(g_zfs,
+ cb.cb_batchedsnaps, cb.cb_defer_destroy);
+ }
+ if (err != 0)
+ rv = 1;
}
- return (0);
+out:
+ fnvlist_free(cb.cb_batchedsnaps);
+ fnvlist_free(cb.cb_nvl);
+ if (zhp != NULL)
+ zfs_close(zhp);
+ return (rv);
}
static boolean_t
@@ -1932,9 +1973,11 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data)
/*
* If they did "zfs upgrade -a", then we could
* be doing ioctls to different pools. We need
- * to log this history once to each pool.
+ * to log this history once to each pool, and bypass
+ * the normal history logging that happens in main().
*/
- verify(zpool_stage_history(g_zfs, history_str) == 0);
+ (void) zpool_log_history(g_zfs, history_str);
+ log_history = B_FALSE;
}
if (zfs_prop_set(zhp, "version", verstr) == 0)
cb->cb_numupgraded++;
@@ -3472,6 +3515,32 @@ zfs_do_set(int argc, char **argv)
return (ret);
}
+typedef struct snap_cbdata {
+ nvlist_t *sd_nvl;
+ boolean_t sd_recursive;
+ const char *sd_snapname;
+} snap_cbdata_t;
+
+static int
+zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
+{
+ snap_cbdata_t *sd = arg;
+ char *name;
+ int rv = 0;
+ int error;
+
+ error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
+ if (error == -1)
+ nomem();
+ fnvlist_add_boolean(sd->sd_nvl, name);
+ free(name);
+
+ if (sd->sd_recursive)
+ rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ zfs_close(zhp);
+ return (rv);
+}
+
/*
* zfs snapshot [-r] [-o prop=value] ... <fs@snap>
*
@@ -3481,13 +3550,16 @@ zfs_do_set(int argc, char **argv)
static int
zfs_do_snapshot(int argc, char **argv)
{
- boolean_t recursive = B_FALSE;
int ret = 0;
char c;
nvlist_t *props;
+ snap_cbdata_t sd = { 0 };
+ boolean_t multiple_snaps = B_FALSE;
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
nomem();
+ if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
/* check options */
while ((c = getopt(argc, argv, "ro:")) != -1) {
@@ -3497,7 +3569,8 @@ zfs_do_snapshot(int argc, char **argv)
return (1);
break;
case 'r':
- recursive = B_TRUE;
+ sd.sd_recursive = B_TRUE;
+ multiple_snaps = B_TRUE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
@@ -3514,18 +3587,35 @@ zfs_do_snapshot(int argc, char **argv)
(void) fprintf(stderr, gettext("missing snapshot argument\n"));
goto usage;
}
- if (argc > 1) {
- (void) fprintf(stderr, gettext("too many arguments\n"));
- goto usage;
+
+ if (argc > 1)
+ multiple_snaps = B_TRUE;
+ for (; argc > 0; argc--, argv++) {
+ char *atp;
+ zfs_handle_t *zhp;
+
+ atp = strchr(argv[0], '@');
+ if (atp == NULL)
+ goto usage;
+ *atp = '\0';
+ sd.sd_snapname = atp + 1;
+ zhp = zfs_open(g_zfs, argv[0],
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+ goto usage;
+ if (zfs_snapshot_cb(zhp, &sd) != 0)
+ goto usage;
}
- ret = zfs_snapshot(g_zfs, argv[0], recursive, props);
+ ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
+ nvlist_free(sd.sd_nvl);
nvlist_free(props);
- if (ret && recursive)
+ if (ret != 0 && multiple_snaps)
(void) fprintf(stderr, gettext("no snapshots were created\n"));
return (ret != 0);
usage:
+ nvlist_free(sd.sd_nvl);
nvlist_free(props);
usage(B_FALSE);
return (-1);
@@ -5068,28 +5158,12 @@ cleanup2:
return (error);
}
-/*
- * zfs allow [-r] [-t] <tag> <snap> ...
- *
- * -r Recursively hold
- * -t Temporary hold (hidden option)
- *
- * Apply a user-hold with the given tag to the list of snapshots.
- */
static int
zfs_do_allow(int argc, char **argv)
{
return (zfs_do_allow_unallow_impl(argc, argv, B_FALSE));
}
-/*
- * zfs unallow [-r] [-t] <tag> <snap> ...
- *
- * -r Recursively hold
- * -t Temporary hold (hidden option)
- *
- * Apply a user-hold with the given tag to the list of snapshots.
- */
static int
zfs_do_unallow(int argc, char **argv)
{
@@ -5103,7 +5177,6 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
int i;
const char *tag;
boolean_t recursive = B_FALSE;
- boolean_t temphold = B_FALSE;
const char *opts = holding ? "rt" : "r";
int c;
@@ -5113,9 +5186,6 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
case 'r':
recursive = B_TRUE;
break;
- case 't':
- temphold = B_TRUE;
- break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
@@ -5164,7 +5234,7 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
}
if (holding) {
if (zfs_hold(zhp, delim+1, tag, recursive,
- temphold, B_FALSE, -1, 0, 0) != 0)
+ B_FALSE, -1) != 0)
++errors;
} else {
if (zfs_release(zhp, delim+1, tag, recursive) != 0)
@@ -5180,7 +5250,6 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
* zfs hold [-r] [-t] <tag> <snap> ...
*
* -r Recursively hold
- * -t Temporary hold (hidden option)
*
* Apply a user-hold with the given tag to the list of snapshots.
*/
@@ -6602,8 +6671,7 @@ main(int argc, char **argv)
return (1);
}
- zpool_set_history_str("zfs", argc, argv, history_str);
- verify(zpool_stage_history(g_zfs, history_str) == 0);
+ zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
libzfs_print_on_error(g_zfs, B_TRUE);
@@ -6672,6 +6740,9 @@ main(int argc, char **argv)
(void) fclose(mnttab_file);
+ if (ret == 0 && log_history)
+ (void) zpool_log_history(g_zfs, history_str);
+
libzfs_fini(g_zfs);
/*
diff --git a/cddl/contrib/opensolaris/cmd/zhack/zhack.c b/cddl/contrib/opensolaris/cmd/zhack/zhack.c
index 2618cea32b41..d80b3a013d3e 100644
--- a/cddl/contrib/opensolaris/cmd/zhack/zhack.c
+++ b/cddl/contrib/opensolaris/cmd/zhack/zhack.c
@@ -46,6 +46,7 @@
#include <sys/zio_checksum.h>
#include <sys/zio_compress.h>
#include <sys/zfeature.h>
+#include <sys/dmu_tx.h>
#undef ZFS_MAXNAMELEN
#undef verify
#include <libzfs.h>
@@ -273,12 +274,15 @@ zhack_do_feature_stat(int argc, char **argv)
}
static void
-feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx)
+feature_enable_sync(void *arg, dmu_tx_t *tx)
{
- spa_t *spa = arg1;
- zfeature_info_t *feature = arg2;
+ spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+ zfeature_info_t *feature = arg;
spa_feature_enable(spa, feature, tx);
+ spa_history_log_internal(spa, "zhack enable feature", tx,
+ "name=%s can_readonly=%u",
+ feature->fi_guid, feature->fi_can_readonly);
}
static void
@@ -341,8 +345,8 @@ zhack_do_feature_enable(int argc, char **argv)
if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
fatal("feature already enabled: %s", feature.fi_guid);
- VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL,
- feature_enable_sync, spa, &feature, 5));
+ VERIFY0(dsl_sync_task(spa_name(spa), NULL,
+ feature_enable_sync, &feature, 5));
spa_close(spa, FTAG);
@@ -350,21 +354,25 @@ zhack_do_feature_enable(int argc, char **argv)
}
static void
-feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
+feature_incr_sync(void *arg, dmu_tx_t *tx)
{
- spa_t *spa = arg1;
- zfeature_info_t *feature = arg2;
+ spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+ zfeature_info_t *feature = arg;
spa_feature_incr(spa, feature, tx);
+ spa_history_log_internal(spa, "zhack feature incr", tx,
+ "name=%s", feature->fi_guid);
}
static void
-feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
+feature_decr_sync(void *arg, dmu_tx_t *tx)
{
- spa_t *spa = arg1;
- zfeature_info_t *feature = arg2;
+ spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+ zfeature_info_t *feature = arg;
spa_feature_decr(spa, feature, tx);
+ spa_history_log_internal(spa, "zhack feature decr", tx,
+ "name=%s", feature->fi_guid);
}
static void
@@ -435,8 +443,8 @@ zhack_do_feature_ref(int argc, char **argv)
if (decr && !spa_feature_is_active(spa, &feature))
fatal("feature refcount already 0: %s", feature.fi_guid);
- VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL,
- decr ? feature_decr_sync : feature_incr_sync, spa, &feature, 5));
+ VERIFY0(dsl_sync_task(spa_name(spa), NULL,
+ decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
spa_close(spa, FTAG);
}
diff --git a/cddl/contrib/opensolaris/cmd/zinject/translate.c b/cddl/contrib/opensolaris/cmd/zinject/translate.c
index 442f220c442a..af25d3c3c17d 100644
--- a/cddl/contrib/opensolaris/cmd/zinject/translate.c
+++ b/cddl/contrib/opensolaris/cmd/zinject/translate.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <libzfs.h>
@@ -455,6 +456,20 @@ translate_device(const char *pool, const char *device, err_type_t label_type,
&record->zi_guid) == 0);
}
+ /*
+ * Device faults can take on three different forms:
+ * 1). delayed or hanging I/O
+ * 2). zfs label faults
+ * 3). generic disk faults
+ */
+ if (record->zi_timer != 0) {
+ record->zi_cmd = ZINJECT_DELAY_IO;
+ } else if (label_type != TYPE_INVAL) {
+ record->zi_cmd = ZINJECT_LABEL_FAULT;
+ } else {
+ record->zi_cmd = ZINJECT_DEVICE_FAULT;
+ }
+
switch (label_type) {
case TYPE_LABEL_UBERBLOCK:
record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]);
diff --git a/cddl/contrib/opensolaris/cmd/zinject/zinject.c b/cddl/contrib/opensolaris/cmd/zinject/zinject.c
index d17ed534e329..994d6878cc85 100644
--- a/cddl/contrib/opensolaris/cmd/zinject/zinject.c
+++ b/cddl/contrib/opensolaris/cmd/zinject/zinject.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -603,7 +604,7 @@ main(int argc, char **argv)
}
while ((c = getopt(argc, argv,
- ":aA:b:d:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
+ ":aA:b:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
switch (c) {
case 'a':
flags |= ZINJECT_FLUSH_ARC;
@@ -629,6 +630,15 @@ main(int argc, char **argv)
case 'd':
device = optarg;
break;
+ case 'D':
+ record.zi_timer = strtoull(optarg, &end, 10);
+ if (errno != 0 || *end != '\0') {
+ (void) fprintf(stderr, "invalid i/o delay "
+ "value: '%s'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
case 'e':
if (strcasecmp(optarg, "io") == 0) {
error = EIO;
@@ -693,6 +703,7 @@ main(int argc, char **argv)
case 'p':
(void) strlcpy(record.zi_func, optarg,
sizeof (record.zi_func));
+ record.zi_cmd = ZINJECT_PANIC;
break;
case 'q':
quiet = 1;
@@ -766,13 +777,15 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ if (record.zi_duration != 0)
+ record.zi_cmd = ZINJECT_IGNORED_WRITES;
+
if (cancel != NULL) {
/*
* '-c' is invalid with any other options.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
- level != 0 || record.zi_func[0] != '\0' ||
- record.zi_duration != 0) {
+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
(void) fprintf(stderr, "cancel (-c) incompatible with "
"any other options\n");
usage();
@@ -804,8 +817,7 @@ main(int argc, char **argv)
* for doing injection, so handle it separately here.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
- level != 0 || record.zi_func[0] != '\0' ||
- record.zi_duration != 0) {
+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
(void) fprintf(stderr, "device (-d) incompatible with "
"data error injection\n");
usage();
@@ -839,7 +851,7 @@ main(int argc, char **argv)
} else if (raw != NULL) {
if (range != NULL || type != TYPE_INVAL || level != 0 ||
- record.zi_func[0] != '\0' || record.zi_duration != 0) {
+ record.zi_cmd != ZINJECT_UNINITIALIZED) {
(void) fprintf(stderr, "raw (-b) format with "
"any other options\n");
usage();
@@ -862,13 +874,14 @@ main(int argc, char **argv)
return (1);
}
+ record.zi_cmd = ZINJECT_DATA_FAULT;
if (translate_raw(raw, &record) != 0)
return (1);
if (!error)
error = EIO;
- } else if (record.zi_func[0] != '\0') {
+ } else if (record.zi_cmd == ZINJECT_PANIC) {
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
- level != 0 || device != NULL || record.zi_duration != 0) {
+ level != 0 || device != NULL) {
(void) fprintf(stderr, "panic (-p) incompatible with "
"other options\n");
usage();
@@ -886,7 +899,7 @@ main(int argc, char **argv)
if (argv[1] != NULL)
record.zi_type = atoi(argv[1]);
dataset[0] = '\0';
- } else if (record.zi_duration != 0) {
+ } else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) {
if (nowrites == 0) {
(void) fprintf(stderr, "-s or -g meaningless "
"without -I (ignore writes)\n");
@@ -940,6 +953,7 @@ main(int argc, char **argv)
return (1);
}
+ record.zi_cmd = ZINJECT_DATA_FAULT;
if (translate_record(type, argv[0], range, level, &record, pool,
dataset) != 0)
return (1);
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
index 999212c16a0a..c1ac479d939e 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
@@ -18,10 +18,11 @@
.\" information: Portions Copyright [yyyy] [name of copyright owner]
.\"
.\" Copyright (c) 2012 by Delphix. All rights reserved.
+.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
.\"
.\" $FreeBSD$
.\"
-.Dd Aug 28, 2012
+.Dd February 8, 2013
.Dt ZPOOL-FEATURES 7
.Os
.Sh NAME
@@ -185,6 +186,49 @@ This feature is
.Sy active
while there are any filesystems, volumes, or snapshots which were created
after enabling this feature.
+.It Sy lz4_compress
+.Bl -column "READ\-ONLY COMPATIBLE" "org.illumos:lz4_compress"
+.It GUID Ta org.illumos:lz4_compress
+.It READ\-ONLY COMPATIBLE Ta no
+.It DEPENDENCIES Ta none
+.El
+.Pp
+.Sy lz4
+is a high-performance real-time compression algorithm that
+features significantly faster compression and decompression as well as a
+higher compression ratio than the older
+.Sy lzjb
+compression.
+Typically,
+.Sy lz4
+compression is approximately 50% faster on
+compressible data and 200% faster on incompressible data than
+.Sy lzjb .
+It is also approximately 80% faster on decompression, while
+giving approximately 10% better compression ratio.
+.Pp
+When the
+.Sy lz4_compress
+feature is set to
+.Sy enabled ,
+the
+administrator can turn on
+.Sy lz4
+compression on any dataset on the
+pool using the
+.Xr zfs 8
+command. Please note that doing so will
+immediately activate the
+.Sy lz4_compress
+feature on the underlying
+pool (even before any data is written). Since this feature is not
+read-only compatible, this operation will render the pool unimportable
+on systems without support for the
+.Sy lz4_compress
+feature. At the
+moment, this operation cannot be reversed. Booting off of
+.Sy lz4
+-compressed root pools is supported.
.El
.Sh SEE ALSO
.Xr zpool 8
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
index 4c82741ab0e1..715439b22a08 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 15, 2012
+.Dd March 14, 2013
.Dt ZPOOL 8
.Os
.Sh NAME
@@ -1608,14 +1608,15 @@ is specified, the command exits after
.Ar count
reports are printed.
.Pp
-If a scrub or resilver is in progress, this command reports the percentage done
-and the estimated time to completion. Both of these are only approximate,
+If a scrub or resilver is in progress, this command reports the percentage
+done and the estimated time to completion. Both of these are only approximate,
because the amount of data in the pool and the other workloads on the system
can change.
.Bl -tag -width indent
.It Fl x
Only display status for pools that are exhibiting errors or are otherwise
unavailable.
+Warnings about pools not using the latest on-disk format will not be included.
.It Fl v
Displays verbose data error information, printing out a complete list of all
data errors since the last complete pool scrub.
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index dd6c90ba0578..7e0fa18e9f7c 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -192,9 +192,9 @@ static zpool_command_t command_table[] = {
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
-zpool_command_t *current_command;
+static zpool_command_t *current_command;
static char history_str[HIS_MAX_RECORD_LEN];
-
+static boolean_t log_history = B_TRUE;
static uint_t timestamp_fmt = NODATE;
static const char *
@@ -1093,7 +1093,10 @@ zpool_do_destroy(int argc, char **argv)
return (1);
}
- ret = (zpool_destroy(zhp) != 0);
+ /* The history must be logged as part of the export */
+ log_history = B_FALSE;
+
+ ret = (zpool_destroy(zhp, history_str) != 0);
zpool_close(zhp);
@@ -1157,10 +1160,13 @@ zpool_do_export(int argc, char **argv)
continue;
}
+ /* The history must be logged as part of the export */
+ log_history = B_FALSE;
+
if (hardforce) {
- if (zpool_export_force(zhp) != 0)
+ if (zpool_export_force(zhp, history_str) != 0)
ret = 1;
- } else if (zpool_export(zhp, force) != 0) {
+ } else if (zpool_export(zhp, force, history_str) != 0) {
ret = 1;
}
@@ -4031,7 +4037,10 @@ status_callback(zpool_handle_t *zhp, void *data)
* If we were given 'zpool status -x', only report those pools with
* problems.
*/
- if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
+ if (cbp->cb_explain &&
+ (reason == ZPOOL_STATUS_OK ||
+ reason == ZPOOL_STATUS_VERSION_OLDER ||
+ reason == ZPOOL_STATUS_FEAT_DISABLED)) {
if (!cbp->cb_allpools) {
(void) printf(gettext("pool '%s' is healthy\n"),
zpool_get_name(zhp));
@@ -4560,6 +4569,14 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
if (count > 0) {
cbp->cb_first = B_FALSE;
printnl = B_TRUE;
+ /*
+ * If they did "zpool upgrade -a", then we could
+ * be doing ioctls to different pools. We need
+ * to log this history once to each pool, and bypass
+ * the normal history logging that happens in main().
+ */
+ (void) zpool_log_history(g_zfs, history_str);
+ log_history = B_FALSE;
}
}
@@ -4921,8 +4938,8 @@ zpool_do_upgrade(int argc, char **argv)
typedef struct hist_cbdata {
boolean_t first;
- int longfmt;
- int internal;
+ boolean_t longfmt;
+ boolean_t internal;
} hist_cbdata_t;
/*
@@ -4934,21 +4951,8 @@ get_history_one(zpool_handle_t *zhp, void *data)
nvlist_t *nvhis;
nvlist_t **records;
uint_t numrecords;
- char *cmdstr;
- char *pathstr;
- uint64_t dst_time;
- time_t tsec;
- struct tm t;
- char tbuf[30];
int ret, i;
- uint64_t who;
- struct passwd *pwd;
- char *hostname;
- char *zonename;
- char internalstr[MAXPATHLEN];
hist_cbdata_t *cb = (hist_cbdata_t *)data;
- uint64_t txg;
- uint64_t ievent;
cb->first = B_FALSE;
@@ -4960,64 +4964,94 @@ get_history_one(zpool_handle_t *zhp, void *data)
verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
&records, &numrecords) == 0);
for (i = 0; i < numrecords; i++) {
- if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
- &dst_time) != 0)
- continue;
+ nvlist_t *rec = records[i];
+ char tbuf[30] = "";
- /* is it an internal event or a standard event? */
- if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
- &cmdstr) != 0) {
- if (cb->internal == 0)
- continue;
+ if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
+ time_t tsec;
+ struct tm t;
+
+ tsec = fnvlist_lookup_uint64(records[i],
+ ZPOOL_HIST_TIME);
+ (void) localtime_r(&tsec, &t);
+ (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
+ }
- if (nvlist_lookup_uint64(records[i],
- ZPOOL_HIST_INT_EVENT, &ievent) != 0)
+ if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
+ (void) printf("%s %s", tbuf,
+ fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
+ } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
+ int ievent =
+ fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
+ if (!cb->internal)
+ continue;
+ if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
+ (void) printf("%s unrecognized record:\n",
+ tbuf);
+ dump_nvlist(rec, 4);
+ continue;
+ }
+ (void) printf("%s [internal %s txg:%lld] %s", tbuf,
+ zfs_history_event_names[ievent],
+ fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
+ fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
+ } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
+ if (!cb->internal)
continue;
- verify(nvlist_lookup_uint64(records[i],
- ZPOOL_HIST_TXG, &txg) == 0);
- verify(nvlist_lookup_string(records[i],
- ZPOOL_HIST_INT_STR, &pathstr) == 0);
- if (ievent >= LOG_END)
+ (void) printf("%s [txg:%lld] %s", tbuf,
+ fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
+ fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
+ if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
+ (void) printf(" %s (%llu)",
+ fnvlist_lookup_string(rec,
+ ZPOOL_HIST_DSNAME),
+ fnvlist_lookup_uint64(rec,
+ ZPOOL_HIST_DSID));
+ }
+ (void) printf(" %s", fnvlist_lookup_string(rec,
+ ZPOOL_HIST_INT_STR));
+ } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
+ if (!cb->internal)
continue;
- (void) snprintf(internalstr,
- sizeof (internalstr),
- "[internal %s txg:%lld] %s",
- zfs_history_event_names[ievent], txg,
- pathstr);
- cmdstr = internalstr;
+ (void) printf("%s ioctl %s\n", tbuf,
+ fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
+ if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
+ (void) printf(" input:\n");
+ dump_nvlist(fnvlist_lookup_nvlist(rec,
+ ZPOOL_HIST_INPUT_NVL), 8);
+ }
+ if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
+ (void) printf(" output:\n");
+ dump_nvlist(fnvlist_lookup_nvlist(rec,
+ ZPOOL_HIST_OUTPUT_NVL), 8);
+ }
+ } else {
+ if (!cb->internal)
+ continue;
+ (void) printf("%s unrecognized record:\n", tbuf);
+ dump_nvlist(rec, 4);
}
- tsec = dst_time;
- (void) localtime_r(&tsec, &t);
- (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
- (void) printf("%s %s", tbuf, cmdstr);
if (!cb->longfmt) {
(void) printf("\n");
continue;
}
(void) printf(" [");
- if (nvlist_lookup_uint64(records[i],
- ZPOOL_HIST_WHO, &who) == 0) {
- pwd = getpwuid((uid_t)who);
- if (pwd)
- (void) printf("user %s on",
- pwd->pw_name);
- else
- (void) printf("user %d on",
- (int)who);
- } else {
- (void) printf(gettext("no info]\n"));
- continue;
+ if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
+ uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
+ struct passwd *pwd = getpwuid(who);
+ (void) printf("user %d ", (int)who);
+ if (pwd != NULL)
+ (void) printf("(%s) ", pwd->pw_name);
}
- if (nvlist_lookup_string(records[i],
- ZPOOL_HIST_HOST, &hostname) == 0) {
- (void) printf(" %s", hostname);
+ if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
+ (void) printf("on %s",
+ fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
}
- if (nvlist_lookup_string(records[i],
- ZPOOL_HIST_ZONE, &zonename) == 0) {
- (void) printf(":%s", zonename);
+ if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
+ (void) printf(":%s",
+ fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
}
-
(void) printf("]");
(void) printf("\n");
}
@@ -5032,8 +5066,6 @@ get_history_one(zpool_handle_t *zhp, void *data)
*
* Displays the history of commands that modified pools.
*/
-
-
int
zpool_do_history(int argc, char **argv)
{
@@ -5046,10 +5078,10 @@ zpool_do_history(int argc, char **argv)
while ((c = getopt(argc, argv, "li")) != -1) {
switch (c) {
case 'l':
- cbdata.longfmt = 1;
+ cbdata.longfmt = B_TRUE;
break;
case 'i':
- cbdata.internal = 1;
+ cbdata.internal = B_TRUE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
@@ -5274,8 +5306,7 @@ main(int argc, char **argv)
if (strcmp(cmdname, "-?") == 0)
usage(B_TRUE);
- zpool_set_history_str("zpool", argc, argv, history_str);
- verify(zpool_stage_history(g_zfs, history_str) == 0);
+ zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
/*
* Run the appropriate command.
@@ -5302,6 +5333,9 @@ main(int argc, char **argv)
usage(B_FALSE);
}
+ if (ret == 0 && log_history)
+ (void) zpool_log_history(g_zfs, history_str);
+
libzfs_fini(g_zfs);
/*
diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
index 9c38b3f34348..ef776a4c7b3f 100644
--- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c
+++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
@@ -104,10 +104,12 @@
#include <sys/metaslab_impl.h>
#include <sys/dsl_prop.h>
#include <sys/dsl_dataset.h>
+#include <sys/dsl_destroy.h>
#include <sys/dsl_scan.h>
#include <sys/zio_checksum.h>
#include <sys/refcount.h>
#include <sys/zfeature.h>
+#include <sys/dsl_userhold.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
@@ -367,7 +369,7 @@ ztest_info_t ztest_info[] = {
{ ztest_scrub, 1, &zopt_rarely },
{ ztest_spa_upgrade, 1, &zopt_rarely },
{ ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
- { ztest_vdev_attach_detach, 1, &zopt_rarely },
+ { ztest_vdev_attach_detach, 1, &zopt_sometimes },
{ ztest_vdev_LUN_growth, 1, &zopt_rarely },
{ ztest_vdev_add_remove, 1,
&ztest_opts.zo_vdevtime },
@@ -1008,9 +1010,8 @@ ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value,
uint64_t curval;
int error;
- error = dsl_prop_set(osname, propname,
- (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL),
- sizeof (value), 1, &value);
+ error = dsl_prop_set_int(osname, propname,
+ (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), value);
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
@@ -1018,8 +1019,7 @@ ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value,
}
ASSERT0(error);
- VERIFY3U(dsl_prop_get(osname, propname, sizeof (curval),
- 1, &curval, setpoint), ==, 0);
+ VERIFY0(dsl_prop_get_integer(osname, propname, &curval, setpoint));
if (ztest_opts.zo_verbose >= 6) {
VERIFY(zfs_prop_index_to_string(prop, curval, &valname) == 0);
@@ -2332,7 +2332,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
*/
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
VERIFY3U(ENOENT, ==,
- spa_create("ztest_bad_file", nvroot, NULL, NULL, NULL));
+ spa_create("ztest_bad_file", nvroot, NULL, NULL));
nvlist_free(nvroot);
/*
@@ -2340,7 +2340,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
*/
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 2, 1);
VERIFY3U(ENOENT, ==,
- spa_create("ztest_bad_mirror", nvroot, NULL, NULL, NULL));
+ spa_create("ztest_bad_mirror", nvroot, NULL, NULL));
nvlist_free(nvroot);
/*
@@ -2349,7 +2349,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
*/
(void) rw_rdlock(&ztest_name_lock);
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
- VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL, NULL));
+ VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL));
nvlist_free(nvroot);
VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
VERIFY3U(EBUSY, ==, spa_destroy(zo->zo_pool));
@@ -2407,7 +2407,7 @@ ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
props = fnvlist_alloc();
fnvlist_add_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), version);
- VERIFY0(spa_create(name, nvroot, props, NULL, NULL));
+ VERIFY0(spa_create(name, nvroot, props, NULL));
fnvlist_free(nvroot);
fnvlist_free(props);
@@ -2481,8 +2481,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
int error;
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
- leaves =
- MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz;
+ leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz;
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
@@ -3182,7 +3181,7 @@ ztest_objset_destroy_cb(const char *name, void *arg)
/*
* Verify that the dataset contains a directory object.
*/
- VERIFY3U(0, ==, dmu_objset_hold(name, FTAG, &os));
+ VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, FTAG, &os));
error = dmu_object_info(os, ZTEST_DIROBJ, &doi);
if (error != ENOENT) {
/* We could have crashed in the middle of destroying it */
@@ -3190,12 +3189,16 @@ ztest_objset_destroy_cb(const char *name, void *arg)
ASSERT3U(doi.doi_type, ==, DMU_OT_ZAP_OTHER);
ASSERT3S(doi.doi_physical_blocks_512, >=, 0);
}
- dmu_objset_rele(os, FTAG);
+ dmu_objset_disown(os, FTAG);
/*
* Destroy the dataset.
*/
- VERIFY3U(0, ==, dmu_objset_destroy(name, B_FALSE));
+ if (strchr(name, '@') != NULL) {
+ VERIFY0(dsl_destroy_snapshot(name, B_FALSE));
+ } else {
+ VERIFY0(dsl_destroy_head(name));
+ }
return (0);
}
@@ -3205,17 +3208,17 @@ ztest_snapshot_create(char *osname, uint64_t id)
char snapname[MAXNAMELEN];
int error;
- (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname,
- (u_longlong_t)id);
+ (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id);
- error = dmu_objset_snapshot(osname, strchr(snapname, '@') + 1,
- NULL, NULL, B_FALSE, B_FALSE, -1);
+ error = dmu_objset_snapshot_one(osname, snapname);
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
return (B_FALSE);
}
- if (error != 0 && error != EEXIST)
- fatal(0, "ztest_snapshot_create(%s) = %d", snapname, error);
+ if (error != 0 && error != EEXIST) {
+ fatal(0, "ztest_snapshot_create(%s@%s) = %d", osname,
+ snapname, error);
+ }
return (B_TRUE);
}
@@ -3228,7 +3231,7 @@ ztest_snapshot_destroy(char *osname, uint64_t id)
(void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname,
(u_longlong_t)id);
- error = dmu_objset_destroy(snapname, B_FALSE);
+ error = dsl_destroy_snapshot(snapname, B_FALSE);
if (error != 0 && error != ENOENT)
fatal(0, "ztest_snapshot_destroy(%s) = %d", snapname, error);
return (B_TRUE);
@@ -3274,7 +3277,8 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
/*
* Verify that the destroyed dataset is no longer in the namespace.
*/
- VERIFY3U(ENOENT, ==, dmu_objset_hold(name, FTAG, &os));
+ VERIFY3U(ENOENT, ==, dmu_objset_own(name, DMU_OST_OTHER, B_TRUE,
+ FTAG, &os));
/*
* Verify that we can create a new dataset.
@@ -3289,8 +3293,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_objset_create(%s) = %d", name, error);
}
- VERIFY3U(0, ==,
- dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os));
+ VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os));
ztest_zd_init(&zdtmp, NULL, os);
@@ -3366,21 +3369,21 @@ ztest_dsl_dataset_cleanup(char *osname, uint64_t id)
(void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id);
(void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id);
- error = dmu_objset_destroy(clone2name, B_FALSE);
+ error = dsl_destroy_head(clone2name);
if (error && error != ENOENT)
- fatal(0, "dmu_objset_destroy(%s) = %d", clone2name, error);
- error = dmu_objset_destroy(snap3name, B_FALSE);
+ fatal(0, "dsl_destroy_head(%s) = %d", clone2name, error);
+ error = dsl_destroy_snapshot(snap3name, B_FALSE);
if (error && error != ENOENT)
- fatal(0, "dmu_objset_destroy(%s) = %d", snap3name, error);
- error = dmu_objset_destroy(snap2name, B_FALSE);
+ fatal(0, "dsl_destroy_snapshot(%s) = %d", snap3name, error);
+ error = dsl_destroy_snapshot(snap2name, B_FALSE);
if (error && error != ENOENT)
- fatal(0, "dmu_objset_destroy(%s) = %d", snap2name, error);
- error = dmu_objset_destroy(clone1name, B_FALSE);
+ fatal(0, "dsl_destroy_snapshot(%s) = %d", snap2name, error);
+ error = dsl_destroy_head(clone1name);
if (error && error != ENOENT)
- fatal(0, "dmu_objset_destroy(%s) = %d", clone1name, error);
- error = dmu_objset_destroy(snap1name, B_FALSE);
+ fatal(0, "dsl_destroy_head(%s) = %d", clone1name, error);
+ error = dsl_destroy_snapshot(snap1name, B_FALSE);
if (error && error != ENOENT)
- fatal(0, "dmu_objset_destroy(%s) = %d", snap1name, error);
+ fatal(0, "dsl_destroy_snapshot(%s) = %d", snap1name, error);
}
/*
@@ -3389,8 +3392,7 @@ ztest_dsl_dataset_cleanup(char *osname, uint64_t id)
void
ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
{
- objset_t *clone;
- dsl_dataset_t *ds;
+ objset_t *os;
char snap1name[MAXNAMELEN];
char clone1name[MAXNAMELEN];
char snap2name[MAXNAMELEN];
@@ -3409,8 +3411,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
(void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id);
(void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id);
- error = dmu_objset_snapshot(osname, strchr(snap1name, '@')+1,
- NULL, NULL, B_FALSE, B_FALSE, -1);
+ error = dmu_objset_snapshot_one(osname, strchr(snap1name, '@') + 1);
if (error && error != EEXIST) {
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
@@ -3419,12 +3420,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error);
}
- error = dmu_objset_hold(snap1name, FTAG, &clone);
- if (error)
- fatal(0, "dmu_open_snapshot(%s) = %d", snap1name, error);
-
- error = dmu_objset_clone(clone1name, dmu_objset_ds(clone), 0);
- dmu_objset_rele(clone, FTAG);
+ error = dmu_objset_clone(clone1name, snap1name);
if (error) {
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
@@ -3433,8 +3429,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_objset_create(%s) = %d", clone1name, error);
}
- error = dmu_objset_snapshot(clone1name, strchr(snap2name, '@')+1,
- NULL, NULL, B_FALSE, B_FALSE, -1);
+ error = dmu_objset_snapshot_one(clone1name, strchr(snap2name, '@') + 1);
if (error && error != EEXIST) {
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
@@ -3443,8 +3438,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_open_snapshot(%s) = %d", snap2name, error);
}
- error = dmu_objset_snapshot(clone1name, strchr(snap3name, '@')+1,
- NULL, NULL, B_FALSE, B_FALSE, -1);
+ error = dmu_objset_snapshot_one(clone1name, strchr(snap3name, '@') + 1);
if (error && error != EEXIST) {
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
@@ -3453,12 +3447,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error);
}
- error = dmu_objset_hold(snap3name, FTAG, &clone);
- if (error)
- fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error);
-
- error = dmu_objset_clone(clone2name, dmu_objset_ds(clone), 0);
- dmu_objset_rele(clone, FTAG);
+ error = dmu_objset_clone(clone2name, snap3name);
if (error) {
if (error == ENOSPC) {
ztest_record_enospc(FTAG);
@@ -3467,14 +3456,14 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_objset_create(%s) = %d", clone2name, error);
}
- error = dsl_dataset_own(snap2name, B_FALSE, FTAG, &ds);
+ error = dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, FTAG, &os);
if (error)
- fatal(0, "dsl_dataset_own(%s) = %d", snap2name, error);
+ fatal(0, "dmu_objset_own(%s) = %d", snap2name, error);
error = dsl_dataset_promote(clone2name, NULL);
if (error != EBUSY)
fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name,
error);
- dsl_dataset_disown(ds, FTAG);
+ dmu_objset_disown(os, FTAG);
out:
ztest_dsl_dataset_cleanup(osname, id);
@@ -4286,7 +4275,7 @@ ztest_zap_parallel(ztest_ds_t *zd, uint64_t id)
}
count = -1ULL;
- VERIFY(zap_count(os, object, &count) == 0);
+ VERIFY0(zap_count(os, object, &count));
ASSERT(count != -1ULL);
/*
@@ -4597,6 +4586,22 @@ ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id)
(void) rw_unlock(&ztest_name_lock);
}
+static int
+user_release_one(const char *snapname, const char *holdname)
+{
+ nvlist_t *snaps, *holds;
+ int error;
+
+ snaps = fnvlist_alloc();
+ holds = fnvlist_alloc();
+ fnvlist_add_boolean(holds, holdname);
+ fnvlist_add_nvlist(snaps, snapname, holds);
+ fnvlist_free(holds);
+ error = dsl_dataset_user_release(snaps, NULL);
+ fnvlist_free(snaps);
+ return (error);
+}
+
/*
* Test snapshot hold/release and deferred destroy.
*/
@@ -4611,29 +4616,36 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
char clonename[100];
char tag[100];
char osname[MAXNAMELEN];
+ nvlist_t *holds;
(void) rw_rdlock(&ztest_name_lock);
dmu_objset_name(os, osname);
- (void) snprintf(snapname, 100, "sh1_%llu", id);
- (void) snprintf(fullname, 100, "%s@%s", osname, snapname);
- (void) snprintf(clonename, 100, "%s/ch1_%llu", osname, id);
- (void) snprintf(tag, 100, "%tag_%llu", id);
+ (void) snprintf(snapname, sizeof (snapname), "sh1_%llu", id);
+ (void) snprintf(fullname, sizeof (fullname), "%s@%s", osname, snapname);
+ (void) snprintf(clonename, sizeof (clonename),
+ "%s/ch1_%llu", osname, id);
+ (void) snprintf(tag, sizeof (tag), "tag_%llu", id);
/*
* Clean up from any previous run.
*/
- (void) dmu_objset_destroy(clonename, B_FALSE);
- (void) dsl_dataset_user_release(osname, snapname, tag, B_FALSE);
- (void) dmu_objset_destroy(fullname, B_FALSE);
+ error = dsl_destroy_head(clonename);
+ if (error != ENOENT)
+ ASSERT0(error);
+ error = user_release_one(fullname, tag);
+ if (error != ESRCH && error != ENOENT)
+ ASSERT0(error);
+ error = dsl_destroy_snapshot(fullname, B_FALSE);
+ if (error != ENOENT)
+ ASSERT0(error);
/*
* Create snapshot, clone it, mark snap for deferred destroy,
* destroy clone, verify snap was also destroyed.
*/
- error = dmu_objset_snapshot(osname, snapname, NULL, NULL, FALSE,
- FALSE, -1);
+ error = dmu_objset_snapshot_one(osname, snapname);
if (error) {
if (error == ENOSPC) {
ztest_record_enospc("dmu_objset_snapshot");
@@ -4642,12 +4654,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
}
- error = dmu_objset_hold(fullname, FTAG, &origin);
- if (error)
- fatal(0, "dmu_objset_hold(%s) = %d", fullname, error);
-
- error = dmu_objset_clone(clonename, dmu_objset_ds(origin), 0);
- dmu_objset_rele(origin, FTAG);
+ error = dmu_objset_clone(clonename, fullname);
if (error) {
if (error == ENOSPC) {
ztest_record_enospc("dmu_objset_clone");
@@ -4656,15 +4663,15 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_objset_clone(%s) = %d", clonename, error);
}
- error = dmu_objset_destroy(fullname, B_TRUE);
+ error = dsl_destroy_snapshot(fullname, B_TRUE);
if (error) {
- fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d",
+ fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d",
fullname, error);
}
- error = dmu_objset_destroy(clonename, B_FALSE);
+ error = dsl_destroy_head(clonename);
if (error)
- fatal(0, "dmu_objset_destroy(%s) = %d", clonename, error);
+ fatal(0, "dsl_destroy_head(%s) = %d", clonename, error);
error = dmu_objset_hold(fullname, FTAG, &origin);
if (error != ENOENT)
@@ -4675,8 +4682,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
* destroy a held snapshot, mark for deferred destroy,
* release hold, verify snapshot was destroyed.
*/
- error = dmu_objset_snapshot(osname, snapname, NULL, NULL, FALSE,
- FALSE, -1);
+ error = dmu_objset_snapshot_one(osname, snapname);
if (error) {
if (error == ENOSPC) {
ztest_record_enospc("dmu_objset_snapshot");
@@ -4685,28 +4691,31 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
}
- error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE,
- B_TRUE, -1);
+ holds = fnvlist_alloc();
+ fnvlist_add_string(holds, fullname, tag);
+ error = dsl_dataset_user_hold(holds, 0, NULL);
+ fnvlist_free(holds);
+
if (error)
fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag);
- error = dmu_objset_destroy(fullname, B_FALSE);
+ error = dsl_destroy_snapshot(fullname, B_FALSE);
if (error != EBUSY) {
- fatal(0, "dmu_objset_destroy(%s, B_FALSE) = %d",
+ fatal(0, "dsl_destroy_snapshot(%s, B_FALSE) = %d",
fullname, error);
}
- error = dmu_objset_destroy(fullname, B_TRUE);
+ error = dsl_destroy_snapshot(fullname, B_TRUE);
if (error) {
- fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d",
+ fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d",
fullname, error);
}
- error = dsl_dataset_user_release(osname, snapname, tag, B_FALSE);
+ error = user_release_one(fullname, tag);
if (error)
- fatal(0, "dsl_dataset_user_release(%s)", fullname, tag);
+ fatal(0, "user_release_one(%s)", fullname, tag);
- VERIFY(dmu_objset_hold(fullname, FTAG, &origin) == ENOENT);
+ VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT);
out:
(void) rw_unlock(&ztest_name_lock);
@@ -4960,8 +4969,12 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
*/
for (int i = 0; i < copies; i++) {
uint64_t offset = i * blocksize;
- VERIFY0(dmu_buf_hold(os, object, offset, FTAG, &db,
- DMU_READ_NO_PREFETCH));
+ int error = dmu_buf_hold(os, object, offset, FTAG, &db,
+ DMU_READ_NO_PREFETCH);
+ if (error != 0) {
+ fatal(B_FALSE, "dmu_buf_hold(%p, %llu, %llu) = %u",
+ os, (long long)object, (long long) offset, error);
+ }
ASSERT(db->db_offset == offset);
ASSERT(db->db_size == blocksize);
ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) ||
@@ -5172,6 +5185,7 @@ ztest_spa_import_export(char *oldname, char *newname)
nvlist_t *config, *newconfig;
uint64_t pool_guid;
spa_t *spa;
+ int error;
if (ztest_opts.zo_verbose >= 4) {
(void) printf("import/export: old = %s, new = %s\n",
@@ -5216,7 +5230,12 @@ ztest_spa_import_export(char *oldname, char *newname)
/*
* Import it under the new name.
*/
- VERIFY3U(0, ==, spa_import(newname, config, NULL, 0));
+ error = spa_import(newname, config, NULL, 0);
+ if (error != 0) {
+ dump_nvlist(config, 0);
+ fatal(B_FALSE, "couldn't import pool %s as %s: error %u",
+ oldname, newname, error);
+ }
ztest_walk_pool_directory("pools after import");
@@ -5423,7 +5442,7 @@ ztest_dataset_open(int d)
}
ASSERT(error == 0 || error == EEXIST);
- VERIFY0(dmu_objset_hold(name, zd, &os));
+ VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, zd, &os));
(void) rw_unlock(&ztest_name_lock);
ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os);
@@ -5464,7 +5483,7 @@ ztest_dataset_close(int d)
ztest_ds_t *zd = &ztest_ds[d];
zil_close(zd->zd_zilog);
- dmu_objset_rele(zd->zd_os, zd);
+ dmu_objset_disown(zd->zd_os, zd);
ztest_zd_fini(zd);
}
@@ -5508,13 +5527,14 @@ ztest_run(ztest_shared_t *zs)
* Open our pool.
*/
kernel_init(FREAD | FWRITE);
- VERIFY(spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0);
+ VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
spa->spa_debug = B_TRUE;
ztest_spa = spa;
- VERIFY3U(0, ==, dmu_objset_hold(ztest_opts.zo_pool, FTAG, &os));
+ VERIFY0(dmu_objset_own(ztest_opts.zo_pool,
+ DMU_OST_ANY, B_TRUE, FTAG, &os));
zs->zs_guid = dmu_objset_fsid_guid(os);
- dmu_objset_rele(os, FTAG);
+ dmu_objset_disown(os, FTAG);
spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN;
@@ -5791,8 +5811,7 @@ ztest_init(ztest_shared_t *zs)
spa_feature_table[i].fi_uname);
VERIFY3U(0, ==, nvlist_add_uint64(props, buf, 0));
}
- VERIFY3U(0, ==, spa_create(ztest_opts.zo_pool, nvroot, props,
- NULL, NULL));
+ VERIFY3U(0, ==, spa_create(ztest_opts.zo_pool, nvroot, props, NULL));
nvlist_free(nvroot);
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
index 42b66458d477..b0f2b4a1af32 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
@@ -26,6 +26,7 @@
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <stdlib.h>
@@ -894,33 +895,14 @@ dt_aggregate_valcmp(const void *lhs, const void *rhs)
caddr_t rdata = rh->dtahe_data.dtada_data;
dtrace_recdesc_t *lrec, *rrec;
int64_t *laddr, *raddr;
- int rval, i;
-
- if ((rval = dt_aggregate_hashcmp(lhs, rhs)) != 0)
- return (rval);
-
- if (lagg->dtagd_nrecs > ragg->dtagd_nrecs)
- return (DT_GREATERTHAN);
-
- if (lagg->dtagd_nrecs < ragg->dtagd_nrecs)
- return (DT_LESSTHAN);
+ int rval;
- for (i = 0; i < lagg->dtagd_nrecs; i++) {
- lrec = &lagg->dtagd_rec[i];
- rrec = &ragg->dtagd_rec[i];
+ assert(lagg->dtagd_nrecs == ragg->dtagd_nrecs);
- if (lrec->dtrd_offset < rrec->dtrd_offset)
- return (DT_LESSTHAN);
-
- if (lrec->dtrd_offset > rrec->dtrd_offset)
- return (DT_GREATERTHAN);
+ lrec = &lagg->dtagd_rec[lagg->dtagd_nrecs - 1];
+ rrec = &ragg->dtagd_rec[ragg->dtagd_nrecs - 1];
- if (lrec->dtrd_action < rrec->dtrd_action)
- return (DT_LESSTHAN);
-
- if (lrec->dtrd_action > rrec->dtrd_action)
- return (DT_GREATERTHAN);
- }
+ assert(lrec->dtrd_action == rrec->dtrd_action);
laddr = (int64_t *)(uintptr_t)(ldata + lrec->dtrd_offset);
raddr = (int64_t *)(uintptr_t)(rdata + rrec->dtrd_offset);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
index d5423f634d6f..57009935f937 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -663,18 +664,48 @@ static void
dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
{
dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+ boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE);
+ const char *act = istrace ? "trace" : "print";
if (dt_node_is_void(dnp->dn_args)) {
- dnerror(dnp->dn_args, D_TRACE_VOID,
- "trace( ) may not be applied to a void expression\n");
+ dnerror(dnp->dn_args, istrace ? D_TRACE_VOID : D_PRINT_VOID,
+ "%s( ) may not be applied to a void expression\n", act);
}
- if (dt_node_is_dynamic(dnp->dn_args)) {
- dnerror(dnp->dn_args, D_TRACE_DYN,
- "trace( ) may not be applied to a dynamic expression\n");
+ if (dt_node_resolve(dnp->dn_args, DT_IDENT_XLPTR) != NULL) {
+ dnerror(dnp->dn_args, istrace ? D_TRACE_DYN : D_PRINT_DYN,
+ "%s( ) may not be applied to a translated pointer\n", act);
}
dt_cg(yypcb, dnp->dn_args);
+
+ /*
+ * The print() action behaves identically to trace(), except that it
+ * stores the CTF type of the argument (if present) within the DOF for
+ * the DIFEXPR action. To do this, we set the 'dtsd_strdata' to point
+ * to the fully-qualified CTF type ID for the result of the DIF
+ * action. We use the ID instead of the name to handles complex types
+ * like arrays and function pointers that can't be resolved by
+ * ctf_type_lookup(). This is later processed by dtrace_dof_create()
+ * and turned into a reference into the string table so that we can
+ * get the type information when we process the data after the fact.
+ */
+ if (dnp->dn_ident->di_id == DT_ACT_PRINT) {
+ dt_node_t *dret;
+ size_t n;
+ dt_module_t *dmp;
+
+ dret = yypcb->pcb_dret;
+ dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
+
+ n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name, dret->dn_type) + 1;
+ sdp->dtsd_strdata = dt_alloc(dtp, n);
+ if (sdp->dtsd_strdata == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ (void) snprintf(sdp->dtsd_strdata, n, "%s`%ld", dmp->dm_name,
+ dret->dn_type);
+ }
+
ap->dtad_difo = dt_as(yypcb);
ap->dtad_kind = DTRACEACT_DIFEXPR;
}
@@ -685,7 +716,8 @@ dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
dt_node_t *addr = dnp->dn_args;
- dt_node_t *size = dnp->dn_args->dn_list;
+ dt_node_t *max = dnp->dn_args->dn_list;
+ dt_node_t *size;
char n[DT_TYPE_NAMELEN];
@@ -697,17 +729,37 @@ dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dt_node_type_name(addr, n, sizeof (n)));
}
- if (dt_node_is_posconst(size) == 0) {
- dnerror(size, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
+ if (dt_node_is_posconst(max) == 0) {
+ dnerror(max, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
"be a non-zero positive integral constant expression\n");
}
+ if ((size = max->dn_list) != NULL) {
+ if (size->dn_list != NULL) {
+ dnerror(size, D_TRACEMEM_ARGS, "tracemem ( ) prototype "
+ "mismatch: expected at most 3 args\n");
+ }
+
+ if (!dt_node_is_scalar(size)) {
+ dnerror(size, D_TRACEMEM_DYNSIZE, "tracemem ( ) "
+ "dynamic size (argument #3) must be of "
+ "scalar type\n");
+ }
+
+ dt_cg(yypcb, size);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_difo->dtdo_rtype = dt_int_rtype;
+ ap->dtad_kind = DTRACEACT_TRACEMEM_DYNSIZE;
+
+ ap = dt_stmt_action(dtp, sdp);
+ }
+
dt_cg(yypcb, addr);
ap->dtad_difo = dt_as(yypcb);
- ap->dtad_kind = DTRACEACT_DIFEXPR;
+ ap->dtad_kind = DTRACEACT_TRACEMEM;
ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
- ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = max->dn_value;
}
static void
@@ -1078,6 +1130,9 @@ dt_compile_fun(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
case DT_ACT_PANIC:
dt_action_panic(dtp, dnp->dn_expr, sdp);
break;
+ case DT_ACT_PRINT:
+ dt_action_trace(dtp, dnp->dn_expr, sdp);
+ break;
case DT_ACT_PRINTA:
dt_action_printa(dtp, dnp->dn_expr, sdp);
break;
@@ -2489,7 +2544,8 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
}
out:
- if (context != DT_CTX_DTYPE && DT_TREEDUMP_PASS(dtp, 3))
+ if (context != DT_CTX_DTYPE && yypcb->pcb_root != NULL &&
+ DT_TREEDUMP_PASS(dtp, 3))
dt_node_printr(yypcb->pcb_root, stderr, 0);
if (dtp->dt_cdefs_fd != -1 && (ftruncate64(dtp->dt_cdefs_fd, 0) == -1 ||
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
index a33cccd676d2..e748ff2b3ade 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
@@ -19,12 +19,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/sysmacros.h>
@@ -193,9 +196,6 @@ dt_cg_ptrsize(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
ssize_t size;
int sreg;
- if ((sreg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
type = ctf_type_resolve(ctfp, dnp->dn_type);
kind = ctf_type_kind(ctfp, type);
assert(kind == CTF_K_POINTER || kind == CTF_K_ARRAY);
@@ -212,6 +212,7 @@ dt_cg_ptrsize(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
if ((size = ctf_type_size(ctfp, type)) == 1)
return; /* multiply or divide by one can be omitted */
+ sreg = dt_regset_alloc(drp);
dt_cg_setx(dlp, sreg, size);
instr = DIF_INSTR_FMT(op, dreg, sreg, dreg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -251,9 +252,7 @@ dt_cg_field_get(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
assert(dnp->dn_op == DT_TOK_PTR || dnp->dn_op == DT_TOK_DOT);
r1 = dnp->dn_left->dn_reg;
-
- if ((r2 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ r2 = dt_regset_alloc(drp);
/*
* On little-endian architectures, ctm_offset counts from the right so
@@ -356,10 +355,9 @@ dt_cg_field_set(dt_node_t *src, dt_irlist_t *dlp,
"bits %u\n", m.ctm_offset, m.ctm_type, e.cte_bits);
}
- if ((r1 = dt_regset_alloc(drp)) == -1 ||
- (r2 = dt_regset_alloc(drp)) == -1 ||
- (r3 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ r1 = dt_regset_alloc(drp);
+ r2 = dt_regset_alloc(drp);
+ r3 = dt_regset_alloc(drp);
/*
* Compute shifts and masks. We need to compute "shift" as the amount
@@ -423,8 +421,7 @@ dt_cg_store(dt_node_t *src, dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dst)
size = dt_node_type_size(src);
if (src->dn_flags & DT_NF_REF) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ reg = dt_regset_alloc(drp);
dt_cg_setx(dlp, reg, size);
instr = DIF_INSTR_COPYS(src->dn_reg, reg, dst->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -474,30 +471,58 @@ dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst,
size_t dstsize = dt_node_type_size(dst);
dif_instr_t instr;
- int reg, n;
+ int rg;
- if (dt_node_is_scalar(dst) && (dstsize < srcsize ||
- (src->dn_flags & DT_NF_SIGNED) ^ (dst->dn_flags & DT_NF_SIGNED))) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ if (!dt_node_is_scalar(dst))
+ return; /* not a scalar */
+ if (dstsize == srcsize &&
+ ((src->dn_flags ^ dst->dn_flags) & DT_NF_SIGNED) != 0)
+ return; /* not narrowing or changing signed-ness */
+ if (dstsize > srcsize && (src->dn_flags & DT_NF_SIGNED) == 0)
+ return; /* nothing to do in this case */
- if (dstsize < srcsize)
- n = sizeof (uint64_t) * NBBY - dstsize * NBBY;
- else
- n = sizeof (uint64_t) * NBBY - srcsize * NBBY;
+ rg = dt_regset_alloc(drp);
+
+ if (dstsize > srcsize) {
+ int n = sizeof (uint64_t) * NBBY - srcsize * NBBY;
+ int s = (dstsize - srcsize) * NBBY;
- dt_cg_setx(dlp, reg, n);
+ dt_cg_setx(dlp, rg, n);
- instr = DIF_INSTR_FMT(DIF_OP_SLL,
- src->dn_reg, reg, dst->dn_reg);
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, src->dn_reg, rg, dst->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
- instr = DIF_INSTR_FMT((dst->dn_flags & DT_NF_SIGNED) ?
- DIF_OP_SRA : DIF_OP_SRL, dst->dn_reg, reg, dst->dn_reg);
+ if ((dst->dn_flags & DT_NF_SIGNED) || n == s) {
+ instr = DIF_INSTR_FMT(DIF_OP_SRA,
+ dst->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ } else {
+ dt_cg_setx(dlp, rg, s);
+ instr = DIF_INSTR_FMT(DIF_OP_SRA,
+ dst->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_cg_setx(dlp, rg, n - s);
+ instr = DIF_INSTR_FMT(DIF_OP_SRL,
+ dst->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ }
+ } else if (dstsize != sizeof (uint64_t)) {
+ int n = sizeof (uint64_t) * NBBY - dstsize * NBBY;
+
+ dt_cg_setx(dlp, rg, n);
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, src->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_FMT((dst->dn_flags & DT_NF_SIGNED) ?
+ DIF_OP_SRA : DIF_OP_SRL, dst->dn_reg, rg, dst->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
- dt_regset_free(drp, reg);
}
+
+ dt_regset_free(drp, rg);
}
/*
@@ -523,8 +548,7 @@ dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
for (dnp = args; dnp != NULL; dnp = dnp->dn_list)
dt_cg_node(dnp, dlp, drp);
- dt_irlist_append(dlp,
- dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
for (dnp = args; dnp != NULL; dnp = dnp->dn_list, i++) {
dtrace_diftype_t t;
@@ -538,17 +562,18 @@ dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
dt_cg_typecast(dnp, &isp->dis_args[i], dlp, drp);
isp->dis_args[i].dn_reg = -1;
- if (t.dtdt_flags & DIF_TF_BYREF)
+ if (t.dtdt_flags & DIF_TF_BYREF) {
op = DIF_OP_PUSHTR;
- else
+ if (t.dtdt_size != 0) {
+ reg = dt_regset_alloc(drp);
+ dt_cg_setx(dlp, reg, t.dtdt_size);
+ } else {
+ reg = DIF_REG_R0;
+ }
+ } else {
op = DIF_OP_PUSHTV;
-
- if (t.dtdt_size != 0) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
- dt_cg_setx(dlp, reg, t.dtdt_size);
- } else
reg = DIF_REG_R0;
+ }
instr = DIF_INSTR_PUSHTS(op, t.dtdt_kind, reg, dnp->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -629,9 +654,7 @@ dt_cg_prearith_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp, uint_t op)
dt_cg_node(dnp->dn_child, dlp, drp);
dnp->dn_reg = dnp->dn_child->dn_reg;
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ reg = dt_regset_alloc(drp);
dt_cg_setx(dlp, reg, size);
instr = DIF_INSTR_FMT(op, dnp->dn_reg, reg, dnp->dn_reg);
@@ -688,9 +711,7 @@ dt_cg_postarith_op(dt_node_t *dnp, dt_irlist_t *dlp,
dt_cg_node(dnp->dn_child, dlp, drp);
dnp->dn_reg = dnp->dn_child->dn_reg;
- if ((nreg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ nreg = dt_regset_alloc(drp);
dt_cg_setx(dlp, nreg, size);
instr = DIF_INSTR_FMT(op, dnp->dn_reg, nreg, nreg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -1008,9 +1029,7 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
* set it to the size of our data structure, and then replace
* it with the result of an allocs of the specified size.
*/
- if ((r1 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ r1 = dt_regset_alloc(drp);
dt_cg_setx(dlp, r1,
ctf_type_size(dxp->dx_dst_ctfp, dxp->dx_dst_base));
@@ -1054,8 +1073,7 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
* and add r1 to it before storing the result.
*/
if (ctm.ctm_offset != 0) {
- if ((r2 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ r2 = dt_regset_alloc(drp);
/*
* Add the member offset rounded down to the
@@ -1142,8 +1160,7 @@ dt_cg_assoc_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_ident->di_flags & DT_IDFLG_TLS)
op = DIF_OP_LDTAA;
@@ -1273,9 +1290,7 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
if ((size = dt_node_type_size(dnp)) == sizeof (uint64_t))
return;
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ reg = dt_regset_alloc(drp);
assert(size < sizeof (uint64_t));
n = sizeof (uint64_t) * NBBY - size * NBBY;
@@ -1372,6 +1387,162 @@ dt_cg_func_typeref(dtrace_hdl_t *dtp, dt_node_t *dnp)
typs->dn_value = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type);
}
+typedef struct dt_xlmemb {
+ dt_ident_t *dtxl_idp; /* translated ident */
+ dt_irlist_t *dtxl_dlp; /* instruction list */
+ dt_regset_t *dtxl_drp; /* register set */
+ int dtxl_sreg; /* location of the translation input */
+ int dtxl_dreg; /* location of our allocated buffer */
+} dt_xlmemb_t;
+
+/*ARGSUSED*/
+static int
+dt_cg_xlate_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+ dt_xlmemb_t *dx = arg;
+ dt_ident_t *idp = dx->dtxl_idp;
+ dt_irlist_t *dlp = dx->dtxl_dlp;
+ dt_regset_t *drp = dx->dtxl_drp;
+
+ dt_node_t *mnp;
+ dt_xlator_t *dxp;
+
+ int reg, treg;
+ uint32_t instr;
+ size_t size;
+
+ /* Generate code for the translation. */
+ dxp = idp->di_data;
+ mnp = dt_xlator_member(dxp, name);
+
+ /* If there's no translator for the given member, skip it. */
+ if (mnp == NULL)
+ return (0);
+
+ dxp->dx_ident->di_flags |= DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = dx->dtxl_sreg;
+
+ dt_cg_node(mnp->dn_membexpr, dlp, drp);
+
+ dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = 0;
+
+ treg = mnp->dn_membexpr->dn_reg;
+
+ /* Compute the offset into our buffer and store the result there. */
+ reg = dt_regset_alloc(drp);
+
+ dt_cg_setx(dlp, reg, off / NBBY);
+ instr = DIF_INSTR_FMT(DIF_OP_ADD, dx->dtxl_dreg, reg, reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ size = ctf_type_size(mnp->dn_membexpr->dn_ctfp,
+ mnp->dn_membexpr->dn_type);
+ if (dt_node_is_scalar(mnp->dn_membexpr)) {
+ /*
+ * Copying scalars is simple.
+ */
+ switch (size) {
+ case 1:
+ instr = DIF_INSTR_STORE(DIF_OP_STB, treg, reg);
+ break;
+ case 2:
+ instr = DIF_INSTR_STORE(DIF_OP_STH, treg, reg);
+ break;
+ case 4:
+ instr = DIF_INSTR_STORE(DIF_OP_STW, treg, reg);
+ break;
+ case 8:
+ instr = DIF_INSTR_STORE(DIF_OP_STX, treg, reg);
+ break;
+ default:
+ xyerror(D_UNKNOWN, "internal error -- unexpected "
+ "size: %lu\n", (ulong_t)size);
+ }
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ } else if (dt_node_is_string(mnp->dn_membexpr)) {
+ int szreg;
+
+ /*
+ * Use the copys instruction for strings.
+ */
+ szreg = dt_regset_alloc(drp);
+ dt_cg_setx(dlp, szreg, size);
+ instr = DIF_INSTR_COPYS(treg, szreg, reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, szreg);
+ } else {
+ int szreg;
+
+ /*
+ * If it's anything else then we'll just bcopy it.
+ */
+ szreg = dt_regset_alloc(drp);
+ dt_cg_setx(dlp, szreg, size);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
+ instr = DIF_INSTR_PUSHTS(DIF_OP_PUSHTV, DIF_TYPE_CTF,
+ DIF_REG_R0, treg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ instr = DIF_INSTR_PUSHTS(DIF_OP_PUSHTV, DIF_TYPE_CTF,
+ DIF_REG_R0, reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ instr = DIF_INSTR_PUSHTS(DIF_OP_PUSHTV, DIF_TYPE_CTF,
+ DIF_REG_R0, szreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ instr = DIF_INSTR_CALL(DIF_SUBR_BCOPY, szreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, szreg);
+ }
+
+ dt_regset_free(drp, reg);
+ dt_regset_free(drp, treg);
+
+ return (0);
+}
+
+/*
+ * If we're expanding a translated type, we create an appropriately sized
+ * buffer with alloca() and then translate each member into it.
+ */
+static int
+dt_cg_xlate_expand(dt_node_t *dnp, dt_ident_t *idp, dt_irlist_t *dlp,
+ dt_regset_t *drp)
+{
+ dt_xlmemb_t dlm;
+ uint32_t instr;
+ int dreg;
+ size_t size;
+
+ dreg = dt_regset_alloc(drp);
+ size = ctf_type_size(dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type);
+
+ /* Call alloca() to create the buffer. */
+ dt_cg_setx(dlp, dreg, size);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
+
+ instr = DIF_INSTR_PUSHTS(DIF_OP_PUSHTV, DIF_TYPE_CTF, DIF_REG_R0, dreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_CALL(DIF_SUBR_ALLOCA, dreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ /* Generate the translation for each member. */
+ dlm.dtxl_idp = idp;
+ dlm.dtxl_dlp = dlp;
+ dlm.dtxl_drp = drp;
+ dlm.dtxl_sreg = dnp->dn_reg;
+ dlm.dtxl_dreg = dreg;
+ (void) ctf_member_iter(dnp->dn_ident->di_ctfp,
+ dnp->dn_ident->di_type, dt_cg_xlate_member,
+ &dlm);
+
+ return (dreg);
+}
+
static void
dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
{
@@ -1384,7 +1555,6 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_ident_t *idp;
ssize_t stroff;
uint_t op;
- int reg;
switch (dnp->dn_op) {
case DT_TOK_COMMA:
@@ -1586,7 +1756,16 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_node(dnp->dn_child, dlp, drp);
dnp->dn_reg = dnp->dn_child->dn_reg;
- if (!(dnp->dn_flags & DT_NF_REF)) {
+ if (dt_node_is_dynamic(dnp->dn_child)) {
+ int reg;
+ idp = dt_node_resolve(dnp->dn_child, DT_IDENT_XLPTR);
+ assert(idp != NULL);
+ reg = dt_cg_xlate_expand(dnp, idp, dlp, drp);
+
+ dt_regset_free(drp, dnp->dn_child->dn_reg);
+ dnp->dn_reg = reg;
+
+ } else if (!(dnp->dn_flags & DT_NF_REF)) {
uint_t ubit = dnp->dn_flags & DT_NF_USERLAND;
/*
@@ -1622,10 +1801,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
case DT_TOK_SIZEOF: {
size_t size = dt_node_sizeof(dnp->dn_child);
-
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ dnp->dn_reg = dt_regset_alloc(drp);
assert(size != 0);
dt_cg_setx(dlp, dnp->dn_reg, size);
break;
@@ -1650,8 +1826,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
assert(dxp->dx_ident->di_flags & DT_IDFLG_CGREG);
assert(dxp->dx_ident->di_id != 0);
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
if (dxp->dx_arg == -1) {
instr = DIF_INSTR_MOV(
@@ -1735,8 +1910,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
if (m.ctm_offset != 0) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ int reg;
+
+ reg = dt_regset_alloc(drp);
/*
* If the offset is not aligned on a byte boundary, it
@@ -1782,8 +1958,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
break;
case DT_TOK_STRING:
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
assert(dnp->dn_kind == DT_NODE_STRING);
stroff = dt_strtab_insert(yypcb->pcb_strtab, dnp->dn_string);
@@ -1806,8 +1981,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
*/
if (dnp->dn_kind == DT_NODE_VAR &&
(dnp->dn_ident->di_flags & DT_IDFLG_CGREG)) {
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
instr = DIF_INSTR_MOV(dnp->dn_ident->di_id,
dnp->dn_reg);
dt_irlist_append(dlp,
@@ -1848,11 +2022,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
- instr = DIF_INSTR_CALL(
- dnp->dn_ident->di_id, dnp->dn_reg);
+ dnp->dn_reg = dt_regset_alloc(drp);
+ instr = DIF_INSTR_CALL(dnp->dn_ident->di_id,
+ dnp->dn_reg);
dt_irlist_append(dlp,
dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -1880,8 +2052,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
break;
}
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL)
op = DIF_OP_LDLS;
@@ -1911,9 +2082,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dtrace_errmsg(dtp, dtrace_errno(dtp)));
}
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ dnp->dn_reg = dt_regset_alloc(drp);
dt_cg_xsetx(dlp, dnp->dn_ident,
DT_LBL_NONE, dnp->dn_reg, sym.st_value);
@@ -1933,9 +2102,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
break;
case DT_TOK_INT:
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ dnp->dn_reg = dt_regset_alloc(drp);
dt_cg_setx(dlp, dnp->dn_reg, dnp->dn_value);
break;
@@ -1950,6 +2117,7 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
{
dif_instr_t instr;
dt_xlator_t *dxp;
+ dt_ident_t *idp;
if (pcb->pcb_regs == NULL && (pcb->pcb_regs =
dt_regset_create(pcb->pcb_hdl->dt_conf.dtc_difintregs)) == NULL)
@@ -1976,9 +2144,9 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
assert(pcb->pcb_dret == NULL);
pcb->pcb_dret = dnp;
- if (dt_node_is_dynamic(dnp)) {
+ if (dt_node_resolve(dnp, DT_IDENT_XLPTR) != NULL) {
dnerror(dnp, D_CG_DYN, "expression cannot evaluate to result "
- "of dynamic type\n");
+ "of a translated pointer\n");
}
/*
@@ -1994,6 +2162,14 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
}
dt_cg_node(dnp, &pcb->pcb_ir, pcb->pcb_regs);
+
+ if ((idp = dt_node_resolve(dnp, DT_IDENT_XLSOU)) != NULL) {
+ int reg = dt_cg_xlate_expand(dnp, idp,
+ &pcb->pcb_ir, pcb->pcb_regs);
+ dt_regset_free(pcb->pcb_regs, dnp->dn_reg);
+ dnp->dn_reg = reg;
+ }
+
instr = DIF_INSTR_RET(dnp->dn_reg);
dt_regset_free(pcb->pcb_regs, dnp->dn_reg);
dt_irlist_append(&pcb->pcb_ir, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -2003,4 +2179,7 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
dxp->dx_ident->di_id = 0;
dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;
}
+
+ dt_regset_free(pcb->pcb_regs, 0);
+ dt_regset_assert_free(pcb->pcb_regs);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
index a4f2de8b379e..c9e157bafb5d 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
@@ -25,6 +25,7 @@
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <stdlib.h>
@@ -38,6 +39,7 @@
#include <alloca.h>
#endif
#include <dt_impl.h>
+#include <dt_pq.h>
#if !defined(sun)
#include <libproc_compat.h>
#endif
@@ -442,17 +444,8 @@ dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_epid_t last,
offs += epd->dtepd_size;
do {
- if (offs >= buf->dtbd_size) {
- /*
- * We're at the end -- maybe. If the oldest
- * record is non-zero, we need to wrap.
- */
- if (buf->dtbd_oldest != 0) {
- offs = 0;
- } else {
- goto out;
- }
- }
+ if (offs >= buf->dtbd_size)
+ goto out;
next = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs);
@@ -832,7 +825,7 @@ dt_print_stddev(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
/*ARGSUSED*/
int
dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
- size_t nbytes, int width, int quiet, int raw)
+ size_t nbytes, int width, int quiet, int forceraw)
{
/*
* If the byte stream is a series of printable characters, followed by
@@ -845,7 +838,10 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
if (nbytes == 0)
return (0);
- if (raw || dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
+ if (forceraw)
+ goto raw;
+
+ if (dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
goto raw;
for (i = 0; i < nbytes; i++) {
@@ -2010,25 +2006,27 @@ dt_setopt(dtrace_hdl_t *dtp, const dtrace_probedata_t *data,
}
static int
-dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf,
+dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu,
+ dtrace_bufdesc_t *buf, boolean_t just_one,
dtrace_consume_probe_f *efunc, dtrace_consume_rec_f *rfunc, void *arg)
{
dtrace_epid_t id;
- size_t offs, start = buf->dtbd_oldest, end = buf->dtbd_size;
+ size_t offs;
int flow = (dtp->dt_options[DTRACEOPT_FLOWINDENT] != DTRACEOPT_UNSET);
int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
int rval, i, n;
- dtrace_epid_t last = DTRACE_EPIDNONE;
+ uint64_t tracememsize = 0;
dtrace_probedata_t data;
uint64_t drops;
- caddr_t addr;
bzero(&data, sizeof (data));
data.dtpda_handle = dtp;
data.dtpda_cpu = cpu;
+ data.dtpda_flow = dtp->dt_flow;
+ data.dtpda_indent = dtp->dt_indent;
+ data.dtpda_prefix = dtp->dt_prefix;
-again:
- for (offs = start; offs < end; ) {
+ for (offs = buf->dtbd_oldest; offs < buf->dtbd_size; ) {
dtrace_eprobedesc_t *epd;
/*
@@ -2063,7 +2061,8 @@ again:
}
if (flow)
- (void) dt_flowindent(dtp, &data, last, buf, offs);
+ (void) dt_flowindent(dtp, &data, dtp->dt_last_epid,
+ buf, offs);
rval = (*efunc)(&data, arg);
@@ -2082,6 +2081,7 @@ again:
return (dt_set_errno(dtp, EDT_BADRVAL));
for (i = 0; i < epd->dtepd_nrecs; i++) {
+ caddr_t addr;
dtrace_recdesc_t *rec = &epd->dtepd_rec[i];
dtrace_actkind_t act = rec->dtrd_action;
@@ -2187,6 +2187,13 @@ again:
}
}
+ if (act == DTRACEACT_TRACEMEM_DYNSIZE &&
+ rec->dtrd_size == sizeof (uint64_t)) {
+ /* LINTED - alignment */
+ tracememsize = *((unsigned long long *)addr);
+ continue;
+ }
+
rval = (*rfunc)(&data, rec, arg);
if (rval == DTRACE_CONSUME_NEXT)
@@ -2290,6 +2297,35 @@ again:
goto nextrec;
}
+ /*
+ * If this is a DIF expression, and the record has a
+ * format set, this indicates we have a CTF type name
+ * associated with the data and we should try to print
+ * it out by type.
+ */
+ if (act == DTRACEACT_DIFEXPR) {
+ const char *strdata = dt_strdata_lookup(dtp,
+ rec->dtrd_format);
+ if (strdata != NULL) {
+ n = dtrace_print(dtp, fp, strdata,
+ addr, rec->dtrd_size);
+
+ /*
+ * dtrace_print() will return -1 on
+ * error, or return the number of bytes
+ * consumed. It will return 0 if the
+ * type couldn't be determined, and we
+ * should fall through to the normal
+ * trace method.
+ */
+ if (n < 0)
+ return (-1);
+
+ if (n > 0)
+ goto nextrec;
+ }
+ }
+
nofmt:
if (act == DTRACEACT_PRINTA) {
dt_print_aggdata_t pd;
@@ -2358,6 +2394,23 @@ nofmt:
goto nextrec;
}
+ if (act == DTRACEACT_TRACEMEM) {
+ if (tracememsize == 0 ||
+ tracememsize > rec->dtrd_size) {
+ tracememsize = rec->dtrd_size;
+ }
+
+ n = dt_print_bytes(dtp, fp, addr,
+ tracememsize, 33, quiet, 1);
+
+ tracememsize = 0;
+
+ if (n < 0)
+ return (-1);
+
+ goto nextrec;
+ }
+
switch (rec->dtrd_size) {
case sizeof (uint64_t):
n = dt_printf(dtp, fp,
@@ -2400,14 +2453,16 @@ nextrec:
rval = (*rfunc)(&data, NULL, arg);
nextepid:
offs += epd->dtepd_size;
- last = id;
+ dtp->dt_last_epid = id;
+ if (just_one) {
+ buf->dtbd_oldest = offs;
+ break;
+ }
}
- if (buf->dtbd_oldest != 0 && start == buf->dtbd_oldest) {
- end = buf->dtbd_oldest;
- start = 0;
- goto again;
- }
+ dtp->dt_flow = data.dtpda_flow;
+ dtp->dt_indent = data.dtpda_indent;
+ dtp->dt_prefix = data.dtpda_prefix;
if ((drops = buf->dtbd_drops) == 0)
return (0);
@@ -2420,6 +2475,130 @@ nextepid:
return (dt_handle_cpudrop(dtp, cpu, DTRACEDROP_PRINCIPAL, drops));
}
+/*
+ * Reduce memory usage by shrinking the buffer if it's no more than half full.
+ * Note, we need to preserve the alignment of the data at dtbd_oldest, which is
+ * only 4-byte aligned.
+ */
+static void
+dt_realloc_buf(dtrace_hdl_t *dtp, dtrace_bufdesc_t *buf, int cursize)
+{
+ uint64_t used = buf->dtbd_size - buf->dtbd_oldest;
+ if (used < cursize / 2) {
+ int misalign = buf->dtbd_oldest & (sizeof (uint64_t) - 1);
+ char *newdata = dt_alloc(dtp, used + misalign);
+ if (newdata == NULL)
+ return;
+ bzero(newdata, misalign);
+ bcopy(buf->dtbd_data + buf->dtbd_oldest,
+ newdata + misalign, used);
+ dt_free(dtp, buf->dtbd_data);
+ buf->dtbd_oldest = misalign;
+ buf->dtbd_size = used + misalign;
+ buf->dtbd_data = newdata;
+ }
+}
+
+/*
+ * If the ring buffer has wrapped, the data is not in order. Rearrange it
+ * so that it is. Note, we need to preserve the alignment of the data at
+ * dtbd_oldest, which is only 4-byte aligned.
+ */
+static int
+dt_unring_buf(dtrace_hdl_t *dtp, dtrace_bufdesc_t *buf)
+{
+ int misalign;
+ char *newdata, *ndp;
+
+ if (buf->dtbd_oldest == 0)
+ return (0);
+
+ misalign = buf->dtbd_oldest & (sizeof (uint64_t) - 1);
+ newdata = ndp = dt_alloc(dtp, buf->dtbd_size + misalign);
+
+ if (newdata == NULL)
+ return (-1);
+
+ assert(0 == (buf->dtbd_size & (sizeof (uint64_t) - 1)));
+
+ bzero(ndp, misalign);
+ ndp += misalign;
+
+ bcopy(buf->dtbd_data + buf->dtbd_oldest, ndp,
+ buf->dtbd_size - buf->dtbd_oldest);
+ ndp += buf->dtbd_size - buf->dtbd_oldest;
+
+ bcopy(buf->dtbd_data, ndp, buf->dtbd_oldest);
+
+ dt_free(dtp, buf->dtbd_data);
+ buf->dtbd_oldest = 0;
+ buf->dtbd_data = newdata;
+ buf->dtbd_size += misalign;
+
+ return (0);
+}
+
+static void
+dt_put_buf(dtrace_hdl_t *dtp, dtrace_bufdesc_t *buf)
+{
+ dt_free(dtp, buf->dtbd_data);
+ dt_free(dtp, buf);
+}
+
+/*
+ * Returns 0 on success, in which case *cbp will be filled in if we retrieved
+ * data, or NULL if there is no data for this CPU.
+ * Returns -1 on failure and sets dt_errno.
+ */
+static int
+dt_get_buf(dtrace_hdl_t *dtp, int cpu, dtrace_bufdesc_t **bufp)
+{
+ dtrace_optval_t size;
+ dtrace_bufdesc_t *buf = dt_zalloc(dtp, sizeof (*buf));
+ int error;
+
+ if (buf == NULL)
+ return (-1);
+
+ (void) dtrace_getopt(dtp, "bufsize", &size);
+ buf->dtbd_data = dt_alloc(dtp, size);
+ if (buf->dtbd_data == NULL) {
+ dt_free(dtp, buf);
+ return (-1);
+ }
+ buf->dtbd_size = size;
+ buf->dtbd_cpu = cpu;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
+ dt_put_buf(dtp, buf);
+ /*
+ * If we failed with ENOENT, it may be because the
+ * CPU was unconfigured -- this is okay. Any other
+ * error, however, is unexpected.
+ */
+ if (errno == ENOENT) {
+ *bufp = NULL;
+ return (0);
+ }
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ error = dt_unring_buf(dtp, buf);
+ if (error != 0) {
+ dt_put_buf(dtp, buf);
+ return (error);
+ }
+ dt_realloc_buf(dtp, buf, size);
+
+ *bufp = buf;
+ return (0);
+}
+
typedef struct dt_begin {
dtrace_consume_probe_f *dtbgn_probefunc;
dtrace_consume_rec_f *dtbgn_recfunc;
@@ -2432,7 +2611,7 @@ typedef struct dt_begin {
static int
dt_consume_begin_probe(const dtrace_probedata_t *data, void *arg)
{
- dt_begin_t *begin = (dt_begin_t *)arg;
+ dt_begin_t *begin = arg;
dtrace_probedesc_t *pd = data->dtpda_pdesc;
int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0);
@@ -2457,7 +2636,7 @@ static int
dt_consume_begin_record(const dtrace_probedata_t *data,
const dtrace_recdesc_t *rec, void *arg)
{
- dt_begin_t *begin = (dt_begin_t *)arg;
+ dt_begin_t *begin = arg;
return (begin->dtbgn_recfunc(data, rec, begin->dtbgn_arg));
}
@@ -2483,7 +2662,7 @@ dt_consume_begin_error(const dtrace_errdata_t *data, void *arg)
}
static int
-dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
+dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp,
dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg)
{
/*
@@ -2507,33 +2686,19 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
* first pass, and that we only process ERROR enablings _not_ induced
* by BEGIN enablings in the second pass.
*/
+
dt_begin_t begin;
processorid_t cpu = dtp->dt_beganon;
- dtrace_bufdesc_t nbuf;
-#if !defined(sun)
- dtrace_bufdesc_t *pbuf;
-#endif
int rval, i;
static int max_ncpus;
- dtrace_optval_t size;
+ dtrace_bufdesc_t *buf;
dtp->dt_beganon = -1;
-#if defined(sun)
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
-#else
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
-#endif
- /*
- * We really don't expect this to fail, but it is at least
- * technically possible for this to fail with ENOENT. In this
- * case, we just drive on...
- */
- if (errno == ENOENT)
- return (0);
-
- return (dt_set_errno(dtp, errno));
- }
+ if (dt_get_buf(dtp, cpu, &buf) != 0)
+ return (-1);
+ if (buf == NULL)
+ return (0);
if (!dtp->dt_stopped || buf->dtbd_cpu != dtp->dt_endedon) {
/*
@@ -2541,7 +2706,10 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
* we are, we actually processed any END probes on another
* CPU. We can simply consume this buffer and return.
*/
- return (dt_consume_cpu(dtp, fp, cpu, buf, pf, rf, arg));
+ rval = dt_consume_cpu(dtp, fp, cpu, buf, B_FALSE,
+ pf, rf, arg);
+ dt_put_buf(dtp, buf);
+ return (rval);
}
begin.dtbgn_probefunc = pf;
@@ -2558,61 +2726,41 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
dtp->dt_errhdlr = dt_consume_begin_error;
dtp->dt_errarg = &begin;
- rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe,
- dt_consume_begin_record, &begin);
+ rval = dt_consume_cpu(dtp, fp, cpu, buf, B_FALSE,
+ dt_consume_begin_probe, dt_consume_begin_record, &begin);
dtp->dt_errhdlr = begin.dtbgn_errhdlr;
dtp->dt_errarg = begin.dtbgn_errarg;
- if (rval != 0)
+ if (rval != 0) {
+ dt_put_buf(dtp, buf);
return (rval);
-
- /*
- * Now allocate a new buffer. We'll use this to deal with every other
- * CPU.
- */
- bzero(&nbuf, sizeof (dtrace_bufdesc_t));
- (void) dtrace_getopt(dtp, "bufsize", &size);
- if ((nbuf.dtbd_data = malloc(size)) == NULL)
- return (dt_set_errno(dtp, EDT_NOMEM));
+ }
if (max_ncpus == 0)
max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
for (i = 0; i < max_ncpus; i++) {
- nbuf.dtbd_cpu = i;
-
+ dtrace_bufdesc_t *nbuf;
if (i == cpu)
continue;
-#if defined(sun)
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &nbuf) == -1) {
-#else
- pbuf = &nbuf;
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &pbuf) == -1) {
-#endif
- /*
- * If we failed with ENOENT, it may be because the
- * CPU was unconfigured -- this is okay. Any other
- * error, however, is unexpected.
- */
- if (errno == ENOENT)
- continue;
-
- free(nbuf.dtbd_data);
-
- return (dt_set_errno(dtp, errno));
+ if (dt_get_buf(dtp, i, &nbuf) != 0) {
+ dt_put_buf(dtp, buf);
+ return (-1);
}
+ if (nbuf == NULL)
+ continue;
- if ((rval = dt_consume_cpu(dtp, fp,
- i, &nbuf, pf, rf, arg)) != 0) {
- free(nbuf.dtbd_data);
+ rval = dt_consume_cpu(dtp, fp, i, nbuf, B_FALSE,
+ pf, rf, arg);
+ dt_put_buf(dtp, nbuf);
+ if (rval != 0) {
+ dt_put_buf(dtp, buf);
return (rval);
}
}
- free(nbuf.dtbd_data);
-
/*
* Okay -- we're done with the other buffers. Now we want to
* reconsume the first buffer -- but this time we're looking for
@@ -2627,8 +2775,8 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
dtp->dt_errhdlr = dt_consume_begin_error;
dtp->dt_errarg = &begin;
- rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe,
- dt_consume_begin_record, &begin);
+ rval = dt_consume_cpu(dtp, fp, cpu, buf, B_FALSE,
+ dt_consume_begin_probe, dt_consume_begin_record, &begin);
dtp->dt_errhdlr = begin.dtbgn_errhdlr;
dtp->dt_errarg = begin.dtbgn_errarg;
@@ -2636,11 +2784,32 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
return (rval);
}
+/* ARGSUSED */
+static uint64_t
+dt_buf_oldest(void *elem, void *arg)
+{
+ dtrace_bufdesc_t *buf = elem;
+ size_t offs = buf->dtbd_oldest;
+
+ while (offs < buf->dtbd_size) {
+ dtrace_rechdr_t *dtrh =
+ /* LINTED - alignment */
+ (dtrace_rechdr_t *)(buf->dtbd_data + offs);
+ if (dtrh->dtrh_epid == DTRACE_EPIDNONE) {
+ offs += sizeof (dtrace_epid_t);
+ } else {
+ return (DTRACE_RECORD_LOAD_TIMESTAMP(dtrh));
+ }
+ }
+
+ /* There are no records left; use the time the buffer was retrieved. */
+ return (buf->dtbd_timestamp);
+}
+
int
dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg)
{
- dtrace_bufdesc_t *buf = &dtp->dt_buf;
dtrace_optval_t size;
static int max_ncpus;
int i, rval;
@@ -2668,79 +2837,158 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
if (rf == NULL)
rf = (dtrace_consume_rec_f *)dt_nullrec;
- if (buf->dtbd_data == NULL) {
- (void) dtrace_getopt(dtp, "bufsize", &size);
- if ((buf->dtbd_data = malloc(size)) == NULL)
- return (dt_set_errno(dtp, EDT_NOMEM));
-
- buf->dtbd_size = size;
- }
-
- /*
- * If we have just begun, we want to first process the CPU that
- * executed the BEGIN probe (if any).
- */
- if (dtp->dt_active && dtp->dt_beganon != -1) {
- buf->dtbd_cpu = dtp->dt_beganon;
- if ((rval = dt_consume_begin(dtp, fp, buf, pf, rf, arg)) != 0)
- return (rval);
- }
-
- for (i = 0; i < max_ncpus; i++) {
- buf->dtbd_cpu = i;
-
+ if (dtp->dt_options[DTRACEOPT_TEMPORAL] == DTRACEOPT_UNSET) {
/*
- * If we have stopped, we want to process the CPU on which the
- * END probe was processed only _after_ we have processed
- * everything else.
+ * The output will not be in the order it was traced. Rather,
+ * we will consume all of the data from each CPU's buffer in
+ * turn. We apply special handling for the records from BEGIN
+ * and END probes so that they are consumed first and last,
+ * respectively.
+ *
+ * If we have just begun, we want to first process the CPU that
+ * executed the BEGIN probe (if any).
*/
- if (dtp->dt_stopped && (i == dtp->dt_endedon))
- continue;
+ if (dtp->dt_active && dtp->dt_beganon != -1 &&
+ (rval = dt_consume_begin(dtp, fp, pf, rf, arg)) != 0)
+ return (rval);
+
+ for (i = 0; i < max_ncpus; i++) {
+ dtrace_bufdesc_t *buf;
-#if defined(sun)
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
-#else
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
-#endif
/*
- * If we failed with ENOENT, it may be because the
- * CPU was unconfigured -- this is okay. Any other
- * error, however, is unexpected.
+ * If we have stopped, we want to process the CPU on
+ * which the END probe was processed only _after_ we
+ * have processed everything else.
*/
- if (errno == ENOENT)
+ if (dtp->dt_stopped && (i == dtp->dt_endedon))
continue;
- return (dt_set_errno(dtp, errno));
+ if (dt_get_buf(dtp, i, &buf) != 0)
+ return (-1);
+ if (buf == NULL)
+ continue;
+
+ dtp->dt_flow = 0;
+ dtp->dt_indent = 0;
+ dtp->dt_prefix = NULL;
+ rval = dt_consume_cpu(dtp, fp, i,
+ buf, B_FALSE, pf, rf, arg);
+ dt_put_buf(dtp, buf);
+ if (rval != 0)
+ return (rval);
}
+ if (dtp->dt_stopped) {
+ dtrace_bufdesc_t *buf;
+
+ if (dt_get_buf(dtp, dtp->dt_endedon, &buf) != 0)
+ return (-1);
+ if (buf == NULL)
+ return (0);
- if ((rval = dt_consume_cpu(dtp, fp, i, buf, pf, rf, arg)) != 0)
+ rval = dt_consume_cpu(dtp, fp, dtp->dt_endedon,
+ buf, B_FALSE, pf, rf, arg);
+ dt_put_buf(dtp, buf);
return (rval);
- }
+ }
+ } else {
+ /*
+ * The output will be in the order it was traced (or for
+ * speculations, when it was committed). We retrieve a buffer
+ * from each CPU and put it into a priority queue, which sorts
+ * based on the first entry in the buffer. This is sufficient
+ * because entries within a buffer are already sorted.
+ *
+ * We then consume records one at a time, always consuming the
+ * oldest record, as determined by the priority queue. When
+ * we reach the end of the time covered by these buffers,
+ * we need to stop and retrieve more records on the next pass.
+ * The kernel tells us the time covered by each buffer, in
+ * dtbd_timestamp. The first buffer's timestamp tells us the
+ * time covered by all buffers, as subsequently retrieved
+ * buffers will cover to a more recent time.
+ */
- if (!dtp->dt_stopped)
- return (0);
+ uint64_t *drops = alloca(max_ncpus * sizeof (uint64_t));
+ uint64_t first_timestamp = 0;
+ uint_t cookie = 0;
+ dtrace_bufdesc_t *buf;
- buf->dtbd_cpu = dtp->dt_endedon;
+ bzero(drops, max_ncpus * sizeof (uint64_t));
+
+ if (dtp->dt_bufq == NULL) {
+ dtp->dt_bufq = dt_pq_init(dtp, max_ncpus * 2,
+ dt_buf_oldest, NULL);
+ if (dtp->dt_bufq == NULL) /* ENOMEM */
+ return (-1);
+ }
+
+ /* Retrieve data from each CPU. */
+ (void) dtrace_getopt(dtp, "bufsize", &size);
+ for (i = 0; i < max_ncpus; i++) {
+ dtrace_bufdesc_t *buf;
+
+ if (dt_get_buf(dtp, i, &buf) != 0)
+ return (-1);
+ if (buf != NULL) {
+ if (first_timestamp == 0)
+ first_timestamp = buf->dtbd_timestamp;
+ assert(buf->dtbd_timestamp >= first_timestamp);
+
+ dt_pq_insert(dtp->dt_bufq, buf);
+ drops[i] = buf->dtbd_drops;
+ buf->dtbd_drops = 0;
+ }
+ }
+
+ /* Consume records. */
+ for (;;) {
+ dtrace_bufdesc_t *buf = dt_pq_pop(dtp->dt_bufq);
+ uint64_t timestamp;
+
+ if (buf == NULL)
+ break;
+
+ timestamp = dt_buf_oldest(buf, dtp);
+ /* XXX: assert(timestamp >= dtp->dt_last_timestamp); */
+ dtp->dt_last_timestamp = timestamp;
+
+ if (timestamp == buf->dtbd_timestamp) {
+ /*
+ * We've reached the end of the time covered
+ * by this buffer. If this is the oldest
+ * buffer, we must do another pass
+ * to retrieve more data.
+ */
+ dt_put_buf(dtp, buf);
+ if (timestamp == first_timestamp &&
+ !dtp->dt_stopped)
+ break;
+ continue;
+ }
+
+ if ((rval = dt_consume_cpu(dtp, fp,
+ buf->dtbd_cpu, buf, B_TRUE, pf, rf, arg)) != 0)
+ return (rval);
+ dt_pq_insert(dtp->dt_bufq, buf);
+ }
+
+ /* Consume drops. */
+ for (i = 0; i < max_ncpus; i++) {
+ if (drops[i] != 0) {
+ int error = dt_handle_cpudrop(dtp, i,
+ DTRACEDROP_PRINCIPAL, drops[i]);
+ if (error != 0)
+ return (error);
+ }
+ }
-#if defined(sun)
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
-#else
- if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
-#endif
/*
- * This _really_ shouldn't fail, but it is strictly speaking
- * possible for this to return ENOENT if the CPU that called
- * the END enabling somehow managed to become unconfigured.
- * It's unclear how the user can possibly expect anything
- * rational to happen in this case -- the state has been thrown
- * out along with the unconfigured CPU -- so we'll just drive
- * on...
+ * Reduce memory usage by re-allocating smaller buffers
+ * for the "remnants".
*/
- if (errno == ENOENT)
- return (0);
-
- return (dt_set_errno(dtp, errno));
+ while (buf = dt_pq_walk(dtp->dt_bufq, &cookie))
+ dt_realloc_buf(dtp, buf, buf->dtbd_size);
}
- return (dt_consume_cpu(dtp, fp, dtp->dt_endedon, buf, pf, rf, arg));
+ return (0);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
index f4bb0c4bbae3..fff4235a6bc3 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
@@ -19,12 +19,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <strings.h>
#include <stdio.h>
@@ -212,12 +215,22 @@ dt_dis_pushts(const dtrace_difo_t *dp,
{
static const char *const tnames[] = { "D type", "string" };
uint_t type = DIF_INSTR_TYPE(in);
+ const char *pad;
- (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u, %%r%u",
- name, type, DIF_INSTR_R2(in), DIF_INSTR_RS(in));
+ if (DIF_INSTR_OP(in) == DIF_OP_PUSHTV) {
+ (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u",
+ name, type, DIF_INSTR_RS(in));
+ pad = "\t\t";
+ } else {
+ (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u, %%r%u",
+ name, type, DIF_INSTR_R2(in), DIF_INSTR_RS(in));
+ pad = "\t";
+ }
- if (type < sizeof (tnames) / sizeof (tnames[0]))
- (void) fprintf(fp, "\t! DT_TYPE(%u) = %s", type, tnames[type]);
+ if (type < sizeof (tnames) / sizeof (tnames[0])) {
+ (void) fprintf(fp, "%s! DT_TYPE(%u) = %s", pad,
+ type, tnames[type]);
+ }
}
static void
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
index 6ed9480ecfa9..01ef0f998e82 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/types.h>
@@ -758,16 +759,23 @@ dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags)
dofa[i].dofa_difo = DOF_SECIDX_NONE;
/*
- * If the first action in a statement has format data,
- * add the format string to the global string table.
+ * If the first action in a statement has string data,
+ * add the string to the global string table. This can
+ * be due either to a printf() format string
+ * (dtsd_fmtdata) or a print() type string
+ * (dtsd_strdata).
*/
if (sdp != NULL && ap == sdp->dtsd_action) {
if (sdp->dtsd_fmtdata != NULL) {
(void) dtrace_printf_format(dtp,
sdp->dtsd_fmtdata, fmt, maxfmt + 1);
strndx = dof_add_string(ddo, fmt);
- } else
+ } else if (sdp->dtsd_strdata != NULL) {
+ strndx = dof_add_string(ddo,
+ sdp->dtsd_strdata);
+ } else {
strndx = 0; /* use dtad_arg instead */
+ }
if ((next = dt_list_next(next)) != NULL)
sdp = next->ds_desc;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
index a28505c12de6..66776beed21d 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
@@ -18,11 +18,16 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#include <string.h>
#include <strings.h>
#include <dt_impl.h>
@@ -37,7 +42,6 @@ static const struct {
{ EDT_VERSREDUCED, "Requested version conflicts with earlier setting" },
{ EDT_CTF, "Unexpected libctf error" },
{ EDT_COMPILER, "Error in D program compilation" },
- { EDT_NOREG, "Insufficient registers to generate code" },
{ EDT_NOTUPREG, "Insufficient tuple registers to generate code" },
{ EDT_NOMEM, "Memory allocation failure" },
{ EDT_INT2BIG, "Integer constant table limit exceeded" },
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
index 8495f1584111..353f581adc7f 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
@@ -24,11 +24,14 @@
* Use is subject to license terms.
*/
+ /*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#ifndef _DT_ERRTAGS_H
#define _DT_ERRTAGS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -187,8 +190,12 @@ typedef enum {
D_PRINTA_AGGPROTO, /* printa() aggregation mismatch */
D_TRACE_VOID, /* trace() argument has void type */
D_TRACE_DYN, /* trace() argument has dynamic type */
+ D_PRINT_VOID, /* print() argument has void type */
+ D_PRINT_DYN, /* print() argument has dynamic type */
D_TRACEMEM_ADDR, /* tracemem() address bad type */
D_TRACEMEM_SIZE, /* tracemem() size bad type */
+ D_TRACEMEM_ARGS, /* tracemem() illegal number of args */
+ D_TRACEMEM_DYNSIZE, /* tracemem() dynamic size bad type */
D_STACK_PROTO, /* stack() prototype mismatch */
D_STACK_SIZE, /* stack() size argument bad type */
D_USTACK_FRAMES, /* ustack() frames arg bad type */
@@ -253,6 +260,7 @@ typedef enum {
D_LLQUANT_FACTOREVEN, /* llquantize() bad # steps/factor */
D_LLQUANT_FACTORSMALL, /* llquantize() magnitude too small */
D_LLQUANT_MAGTOOBIG, /* llquantize() high mag too large */
+ D_NOREG, /* no available internal registers */
D_PRINTM_ADDR, /* printm() memref bad type */
D_PRINTM_SIZE, /* printm() size bad type */
D_PRINTT_ADDR, /* printt() typeref bad type */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
index 99498d9fd470..e4b1db55fa10 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
@@ -26,6 +26,7 @@
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _DT_IMPL_H
@@ -63,6 +64,7 @@ extern "C" {
#include <dt_proc.h>
#include <dt_dof.h>
#include <dt_pcb.h>
+#include <dt_pq.h>
struct dt_module; /* see below */
struct dt_pfdict; /* see <dt_printf.h> */
@@ -238,6 +240,7 @@ struct dtrace_hdl {
uint_t dt_provbuckets; /* number of provider hash buckets */
uint_t dt_nprovs; /* number of providers in hash and list */
dt_proc_hash_t *dt_procs; /* hash table of grabbed process handles */
+ char **dt_proc_env; /* additional environment variables */
dt_intdesc_t dt_ints[6]; /* cached integer type descriptions */
ctf_id_t dt_type_func; /* cached CTF identifier for function type */
ctf_id_t dt_type_fptr; /* cached CTF identifier for function pointer */
@@ -253,8 +256,10 @@ struct dtrace_hdl {
dtrace_aggdesc_t **dt_aggdesc; /* aggregation descriptions */
int dt_maxformat; /* max format ID */
void **dt_formats; /* pointer to format array */
+ int dt_maxstrdata; /* max strdata ID */
+ char **dt_strdata; /* pointer to strdata array */
dt_aggregate_t dt_aggregate; /* aggregate */
- dtrace_bufdesc_t dt_buf; /* staging buffer */
+ dt_pq_t *dt_bufq; /* CPU-specific data queue */
struct dt_pfdict *dt_pfdict; /* dictionary of printf conversions */
dt_version_t dt_vmax; /* optional ceiling on program API binding */
dtrace_attribute_t dt_amin; /* optional floor on program attributes */
@@ -323,6 +328,11 @@ struct dtrace_hdl {
struct utsname dt_uts; /* uname(2) information for system */
dt_list_t dt_lib_dep; /* scratch linked-list of lib dependencies */
dt_list_t dt_lib_dep_sorted; /* dependency sorted library list */
+ dtrace_flowkind_t dt_flow; /* flow kind */
+ const char *dt_prefix; /* recommended flow prefix */
+ int dt_indent; /* recommended flow indent */
+ dtrace_epid_t dt_last_epid; /* most recently consumed EPID */
+ uint64_t dt_last_timestamp; /* most recently consumed timestamp */
};
/*
@@ -438,8 +448,9 @@ struct dtrace_hdl {
#define DT_ACT_UMOD DT_ACT(26) /* umod() action */
#define DT_ACT_UADDR DT_ACT(27) /* uaddr() action */
#define DT_ACT_SETOPT DT_ACT(28) /* setopt() action */
-#define DT_ACT_PRINTM DT_ACT(29) /* printm() action */
-#define DT_ACT_PRINTT DT_ACT(30) /* printt() action */
+#define DT_ACT_PRINT DT_ACT(29) /* print() action */
+#define DT_ACT_PRINTM DT_ACT(30) /* printm() action */
+#define DT_ACT_PRINTT DT_ACT(31) /* printt() action */
/*
* Sentinel to tell freopen() to restore the saved stdout. This must not
@@ -457,7 +468,6 @@ enum {
EDT_VERSREDUCED, /* requested API version has been reduced */
EDT_CTF, /* libctf called failed (dt_ctferr has more) */
EDT_COMPILER, /* error in D program compilation */
- EDT_NOREG, /* register allocation failure */
EDT_NOTUPREG, /* tuple register allocation failure */
EDT_NOMEM, /* memory allocation failure */
EDT_INT2BIG, /* integer limit exceeded */
@@ -641,6 +651,9 @@ extern void dt_aggid_destroy(dtrace_hdl_t *);
extern void *dt_format_lookup(dtrace_hdl_t *, int);
extern void dt_format_destroy(dtrace_hdl_t *);
+extern const char *dt_strdata_lookup(dtrace_hdl_t *, int);
+extern void dt_strdata_destroy(dtrace_hdl_t *);
+
extern int dt_print_quantize(dtrace_hdl_t *, FILE *,
const void *, size_t, uint64_t);
extern int dt_print_lquantize(dtrace_hdl_t *, FILE *,
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c
index 1c5c868bb4b0..c6d92c87eb40 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c
@@ -23,7 +23,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
#include <stdlib.h>
#include <strings.h>
@@ -35,10 +37,81 @@
#include <dt_printf.h>
static int
+dt_strdata_add(dtrace_hdl_t *dtp, dtrace_recdesc_t *rec, void ***data, int *max)
+{
+ int maxformat;
+ dtrace_fmtdesc_t fmt;
+ void *result;
+
+ if (rec->dtrd_format == 0)
+ return (0);
+
+ if (rec->dtrd_format <= *max &&
+ (*data)[rec->dtrd_format - 1] != NULL) {
+ return (0);
+ }
+
+ bzero(&fmt, sizeof (fmt));
+ fmt.dtfd_format = rec->dtrd_format;
+ fmt.dtfd_string = NULL;
+ fmt.dtfd_length = 0;
+
+ if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ if ((fmt.dtfd_string = dt_alloc(dtp, fmt.dtfd_length)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) {
+ free(fmt.dtfd_string);
+ return (dt_set_errno(dtp, errno));
+ }
+
+ while (rec->dtrd_format > (maxformat = *max)) {
+ int new_max = maxformat ? (maxformat << 1) : 1;
+ size_t nsize = new_max * sizeof (void *);
+ size_t osize = maxformat * sizeof (void *);
+ void **new_data = dt_zalloc(dtp, nsize);
+
+ if (new_data == NULL) {
+ dt_free(dtp, fmt.dtfd_string);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bcopy(*data, new_data, osize);
+ free(*data);
+
+ *data = new_data;
+ *max = new_max;
+ }
+
+ switch (rec->dtrd_action) {
+ case DTRACEACT_DIFEXPR:
+ result = fmt.dtfd_string;
+ break;
+ case DTRACEACT_PRINTA:
+ result = dtrace_printa_create(dtp, fmt.dtfd_string);
+ dt_free(dtp, fmt.dtfd_string);
+ break;
+ default:
+ result = dtrace_printf_create(dtp, fmt.dtfd_string);
+ dt_free(dtp, fmt.dtfd_string);
+ break;
+ }
+
+ if (result == NULL)
+ return (-1);
+
+ (*data)[rec->dtrd_format - 1] = result;
+
+ return (0);
+}
+
+static int
dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id)
{
dtrace_id_t max;
- int rval, i, maxformat;
+ int rval, i;
dtrace_eprobedesc_t *enabled, *nenabled;
dtrace_probedesc_t *probe;
@@ -132,71 +205,23 @@ dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id)
}
for (i = 0; i < enabled->dtepd_nrecs; i++) {
- dtrace_fmtdesc_t fmt;
dtrace_recdesc_t *rec = &enabled->dtepd_rec[i];
- if (!DTRACEACT_ISPRINTFLIKE(rec->dtrd_action))
- continue;
-
- if (rec->dtrd_format == 0)
- continue;
-
- if (rec->dtrd_format <= dtp->dt_maxformat &&
- dtp->dt_formats[rec->dtrd_format - 1] != NULL)
- continue;
-
- bzero(&fmt, sizeof (fmt));
- fmt.dtfd_format = rec->dtrd_format;
- fmt.dtfd_string = NULL;
- fmt.dtfd_length = 0;
-
- if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) {
- rval = dt_set_errno(dtp, errno);
- goto err;
- }
-
- if ((fmt.dtfd_string = malloc(fmt.dtfd_length)) == NULL) {
- rval = dt_set_errno(dtp, EDT_NOMEM);
- goto err;
- }
-
- if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) {
- rval = dt_set_errno(dtp, errno);
- free(fmt.dtfd_string);
- goto err;
- }
-
- while (rec->dtrd_format > (maxformat = dtp->dt_maxformat)) {
- int new_max = maxformat ? (maxformat << 1) : 1;
- size_t nsize = new_max * sizeof (void *);
- size_t osize = maxformat * sizeof (void *);
- void **new_formats = malloc(nsize);
-
- if (new_formats == NULL) {
- rval = dt_set_errno(dtp, EDT_NOMEM);
- free(fmt.dtfd_string);
+ if (DTRACEACT_ISPRINTFLIKE(rec->dtrd_action)) {
+ if (dt_strdata_add(dtp, rec, &dtp->dt_formats,
+ &dtp->dt_maxformat) != 0) {
+ rval = -1;
+ goto err;
+ }
+ } else if (rec->dtrd_action == DTRACEACT_DIFEXPR) {
+ if (dt_strdata_add(dtp, rec,
+ (void ***)&dtp->dt_strdata,
+ &dtp->dt_maxstrdata) != 0) {
+ rval = -1;
goto err;
}
-
- bzero(new_formats, nsize);
- bcopy(dtp->dt_formats, new_formats, osize);
- free(dtp->dt_formats);
-
- dtp->dt_formats = new_formats;
- dtp->dt_maxformat = new_max;
}
- dtp->dt_formats[rec->dtrd_format - 1] =
- rec->dtrd_action == DTRACEACT_PRINTA ?
- dtrace_printa_create(dtp, fmt.dtfd_string) :
- dtrace_printf_create(dtp, fmt.dtfd_string);
-
- free(fmt.dtfd_string);
-
- if (dtp->dt_formats[rec->dtrd_format - 1] == NULL) {
- rval = -1; /* dt_errno is set for us */
- goto err;
- }
}
dtp->dt_pdesc[id] = probe;
@@ -440,3 +465,28 @@ dt_aggid_destroy(dtrace_hdl_t *dtp)
dtp->dt_aggdesc = NULL;
dtp->dt_maxagg = 0;
}
+
+const char *
+dt_strdata_lookup(dtrace_hdl_t *dtp, int idx)
+{
+ if (idx == 0 || idx > dtp->dt_maxstrdata)
+ return (NULL);
+
+ if (dtp->dt_strdata == NULL)
+ return (NULL);
+
+ return (dtp->dt_strdata[idx - 1]);
+}
+
+void
+dt_strdata_destroy(dtrace_hdl_t *dtp)
+{
+ int i;
+
+ for (i = 0; i < dtp->dt_maxstrdata; i++) {
+ free(dtp->dt_strdata[i]);
+ }
+
+ free(dtp->dt_strdata);
+ dtp->dt_strdata = NULL;
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
index c2d817a79e6e..eae0b016f9c9 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/types.h>
@@ -91,7 +92,7 @@
/*
* The version number should be increased for every customer visible release
- * of Solaris. The major number should be incremented when a fundamental
+ * of DTrace. The major number should be incremented when a fundamental
* change has been made that would affect all consumers, and would reflect
* sweeping changes to DTrace or the D language. The minor number should be
* incremented when a change is introduced that could break scripts that had
@@ -116,8 +117,13 @@
#define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2)
#define DT_VERS_1_6_3 DT_VERSION_NUMBER(1, 6, 3)
#define DT_VERS_1_7 DT_VERSION_NUMBER(1, 7, 0)
-#define DT_VERS_LATEST DT_VERS_1_7
-#define DT_VERS_STRING "Sun D 1.7"
+#define DT_VERS_1_7_1 DT_VERSION_NUMBER(1, 7, 1)
+#define DT_VERS_1_8 DT_VERSION_NUMBER(1, 8, 0)
+#define DT_VERS_1_8_1 DT_VERSION_NUMBER(1, 8, 1)
+#define DT_VERS_1_9 DT_VERSION_NUMBER(1, 9, 0)
+#define DT_VERS_1_9_1 DT_VERSION_NUMBER(1, 9, 1)
+#define DT_VERS_LATEST DT_VERS_1_9_1
+#define DT_VERS_STRING "Sun D 1.9.1"
const dt_version_t _dtrace_versions[] = {
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@@ -134,6 +140,11 @@ const dt_version_t _dtrace_versions[] = {
DT_VERS_1_6_2, /* D API 1.6.2 */
DT_VERS_1_6_3, /* D API 1.6.3 */
DT_VERS_1_7, /* D API 1.7 */
+ DT_VERS_1_7_1, /* D API 1.7.1 */
+ DT_VERS_1_8, /* D API 1.8 */
+ DT_VERS_1_8_1, /* D API 1.8.1 */
+ DT_VERS_1_9, /* D API 1.9 */
+ DT_VERS_1_9_1, /* D API 1.9.1 */
0
};
@@ -289,7 +300,7 @@ static const dt_ident_t _dtrace_globals[] = {
{ "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "stack(...)" },
{ "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
- &dt_idops_func, "string(int64_t)" },
+ &dt_idops_func, "string(int64_t, [int])" },
{ "llquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LLQUANTIZE, DT_ATTR_STABCMN,
DT_VERS_1_7, &dt_idops_func,
"void(@, int32_t, int32_t, int32_t, int32_t, ...)" },
@@ -351,6 +362,8 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_type, "pid_t" },
{ "ppid", DT_IDENT_SCALAR, 0, DIF_VAR_PPID, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_type, "pid_t" },
+{ "print", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINT, DT_ATTR_STABCMN, DT_VERS_1_9,
+ &dt_idops_func, "void(@)" },
{ "printa", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTA, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "void(@, ...)" },
{ "printf", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTF, DT_ATTR_STABCMN, DT_VERS_1_0,
@@ -457,11 +470,15 @@ static const dt_ident_t _dtrace_globals[] = {
{ "timestamp", DT_IDENT_SCALAR, 0, DIF_VAR_TIMESTAMP,
DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_type, "uint64_t" },
+{ "tolower", DT_IDENT_FUNC, 0, DIF_SUBR_TOLOWER, DT_ATTR_STABCMN, DT_VERS_1_8,
+ &dt_idops_func, "string(const char *)" },
+{ "toupper", DT_IDENT_FUNC, 0, DIF_SUBR_TOUPPER, DT_ATTR_STABCMN, DT_VERS_1_8,
+ &dt_idops_func, "string(const char *)" },
{ "trace", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACE, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "void(@)" },
{ "tracemem", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACEMEM,
DT_ATTR_STABCMN, DT_VERS_1_0,
- &dt_idops_func, "void(@, size_t)" },
+ &dt_idops_func, "void(@, size_t, ...)" },
{ "trunc", DT_IDENT_ACTFUNC, 0, DT_ACT_TRUNC, DT_ATTR_STABCMN,
DT_VERS_1_0, &dt_idops_func, "void(...)" },
{ "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1,
@@ -1115,7 +1132,7 @@ alloc:
#if defined(sun)
dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
#else
- dtp->dt_prcmode = DT_PROC_STOP_MAIN;
+ dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
#endif
dtp->dt_linkmode = DT_LINK_KERNEL;
dtp->dt_linktype = DT_LTYP_ELF;
@@ -1136,7 +1153,7 @@ alloc:
dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *));
dtp->dt_provbuckets = _dtrace_strbuckets;
dtp->dt_provs = calloc(dtp->dt_provbuckets, sizeof (dt_provider_t *));
- dt_proc_hash_create(dtp);
+ dt_proc_init(dtp);
dtp->dt_vmax = DT_VERS_LATEST;
dtp->dt_cpp_path = strdup(_dtrace_defcpp);
dtp->dt_cpp_argv = malloc(sizeof (char *));
@@ -1150,8 +1167,9 @@ alloc:
(void) uname(&dtp->dt_uts);
if (dtp->dt_mods == NULL || dtp->dt_provs == NULL ||
- dtp->dt_procs == NULL || dtp->dt_ld_path == NULL ||
- dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL)
+ dtp->dt_procs == NULL || dtp->dt_proc_env == NULL ||
+ dtp->dt_ld_path == NULL || dtp->dt_cpp_path == NULL ||
+ dtp->dt_cpp_argv == NULL)
return (set_open_errno(dtp, errp, EDT_NOMEM));
for (i = 0; i < DTRACEOPT_MAX; i++)
@@ -1563,7 +1581,7 @@ dtrace_close(dtrace_hdl_t *dtp)
int i;
if (dtp->dt_procs != NULL)
- dt_proc_hash_destroy(dtp);
+ dt_proc_fini(dtp);
while ((pgp = dt_list_next(&dtp->dt_programs)) != NULL)
dt_program_destroy(dtp, pgp);
@@ -1612,9 +1630,9 @@ dtrace_close(dtrace_hdl_t *dtp)
dt_epid_destroy(dtp);
dt_aggid_destroy(dtp);
dt_format_destroy(dtp);
+ dt_strdata_destroy(dtp);
dt_buffered_destroy(dtp);
dt_aggregate_destroy(dtp);
- free(dtp->dt_buf.dtbd_data);
dt_pfdict_destroy(dtp);
dt_provmod_destroy(&dtp->dt_provmod);
dt_dof_fini(dtp);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
index fa1407f83c12..020df2fe73e2 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
@@ -26,6 +26,10 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#include <sys/resource.h>
#include <sys/mman.h>
#include <sys/types.h>
@@ -368,6 +372,61 @@ dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
return (0);
}
+static int
+dt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char **p;
+ char *var;
+ int i;
+
+ /*
+ * We can't effectively set environment variables from #pragma lines
+ * since the processes have already been spawned.
+ */
+ if (dtp->dt_pcb != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (!option && strchr(arg, '=') != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++)
+ continue;
+
+ for (p = dtp->dt_proc_env; *p != NULL; p++) {
+ var = strchr(*p, '=');
+ if (var == NULL)
+ var = *p + strlen(*p);
+ if (strncmp(*p, arg, var - *p) == 0) {
+ dt_free(dtp, *p);
+ *p = dtp->dt_proc_env[i - 1];
+ dtp->dt_proc_env[i - 1] = NULL;
+ i--;
+ }
+ }
+
+ if (option) {
+ if ((var = strdup(arg)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) {
+ dt_free(dtp, var);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bcopy(dtp->dt_proc_env, p, sizeof (char *) * i);
+ dt_free(dtp, dtp->dt_proc_env);
+ dtp->dt_proc_env = p;
+
+ dtp->dt_proc_env[i - 1] = var;
+ dtp->dt_proc_env[i] = NULL;
+ }
+
+ return (0);
+}
+
/*ARGSUSED*/
static int
dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
@@ -411,7 +470,6 @@ dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
return (0);
}
-
/*ARGSUSED*/
static int
dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
@@ -912,6 +970,7 @@ static const dt_option_t _dtrace_ctoptions[] = {
{ "pgmax", dt_opt_pgmax },
{ "preallocate", dt_opt_preallocate },
{ "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
+ { "setenv", dt_opt_setenv, 1 },
{ "stdc", dt_opt_stdc },
{ "strip", dt_opt_dflags, DTRACE_D_STRIP },
{ "syslibdir", dt_opt_syslibdir },
@@ -920,6 +979,7 @@ static const dt_option_t _dtrace_ctoptions[] = {
{ "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
{ "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
{ "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
+ { "unsetenv", dt_opt_setenv, 0 },
{ "verbose", dt_opt_cflags, DTRACE_C_DIFV },
{ "version", dt_opt_version },
{ "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
@@ -947,6 +1007,7 @@ static const dt_option_t _dtrace_rtoptions[] = {
{ "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
{ "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
{ "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
+ { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL },
{ NULL, NULL, 0 }
};
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
index aafe6479f9ab..5b3be7de728e 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -23,6 +23,7 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -96,6 +97,7 @@
*/
#include <sys/param.h>
+#include <sys/sysmacros.h>
#include <limits.h>
#include <setjmp.h>
#include <strings.h>
@@ -1862,6 +1864,38 @@ dt_node_op1(int op, dt_node_t *cp)
return (dnp);
}
+/*
+ * If an integer constant is being cast to another integer type, we can
+ * perform the cast as part of integer constant folding in this pass. We must
+ * take action when the integer is being cast to a smaller type or if it is
+ * changing signed-ness. If so, we first shift rp's bits bits high (losing
+ * excess bits if narrowing) and then shift them down with either a logical
+ * shift (unsigned) or arithmetic shift (signed).
+ */
+static void
+dt_cast(dt_node_t *lp, dt_node_t *rp)
+{
+ size_t srcsize = dt_node_type_size(rp);
+ size_t dstsize = dt_node_type_size(lp);
+
+ if (dstsize < srcsize) {
+ int n = (sizeof (uint64_t) - dstsize) * NBBY;
+ rp->dn_value <<= n;
+ rp->dn_value >>= n;
+ } else if (dstsize > srcsize) {
+ int n = (sizeof (uint64_t) - srcsize) * NBBY;
+ int s = (dstsize - srcsize) * NBBY;
+
+ rp->dn_value <<= n;
+ if (rp->dn_flags & DT_NF_SIGNED) {
+ rp->dn_value = (intmax_t)rp->dn_value >> s;
+ rp->dn_value >>= n - s;
+ } else {
+ rp->dn_value >>= n;
+ }
+ }
+}
+
dt_node_t *
dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
{
@@ -2011,32 +2045,9 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
}
}
- /*
- * If an integer constant is being cast to another integer type, we can
- * perform the cast as part of integer constant folding in this pass.
- * We must take action when the integer is being cast to a smaller type
- * or if it is changing signed-ness. If so, we first shift rp's bits
- * bits high (losing excess bits if narrowing) and then shift them down
- * with either a logical shift (unsigned) or arithmetic shift (signed).
- */
if (op == DT_TOK_LPAR && rp->dn_kind == DT_NODE_INT &&
dt_node_is_integer(lp)) {
- size_t srcsize = dt_node_type_size(rp);
- size_t dstsize = dt_node_type_size(lp);
-
- if ((dstsize < srcsize) || ((lp->dn_flags & DT_NF_SIGNED) ^
- (rp->dn_flags & DT_NF_SIGNED))) {
- int n = dstsize < srcsize ?
- (sizeof (uint64_t) * NBBY - dstsize * NBBY) :
- (sizeof (uint64_t) * NBBY - srcsize * NBBY);
-
- rp->dn_value <<= n;
- if (lp->dn_flags & DT_NF_SIGNED)
- rp->dn_value = (intmax_t)rp->dn_value >> n;
- else
- rp->dn_value = rp->dn_value >> n;
- }
-
+ dt_cast(lp, rp);
dt_node_type_propagate(lp, rp);
dt_node_attr_assign(rp, dt_attr_min(lp->dn_attr, rp->dn_attr));
dt_node_free(lp);
@@ -2895,14 +2906,14 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
case DT_TOK_DEREF:
/*
* If the deref operator is applied to a translated pointer,
- * we can just set our output type to the base translation.
+ * we set our output type to the output of the translation.
*/
if ((idp = dt_node_resolve(cp, DT_IDENT_XLPTR)) != NULL) {
dt_xlator_t *dxp = idp->di_data;
dnp->dn_ident = &dxp->dx_souid;
dt_node_type_assign(dnp,
- DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type);
break;
}
@@ -3078,6 +3089,31 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
return (dnp);
}
+static void
+dt_assign_common(dt_node_t *dnp)
+{
+ dt_node_t *lp = dnp->dn_left;
+ dt_node_t *rp = dnp->dn_right;
+ int op = dnp->dn_op;
+
+ if (rp->dn_kind == DT_NODE_INT)
+ dt_cast(lp, rp);
+
+ if (!(lp->dn_flags & DT_NF_LVALUE)) {
+ xyerror(D_OP_LVAL, "operator %s requires modifiable "
+ "lvalue as an operand\n", opstr(op));
+ /* see K&R[A7.17] */
+ }
+
+ if (!(lp->dn_flags & DT_NF_WRITABLE)) {
+ xyerror(D_OP_WRITE, "operator %s can only be applied "
+ "to a writable variable\n", opstr(op));
+ }
+
+ dt_node_type_propagate(lp, dnp); /* see K&R[A7.17] */
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+}
+
static dt_node_t *
dt_cook_op2(dt_node_t *dnp, uint_t idflags)
{
@@ -3556,19 +3592,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
}
}
asgn_common:
- if (!(lp->dn_flags & DT_NF_LVALUE)) {
- xyerror(D_OP_LVAL, "operator %s requires modifiable "
- "lvalue as an operand\n", opstr(op));
- /* see K&R[A7.17] */
- }
-
- if (!(lp->dn_flags & DT_NF_WRITABLE)) {
- xyerror(D_OP_WRITE, "operator %s can only be applied "
- "to a writable variable\n", opstr(op));
- }
-
- dt_node_type_propagate(lp, dnp); /* see K&R[A7.17] */
- dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ dt_assign_common(dnp);
break;
case DT_TOK_PTR:
@@ -3873,6 +3897,14 @@ asgn_common:
dt_node_type_propagate(lp, dnp); /* see K&R[A7.5] */
dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+
+ /*
+ * If it's a pointer then should be able to (attempt to)
+ * assign to it.
+ */
+ if (lkind == CTF_K_POINTER)
+ dnp->dn_flags |= DT_NF_WRITABLE;
+
break;
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c
new file mode 100644
index 000000000000..a16397174dc0
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c
@@ -0,0 +1,161 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <dtrace.h>
+#include <dt_impl.h>
+#include <dt_pq.h>
+#include <assert.h>
+
+/*
+ * Create a new priority queue.
+ *
+ * size is the maximum number of items that will be stored in the priority
+ * queue at one time.
+ */
+dt_pq_t *
+dt_pq_init(dtrace_hdl_t *dtp, uint_t size, dt_pq_value_f value_cb, void *cb_arg)
+{
+ dt_pq_t *p;
+ assert(size > 1);
+
+ if ((p = dt_zalloc(dtp, sizeof (dt_pq_t))) == NULL)
+ return (NULL);
+
+ p->dtpq_items = dt_zalloc(dtp, size * sizeof (p->dtpq_items[0]));
+ if (p->dtpq_items == NULL) {
+ dt_free(dtp, p);
+ return (NULL);
+ }
+
+ p->dtpq_hdl = dtp;
+ p->dtpq_size = size;
+ p->dtpq_last = 1;
+ p->dtpq_value = value_cb;
+ p->dtpq_arg = cb_arg;
+
+ return (p);
+}
+
+void
+dt_pq_fini(dt_pq_t *p)
+{
+ dtrace_hdl_t *dtp = p->dtpq_hdl;
+
+ dt_free(dtp, p->dtpq_items);
+ dt_free(dtp, p);
+}
+
+static uint64_t
+dt_pq_getvalue(dt_pq_t *p, uint_t index)
+{
+ void *item = p->dtpq_items[index];
+ return (p->dtpq_value(item, p->dtpq_arg));
+}
+
+void
+dt_pq_insert(dt_pq_t *p, void *item)
+{
+ uint_t i;
+
+#if !defined(sun)
+ if (p->dtpq_last >= p->dtpq_size)
+ return;
+#endif
+ assert(p->dtpq_last < p->dtpq_size);
+
+ i = p->dtpq_last++;
+ p->dtpq_items[i] = item;
+
+ while (i > 1 && dt_pq_getvalue(p, i) < dt_pq_getvalue(p, i / 2)) {
+ void *tmp = p->dtpq_items[i];
+ p->dtpq_items[i] = p->dtpq_items[i / 2];
+ p->dtpq_items[i / 2] = tmp;
+ i /= 2;
+ }
+}
+
+/*
+ * Return elements from the priority queue. *cookie should be zero when first
+ * called. Returns NULL when there are no more elements.
+ */
+void *
+dt_pq_walk(dt_pq_t *p, uint_t *cookie)
+{
+ (*cookie)++;
+ if (*cookie >= p->dtpq_last)
+ return (NULL);
+
+ return (p->dtpq_items[*cookie]);
+}
+
+void *
+dt_pq_pop(dt_pq_t *p)
+{
+ uint_t i = 1;
+ void *ret;
+
+ assert(p->dtpq_last > 0);
+
+ if (p->dtpq_last == 1)
+ return (NULL);
+
+ ret = p->dtpq_items[1];
+
+ p->dtpq_last--;
+ p->dtpq_items[1] = p->dtpq_items[p->dtpq_last];
+ p->dtpq_items[p->dtpq_last] = NULL;
+
+ for (;;) {
+ uint_t lc = i * 2;
+ uint_t rc = i * 2 + 1;
+ uint_t c;
+ uint64_t v;
+ void *tmp;
+
+ if (lc >= p->dtpq_last)
+ break;
+
+ if (rc >= p->dtpq_last) {
+ c = lc;
+ v = dt_pq_getvalue(p, lc);
+ } else {
+ uint64_t lv = dt_pq_getvalue(p, lc);
+ uint64_t rv = dt_pq_getvalue(p, rc);
+
+ if (lv < rv) {
+ c = lc;
+ v = lv;
+ } else {
+ c = rc;
+ v = rv;
+ }
+ }
+
+ if (v >= dt_pq_getvalue(p, i))
+ break;
+
+ tmp = p->dtpq_items[i];
+ p->dtpq_items[i] = p->dtpq_items[c];
+ p->dtpq_items[c] = tmp;
+
+ i = c;
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.h
new file mode 100644
index 000000000000..8184a90c6656
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.h
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef _DT_PQ_H
+#define _DT_PQ_H
+
+#include <dtrace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint64_t (*dt_pq_value_f)(void *, void *);
+
+typedef struct dt_pq {
+ dtrace_hdl_t *dtpq_hdl; /* dtrace handle */
+ void **dtpq_items; /* array of elements */
+ uint_t dtpq_size; /* count of allocated elements */
+ uint_t dtpq_last; /* next free slot */
+ dt_pq_value_f dtpq_value; /* callback to get the value */
+ void *dtpq_arg; /* callback argument */
+} dt_pq_t;
+
+extern dt_pq_t *dt_pq_init(dtrace_hdl_t *, uint_t size, dt_pq_value_f, void *);
+extern void dt_pq_fini(dt_pq_t *);
+
+extern void dt_pq_insert(dt_pq_t *, void *);
+extern void *dt_pq_pop(dt_pq_t *);
+extern void *dt_pq_walk(dt_pq_t *, uint_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PQ_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
index 00578f43350f..760c2f675788 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
@@ -241,6 +241,8 @@ dt_pragma_depends(const char *prname, dt_node_t *cnp)
int found;
dt_lib_depend_t *dld;
char lib[MAXPATHLEN];
+ size_t plen;
+ char *provs, *cpy, *tok;
if (cnp == NULL || nnp == NULL ||
cnp->dn_kind != DT_NODE_IDENT || nnp->dn_kind != DT_NODE_IDENT) {
@@ -248,9 +250,31 @@ dt_pragma_depends(const char *prname, dt_node_t *cnp)
"<class> <name>\n", prname);
}
- if (strcmp(cnp->dn_string, "provider") == 0)
- found = dt_provider_lookup(dtp, nnp->dn_string) != NULL;
- else if (strcmp(cnp->dn_string, "module") == 0) {
+ if (strcmp(cnp->dn_string, "provider") == 0) {
+ /*
+ * First try to get the provider list using the
+ * debug.dtrace.providers sysctl, since that'll work even if
+ * we're not running as root.
+ */
+ provs = NULL;
+ if (sysctlbyname("debug.dtrace.providers", NULL, &plen, NULL, 0) ||
+ ((provs = dt_alloc(dtp, plen)) == NULL) ||
+ sysctlbyname("debug.dtrace.providers", provs, &plen, NULL, 0))
+ found = dt_provider_lookup(dtp, nnp->dn_string) != NULL;
+ else {
+ found = B_FALSE;
+ for (cpy = provs; (tok = strsep(&cpy, " ")) != NULL; )
+ if (strcmp(tok, nnp->dn_string) == 0) {
+ found = B_TRUE;
+ break;
+ }
+ if (found == B_FALSE)
+ found = dt_provider_lookup(dtp,
+ nnp->dn_string) != NULL;
+ }
+ if (provs != NULL)
+ dt_free(dtp, provs);
+ } else if (strcmp(cnp->dn_string, "module") == 0) {
dt_module_t *mp = dt_module_lookup_by_name(dtp, nnp->dn_string);
found = mp != NULL && dt_module_getctf(dtp, mp) != NULL;
} else if (strcmp(cnp->dn_string, "library") == 0) {
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
new file mode 100644
index 000000000000..261fc8ced4d5
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
@@ -0,0 +1,648 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+/*
+ * DTrace print() action
+ *
+ * This file contains the post-processing logic for the print() action. The
+ * print action behaves identically to trace() in that it generates a
+ * DTRACEACT_DIFEXPR action, but the action argument field refers to a CTF type
+ * string stored in the DOF string table (similar to printf formats). We
+ * take the result of the trace action and post-process it in the fashion of
+ * MDB's ::print dcmd.
+ *
+ * This implementation differs from MDB's in the following ways:
+ *
+ * - We do not expose any options or flags. The behavior of print() is
+ * equivalent to "::print -tn".
+ *
+ * - MDB will display "holes" in structures (unused padding between
+ * members).
+ *
+ * - When printing arrays of structures, MDB will leave a trailing ','
+ * after the last element.
+ *
+ * - MDB will print time_t types as date and time.
+ *
+ * - MDB will detect when an enum is actually the OR of several flags,
+ * and print it out with the constituent flags separated.
+ *
+ * - For large arrays, MDB will print the first few members and then
+ * print a "..." continuation line.
+ *
+ * - MDB will break and wrap arrays at 80 columns.
+ *
+ * - MDB prints out floats and doubles by hand, as it must run in kmdb
+ * context. We're able to leverage the printf() format strings,
+ * but the result is a slightly different format.
+ */
+
+#include <sys/sysmacros.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <alloca.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <dt_module.h>
+#include <dt_printf.h>
+#include <dt_string.h>
+#include <dt_impl.h>
+
+/* determines whether the given integer CTF encoding is a character */
+#define CTF_IS_CHAR(e) \
+ (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == \
+ (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY)
+/* determines whether the given CTF kind is a struct or union */
+#define CTF_IS_STRUCTLIKE(k) \
+ ((k) == CTF_K_STRUCT || (k) == CTF_K_UNION)
+
+/*
+ * Print structure passed down recursively through printing algorithm.
+ */
+typedef struct dt_printarg {
+ caddr_t pa_addr; /* base address of trace data */
+ ctf_file_t *pa_ctfp; /* CTF container */
+ int pa_depth; /* member depth */
+ int pa_nest; /* nested array depth */
+ FILE *pa_file; /* output file */
+} dt_printarg_t;
+
+static int dt_print_member(const char *, ctf_id_t, ulong_t, int, void *);
+
+/*
+ * Safe version of ctf_type_name() that will fall back to just "<ctfid>" if it
+ * can't resolve the type.
+ */
+static void
+dt_print_type_name(ctf_file_t *ctfp, ctf_id_t id, char *buf, size_t buflen)
+{
+ if (ctf_type_name(ctfp, id, buf, buflen) == NULL)
+ (void) snprintf(buf, buflen, "<%ld>", id);
+}
+
+/*
+ * Print any necessary trailing braces for structures or unions. We don't get
+ * invoked when a struct or union ends, so we infer the need to print braces
+ * based on the depth the last time we printed something and the new depth.
+ */
+static void
+dt_print_trailing_braces(dt_printarg_t *pap, int depth)
+{
+ int d;
+
+ for (d = pap->pa_depth; d > depth; d--) {
+ (void) fprintf(pap->pa_file, "%*s}%s",
+ (d + pap->pa_nest - 1) * 4, "",
+ d == depth + 1 ? "" : "\n");
+ }
+}
+
+/*
+ * Print the appropriate amount of indentation given the current depth and
+ * array nesting.
+ */
+static void
+dt_print_indent(dt_printarg_t *pap)
+{
+ (void) fprintf(pap->pa_file, "%*s",
+ (pap->pa_depth + pap->pa_nest) * 4, "");
+}
+
+/*
+ * Print a bitfield. It's worth noting that the D compiler support for
+ * bitfields is currently broken; printing "D`user_desc_t" (pulled in by the
+ * various D provider files) will produce incorrect results compared to
+ * "genunix`user_desc_t".
+ */
+static void
+print_bitfield(dt_printarg_t *pap, ulong_t off, ctf_encoding_t *ep)
+{
+ FILE *fp = pap->pa_file;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+ uint64_t mask = (1ULL << ep->cte_bits) - 1;
+ uint64_t value = 0;
+ size_t size = (ep->cte_bits + (NBBY - 1)) / NBBY;
+ uint8_t *buf = (uint8_t *)&value;
+ uint8_t shift;
+
+ /*
+ * On big-endian machines, we need to adjust the buf pointer to refer
+ * to the lowest 'size' bytes in 'value', and we need to shift based on
+ * the offset from the end of the data, not the offset of the start.
+ */
+#ifdef _BIG_ENDIAN
+ buf += sizeof (value) - size;
+ off += ep->cte_bits;
+#endif
+ bcopy(addr, buf, size);
+ shift = off % NBBY;
+
+ /*
+ * Offsets are counted from opposite ends on little- and
+ * big-endian machines.
+ */
+#ifdef _BIG_ENDIAN
+ shift = NBBY - shift;
+#endif
+
+ /*
+ * If the bits we want do not begin on a byte boundary, shift the data
+ * right so that the value is in the lowest 'cte_bits' of 'value'.
+ */
+ if (off % NBBY != 0)
+ value >>= shift;
+ value &= mask;
+
+ (void) fprintf(fp, "%#llx", (u_longlong_t)value);
+}
+
+/*
+ * Dump the contents of memory as a fixed-size integer in hex.
+ */
+static void
+dt_print_hex(FILE *fp, caddr_t addr, size_t size)
+{
+ switch (size) {
+ case sizeof (uint8_t):
+ (void) fprintf(fp, "%#x", *(uint8_t *)addr);
+ break;
+ case sizeof (uint16_t):
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%#x", *(uint16_t *)addr);
+ break;
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%#x", *(uint32_t *)addr);
+ break;
+ case sizeof (uint64_t):
+ (void) fprintf(fp, "%#llx",
+ /* LINTED - alignment */
+ (unsigned long long)*(uint64_t *)addr);
+ break;
+ default:
+ (void) fprintf(fp, "<invalid size %u>", (uint_t)size);
+ }
+}
+
+/*
+ * Print an integer type. Before dumping the contents via dt_print_hex(), we
+ * first check the encoding to see if it's part of a bitfield or a character.
+ */
+static void
+dt_print_int(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ ctf_encoding_t e;
+ size_t size;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+
+ if (ctf_type_encoding(ctfp, base, &e) == CTF_ERR) {
+ (void) fprintf(fp, "<unknown encoding>");
+ return;
+ }
+
+ /*
+ * This comes from MDB - it's not clear under what circumstances this
+ * would be found.
+ */
+ if (e.cte_format & CTF_INT_VARARGS) {
+ (void) fprintf(fp, "...");
+ return;
+ }
+
+ /*
+ * We print this as a bitfield if the bit encoding indicates it's not
+ * an even power of two byte size, or is larger than 8 bytes.
+ */
+ size = e.cte_bits / NBBY;
+ if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1)) != 0) {
+ print_bitfield(pap, off, &e);
+ return;
+ }
+
+ /*
+ * If this is a character, print it out as such.
+ */
+ if (CTF_IS_CHAR(e)) {
+ char c = *(char *)addr;
+ if (isprint(c))
+ (void) fprintf(fp, "'%c'", c);
+ else if (c == 0)
+ (void) fprintf(fp, "'\\0'");
+ else
+ (void) fprintf(fp, "'\\%03o'", c);
+ return;
+ }
+
+ dt_print_hex(fp, addr, size);
+}
+
+/*
+ * Print a floating point (float, double, long double) value.
+ */
+/* ARGSUSED */
+static void
+dt_print_float(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ ctf_encoding_t e;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+
+ if (ctf_type_encoding(ctfp, base, &e) == 0) {
+ if (e.cte_format == CTF_FP_SINGLE &&
+ e.cte_bits == sizeof (float) * NBBY) {
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%+.7e", *((float *)addr));
+ } else if (e.cte_format == CTF_FP_DOUBLE &&
+ e.cte_bits == sizeof (double) * NBBY) {
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%+.7e", *((double *)addr));
+ } else if (e.cte_format == CTF_FP_LDOUBLE &&
+ e.cte_bits == sizeof (long double) * NBBY) {
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%+.16LE", *((long double *)addr));
+ } else {
+ (void) fprintf(fp, "<unknown encoding>");
+ }
+ }
+}
+
+/*
+ * A pointer is printed as a fixed-size integer. This is used both for
+ * pointers and functions.
+ */
+static void
+dt_print_ptr(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+ size_t size = ctf_type_size(ctfp, base);
+
+ dt_print_hex(fp, addr, size);
+}
+
+/*
+ * Print out an array. This is somewhat complex, as we must manually visit
+ * each member, and recursively invoke ctf_type_visit() for each member. If
+ * the members are non-structs, then we print them out directly:
+ *
+ * [ 0x14, 0x2e, 0 ]
+ *
+ * If they are structs, then we print out the necessary leading and trailing
+ * braces, to end up with:
+ *
+ * [
+ * type {
+ * ...
+ * },
+ * type {
+ * ...
+ * }
+ * ]
+ *
+ * We also use a heuristic to detect whether the array looks like a character
+ * array. If the encoding indicates it's a character, and we have all
+ * printable characters followed by a null byte, then we display it as a
+ * string:
+ *
+ * [ "string" ]
+ */
+static void
+dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+ ctf_arinfo_t car;
+ ssize_t eltsize;
+ ctf_encoding_t e;
+ int i;
+ boolean_t isstring;
+ int kind;
+ ctf_id_t rtype;
+
+ if (ctf_array_info(ctfp, base, &car) == CTF_ERR) {
+ (void) fprintf(fp, "0x%p", (void *)addr);
+ return;
+ }
+
+ if ((eltsize = ctf_type_size(ctfp, car.ctr_contents)) < 0 ||
+ (rtype = ctf_type_resolve(ctfp, car.ctr_contents)) == CTF_ERR ||
+ (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR) {
+ (void) fprintf(fp, "<invalid type %lu>", car.ctr_contents);
+ return;
+ }
+
+ /* see if this looks like a string */
+ isstring = B_FALSE;
+ if (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(ctfp, rtype, &e) != CTF_ERR && CTF_IS_CHAR(e)) {
+ char c;
+ for (i = 0; i < car.ctr_nelems; i++) {
+ c = *((char *)addr + eltsize * i);
+ if (!isprint(c) || c == '\0')
+ break;
+ }
+
+ if (i != car.ctr_nelems && c == '\0')
+ isstring = B_TRUE;
+ }
+
+ /*
+ * As a slight aesthetic optimization, if we are a top-level type, then
+ * don't bother printing out the brackets. This lets print("foo") look
+ * like:
+ *
+ * string "foo"
+ *
+ * As D will internally represent this as a char[256] array.
+ */
+ if (!isstring || pap->pa_depth != 0)
+ (void) fprintf(fp, "[ ");
+
+ if (isstring)
+ (void) fprintf(fp, "\"");
+
+ for (i = 0; i < car.ctr_nelems; i++) {
+ if (isstring) {
+ char c = *((char *)addr + eltsize * i);
+ if (c == '\0')
+ break;
+ (void) fprintf(fp, "%c", c);
+ } else {
+ /*
+ * Recursively invoke ctf_type_visit() on each member.
+ * We setup a new printarg struct with 'pa_nest' set to
+ * indicate that we are within a nested array.
+ */
+ dt_printarg_t pa = *pap;
+ pa.pa_nest += pap->pa_depth + 1;
+ pa.pa_depth = 0;
+ pa.pa_addr = addr + eltsize * i;
+ (void) ctf_type_visit(ctfp, car.ctr_contents,
+ dt_print_member, &pa);
+
+ dt_print_trailing_braces(&pa, 0);
+ if (i != car.ctr_nelems - 1)
+ (void) fprintf(fp, ", ");
+ else if (CTF_IS_STRUCTLIKE(kind))
+ (void) fprintf(fp, "\n");
+ }
+ }
+
+ if (isstring)
+ (void) fprintf(fp, "\"");
+
+ if (!isstring || pap->pa_depth != 0) {
+ if (CTF_IS_STRUCTLIKE(kind))
+ dt_print_indent(pap);
+ else
+ (void) fprintf(fp, " ");
+ (void) fprintf(fp, "]");
+ }
+}
+
+/*
+ * This isued by both structs and unions to print the leading brace.
+ */
+/* ARGSUSED */
+static void
+dt_print_structlike(ctf_id_t id, ulong_t off, dt_printarg_t *pap)
+{
+ (void) fprintf(pap->pa_file, "{");
+}
+
+/*
+ * For enums, we try to print the enum name, and fall back to the value if it
+ * can't be determined. We do not do any fancy flag processing like mdb.
+ */
+/* ARGSUSED */
+static void
+dt_print_enum(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ const char *ename;
+ int value = 0;
+
+ if ((ename = ctf_enum_name(ctfp, base, value)) != NULL)
+ (void) fprintf(fp, "%s", ename);
+ else
+ (void) fprintf(fp, "%d", value);
+}
+
+/*
+ * Forward declaration. There's not much to do here without the complete
+ * type information, so just print out this fact and drive on.
+ */
+/* ARGSUSED */
+static void
+dt_print_tag(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ (void) fprintf(pap->pa_file, "<forward decl>");
+}
+
+typedef void dt_printarg_f(ctf_id_t, ulong_t, dt_printarg_t *);
+
+static dt_printarg_f *const dt_printfuncs[] = {
+ dt_print_int, /* CTF_K_INTEGER */
+ dt_print_float, /* CTF_K_FLOAT */
+ dt_print_ptr, /* CTF_K_POINTER */
+ dt_print_array, /* CTF_K_ARRAY */
+ dt_print_ptr, /* CTF_K_FUNCTION */
+ dt_print_structlike, /* CTF_K_STRUCT */
+ dt_print_structlike, /* CTF_K_UNION */
+ dt_print_enum, /* CTF_K_ENUM */
+ dt_print_tag /* CTF_K_FORWARD */
+};
+
+/*
+ * Print one member of a structure. This callback is invoked from
+ * ctf_type_visit() recursively.
+ */
+static int
+dt_print_member(const char *name, ctf_id_t id, ulong_t off, int depth,
+ void *data)
+{
+ char type[DT_TYPE_NAMELEN];
+ int kind;
+ dt_printarg_t *pap = data;
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ boolean_t arraymember;
+ boolean_t brief;
+ ctf_encoding_t e;
+ ctf_id_t rtype;
+
+ dt_print_trailing_braces(pap, depth);
+ /*
+ * dt_print_trailing_braces() doesn't include the trailing newline; add
+ * it here if necessary.
+ */
+ if (depth < pap->pa_depth)
+ (void) fprintf(fp, "\n");
+ pap->pa_depth = depth;
+
+ if ((rtype = ctf_type_resolve(ctfp, id)) == CTF_ERR ||
+ (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR ||
+ kind < CTF_K_INTEGER || kind > CTF_K_FORWARD) {
+ dt_print_indent(pap);
+ (void) fprintf(fp, "%s = <invalid type %lu>", name, id);
+ return (0);
+ }
+
+ dt_print_type_name(ctfp, id, type, sizeof (type));
+
+ arraymember = (pap->pa_nest != 0 && depth == 0);
+ brief = (arraymember && !CTF_IS_STRUCTLIKE(kind));
+
+ if (!brief) {
+ /*
+ * If this is a direct array member and a struct (otherwise
+ * brief would be true), then print a trailing newline, as the
+ * array printing code doesn't include it because it might be a
+ * simple type.
+ */
+ if (arraymember)
+ (void) fprintf(fp, "\n");
+ dt_print_indent(pap);
+
+ /* always print the type */
+ (void) fprintf(fp, "%s", type);
+ if (name[0] != '\0') {
+ /*
+ * For aesthetics, we don't include a space between the
+ * type name and member name if the type is a pointer.
+ * This will give us "void *foo =" instead of "void *
+ * foo =". Unions also have the odd behavior that the
+ * type name is returned as "union ", with a trailing
+ * space, so we also avoid printing a space if the type
+ * name already ends with a space.
+ */
+ if (type[strlen(type) - 1] != '*' &&
+ type[strlen(type) -1] != ' ') {
+ (void) fprintf(fp, " ");
+ }
+ (void) fprintf(fp, "%s", name);
+
+ /*
+ * If this looks like a bitfield, or is an integer not
+ * aligned on a byte boundary, print the number of
+ * bits after the name.
+ */
+ if (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(ctfp, id, &e) == 0) {
+ ulong_t bits = e.cte_bits;
+ ulong_t size = bits / NBBY;
+
+ if (bits % NBBY != 0 ||
+ off % NBBY != 0 ||
+ size > 8 ||
+ size != ctf_type_size(ctfp, id)) {
+ (void) fprintf(fp, " :%lu", bits);
+ }
+ }
+
+ (void) fprintf(fp, " =");
+ }
+ (void) fprintf(fp, " ");
+ }
+
+ dt_printfuncs[kind - 1](rtype, off, pap);
+
+ /* direct simple array members are not separated by newlines */
+ if (!brief)
+ (void) fprintf(fp, "\n");
+
+ return (0);
+}
+
+/*
+ * Main print function invoked by dt_consume_cpu().
+ */
+int
+dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
+ caddr_t addr, size_t len)
+{
+ const char *s;
+ char *object;
+ dt_printarg_t pa;
+ ctf_id_t id;
+ dt_module_t *dmp;
+
+ /*
+ * Split the fully-qualified type ID (module`id). This should
+ * always be the format, but if for some reason we don't find the
+ * expected value, return 0 to fall back to the generic trace()
+ * behavior.
+ */
+ for (s = typename; *s != '\0' && *s != '`'; s++)
+ ;
+
+ if (*s != '`')
+ return (0);
+
+ object = alloca(s - typename + 1);
+ bcopy(typename, object, s - typename);
+ object[s - typename] = '\0';
+ id = atoi(s + 1);
+
+ /*
+ * Try to get the CTF kind for this id. If something has gone horribly
+ * wrong and we can't resolve the ID, bail out and let trace() do the
+ * work.
+ */
+ dmp = dt_module_lookup_by_name(dtp, object);
+ if (dmp == NULL || ctf_type_kind(dt_module_getctf(dtp, dmp),
+ id) == CTF_ERR) {
+ return (0);
+ }
+
+ /* setup the print structure and kick off the main print routine */
+ pa.pa_addr = addr;
+ pa.pa_ctfp = dt_module_getctf(dtp, dmp);
+ pa.pa_nest = 0;
+ pa.pa_depth = 0;
+ pa.pa_file = fp;
+ (void) ctf_type_visit(pa.pa_ctfp, id, dt_print_member, &pa);
+
+ dt_print_trailing_braces(&pa, 0);
+
+ return (len);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
index 51f87b03ffd9..24682b2f086e 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#if defined(sun)
@@ -161,7 +162,7 @@ static int
pfcheck_dint(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
{
if (dnp->dn_flags & DT_NF_SIGNED)
- pfd->pfd_flags |= DT_PFCONV_SIGNED;
+ pfd->pfd_fmt[strlen(pfd->pfd_fmt) - 1] = 'i';
else
pfd->pfd_fmt[strlen(pfd->pfd_fmt) - 1] = 'u';
@@ -664,7 +665,7 @@ static const dt_pfconv_t _dtrace_conversions[] = {
{ "hu", "u", "unsigned short", pfcheck_type, pfprint_uint },
{ "hx", "x", "short", pfcheck_xshort, pfprint_uint },
{ "hX", "X", "short", pfcheck_xshort, pfprint_uint },
-{ "i", "i", pfproto_xint, pfcheck_dint, pfprint_dint },
+{ "i", "i", pfproto_xint, pfcheck_xint, pfprint_sint },
{ "I", "s", pfproto_cstr, pfcheck_str, pfprint_inetaddr },
{ "k", "s", "stack", pfcheck_stack, pfprint_stack },
{ "lc", "lc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wint_t */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
index d40a0ae1eb18..45eb5a36da7e 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
@@ -25,6 +25,10 @@
*/
/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
* DTrace Process Control
*
* This file provides a set of routines that permit libdtrace and its clients
@@ -503,7 +507,7 @@ dt_proc_control(void *arg)
dt_proc_control_data_t *datap = arg;
dtrace_hdl_t *dtp = datap->dpcd_hdl;
dt_proc_t *dpr = datap->dpcd_proc;
- dt_proc_hash_t *dph = dpr->dpr_hdl->dt_procs;
+ dt_proc_hash_t *dph = dtp->dt_procs;
struct ps_prochandle *P = dpr->dpr_proc;
int pid = dpr->dpr_pid;
@@ -964,7 +968,8 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
(void) pthread_cond_init(&dpr->dpr_cv, NULL);
#if defined(sun)
- if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) {
+ dpr->dpr_proc = Pxcreate(file, argv, dtp->dt_proc_env, &err, NULL, 0);
+ if (dpr->dpr_proc == NULL) {
#else
if ((err = proc_create(file, argv, pcf, child_arg,
&dpr->dpr_proc)) != 0) {
@@ -1140,30 +1145,75 @@ dt_proc_unlock(dtrace_hdl_t *dtp, struct ps_prochandle *P)
}
void
-dt_proc_hash_create(dtrace_hdl_t *dtp)
+dt_proc_init(dtrace_hdl_t *dtp)
{
+ extern char **environ;
+ static char *envdef[] = {
+ "LD_NOLAZYLOAD=1", /* linker lazy loading hides funcs */
+ NULL
+ };
+ char **p;
+ int i;
+
if ((dtp->dt_procs = dt_zalloc(dtp, sizeof (dt_proc_hash_t) +
- sizeof (dt_proc_t *) * _dtrace_pidbuckets - 1)) != NULL) {
+ sizeof (dt_proc_t *) * _dtrace_pidbuckets - 1)) == NULL)
+ return;
+
+ (void) pthread_mutex_init(&dtp->dt_procs->dph_lock, NULL);
+ (void) pthread_cond_init(&dtp->dt_procs->dph_cv, NULL);
+
+ dtp->dt_procs->dph_hashlen = _dtrace_pidbuckets;
+ dtp->dt_procs->dph_lrulim = _dtrace_pidlrulim;
- (void) pthread_mutex_init(&dtp->dt_procs->dph_lock, NULL);
- (void) pthread_cond_init(&dtp->dt_procs->dph_cv, NULL);
- dtp->dt_procs->dph_hashlen = _dtrace_pidbuckets;
- dtp->dt_procs->dph_lrulim = _dtrace_pidlrulim;
+ /*
+ * Count how big our environment needs to be.
+ */
+ for (i = 1, p = environ; *p != NULL; i++, p++)
+ continue;
+ for (p = envdef; *p != NULL; i++, p++)
+ continue;
+
+ if ((dtp->dt_proc_env = dt_zalloc(dtp, sizeof (char *) * i)) == NULL)
+ return;
+
+ for (i = 0, p = environ; *p != NULL; i++, p++) {
+ if ((dtp->dt_proc_env[i] = strdup(*p)) == NULL)
+ goto err;
}
+ for (p = envdef; *p != NULL; i++, p++) {
+ if ((dtp->dt_proc_env[i] = strdup(*p)) == NULL)
+ goto err;
+ }
+
+ return;
+
+err:
+ while (--i != 0) {
+ dt_free(dtp, dtp->dt_proc_env[i]);
+ }
+ dt_free(dtp, dtp->dt_proc_env);
+ dtp->dt_proc_env = NULL;
}
void
-dt_proc_hash_destroy(dtrace_hdl_t *dtp)
+dt_proc_fini(dtrace_hdl_t *dtp)
{
dt_proc_hash_t *dph = dtp->dt_procs;
dt_proc_t *dpr;
+ char **p;
while ((dpr = dt_list_next(&dph->dph_lrulist)) != NULL)
dt_proc_destroy(dtp, dpr->dpr_proc);
dtp->dt_procs = NULL;
dt_free(dtp, dph);
+
+ for (p = dtp->dt_proc_env; *p != NULL; p++)
+ dt_free(dtp, *p);
+
+ dt_free(dtp, dtp->dt_proc_env);
+ dtp->dt_proc_env = NULL;
}
struct ps_prochandle *
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
index d1fc7652385d..beae6f6d5cda 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
@@ -24,11 +24,13 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#ifndef _DT_PROC_H
#define _DT_PROC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <libproc.h>
#include <dtrace.h>
#include <pthread.h>
@@ -106,8 +108,8 @@ extern void dt_proc_lock(dtrace_hdl_t *, struct ps_prochandle *);
extern void dt_proc_unlock(dtrace_hdl_t *, struct ps_prochandle *);
extern dt_proc_t *dt_proc_lookup(dtrace_hdl_t *, struct ps_prochandle *, int);
-extern void dt_proc_hash_create(dtrace_hdl_t *);
-extern void dt_proc_hash_destroy(dtrace_hdl_t *);
+extern void dt_proc_init(dtrace_hdl_t *);
+extern void dt_proc_fini(dtrace_hdl_t *);
#ifdef __cplusplus
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c
index b110df396718..a325c42cbf23 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <unistd.h>
@@ -352,6 +353,7 @@ dtrace_stmt_destroy(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
if (sdp->dtsd_fmtdata != NULL)
dt_printf_destroy(sdp->dtsd_fmtdata);
+ dt_free(dtp, sdp->dtsd_strdata);
dt_ecbdesc_release(dtp, sdp->dtsd_ecbdesc);
dt_free(dtp, sdp);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
index 05cc15c91257..0c747ed133ca 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
@@ -19,12 +19,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/bitmap.h>
@@ -33,18 +36,19 @@
#include <stdlib.h>
#include <dt_regset.h>
+#include <dt_impl.h>
dt_regset_t *
-dt_regset_create(ulong_t size)
+dt_regset_create(ulong_t nregs)
{
- ulong_t n = BT_BITOUL(size + 1); /* + 1 for %r0 */
+ ulong_t n = BT_BITOUL(nregs);
dt_regset_t *drp = malloc(sizeof (dt_regset_t));
if (drp == NULL)
return (NULL);
drp->dr_bitmap = malloc(sizeof (ulong_t) * n);
- drp->dr_size = size + 1;
+ drp->dr_size = nregs;
if (drp->dr_bitmap == NULL) {
dt_regset_destroy(drp);
@@ -68,6 +72,25 @@ dt_regset_reset(dt_regset_t *drp)
bzero(drp->dr_bitmap, sizeof (ulong_t) * BT_BITOUL(drp->dr_size));
}
+void
+dt_regset_assert_free(dt_regset_t *drp)
+{
+ int reg;
+ boolean_t fail = B_FALSE;
+ for (reg = 0; reg < drp->dr_size; reg++) {
+ if (BT_TEST(drp->dr_bitmap, reg) != 0) {
+ dt_dprintf("%%r%d was left allocated\n", reg);
+ fail = B_TRUE;
+ }
+ }
+
+ /*
+ * We set this during dtest runs to check for register leaks.
+ */
+ if (fail && getenv("DTRACE_DEBUG_REGSET") != NULL)
+ abort();
+}
+
int
dt_regset_alloc(dt_regset_t *drp)
{
@@ -95,13 +118,15 @@ dt_regset_alloc(dt_regset_t *drp)
}
}
- return (-1); /* no available registers */
+ xyerror(D_NOREG, "Insufficient registers to generate code");
+ /*NOTREACHED*/
+ return (-1);
}
void
dt_regset_free(dt_regset_t *drp, int reg)
{
- assert(reg > 0 && reg < drp->dr_size);
+ assert(reg >= 0 && reg < drp->dr_size);
assert(BT_TEST(drp->dr_bitmap, reg) != 0);
BT_CLEAR(drp->dr_bitmap, reg);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
index 25e64d048e60..35082846d9d1 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
@@ -19,16 +19,19 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#ifndef _DT_REGSET_H
#define _DT_REGSET_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifdef __cplusplus
@@ -45,6 +48,7 @@ extern void dt_regset_destroy(dt_regset_t *);
extern void dt_regset_reset(dt_regset_t *);
extern int dt_regset_alloc(dt_regset_t *);
extern void dt_regset_free(dt_regset_t *, int);
+extern void dt_regset_assert_free(dt_regset_t *);
#ifdef __cplusplus
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
index df34eece397f..87211a24b93f 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
@@ -21,6 +21,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Use is subject to license terms.
*/
@@ -617,8 +618,8 @@ dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...)
size_t avail;
/*
- * It's not legal to use buffered ouput if there is not a
- * handler for buffered output.
+ * Using buffered output is not allowed if a handler has
+ * not been installed.
*/
if (dtp->dt_bufhdlr == NULL) {
va_end(ap);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
index eb5ab43b189b..b2e31086cf30 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
@@ -154,6 +154,7 @@ typedef struct dtrace_stmtdesc {
dtrace_actdesc_t *dtsd_action_last; /* last action in action list */
void *dtsd_aggdata; /* aggregation data */
void *dtsd_fmtdata; /* type-specific output data */
+ void *dtsd_strdata; /* type-specific string data */
void (*dtsd_callback)(void); /* callback function for EPID */
void *dtsd_data; /* callback data pointer */
dtrace_attribute_t dtsd_descattr; /* probedesc attributes */
@@ -246,6 +247,18 @@ extern int dtrace_freopen(dtrace_hdl_t *, FILE *, void *,
const void *, size_t);
/*
+ * Type-specific output printing
+ *
+ * The print() action will associate a string data record that is actually the
+ * fully-qualified type name of the data traced by the DIFEXPR action. This is
+ * stored in the same 'format' record from the kernel, but we know by virtue of
+ * the fact that the action is still DIFEXPR that it is actually a reference to
+ * plain string data.
+ */
+extern int dtrace_print(dtrace_hdl_t *, FILE *, const char *,
+ caddr_t, size_t);
+
+/*
* DTrace Work Interface
*/
typedef enum {
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c
index f11ae480a807..9479e83dd777 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c
@@ -24,6 +24,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
@@ -525,7 +529,8 @@ dt_instr_size(uchar_t *instr, dtrace_hdl_t *dtp, pid_t pid, uintptr_t addr,
* another debugger attached to this process. The original instruction
* can't be recovered so this must fail.
*/
- if (x86dis.d86_len == 1 && instr[0] == FASTTRAP_INSTR)
+ if (x86dis.d86_len == 1 &&
+ (uchar_t)x86dis.d86_bytes[0] == FASTTRAP_INSTR)
return (-1);
return (x86dis.d86_len);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 2660059f7a81..274b47b5557a 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -57,7 +57,8 @@ extern "C" {
/*
* libzfs errors
*/
-enum {
+typedef enum zfs_error {
+ EZFS_SUCCESS = 0, /* no error -- success */
EZFS_NOMEM = 2000, /* out of memory */
EZFS_BADPROP, /* invalid property value */
EZFS_PROPREADONLY, /* cannot set readonly property */
@@ -129,7 +130,7 @@ enum {
EZFS_DIFFDATA, /* bad zfs diff data */
EZFS_POOLREADONLY, /* pool is in read-only mode */
EZFS_UNKNOWN
-};
+} zfs_error_t;
/*
* The following data structures are all part
@@ -185,6 +186,9 @@ extern libzfs_handle_t *zfs_get_handle(zfs_handle_t *);
extern void libzfs_print_on_error(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 *);
+
extern int libzfs_errno(libzfs_handle_t *);
extern const char *libzfs_error_action(libzfs_handle_t *);
extern const char *libzfs_error_description(libzfs_handle_t *);
@@ -220,7 +224,7 @@ extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
*/
extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *,
nvlist_t *, nvlist_t *);
-extern int zpool_destroy(zpool_handle_t *);
+extern int zpool_destroy(zpool_handle_t *, const char *);
extern int zpool_add(zpool_handle_t *, nvlist_t *);
typedef struct splitflags {
@@ -343,8 +347,8 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
/*
* Import and export functions
*/
-extern int zpool_export(zpool_handle_t *, boolean_t);
-extern int zpool_export_force(zpool_handle_t *);
+extern int zpool_export(zpool_handle_t *, boolean_t, const char *);
+extern int zpool_export_force(zpool_handle_t *, const char *);
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
char *altroot);
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
@@ -378,7 +382,7 @@ extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
*/
struct zfs_cmd;
-extern const char *zfs_history_event_names[LOG_END];
+extern const char *zfs_history_event_names[];
extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *,
boolean_t verbose);
@@ -386,12 +390,9 @@ extern int zpool_upgrade(zpool_handle_t *, uint64_t);
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
extern int zpool_history_unpack(char *, uint64_t, uint64_t *,
nvlist_t ***, uint_t *);
-extern void zpool_set_history_str(const char *subcommand, int argc,
- char **argv, char *history_str);
-extern int zpool_stage_history(libzfs_handle_t *, const char *);
extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
size_t len);
-extern int zfs_ioctl(libzfs_handle_t *, unsigned long, struct zfs_cmd *);
+extern int zfs_ioctl(libzfs_handle_t *, int request, struct zfs_cmd *);
extern int zpool_get_physpath(zpool_handle_t *, char *, size_t);
extern void zpool_explain_recover(libzfs_handle_t *, const char *, int,
nvlist_t *);
@@ -441,8 +442,6 @@ extern int zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
char *propbuf, int proplen, boolean_t literal);
extern int zfs_prop_get_feature(zfs_handle_t *zhp, const char *propname,
char *buf, size_t len);
-extern int zfs_get_snapused_int(zfs_handle_t *firstsnap, zfs_handle_t *lastsnap,
- uint64_t *usedp);
extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
extern int zfs_prop_inherit(zfs_handle_t *, const char *, boolean_t);
extern const char *zfs_prop_values(zfs_prop_t);
@@ -555,9 +554,11 @@ extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
extern int zfs_destroy(zfs_handle_t *, boolean_t);
extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t);
-extern int zfs_destroy_snaps_nvl(zfs_handle_t *, nvlist_t *, boolean_t);
+extern int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t);
extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
+extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps,
+ nvlist_t *props);
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
typedef struct renameflags {
@@ -609,8 +610,8 @@ extern int zfs_send(zfs_handle_t *, const char *, const char *,
sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
extern int zfs_promote(zfs_handle_t *);
-extern int zfs_hold(zfs_handle_t *, const char *, const char *, boolean_t,
- boolean_t, boolean_t, int, uint64_t, uint64_t);
+extern int zfs_hold(zfs_handle_t *, const char *, const char *,
+ boolean_t, boolean_t, int);
extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t);
extern int zfs_get_holds(zfs_handle_t *, nvlist_t **);
extern uint64_t zvol_volsize_to_reservation(uint64_t, nvlist_t *);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
new file mode 100644
index 000000000000..3c8119de5330
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
@@ -0,0 +1,105 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include "libzfs_compat.h"
+
+int zfs_ioctl_version = ZFS_IOCVER_UNDEF;
+static int zfs_spa_version = -1;
+
+/*
+ * Get zfs_ioctl_version
+ */
+int
+get_zfs_ioctl_version(void)
+{
+ size_t ver_size;
+ int ver = ZFS_IOCVER_NONE;
+
+ ver_size = sizeof(ver);
+ sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0);
+
+ return (ver);
+}
+
+/*
+ * Get the SPA version
+ */
+static int
+get_zfs_spa_version(void)
+{
+ size_t ver_size;
+ int ver = 0;
+
+ ver_size = sizeof(ver);
+ sysctlbyname("vfs.zfs.version.spa", &ver, &ver_size, NULL, 0);
+
+ return (ver);
+}
+
+/*
+ * This is FreeBSD version of ioctl, because Solaris' ioctl() updates
+ * zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
+ * error is returned zc_nvlist_dst_size won't be updated.
+ */
+int
+zcmd_ioctl(int fd, int request, zfs_cmd_t *zc)
+{
+ size_t oldsize;
+ int ret, cflag = ZFS_CMD_COMPAT_NONE;
+
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
+
+ if (zfs_ioctl_version == ZFS_IOCVER_LZC)
+ cflag = ZFS_CMD_COMPAT_LZC;
+ else if (zfs_ioctl_version == ZFS_IOCVER_DEADMAN)
+ cflag = ZFS_CMD_COMPAT_DEADMAN;
+
+ /*
+ * If vfs.zfs.version.ioctl is not defined, assume we have v28
+ * compatible binaries and use vfs.zfs.version.spa to test for v15
+ */
+ if (zfs_ioctl_version < ZFS_IOCVER_DEADMAN) {
+ cflag = ZFS_CMD_COMPAT_V28;
+
+ if (zfs_spa_version < 0)
+ zfs_spa_version = get_zfs_spa_version();
+
+ if (zfs_spa_version == SPA_VERSION_15 ||
+ zfs_spa_version == SPA_VERSION_14 ||
+ zfs_spa_version == SPA_VERSION_13)
+ cflag = ZFS_CMD_COMPAT_V15;
+ }
+
+ oldsize = zc->zc_nvlist_dst_size;
+ ret = zcmd_ioctl_compat(fd, request, zc, cflag);
+
+ if (ret == 0 && oldsize < zc->zc_nvlist_dst_size) {
+ ret = -1;
+ errno = ENOMEM;
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
new file mode 100644
index 000000000000..37616683330a
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_COMPAT_H
+#define _LIBZFS_COMPAT_H
+
+#include <zfs_ioctl_compat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int get_zfs_ioctl_version(void);
+int zcmd_ioctl(int fd, int request, zfs_cmd_t *zc);
+
+#define ioctl(fd, ioc, zc) zcmd_ioctl((fd), (ioc), (zc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_COMPAT_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index 1696cb184dc6..e78bb82c61fb 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -1447,7 +1447,6 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
nvlist_t *nvl = NULL, *realprops;
zfs_prop_t prop;
boolean_t do_prefix = B_TRUE;
- uint64_t idx;
int added_resv;
(void) snprintf(errbuf, sizeof (errbuf),
@@ -2017,10 +2016,7 @@ get_clones_cb(zfs_handle_t *zhp, void *arg)
NULL, NULL, 0, B_TRUE) != 0)
goto out;
if (strcmp(gca->buf, gca->origin) == 0) {
- if (nvlist_add_boolean(gca->value, zfs_get_name(zhp)) != 0) {
- zfs_close(zhp);
- return (no_memory(zhp->zfs_hdl));
- }
+ fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
gca->numclones--;
}
@@ -2711,25 +2707,6 @@ zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
return (0);
}
-int
-zfs_get_snapused_int(zfs_handle_t *firstsnap, zfs_handle_t *lastsnap,
- uint64_t *usedp)
-{
- int err;
- zfs_cmd_t zc = { 0 };
-
- (void) strlcpy(zc.zc_name, lastsnap->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, firstsnap->zfs_name, sizeof (zc.zc_value));
-
- err = ioctl(lastsnap->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_SNAPS, &zc);
- if (err)
- return (err);
-
- *usedp = zc.zc_cookie;
-
- return (0);
-}
-
/*
* Returns the name of the given zfs handle.
*/
@@ -2930,7 +2907,6 @@ create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
*/
for (cp = target + prefixlen + 1;
cp = strchr(cp, '/'); *cp = '/', cp++) {
- char *logstr;
*cp = '\0';
@@ -2941,16 +2917,12 @@ create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
continue;
}
- logstr = hdl->libzfs_log_str;
- hdl->libzfs_log_str = NULL;
if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
NULL) != 0) {
- hdl->libzfs_log_str = logstr;
opname = dgettext(TEXT_DOMAIN, "create");
goto ancestorerr;
}
- hdl->libzfs_log_str = logstr;
h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
if (h == NULL) {
opname = dgettext(TEXT_DOMAIN, "open");
@@ -3008,12 +2980,12 @@ int
zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
nvlist_t *props)
{
- zfs_cmd_t zc = { 0 };
int ret;
uint64_t size = 0;
uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
char errbuf[1024];
uint64_t zoned;
+ dmu_objset_type_t ost;
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot create '%s'"), path);
@@ -3033,17 +3005,16 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
* will return ENOENT, not EEXIST. To prevent this from happening, we
* first try to see if the dataset exists.
*/
- (void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
- if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
+ if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"dataset already exists"));
return (zfs_error(hdl, EZFS_EXISTS, errbuf));
}
if (type == ZFS_TYPE_VOLUME)
- zc.zc_objset_type = DMU_OST_ZVOL;
+ ost = DMU_OST_ZVOL;
else
- zc.zc_objset_type = DMU_OST_ZFS;
+ ost = DMU_OST_ZFS;
if (props && (props = zfs_valid_proplist(hdl, type, props,
zoned, NULL, errbuf)) == 0)
@@ -3095,14 +3066,9 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
}
}
- if (props && zcmd_write_src_nvlist(hdl, &zc, props) != 0)
- return (-1);
- nvlist_free(props);
-
/* create the dataset */
- ret = zfs_ioctl(hdl, ZFS_IOC_CREATE, &zc);
-
- zcmd_free_nvlists(&zc);
+ ret = lzc_create(path, ost, props);
+ nvlist_free(props);
/* check for failure */
if (ret != 0) {
@@ -3228,47 +3194,53 @@ zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
zhp->zfs_name, snapname);
} else {
- ret = zfs_destroy_snaps_nvl(zhp, dd.nvl, defer);
+ ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
}
nvlist_free(dd.nvl);
return (ret);
}
/*
- * Destroys all the snapshots named in the nvlist. They must be underneath
- * the zhp (either snapshots of it, or snapshots of its descendants).
+ * Destroys all the snapshots named in the nvlist.
*/
int
-zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer)
+zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
{
int ret;
- zfs_cmd_t zc = { 0 };
+ nvlist_t *errlist;
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- if (zcmd_write_src_nvlist(zhp->zfs_hdl, &zc, snaps) != 0)
- return (-1);
- zc.zc_defer_destroy = defer;
+ ret = lzc_destroy_snaps(snaps, defer, &errlist);
- ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS_NVL, &zc);
- if (ret != 0) {
+ if (ret == 0)
+ return (0);
+
+ if (nvlist_next_nvpair(errlist, NULL) == NULL) {
char errbuf[1024];
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot destroy snapshots in %s"), zc.zc_name);
+ ret = zfs_standard_error(hdl, ret, errbuf);
+ }
+ for (nvpair_t *pair = nvlist_next_nvpair(errlist, NULL);
+ pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
+ char errbuf[1024];
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
+ nvpair_name(pair));
- switch (errno) {
+ switch (fnvpair_value_int32(pair)) {
case EEXIST:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "snapshot is cloned"));
- return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf));
-
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "snapshot is cloned"));
+ ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
+ break;
default:
- return (zfs_standard_error(zhp->zfs_hdl, errno,
- errbuf));
+ ret = zfs_standard_error(hdl, errno, errbuf);
+ break;
}
}
- return (0);
+ return (ret);
}
/*
@@ -3277,12 +3249,10 @@ zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer)
int
zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
{
- zfs_cmd_t zc = { 0 };
char parent[ZFS_MAXNAMELEN];
int ret;
char errbuf[1024];
libzfs_handle_t *hdl = zhp->zfs_hdl;
- zfs_type_t type;
uint64_t zoned;
assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
@@ -3301,32 +3271,21 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
(void) parent_name(target, parent, sizeof (parent));
/* do the clone */
- if (ZFS_IS_VOLUME(zhp)) {
- zc.zc_objset_type = DMU_OST_ZVOL;
- type = ZFS_TYPE_VOLUME;
- } else {
- zc.zc_objset_type = DMU_OST_ZFS;
- type = ZFS_TYPE_FILESYSTEM;
- }
if (props) {
+ zfs_type_t type;
+ if (ZFS_IS_VOLUME(zhp)) {
+ type = ZFS_TYPE_VOLUME;
+ } else {
+ type = ZFS_TYPE_FILESYSTEM;
+ }
if ((props = zfs_valid_proplist(hdl, type, props, zoned,
zhp, errbuf)) == NULL)
return (-1);
-
- if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
- nvlist_free(props);
- return (-1);
- }
-
- nvlist_free(props);
}
- (void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value));
- ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CREATE, &zc);
-
- zcmd_free_nvlists(&zc);
+ ret = lzc_clone(target, zhp->zfs_name, props);
+ nvlist_free(props);
if (ret != 0) {
switch (errno) {
@@ -3411,74 +3370,134 @@ zfs_promote(zfs_handle_t *zhp)
return (ret);
}
+typedef struct snapdata {
+ nvlist_t *sd_nvl;
+ const char *sd_snapname;
+} snapdata_t;
+
+static int
+zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
+{
+ snapdata_t *sd = arg;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
+
+ fnvlist_add_boolean(sd->sd_nvl, name);
+
+ rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ zfs_close(zhp);
+ return (rv);
+}
+
/*
- * Takes a snapshot of the given dataset.
+ * Creates snapshots. The keys in the snaps nvlist are the snapshots to be
+ * created.
*/
int
-zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
- nvlist_t *props)
+zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
{
- const char *delim;
- char parent[ZFS_MAXNAMELEN];
- zfs_handle_t *zhp;
- zfs_cmd_t zc = { 0 };
int ret;
char errbuf[1024];
+ nvpair_t *elem;
+ nvlist_t *errors;
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot snapshot '%s'"), path);
+ "cannot create snapshots "));
- /* validate the target name */
- if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
+ const char *snapname = nvpair_name(elem);
- if (props) {
- if ((props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
- props, B_FALSE, NULL, errbuf)) == NULL)
- return (-1);
+ /* validate the target name */
+ if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
+ B_TRUE)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot create snapshot '%s'"), snapname);
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+ }
- if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
- nvlist_free(props);
- return (-1);
+ if (props != NULL &&
+ (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
+ props, B_FALSE, NULL, errbuf)) == NULL) {
+ return (-1);
+ }
+
+ ret = lzc_snapshot(snaps, props, &errors);
+
+ if (ret != 0) {
+ boolean_t printed = B_FALSE;
+ for (elem = nvlist_next_nvpair(errors, NULL);
+ elem != NULL;
+ elem = nvlist_next_nvpair(errors, elem)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot create snapshot '%s'"), nvpair_name(elem));
+ (void) zfs_standard_error(hdl,
+ fnvpair_value_int32(elem), errbuf);
+ printed = B_TRUE;
}
+ if (!printed) {
+ switch (ret) {
+ case EXDEV:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "multiple snapshots of same "
+ "fs not allowed"));
+ (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
- nvlist_free(props);
+ break;
+ default:
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ }
+ }
}
- /* make sure the parent exists and is of the appropriate type */
- delim = strchr(path, '@');
- (void) strncpy(parent, path, delim - path);
- parent[delim - path] = '\0';
+ nvlist_free(props);
+ nvlist_free(errors);
+ return (ret);
+}
+
+int
+zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
+ nvlist_t *props)
+{
+ int ret;
+ snapdata_t sd = { 0 };
+ char fsname[ZFS_MAXNAMELEN];
+ char *cp;
+ zfs_handle_t *zhp;
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot snapshot %s"), path);
+
+ if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+
+ (void) strlcpy(fsname, path, sizeof (fsname));
+ cp = strchr(fsname, '@');
+ *cp = '\0';
+ sd.sd_snapname = cp + 1;
- if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
+ if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
ZFS_TYPE_VOLUME)) == NULL) {
- zcmd_free_nvlists(&zc);
return (-1);
}
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value));
- if (ZFS_IS_VOLUME(zhp))
- zc.zc_objset_type = DMU_OST_ZVOL;
- else
- zc.zc_objset_type = DMU_OST_ZFS;
- zc.zc_cookie = recursive;
- ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SNAPSHOT, &zc);
-
- zcmd_free_nvlists(&zc);
-
- /*
- * if it was recursive, the one that actually failed will be in
- * zc.zc_name.
- */
- if (ret != 0) {
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
- (void) zfs_standard_error(hdl, errno, errbuf);
+ verify(nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) == 0);
+ if (recursive) {
+ (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
+ } else {
+ fnvlist_add_boolean(sd.sd_nvl, path);
}
+ ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
+ nvlist_free(sd.sd_nvl);
zfs_close(zhp);
-
return (ret);
}
@@ -3506,17 +3525,13 @@ rollback_destroy(zfs_handle_t *zhp, void *data)
zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
cbp->cb_create) {
- char *logstr;
cbp->cb_dependent = B_TRUE;
cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
rollback_destroy, cbp);
cbp->cb_dependent = B_FALSE;
- logstr = zhp->zfs_hdl->libzfs_log_str;
- zhp->zfs_hdl->libzfs_log_str = NULL;
cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
- zhp->zfs_hdl->libzfs_log_str = logstr;
}
} else {
/* We must destroy this clone; first unmount it */
@@ -4120,7 +4135,7 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
zc.zc_nvlist_dst_size = sizeof (buf);
if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
- char errbuf[ZFS_MAXNAMELEN + 32];
+ char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN,
@@ -4142,37 +4157,94 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
return (0);
}
+struct holdarg {
+ nvlist_t *nvl;
+ const char *snapname;
+ const char *tag;
+ boolean_t recursive;
+};
+
+static int
+zfs_hold_one(zfs_handle_t *zhp, void *arg)
+{
+ struct holdarg *ha = arg;
+ zfs_handle_t *szhp;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zhp->zfs_name, ha->snapname);
+
+ szhp = make_dataset_handle(zhp->zfs_hdl, name);
+ if (szhp) {
+ fnvlist_add_string(ha->nvl, name, ha->tag);
+ zfs_close(szhp);
+ }
+
+ if (ha->recursive)
+ rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
+ zfs_close(zhp);
+ return (rv);
+}
+
int
zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
- boolean_t recursive, boolean_t temphold, boolean_t enoent_ok,
- int cleanup_fd, uint64_t dsobj, uint64_t createtxg)
+ boolean_t recursive, boolean_t enoent_ok, int cleanup_fd)
{
- zfs_cmd_t zc = { 0 };
+ int ret;
+ struct holdarg ha;
+ nvlist_t *errors;
libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char errbuf[1024];
+ nvpair_t *elem;
- ASSERT(!recursive || dsobj == 0);
+ ha.nvl = fnvlist_alloc();
+ ha.snapname = snapname;
+ ha.tag = tag;
+ ha.recursive = recursive;
+ (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
- if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
- >= sizeof (zc.zc_string))
- return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
- zc.zc_cookie = recursive;
- zc.zc_temphold = temphold;
- zc.zc_cleanup_fd = cleanup_fd;
- zc.zc_sendobj = dsobj;
- zc.zc_createtxg = createtxg;
-
- if (zfs_ioctl(hdl, ZFS_IOC_HOLD, &zc) != 0) {
- char errbuf[ZFS_MAXNAMELEN+32];
+ if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+ fnvlist_free(ha.nvl);
+ ret = ENOENT;
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot hold snapshot '%s@%s'"),
+ zhp->zfs_name, snapname);
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ return (ret);
+ }
- /*
- * if it was recursive, the one that actually failed will be in
- * zc.zc_name.
- */
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot hold '%s@%s'"), zc.zc_name, snapname);
- switch (errno) {
+ ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
+ fnvlist_free(ha.nvl);
+
+ if (ret == 0)
+ return (0);
+
+ if (nvlist_next_nvpair(errors, NULL) == NULL) {
+ /* no hold-specific errors */
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot hold"));
+ switch (ret) {
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ }
+ }
+
+ for (elem = nvlist_next_nvpair(errors, NULL);
+ elem != NULL;
+ elem = nvlist_next_nvpair(errors, elem)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot hold snapshot '%s'"), nvpair_name(elem));
+ switch (fnvpair_value_int32(elem)) {
case E2BIG:
/*
* Temporary tags wind up having the ds object id
@@ -4180,66 +4252,131 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
* above, it's still possible for the tag to wind
* up being slightly too long.
*/
- return (zfs_error(hdl, EZFS_TAGTOOLONG, errbuf));
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded"));
- return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
+ (void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
+ break;
case EINVAL:
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
case EEXIST:
- return (zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf));
+ (void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
+ break;
case ENOENT:
if (enoent_ok)
return (ENOENT);
/* FALLTHROUGH */
default:
- return (zfs_standard_error_fmt(hdl, errno, errbuf));
+ (void) zfs_standard_error(hdl,
+ fnvpair_value_int32(elem), errbuf);
}
}
- return (0);
+ fnvlist_free(errors);
+ return (ret);
+}
+
+struct releasearg {
+ nvlist_t *nvl;
+ const char *snapname;
+ const char *tag;
+ boolean_t recursive;
+};
+
+static int
+zfs_release_one(zfs_handle_t *zhp, void *arg)
+{
+ struct holdarg *ha = arg;
+ zfs_handle_t *szhp;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zhp->zfs_name, ha->snapname);
+
+ szhp = make_dataset_handle(zhp->zfs_hdl, name);
+ if (szhp) {
+ nvlist_t *holds = fnvlist_alloc();
+ fnvlist_add_boolean(holds, ha->tag);
+ fnvlist_add_nvlist(ha->nvl, name, holds);
+ zfs_close(szhp);
+ }
+
+ if (ha->recursive)
+ rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
+ zfs_close(zhp);
+ return (rv);
}
int
zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
boolean_t recursive)
{
- zfs_cmd_t zc = { 0 };
+ int ret;
+ struct holdarg ha;
+ nvlist_t *errors;
+ nvpair_t *elem;
libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char errbuf[1024];
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
- if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
- >= sizeof (zc.zc_string))
- return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
- zc.zc_cookie = recursive;
+ ha.nvl = fnvlist_alloc();
+ ha.snapname = snapname;
+ ha.tag = tag;
+ ha.recursive = recursive;
+ (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
+
+ if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+ fnvlist_free(ha.nvl);
+ ret = ENOENT;
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot release hold from snapshot '%s@%s'"),
+ zhp->zfs_name, snapname);
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ return (ret);
+ }
- if (zfs_ioctl(hdl, ZFS_IOC_RELEASE, &zc) != 0) {
- char errbuf[ZFS_MAXNAMELEN+32];
+ ret = lzc_release(ha.nvl, &errors);
+ fnvlist_free(ha.nvl);
- /*
- * if it was recursive, the one that actually failed will be in
- * zc.zc_name.
- */
+ if (ret == 0)
+ return (0);
+
+ if (nvlist_next_nvpair(errors, NULL) == NULL) {
+ /* no hold-specific errors */
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot release '%s' from '%s@%s'"), tag, zc.zc_name,
- snapname);
+ "cannot release"));
switch (errno) {
- case ESRCH:
- return (zfs_error(hdl, EZFS_REFTAG_RELE, errbuf));
case ENOTSUP:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"pool must be upgraded"));
- return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error_fmt(hdl, errno, errbuf);
+ }
+ }
+
+ for (elem = nvlist_next_nvpair(errors, NULL);
+ elem != NULL;
+ elem = nvlist_next_nvpair(errors, elem)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot release hold from snapshot '%s'"),
+ nvpair_name(elem));
+ switch (fnvpair_value_int32(elem)) {
+ case ESRCH:
+ (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
+ break;
case EINVAL:
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
default:
- return (zfs_standard_error_fmt(hdl, errno, errbuf));
+ (void) zfs_standard_error_fmt(hdl,
+ fnvpair_value_int32(elem), errbuf);
}
}
- return (0);
+ fnvlist_free(errors);
+ return (ret);
}
int
@@ -4250,7 +4387,7 @@ zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
int nvsz = 2048;
void *nvbuf;
int err = 0;
- char errbuf[ZFS_MAXNAMELEN+32];
+ char errbuf[1024];
assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
@@ -4315,7 +4452,7 @@ zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
zfs_cmd_t zc = { 0 };
libzfs_handle_t *hdl = zhp->zfs_hdl;
char *nvbuf;
- char errbuf[ZFS_MAXNAMELEN+32];
+ char errbuf[1024];
size_t nvsz;
int err;
@@ -4366,38 +4503,18 @@ zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
int
zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
{
- zfs_cmd_t zc = { 0 };
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- int nvsz = 2048;
- void *nvbuf;
- int err = 0;
- char errbuf[ZFS_MAXNAMELEN+32];
-
- assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
-
-tryagain:
-
- nvbuf = malloc(nvsz);
- if (nvbuf == NULL) {
- err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
- goto out;
- }
+ int err;
+ char errbuf[1024];
- zc.zc_nvlist_dst_size = nvsz;
- zc.zc_nvlist_dst = (uintptr_t)nvbuf;
+ err = lzc_get_holds(zhp->zfs_name, nvl);
- (void) strlcpy(zc.zc_name, zhp->zfs_name, ZFS_MAXNAMELEN);
+ if (err != 0) {
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
- if (zfs_ioctl(hdl, ZFS_IOC_GET_HOLDS, &zc) != 0) {
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
- zc.zc_name);
- switch (errno) {
- case ENOMEM:
- free(nvbuf);
- nvsz = zc.zc_nvlist_dst_size;
- goto tryagain;
-
+ zhp->zfs_name);
+ switch (err) {
case ENOTSUP:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"pool must be upgraded"));
@@ -4413,19 +4530,8 @@ tryagain:
err = zfs_standard_error_fmt(hdl, errno, errbuf);
break;
}
- } else {
- /* success */
- int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
- if (rc) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
- zc.zc_name);
- err = zfs_standard_error_fmt(hdl, rc, errbuf);
- }
}
- free(nvbuf);
-out:
return (err);
}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
index 1c46d32f4bab..11a57a98ae60 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
@@ -23,11 +23,12 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
-#ifndef _LIBFS_IMPL_H
-#define _LIBFS_IMPL_H
+#ifndef _LIBZFS_IMPL_H
+#define _LIBZFS_IMPL_H
#include <sys/dmu.h>
#include <sys/fs/zfs.h>
@@ -38,8 +39,8 @@
#include <libshare.h>
#include <libuutil.h>
#include <libzfs.h>
-
-#include "zfs_ioctl_compat.h"
+#include <libzfs_core.h>
+#include <libzfs_compat.h>
#ifdef __cplusplus
extern "C" {
@@ -69,7 +70,6 @@ struct libzfs_handle {
int libzfs_desc_active;
char libzfs_action[1024];
char libzfs_desc[1024];
- char *libzfs_log_str;
int libzfs_printerr;
int libzfs_storeerr; /* stuff error messages into buffer */
void *libzfs_sharehdl; /* libshare handle */
@@ -214,46 +214,8 @@ extern int zfs_unshare_proto(zfs_handle_t *,
extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t);
-#ifndef sun
-static int zfs_kernel_version = 0;
-
-/*
- * This is FreeBSD version of ioctl, because Solaris' ioctl() updates
- * zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
- * error is returned zc_nvlist_dst_size won't be updated.
- */
-static __inline int
-zcmd_ioctl(int fd, unsigned long cmd, zfs_cmd_t *zc)
-{
- size_t oldsize, zfs_kernel_version_size;
- int version, ret, cflag = ZFS_CMD_COMPAT_NONE;
-
- zfs_kernel_version_size = sizeof(zfs_kernel_version);
- if (zfs_kernel_version == 0) {
- sysctlbyname("vfs.zfs.version.spa", &zfs_kernel_version,
- &zfs_kernel_version_size, NULL, 0);
- }
-
- if (zfs_kernel_version == SPA_VERSION_15 ||
- zfs_kernel_version == SPA_VERSION_14 ||
- zfs_kernel_version == SPA_VERSION_13)
- cflag = ZFS_CMD_COMPAT_V15;
-
- oldsize = zc->zc_nvlist_dst_size;
- ret = zcmd_ioctl_compat(fd, cmd, zc, cflag);
-
- if (ret == 0 && oldsize < zc->zc_nvlist_dst_size) {
- ret = -1;
- errno = ENOMEM;
- }
-
- return (ret);
-}
-#define ioctl(fd, cmd, zc) zcmd_ioctl((fd), (cmd), (zc))
-#endif /* !sun */
-
#ifdef __cplusplus
}
#endif
-#endif /* _LIBFS_IMPL_H */
+#endif /* _LIBZFS_IMPL_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
index 7e39b0b78f2b..fa3d6090d98a 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
@@ -526,13 +526,12 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
* version
* pool guid
* name
- * pool txg (if available)
* comment (if available)
* pool state
* hostid (if available)
* hostname (if available)
*/
- uint64_t state, version, pool_txg;
+ uint64_t state, version;
char *comment = NULL;
version = fnvlist_lookup_uint64(tmp,
@@ -548,11 +547,6 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
fnvlist_add_string(config,
ZPOOL_CONFIG_POOL_NAME, name);
- if (nvlist_lookup_uint64(tmp,
- ZPOOL_CONFIG_POOL_TXG, &pool_txg) == 0)
- fnvlist_add_uint64(config,
- ZPOOL_CONFIG_POOL_TXG, pool_txg);
-
if (nvlist_lookup_string(tmp,
ZPOOL_CONFIG_COMMENT, &comment) == 0)
fnvlist_add_string(config,
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
index a4db909e180e..278bfd4cfd8f 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
*/
@@ -308,12 +308,11 @@ int
zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
zfs_iter_f func, void *arg)
{
- char buf[ZFS_MAXNAMELEN];
- char *comma_separated, *cp;
+ char *buf, *comma_separated, *cp;
int err = 0;
int ret = 0;
- (void) strlcpy(buf, spec_orig, sizeof (buf));
+ buf = zfs_strdup(fs_zhp->zfs_hdl, spec_orig);
cp = buf;
while ((comma_separated = strsep(&cp, ",")) != NULL) {
@@ -371,6 +370,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
}
}
+ free(buf);
return (ret);
}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index 03bc3e6586dd..9b04e08c5e8a 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
+#include <libgen.h>
#include <sys/zfs_ioctl.h>
#include <dlfcn.h>
@@ -1237,7 +1238,7 @@ create_failed:
* datasets left in the pool.
*/
int
-zpool_destroy(zpool_handle_t *zhp)
+zpool_destroy(zpool_handle_t *zhp, const char *log_str)
{
zfs_cmd_t zc = { 0 };
zfs_handle_t *zfp = NULL;
@@ -1249,6 +1250,7 @@ zpool_destroy(zpool_handle_t *zhp)
return (-1);
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_history = (uint64_t)(uintptr_t)log_str;
if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
@@ -1403,8 +1405,9 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
* Exports the pool from the system. The caller must ensure that there are no
* mounted datasets in the pool.
*/
-int
-zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
+static int
+zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
+ const char *log_str)
{
zfs_cmd_t zc = { 0 };
char msg[1024];
@@ -1415,6 +1418,7 @@ zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
zc.zc_cookie = force;
zc.zc_guid = hardforce;
+ zc.zc_history = (uint64_t)(uintptr_t)log_str;
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
switch (errno) {
@@ -1436,15 +1440,15 @@ zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
}
int
-zpool_export(zpool_handle_t *zhp, boolean_t force)
+zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
{
- return (zpool_export_common(zhp, force, B_FALSE));
+ return (zpool_export_common(zhp, force, B_FALSE, log_str));
}
int
-zpool_export_force(zpool_handle_t *zhp)
+zpool_export_force(zpool_handle_t *zhp, const char *log_str)
{
- return (zpool_export_common(zhp, B_TRUE, B_TRUE));
+ return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
}
static void
@@ -3632,40 +3636,30 @@ zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
}
void
-zpool_set_history_str(const char *subcommand, int argc, char **argv,
- char *history_str)
+zfs_save_arguments(int argc, char **argv, char *string, int len)
{
- int i;
-
- (void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
- for (i = 1; i < argc; i++) {
- if (strlen(history_str) + 1 + strlen(argv[i]) >
- HIS_MAX_RECORD_LEN)
- break;
- (void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN);
- (void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
+ (void) strlcpy(string, basename(argv[0]), len);
+ for (int i = 1; i < argc; i++) {
+ (void) strlcat(string, " ", len);
+ (void) strlcat(string, argv[i], len);
}
}
-/*
- * Stage command history for logging.
- */
int
-zpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
+zpool_log_history(libzfs_handle_t *hdl, const char *message)
{
- if (history_str == NULL)
- return (EINVAL);
-
- if (strlen(history_str) > HIS_MAX_RECORD_LEN)
- return (EINVAL);
-
- if (hdl->libzfs_log_str != NULL)
- free(hdl->libzfs_log_str);
-
- if ((hdl->libzfs_log_str = strdup(history_str)) == NULL)
- return (no_memory(hdl));
-
- return (0);
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *args;
+ int err;
+
+ args = fnvlist_alloc();
+ fnvlist_add_string(args, "message", message);
+ err = zcmd_write_src_nvlist(hdl, &zc, args);
+ if (err == 0)
+ err = ioctl(hdl->libzfs_fd, ZFS_IOC_LOG_HISTORY, &zc);
+ nvlist_free(args);
+ zcmd_free_nvlists(&zc);
+ return (err);
}
/*
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
index 662801eec1c7..34cb648f6214 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
@@ -53,6 +53,10 @@
#include <sys/zio_checksum.h>
#include <sys/ddt.h>
+#ifdef __FreeBSD__
+extern int zfs_ioctl_version;
+#endif
+
/* in libzfs_dataset.c */
extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
/* We need to use something for ENODATA. */
@@ -978,9 +982,7 @@ hold_for_send(zfs_handle_t *zhp, send_dump_data_t *sdd)
*/
if (pzhp) {
error = zfs_hold(pzhp, thissnap, sdd->holdtag,
- B_FALSE, B_TRUE, B_TRUE, sdd->cleanup_fd,
- zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID),
- zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG));
+ B_FALSE, B_TRUE, sdd->cleanup_fd);
zfs_close(pzhp);
}
@@ -1719,12 +1721,11 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
err = ENOENT;
}
- if (err != 0 && strncmp(name+baselen, "recv-", 5) != 0) {
+ if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
seq++;
- (void) strncpy(newname, name, baselen);
- (void) snprintf(newname+baselen, ZFS_MAXNAMELEN-baselen,
- "recv-%u-%u", getpid(), seq);
+ (void) snprintf(newname, ZFS_MAXNAMELEN, "%.*srecv-%u-%u",
+ baselen, name, getpid(), seq);
(void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
if (flags->verbose) {
@@ -2676,9 +2677,17 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
/*
* Determine name of destination snapshot, store in zc_value.
*/
- (void) strcpy(zc.zc_top_ds, tosnap);
(void) strcpy(zc.zc_value, tosnap);
(void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value));
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
+ /*
+ * For forward compatibility hide tosnap in zc_value
+ */
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
+ (void) strcpy(zc.zc_value + strlen(zc.zc_value) + 1, tosnap);
+#endif
free(cp);
if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
zcmd_free_nvlists(&zc);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
index 2b802a529a70..6823c07a2513 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
@@ -48,6 +48,7 @@
#include <sys/types.h>
#include <libzfs.h>
+#include <libzfs_core.h>
#include "libzfs_impl.h"
#include "zfs_prop.h"
@@ -659,6 +660,14 @@ libzfs_init(void)
hdl->libzfs_sharetab = fopen(ZFS_EXPORTS_PATH, "r");
+ if (libzfs_core_init() != 0) {
+ (void) close(hdl->libzfs_fd);
+ (void) fclose(hdl->libzfs_mnttab);
+ (void) fclose(hdl->libzfs_sharetab);
+ free(hdl);
+ return (NULL);
+ }
+
zfs_prop_init();
zpool_prop_init();
zpool_feature_init();
@@ -676,14 +685,13 @@ libzfs_fini(libzfs_handle_t *hdl)
if (hdl->libzfs_sharetab)
(void) fclose(hdl->libzfs_sharetab);
zfs_uninit_libshare(hdl);
- if (hdl->libzfs_log_str)
- (void) free(hdl->libzfs_log_str);
zpool_free_handles(hdl);
#ifdef sun
libzfs_fru_clear(hdl, B_TRUE);
#endif
namespace_clear(hdl);
libzfs_mnttab_fini(hdl);
+ libzfs_core_fini();
free(hdl);
}
@@ -857,19 +865,9 @@ zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
}
int
-zfs_ioctl(libzfs_handle_t *hdl, unsigned long request, zfs_cmd_t *zc)
+zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
{
- int error;
-
- zc->zc_history = (uint64_t)(uintptr_t)hdl->libzfs_log_str;
- error = ioctl(hdl->libzfs_fd, request, zc);
- if (hdl->libzfs_log_str) {
- free(hdl->libzfs_log_str);
- hdl->libzfs_log_str = NULL;
- }
- zc->zc_history = 0;
-
- return (error);
+ return (ioctl(hdl->libzfs_fd, request, zc));
}
/*
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
new file mode 100644
index 000000000000..ab23aa1ad2ec
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
@@ -0,0 +1,618 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
+ * It has the following characteristics:
+ *
+ * - Thread Safe. libzfs_core is accessible concurrently from multiple
+ * threads. This is accomplished primarily by avoiding global data
+ * (e.g. caching). Since it's thread-safe, there is no reason for a
+ * process to have multiple libzfs "instances". Therefore, we store
+ * our few pieces of data (e.g. the file descriptor) in global
+ * variables. The fd is reference-counted so that the libzfs_core
+ * library can be "initialized" multiple times (e.g. by different
+ * consumers within the same process).
+ *
+ * - Committed Interface. The libzfs_core interface will be committed,
+ * therefore consumers can compile against it and be confident that
+ * their code will continue to work on future releases of this code.
+ * Currently, the interface is Evolving (not Committed), but we intend
+ * to commit to it once it is more complete and we determine that it
+ * meets the needs of all consumers.
+ *
+ * - Programatic Error Handling. libzfs_core communicates errors with
+ * defined error numbers, and doesn't print anything to stdout/stderr.
+ *
+ * - Thin Layer. libzfs_core is a thin layer, marshaling arguments
+ * to/from the kernel ioctls. There is generally a 1:1 correspondence
+ * between libzfs_core functions and ioctls to /dev/zfs.
+ *
+ * - Clear Atomicity. Because libzfs_core functions are generally 1:1
+ * with kernel ioctls, and kernel ioctls are general atomic, each
+ * libzfs_core function is atomic. For example, creating multiple
+ * snapshots with a single call to lzc_snapshot() is atomic -- it
+ * can't fail with only some of the requested snapshots created, even
+ * in the event of power loss or system crash.
+ *
+ * - Continued libzfs Support. Some higher-level operations (e.g.
+ * support for "zfs send -R") are too complicated to fit the scope of
+ * libzfs_core. This functionality will continue to live in libzfs.
+ * Where appropriate, libzfs will use the underlying atomic operations
+ * of libzfs_core. For example, libzfs may implement "zfs send -R |
+ * zfs receive" by using individual "send one snapshot", rename,
+ * destroy, and "receive one snapshot" operations in libzfs_core.
+ * /sbin/zfs and /zbin/zpool will link with both libzfs and
+ * libzfs_core. Other consumers should aim to use only libzfs_core,
+ * since that will be the supported, stable interface going forwards.
+ */
+
+#define _IN_LIBZFS_CORE_
+
+#include <libzfs_core.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/nvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/zfs_ioctl.h>
+#include "libzfs_core_compat.h"
+#include "libzfs_compat.h"
+
+#ifdef __FreeBSD__
+extern int zfs_ioctl_version;
+#endif
+
+static int g_fd;
+static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
+static int g_refcount;
+
+int
+libzfs_core_init(void)
+{
+ (void) pthread_mutex_lock(&g_lock);
+ if (g_refcount == 0) {
+ g_fd = open("/dev/zfs", O_RDWR);
+ if (g_fd < 0) {
+ (void) pthread_mutex_unlock(&g_lock);
+ return (errno);
+ }
+ }
+ g_refcount++;
+ (void) pthread_mutex_unlock(&g_lock);
+
+ return (0);
+}
+
+void
+libzfs_core_fini(void)
+{
+ (void) pthread_mutex_lock(&g_lock);
+ ASSERT3S(g_refcount, >, 0);
+ g_refcount--;
+ if (g_refcount == 0)
+ (void) close(g_fd);
+ (void) pthread_mutex_unlock(&g_lock);
+}
+
+static int
+lzc_ioctl(zfs_ioc_t ioc, const char *name,
+ nvlist_t *source, nvlist_t **resultp)
+{
+ zfs_cmd_t zc = { 0 };
+ int error = 0;
+ char *packed;
+#ifdef __FreeBSD__
+ nvlist_t *oldsource;
+#endif
+ size_t size;
+
+ ASSERT3S(g_refcount, >, 0);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
+
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
+ oldsource = source;
+ error = lzc_compat_pre(&zc, &ioc, &source);
+ if (error)
+ return (error);
+ }
+#endif
+
+ packed = fnvlist_pack(source, &size);
+ zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
+ zc.zc_nvlist_src_size = size;
+
+ if (resultp != NULL) {
+ *resultp = NULL;
+ zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
+ zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
+ malloc(zc.zc_nvlist_dst_size);
+#ifdef illumos
+ if (zc.zc_nvlist_dst == NULL) {
+#else
+ if (zc.zc_nvlist_dst == 0) {
+#endif
+ error = ENOMEM;
+ goto out;
+ }
+ }
+
+ while (ioctl(g_fd, ioc, &zc) != 0) {
+ if (errno == ENOMEM && resultp != NULL) {
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ zc.zc_nvlist_dst_size *= 2;
+ zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
+ malloc(zc.zc_nvlist_dst_size);
+#ifdef illumos
+ if (zc.zc_nvlist_dst == NULL) {
+#else
+ if (zc.zc_nvlist_dst == 0) {
+#endif
+ error = ENOMEM;
+ goto out;
+ }
+ } else {
+ error = errno;
+ break;
+ }
+ }
+
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
+ lzc_compat_post(&zc, ioc);
+#endif
+ if (zc.zc_nvlist_dst_filled) {
+ *resultp = fnvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
+ zc.zc_nvlist_dst_size);
+ }
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
+ lzc_compat_outnvl(&zc, ioc, resultp);
+#endif
+out:
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
+ if (source != oldsource)
+ nvlist_free(source);
+ source = oldsource;
+ }
+#endif
+ fnvlist_pack_free(packed, size);
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ return (error);
+}
+
+int
+lzc_create(const char *fsname, dmu_objset_type_t type, nvlist_t *props)
+{
+ int error;
+ nvlist_t *args = fnvlist_alloc();
+ fnvlist_add_int32(args, "type", type);
+ if (props != NULL)
+ fnvlist_add_nvlist(args, "props", props);
+ error = lzc_ioctl(ZFS_IOC_CREATE, fsname, args, NULL);
+ nvlist_free(args);
+ return (error);
+}
+
+int
+lzc_clone(const char *fsname, const char *origin,
+ nvlist_t *props)
+{
+ int error;
+ nvlist_t *args = fnvlist_alloc();
+ fnvlist_add_string(args, "origin", origin);
+ if (props != NULL)
+ fnvlist_add_nvlist(args, "props", props);
+ error = lzc_ioctl(ZFS_IOC_CLONE, fsname, args, NULL);
+ nvlist_free(args);
+ return (error);
+}
+
+/*
+ * Creates snapshots.
+ *
+ * The keys in the snaps nvlist are the snapshots to be created.
+ * They must all be in the same pool.
+ *
+ * The props nvlist is properties to set. Currently only user properties
+ * are supported. { user:prop_name -> string value }
+ *
+ * The returned results nvlist will have an entry for each snapshot that failed.
+ * The value will be the (int32) error code.
+ *
+ * The return value will be 0 if all snapshots were created, otherwise it will
+ * be the errno of a (unspecified) snapshot that failed.
+ */
+int
+lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist)
+{
+ nvpair_t *elem;
+ nvlist_t *args;
+ int error;
+ char pool[MAXNAMELEN];
+
+ *errlist = NULL;
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(snaps, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_nvlist(args, "snaps", snaps);
+ if (props != NULL)
+ fnvlist_add_nvlist(args, "props", props);
+
+ error = lzc_ioctl(ZFS_IOC_SNAPSHOT, pool, args, errlist);
+ nvlist_free(args);
+
+ return (error);
+}
+
+/*
+ * Destroys snapshots.
+ *
+ * The keys in the snaps nvlist are the snapshots to be destroyed.
+ * They must all be in the same pool.
+ *
+ * Snapshots that do not exist will be silently ignored.
+ *
+ * If 'defer' is not set, and a snapshot has user holds or clones, the
+ * destroy operation will fail and none of the snapshots will be
+ * destroyed.
+ *
+ * If 'defer' is set, and a snapshot has user holds or clones, it will be
+ * marked for deferred destruction, and will be destroyed when the last hold
+ * or clone is removed/destroyed.
+ *
+ * The return value will be 0 if all snapshots were destroyed (or marked for
+ * later destruction if 'defer' is set) or didn't exist to begin with.
+ *
+ * Otherwise the return value will be the errno of a (unspecified) snapshot
+ * that failed, no snapshots will be destroyed, and the errlist will have an
+ * entry for each snapshot that failed. The value in the errlist will be
+ * the (int32) error code.
+ */
+int
+lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist)
+{
+ nvpair_t *elem;
+ nvlist_t *args;
+ int error;
+ char pool[MAXNAMELEN];
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(snaps, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_nvlist(args, "snaps", snaps);
+ if (defer)
+ fnvlist_add_boolean(args, "defer");
+
+ error = lzc_ioctl(ZFS_IOC_DESTROY_SNAPS, pool, args, errlist);
+ nvlist_free(args);
+
+ return (error);
+
+}
+
+int
+lzc_snaprange_space(const char *firstsnap, const char *lastsnap,
+ uint64_t *usedp)
+{
+ nvlist_t *args;
+ nvlist_t *result;
+ int err;
+ char fs[MAXNAMELEN];
+ char *atp;
+
+ /* determine the fs name */
+ (void) strlcpy(fs, firstsnap, sizeof (fs));
+ atp = strchr(fs, '@');
+ if (atp == NULL)
+ return (EINVAL);
+ *atp = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_string(args, "firstsnap", firstsnap);
+
+ err = lzc_ioctl(ZFS_IOC_SPACE_SNAPS, lastsnap, args, &result);
+ nvlist_free(args);
+ if (err == 0)
+ *usedp = fnvlist_lookup_uint64(result, "used");
+ fnvlist_free(result);
+
+ return (err);
+}
+
+boolean_t
+lzc_exists(const char *dataset)
+{
+ /*
+ * The objset_stats ioctl is still legacy, so we need to construct our
+ * own zfs_cmd_t rather than using zfsc_ioctl().
+ */
+ zfs_cmd_t zc = { 0 };
+
+ (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
+ return (ioctl(g_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0);
+}
+
+/*
+ * Create "user holds" on snapshots. If there is a hold on a snapshot,
+ * the snapshot can not be destroyed. (However, it can be marked for deletion
+ * by lzc_destroy_snaps(defer=B_TRUE).)
+ *
+ * The keys in the nvlist are snapshot names.
+ * The snapshots must all be in the same pool.
+ * The value is the name of the hold (string type).
+ *
+ * If cleanup_fd is not -1, it must be the result of open("/dev/zfs", O_EXCL).
+ * In this case, when the cleanup_fd is closed (including on process
+ * termination), the holds will be released. If the system is shut down
+ * uncleanly, the holds will be released when the pool is next opened
+ * or imported.
+ *
+ * The return value will be 0 if all holds were created. Otherwise the return
+ * value will be the errno of a (unspecified) hold that failed, no holds will
+ * be created, and the errlist will have an entry for each hold that
+ * failed (name = snapshot). The value in the errlist will be the error
+ * code (int32).
+ */
+int
+lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist)
+{
+ char pool[MAXNAMELEN];
+ nvlist_t *args;
+ nvpair_t *elem;
+ int error;
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(holds, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_nvlist(args, "holds", holds);
+ if (cleanup_fd != -1)
+ fnvlist_add_int32(args, "cleanup_fd", cleanup_fd);
+
+ error = lzc_ioctl(ZFS_IOC_HOLD, pool, args, errlist);
+ nvlist_free(args);
+ return (error);
+}
+
+/*
+ * Release "user holds" on snapshots. If the snapshot has been marked for
+ * deferred destroy (by lzc_destroy_snaps(defer=B_TRUE)), it does not have
+ * any clones, and all the user holds are removed, then the snapshot will be
+ * destroyed.
+ *
+ * The keys in the nvlist are snapshot names.
+ * The snapshots must all be in the same pool.
+ * The value is a nvlist whose keys are the holds to remove.
+ *
+ * The return value will be 0 if all holds were removed.
+ * Otherwise the return value will be the errno of a (unspecified) release
+ * that failed, no holds will be released, and the errlist will have an
+ * entry for each snapshot that has failed releases (name = snapshot).
+ * The value in the errlist will be the error code (int32) of a failed release.
+ */
+int
+lzc_release(nvlist_t *holds, nvlist_t **errlist)
+{
+ char pool[MAXNAMELEN];
+ nvpair_t *elem;
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(holds, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ return (lzc_ioctl(ZFS_IOC_RELEASE, pool, holds, errlist));
+}
+
+/*
+ * Retrieve list of user holds on the specified snapshot.
+ *
+ * On success, *holdsp will be set to a nvlist which the caller must free.
+ * The keys are the names of the holds, and the value is the creation time
+ * of the hold (uint64) in seconds since the epoch.
+ */
+int
+lzc_get_holds(const char *snapname, nvlist_t **holdsp)
+{
+ int error;
+ nvlist_t *innvl = fnvlist_alloc();
+ error = lzc_ioctl(ZFS_IOC_GET_HOLDS, snapname, innvl, holdsp);
+ fnvlist_free(innvl);
+ return (error);
+}
+
+/*
+ * If fromsnap is NULL, a full (non-incremental) stream will be sent.
+ */
+int
+lzc_send(const char *snapname, const char *fromsnap, int fd)
+{
+ nvlist_t *args;
+ int err;
+
+ args = fnvlist_alloc();
+ fnvlist_add_int32(args, "fd", fd);
+ if (fromsnap != NULL)
+ fnvlist_add_string(args, "fromsnap", fromsnap);
+ err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
+ nvlist_free(args);
+ return (err);
+}
+
+/*
+ * If fromsnap is NULL, a full (non-incremental) stream will be estimated.
+ */
+int
+lzc_send_space(const char *snapname, const char *fromsnap, uint64_t *spacep)
+{
+ nvlist_t *args;
+ nvlist_t *result;
+ int err;
+
+ args = fnvlist_alloc();
+ if (fromsnap != NULL)
+ fnvlist_add_string(args, "fromsnap", fromsnap);
+ err = lzc_ioctl(ZFS_IOC_SEND_SPACE, snapname, args, &result);
+ nvlist_free(args);
+ if (err == 0)
+ *spacep = fnvlist_lookup_uint64(result, "space");
+ nvlist_free(result);
+ return (err);
+}
+
+static int
+recv_read(int fd, void *buf, int ilen)
+{
+ char *cp = buf;
+ int rv;
+ int len = ilen;
+
+ do {
+ rv = read(fd, cp, len);
+ cp += rv;
+ len -= rv;
+ } while (rv > 0);
+
+ if (rv < 0 || len != 0)
+ return (EIO);
+
+ return (0);
+}
+
+/*
+ * The simplest receive case: receive from the specified fd, creating the
+ * specified snapshot. Apply the specified properties a "received" properties
+ * (which can be overridden by locally-set properties). If the stream is a
+ * clone, its origin snapshot must be specified by 'origin'. The 'force'
+ * flag will cause the target filesystem to be rolled back or destroyed if
+ * necessary to receive.
+ *
+ * Return 0 on success or an errno on failure.
+ *
+ * Note: this interface does not work on dedup'd streams
+ * (those with DMU_BACKUP_FEATURE_DEDUP).
+ */
+int
+lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
+ boolean_t force, int fd)
+{
+ /*
+ * The receive ioctl is still legacy, so we need to construct our own
+ * zfs_cmd_t rather than using zfsc_ioctl().
+ */
+ zfs_cmd_t zc = { 0 };
+ char *atp;
+ char *packed = NULL;
+ size_t size;
+ dmu_replay_record_t drr;
+ int error;
+
+ ASSERT3S(g_refcount, >, 0);
+
+ /* zc_name is name of containing filesystem */
+ (void) strlcpy(zc.zc_name, snapname, sizeof (zc.zc_name));
+ atp = strchr(zc.zc_name, '@');
+ if (atp == NULL)
+ return (EINVAL);
+ *atp = '\0';
+
+ /* if the fs does not exist, try its parent. */
+ if (!lzc_exists(zc.zc_name)) {
+ char *slashp = strrchr(zc.zc_name, '/');
+ if (slashp == NULL)
+ return (ENOENT);
+ *slashp = '\0';
+
+ }
+
+ /* zc_value is full name of the snapshot to create */
+ (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
+
+ if (props != NULL) {
+ /* zc_nvlist_src is props to set */
+ packed = fnvlist_pack(props, &size);
+ zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
+ zc.zc_nvlist_src_size = size;
+ }
+
+ /* zc_string is name of clone origin (if DRR_FLAG_CLONE) */
+ if (origin != NULL)
+ (void) strlcpy(zc.zc_string, origin, sizeof (zc.zc_string));
+
+ /* zc_begin_record is non-byteswapped BEGIN record */
+ error = recv_read(fd, &drr, sizeof (drr));
+ if (error != 0)
+ goto out;
+ zc.zc_begin_record = drr.drr_u.drr_begin;
+
+ /* zc_cookie is fd to read from */
+ zc.zc_cookie = fd;
+
+ /* zc guid is force flag */
+ zc.zc_guid = force;
+
+ /* zc_cleanup_fd is unused */
+ zc.zc_cleanup_fd = -1;
+
+ error = ioctl(g_fd, ZFS_IOC_RECV, &zc);
+ if (error != 0)
+ error = errno;
+
+out:
+ if (packed != NULL)
+ fnvlist_pack_free(packed, size);
+ free((void*)(uintptr_t)zc.zc_nvlist_dst);
+ return (error);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
new file mode 100644
index 000000000000..b10098b378c6
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_CORE_H
+#define _LIBZFS_CORE_H
+
+#include <libnvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int libzfs_core_init(void);
+void libzfs_core_fini(void);
+
+int lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist);
+int lzc_create(const char *fsname, dmu_objset_type_t type, nvlist_t *props);
+int lzc_clone(const char *fsname, const char *origin, nvlist_t *props);
+int lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist);
+
+int lzc_snaprange_space(const char *firstsnap, const char *lastsnap,
+ uint64_t *usedp);
+
+int lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist);
+int lzc_release(nvlist_t *holds, nvlist_t **errlist);
+int lzc_get_holds(const char *snapname, nvlist_t **holdsp);
+
+int lzc_send(const char *snapname, const char *fromsnap, int fd);
+int lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
+ boolean_t force, int fd);
+int lzc_send_space(const char *snapname, const char *fromsnap,
+ uint64_t *result);
+
+boolean_t lzc_exists(const char *dataset);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_CORE_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
new file mode 100644
index 000000000000..a3b872ee29da
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
@@ -0,0 +1,189 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include <sys/zfs_ioctl.h>
+#include <zfs_ioctl_compat.h>
+#include "libzfs_core_compat.h"
+
+extern int zfs_ioctl_version;
+
+int
+lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
+{
+ nvlist_t *nvl = NULL;
+ nvpair_t *pair, *hpair;
+ char *buf, *val;
+ zfs_ioc_t vecnum;
+ uint32_t type32;
+ int32_t cleanup_fd;
+ int error = 0;
+ int pos;
+
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
+ return (0);
+
+ vecnum = *ioc;
+
+ switch (vecnum) {
+ case ZFS_IOC_CREATE:
+ type32 = fnvlist_lookup_int32(*source, "type");
+ zc->zc_objset_type = (uint64_t)type32;
+ nvlist_lookup_nvlist(*source, "props", &nvl);
+ *source = nvl;
+ break;
+ case ZFS_IOC_CLONE:
+ buf = fnvlist_lookup_string(*source, "origin");
+ strlcpy(zc->zc_value, buf, MAXPATHLEN);
+ nvlist_lookup_nvlist(*source, "props", &nvl);
+ *ioc = ZFS_IOC_CREATE;
+ *source = nvl;
+ break;
+ case ZFS_IOC_SNAPSHOT:
+ nvl = fnvlist_lookup_nvlist(*source, "snaps");
+ pair = nvlist_next_nvpair(nvl, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
+ } else
+ error = EINVAL;
+ /* old kernel cannot create multiple snapshots */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ nvlist_free(nvl);
+ nvl = NULL;
+ nvlist_lookup_nvlist(*source, "props", &nvl);
+ *source = nvl;
+ break;
+ case ZFS_IOC_SPACE_SNAPS:
+ buf = fnvlist_lookup_string(*source, "firstsnap");
+ strlcpy(zc->zc_value, buf, MAXPATHLEN);
+ break;
+ case ZFS_IOC_DESTROY_SNAPS:
+ nvl = fnvlist_lookup_nvlist(*source, "snaps");
+ pair = nvlist_next_nvpair(nvl, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ } else
+ error = EINVAL;
+ /* old kernel cannot atomically destroy multiple snaps */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ *source = nvl;
+ break;
+ case ZFS_IOC_HOLD:
+ nvl = fnvlist_lookup_nvlist(*source, "holds");
+ pair = nvlist_next_nvpair(nvl, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
+ if (nvpair_value_string(pair, &val) == 0)
+ strlcpy(zc->zc_string, val, MAXNAMELEN);
+ else
+ error = EINVAL;
+ } else
+ error = EINVAL;
+ /* old kernel cannot atomically create multiple holds */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ nvlist_free(nvl);
+ if (nvlist_lookup_int32(*source, "cleanup_fd",
+ &cleanup_fd) == 0)
+ zc->zc_cleanup_fd = cleanup_fd;
+ else
+ zc->zc_cleanup_fd = -1;
+ break;
+ case ZFS_IOC_RELEASE:
+ pair = nvlist_next_nvpair(*source, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
+ if (nvpair_value_nvlist(pair, &nvl) == 0) {
+ hpair = nvlist_next_nvpair(nvl, NULL);
+ if (hpair != NULL)
+ strlcpy(zc->zc_string,
+ nvpair_name(hpair), MAXNAMELEN);
+ else
+ error = EINVAL;
+ if (!error && nvlist_next_nvpair(nvl,
+ hpair) != NULL)
+ error = EOPNOTSUPP;
+ } else
+ error = EINVAL;
+ } else
+ error = EINVAL;
+ /* old kernel cannot atomically release multiple holds */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ return (error);
+}
+
+void
+lzc_compat_post(zfs_cmd_t *zc, const zfs_ioc_t ioc)
+{
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
+ return;
+
+ switch (ioc) {
+ case ZFS_IOC_CREATE:
+ case ZFS_IOC_CLONE:
+ case ZFS_IOC_SNAPSHOT:
+ case ZFS_IOC_SPACE_SNAPS:
+ case ZFS_IOC_DESTROY_SNAPS:
+ zc->zc_nvlist_dst_filled = B_FALSE;
+ break;
+ }
+}
+
+int
+lzc_compat_outnvl(zfs_cmd_t *zc, const zfs_ioc_t ioc, nvlist_t **outnvl)
+{
+ nvlist_t *nvl;
+
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
+ return (0);
+
+ switch (ioc) {
+ case ZFS_IOC_SPACE_SNAPS:
+ nvl = fnvlist_alloc();
+ fnvlist_add_uint64(nvl, "used", zc->zc_cookie);
+ fnvlist_add_uint64(nvl, "compressed", zc->zc_objset_type);
+ fnvlist_add_uint64(nvl, "uncompressed", zc->zc_perm_action);
+ *outnvl = nvl;
+ break;
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h
new file mode 100644
index 000000000000..6527c4b2576f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_CORE_COMPAT_H
+#define _LIBZFS_CORE_COMPAT_H
+
+#include <libnvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ioctl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int lzc_compat_pre(zfs_cmd_t *, zfs_ioc_t *, nvlist_t **);
+void lzc_compat_post(zfs_cmd_t *, const zfs_ioc_t);
+int lzc_compat_outnvl(zfs_cmd_t *, const zfs_ioc_t, nvlist_t **);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_CORE_COMPAT_H */
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
index 56bf7181d8bd..c5c7b66142a0 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
@@ -33,6 +33,7 @@
#include <sys/stat.h>
#include <sys/processor.h>
#include <sys/zfs_context.h>
+#include <sys/rrwlock.h>
#include <sys/zmod.h>
#include <sys/utsname.h>
#include <sys/systeminfo.h>
@@ -45,6 +46,9 @@ int aok;
uint64_t physmem;
vnode_t *rootdir = (vnode_t *)0xabcd1234;
char hw_serial[HW_HOSTID_LEN];
+#ifdef illumos
+kmutex_t cpu_lock;
+#endif
struct utsname utsname = {
"userland", "libzpool", "1", "1", "na"
@@ -842,6 +846,28 @@ ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
return (0);
}
+#ifdef illumos
+/* ARGSUSED */
+cyclic_id_t
+cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
+{
+ return (1);
+}
+
+/* ARGSUSED */
+void
+cyclic_remove(cyclic_id_t id)
+{
+}
+
+/* ARGSUSED */
+int
+cyclic_reprogram(cyclic_id_t id, hrtime_t expiration)
+{
+ return (1);
+}
+#endif
+
/*
* =========================================================================
* kernel emulation setup & teardown
@@ -860,6 +886,8 @@ umem_out_of_memory(void)
void
kernel_init(int mode)
{
+ extern uint_t rrw_tsd_key;
+
umem_nofail_callback(umem_out_of_memory);
physmem = sysconf(_SC_PHYS_PAGES);
@@ -875,7 +903,13 @@ kernel_init(int mode)
system_taskq_init();
+#ifdef illumos
+ mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL);
+#endif
+
spa_init(mode);
+
+ tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
}
void
@@ -923,6 +957,12 @@ crgetuid(cred_t *cr)
return (0);
}
+uid_t
+crgetruid(cred_t *cr)
+{
+ return (0);
+}
+
gid_t
crgetgid(cred_t *cr)
{
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
index 11fb68156edc..21075055a1d8 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
@@ -60,6 +61,8 @@ extern "C" {
#include <umem.h>
#include <inttypes.h>
#include <fsshare.h>
+#include <pthread.h>
+#include <sys/debug.h>
#include <sys/note.h>
#include <sys/types.h>
#include <sys/cred.h>
@@ -84,6 +87,9 @@ extern "C" {
#include <sys/sysevent/dev.h>
#include <machine/atomic.h>
#include <sys/debug.h>
+#ifdef illumos
+#include "zfs.h"
+#endif
#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
@@ -131,28 +137,64 @@ extern int aok;
#ifdef DTRACE_PROBE
#undef DTRACE_PROBE
-#define DTRACE_PROBE(a) ((void)0)
#endif /* DTRACE_PROBE */
+#ifdef illumos
+#define DTRACE_PROBE(a) \
+ ZFS_PROBE0(#a)
+#endif
#ifdef DTRACE_PROBE1
#undef DTRACE_PROBE1
-#define DTRACE_PROBE1(a, b, c) ((void)0)
#endif /* DTRACE_PROBE1 */
+#ifdef illumos
+#define DTRACE_PROBE1(a, b, c) \
+ ZFS_PROBE1(#a, (unsigned long)c)
+#endif
#ifdef DTRACE_PROBE2
#undef DTRACE_PROBE2
-#define DTRACE_PROBE2(a, b, c, d, e) ((void)0)
#endif /* DTRACE_PROBE2 */
+#ifdef illumos
+#define DTRACE_PROBE2(a, b, c, d, e) \
+ ZFS_PROBE2(#a, (unsigned long)c, (unsigned long)e)
+#endif
#ifdef DTRACE_PROBE3
#undef DTRACE_PROBE3
-#define DTRACE_PROBE3(a, b, c, d, e, f, g) ((void)0)
#endif /* DTRACE_PROBE3 */
+#ifdef illumos
+#define DTRACE_PROBE3(a, b, c, d, e, f, g) \
+ ZFS_PROBE3(#a, (unsigned long)c, (unsigned long)e, (unsigned long)g)
+#endif
#ifdef DTRACE_PROBE4
#undef DTRACE_PROBE4
-#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) ((void)0)
#endif /* DTRACE_PROBE4 */
+#ifdef illumos
+#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) \
+ ZFS_PROBE4(#a, (unsigned long)c, (unsigned long)e, (unsigned long)g, \
+ (unsigned long)i)
+#endif
+
+#ifdef illumos
+/*
+ * We use the comma operator so that this macro can be used without much
+ * additional code. For example, "return (EINVAL);" becomes
+ * "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated
+ * twice, so it should not have side effects (e.g. something like:
+ * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
+ */
+#define SET_ERROR(err) (ZFS_SET_ERROR(err), err)
+#else /* !illumos */
+
+#define DTRACE_PROBE(a) ((void)0)
+#define DTRACE_PROBE1(a, b, c) ((void)0)
+#define DTRACE_PROBE2(a, b, c, d, e) ((void)0)
+#define DTRACE_PROBE3(a, b, c, d, e, f, g) ((void)0)
+#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) ((void)0)
+
+#define SET_ERROR(err) (err)
+#endif /* !illumos */
/*
* Threads
@@ -242,6 +284,9 @@ typedef int krw_t;
#define RW_WRITE_HELD(x) ((x)->rw_owner == curthread)
#define RW_LOCK_HELD(x) rw_lock_held(x)
+#undef RW_LOCK_HELD
+#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x))
+
extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
extern void rw_destroy(krwlock_t *rwlp);
extern void rw_enter(krwlock_t *rwlp, krw_t rw);
@@ -252,6 +297,7 @@ extern int rw_lock_held(krwlock_t *rwlp);
#define rw_downgrade(rwlp) do { } while (0)
extern uid_t crgetuid(cred_t *cr);
+extern uid_t crgetruid(cred_t *cr);
extern gid_t crgetgid(cred_t *cr);
extern int crgetngroups(cred_t *cr);
extern gid_t *crgetgroups(cred_t *cr);
@@ -271,6 +317,14 @@ extern void cv_signal(kcondvar_t *cv);
extern void cv_broadcast(kcondvar_t *cv);
/*
+ * Thread-specific data
+ */
+#define tsd_get(k) pthread_getspecific(k)
+#define tsd_set(k, v) pthread_setspecific(k, v)
+#define tsd_create(kp, d) pthread_key_create(kp, d)
+#define tsd_destroy(kp) /* nothing */
+
+/*
* Kernel memory
*/
#define KM_SLEEP UMEM_NOFAIL
@@ -457,6 +511,9 @@ extern vnode_t *rootdir;
extern void delay(clock_t ticks);
+#define SEC_TO_TICK(sec) ((sec) * hz)
+#define NSEC_TO_TICK(usec) ((usec) / (NANOSEC / hz))
+
#define gethrestime_sec() time(NULL)
#define gethrestime(t) \
do {\
@@ -516,7 +573,7 @@ typedef struct callb_cpr {
#define INGLOBALZONE(z) (1)
extern char *kmem_asprintf(const char *fmt, ...);
-#define strfree(str) kmem_free((str), strlen(str)+1)
+#define strfree(str) kmem_free((str), strlen(str) + 1)
/*
* Hostname information
@@ -624,6 +681,36 @@ typedef uint32_t idmap_rid_t;
#define ERESTART (-1)
#endif
+#ifdef illumos
+/*
+ * Cyclic information
+ */
+extern kmutex_t cpu_lock;
+
+typedef uintptr_t cyclic_id_t;
+typedef uint16_t cyc_level_t;
+typedef void (*cyc_func_t)(void *);
+
+#define CY_LOW_LEVEL 0
+#define CY_INFINITY INT64_MAX
+#define CYCLIC_NONE ((cyclic_id_t)0)
+
+typedef struct cyc_time {
+ hrtime_t cyt_when;
+ hrtime_t cyt_interval;
+} cyc_time_t;
+
+typedef struct cyc_handler {
+ cyc_func_t cyh_func;
+ void *cyh_arg;
+ cyc_level_t cyh_level;
+} cyc_handler_t;
+
+extern cyclic_id_t cyclic_add(cyc_handler_t *, cyc_time_t *);
+extern void cyclic_remove(cyclic_id_t);
+extern int cyclic_reprogram(cyclic_id_t, hrtime_t);
+#endif /* illumos */
+
#ifdef __cplusplus
}
#endif
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d b/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d
new file mode 100644
index 000000000000..1351733c807b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+provider zfs {
+ probe probe0(char *probename);
+ probe probe1(char *probename, unsigned long arg1);
+ probe probe2(char *probename, unsigned long arg1, unsigned long arg2);
+ probe probe3(char *probename, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3);
+ probe probe4(char *probename, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4);
+
+ probe set__error(int err);
+};
+
+#pragma D attributes Evolving/Evolving/ISA provider zfs provider
+#pragma D attributes Private/Private/Unknown provider zfs module
+#pragma D attributes Private/Private/Unknown provider zfs function
+#pragma D attributes Evolving/Evolving/ISA provider zfs name
+#pragma D attributes Evolving/Evolving/ISA provider zfs args
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/input.c b/cddl/contrib/opensolaris/tools/ctf/cvt/input.c
index 67ebde702298..240094212f5b 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/input.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/input.c
@@ -387,6 +387,7 @@ GElf_Sym *
symit_next(symit_data_t *si, int type)
{
GElf_Sym sym;
+ char *bname;
int check_sym = (type == STT_OBJECT || type == STT_FUNC);
for (; si->si_next < si->si_nument; si->si_next++) {
@@ -394,8 +395,10 @@ symit_next(symit_data_t *si, int type)
gelf_getsym(si->si_symd, si->si_next, &sym);
si->si_curname = (caddr_t)si->si_strd->d_buf + sym.st_name;
- if (GELF_ST_TYPE(sym.st_info) == STT_FILE)
- si->si_curfile = si->si_curname;
+ if (GELF_ST_TYPE(sym.st_info) == STT_FILE) {
+ bname = strrchr(si->si_curname, '/');
+ si->si_curfile = bname == NULL ? si->si_curname : bname + 1;
+ }
if (GELF_ST_TYPE(sym.st_info) != type ||
sym.st_shndx == SHN_UNDEF)
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
index bfe5b7e6ceb8..af797690a259 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
@@ -363,6 +363,7 @@ sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
for (i = 0; i < nent; i++) {
GElf_Sym sym;
+ char *bname;
iidesc_t **tolist;
GElf_Sym ssym;
iidesc_match_t smatch;
@@ -377,7 +378,8 @@ sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
switch (GELF_ST_TYPE(sym.st_info)) {
case STT_FILE:
- match.iim_file = match.iim_name;
+ bname = strrchr(match.iim_name, '/');
+ match.iim_file = bname == NULL ? match.iim_name : bname + 1;
continue;
case STT_OBJECT:
tolist = iiburst->iib_objts;
diff --git a/cddl/lib/Makefile b/cddl/lib/Makefile
index 14c73b5c610e..53d402a7aaa8 100644
--- a/cddl/lib/Makefile
+++ b/cddl/lib/Makefile
@@ -9,10 +9,12 @@ SUBDIR= ${_drti} \
libnvpair \
libumem \
libuutil \
+ ${_libzfs_core} \
${_libzfs} \
${_libzpool}
.if ${MK_ZFS} != "no"
+_libzfs_core= libzfs_core
_libzfs= libzfs
.if ${MK_LIBTHR} != "no"
_libzpool= libzpool
diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile
index 17f0be6c4c27..4fd7faefc3d8 100644
--- a/cddl/lib/libdtrace/Makefile
+++ b/cddl/lib/libdtrace/Makefile
@@ -31,7 +31,9 @@ SRCS= dt_aggregate.c \
dt_parser.c \
dt_pcb.c \
dt_pid.c \
+ dt_pq.c \
dt_pragma.c \
+ dt_print.c \
dt_printf.c \
dt_proc.c \
dt_program.c \
diff --git a/cddl/lib/libzfs/Makefile b/cddl/lib/libzfs/Makefile
index 9e68da4c3733..5b6b47dcc28c 100644
--- a/cddl/lib/libzfs/Makefile
+++ b/cddl/lib/libzfs/Makefile
@@ -6,8 +6,9 @@
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
LIB= zfs
-DPADD= ${LIBMD} ${LIBPTHREAD} ${LIBUMEM} ${LIBUTIL} ${LIBM} ${LIBNVPAIR}
-LDADD= -lmd -lpthread -lumem -lutil -lm -lnvpair
+DPADD= ${LIBMD} ${LIBPTHREAD} ${LIBUMEM} ${LIBUTIL} ${LIBM} ${LIBNVPAIR} \
+ ${LIBZFS_CORE}
+LDADD= -lmd -lpthread -lumem -lutil -lm -lnvpair -lzfs_core
SRCS= deviceid.c \
fsshare.c \
@@ -17,6 +18,7 @@ SRCS= deviceid.c \
zone.c
SRCS+= libzfs_changelist.c \
+ libzfs_compat.c \
libzfs_config.c \
libzfs_dataset.c \
libzfs_diff.c \
@@ -54,5 +56,6 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs_core/common
.include <bsd.lib.mk>
diff --git a/cddl/lib/libzfs_core/Makefile b/cddl/lib/libzfs_core/Makefile
new file mode 100644
index 000000000000..a470fbc25fb1
--- /dev/null
+++ b/cddl/lib/libzfs_core/Makefile
@@ -0,0 +1,37 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../cddl/compat/opensolaris/misc
+.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
+.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs_core/common
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
+
+LIB= zfs_core
+DPADD= ${LIBNVPAIR}
+LDADD= -lnvpair
+
+SRCS= libzfs_core.c \
+ libzfs_core_compat.c
+
+SRCS+= libzfs_compat.c
+
+WARNS?= 0
+CSTD= c99
+CFLAGS+= -DZFS_NO_ACL
+CFLAGS+= -I${.CURDIR}/../../../sbin/mount
+CFLAGS+= -I${.CURDIR}/../../../cddl/lib/libumem
+CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
+CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
+CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
+CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
+CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
+CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
+CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs_core/common
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
+
+.include <bsd.lib.mk>
diff --git a/cddl/sbin/zfs/Makefile b/cddl/sbin/zfs/Makefile
index 95a476b7a512..a49d278a8e36 100644
--- a/cddl/sbin/zfs/Makefile
+++ b/cddl/sbin/zfs/Makefile
@@ -14,6 +14,7 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
+CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs_core/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libumem/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
@@ -22,7 +23,7 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
DPADD= ${LIBGEOM} ${LIBJAIL} ${LIBNVPAIR} ${LIBUMEM} \
- ${LIBUTIL} ${LIBUUTIL} ${LIBZFS}
-LDADD= -lgeom -ljail -lnvpair -lumem -lutil -luutil -lzfs
+ ${LIBUTIL} ${LIBUUTIL} ${LIBZFS_CORE} ${LIBZFS}
+LDADD= -lgeom -ljail -lnvpair -lumem -lutil -luutil -lzfs_core -lzfs
.include <bsd.prog.mk>
diff --git a/cddl/sbin/zpool/Makefile b/cddl/sbin/zpool/Makefile
index b9d44b61305b..1884d249d21b 100644
--- a/cddl/sbin/zpool/Makefile
+++ b/cddl/sbin/zpool/Makefile
@@ -27,7 +27,7 @@ CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/stat/common
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBNVPAIR} \
- ${LIBUMEM} ${LIBUTIL} ${LIBUUTIL} ${LIBZFS}
-LDADD= -lavl -lgeom -lnvpair -lumem -lutil -luutil -lzfs
+ ${LIBUMEM} ${LIBUTIL} ${LIBUUTIL} ${LIBZFS_CORE} ${LIBZFS}
+LDADD= -lavl -lgeom -lnvpair -lumem -lutil -luutil -lzfs_core -lzfs
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/zinject/Makefile b/cddl/usr.bin/zinject/Makefile
index 2ea066c2cfc2..8c5c141e582e 100644
--- a/cddl/usr.bin/zinject/Makefile
+++ b/cddl/usr.bin/zinject/Makefile
@@ -20,7 +20,7 @@ CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBUUTIL} \
- ${LIBZFS} ${LIBZPOOL}
-LDADD= -lgeom -lm -lnvpair -lumem -luutil -lzfs -lzpool
+ ${LIBZFS_CORE} ${LIBZFS} ${LIBZPOOL}
+LDADD= -lgeom -lm -lnvpair -lumem -luutil -lzfs_core -lzfs -lzpool
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile
index 42c0993b3c24..965300ef2976 100644
--- a/cddl/usr.bin/ztest/Makefile
+++ b/cddl/usr.bin/ztest/Makefile
@@ -19,8 +19,9 @@ CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \
- ${LIBPTHREAD} ${LIBAVL} ${LIBZFS} ${LIBUUTIL}
-LDADD= -lgeom -lm -lnvpair -lumem -lzpool -lpthread -lavl -lzfs -luutil
+ ${LIBPTHREAD} ${LIBAVL} ${LIBZFS_CORE} ${LIBZFS} ${LIBUUTIL}
+LDADD= -lgeom -lm -lnvpair -lumem -lzpool -lpthread -lavl -lzfs_core -lzfs \
+ -luutil
CSTD= c99
diff --git a/cddl/usr.sbin/zdb/Makefile b/cddl/usr.sbin/zdb/Makefile
index bdebda335261..806838560a7d 100644
--- a/cddl/usr.sbin/zdb/Makefile
+++ b/cddl/usr.sbin/zdb/Makefile
@@ -24,8 +24,8 @@ CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
- ${LIBUUTIL} ${LIBZFS} ${LIBZPOOL}
-LDADD= -lgeom -lm -lnvpair -lpthread -lumem -luutil -lzfs -lzpool
+ ${LIBUUTIL} ${LIBZFS_CORE} ${LIBZFS} ${LIBZPOOL}
+LDADD= -lgeom -lm -lnvpair -lpthread -lumem -luutil -lzfs_core -lzfs -lzpool
CFLAGS+= -DDEBUG=1
#DEBUG_FLAGS+= -g
diff --git a/cddl/usr.sbin/zhack/Makefile b/cddl/usr.sbin/zhack/Makefile
index 97ef5751b8ca..f09d2d827674 100644
--- a/cddl/usr.sbin/zhack/Makefile
+++ b/cddl/usr.sbin/zhack/Makefile
@@ -23,8 +23,8 @@ CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
- ${LIBUUTIL} ${LIBZFS} ${LIBZPOOL}
-LDADD= -lgeom -lm -lnvpair -lpthread -lumem -luutil -lzfs -lzpool
+ ${LIBUUTIL} ${LIBZFS_CORE} ${LIBZFS} ${LIBZPOOL}
+LDADD= -lgeom -lm -lnvpair -lpthread -lumem -luutil -lzfs_core -lzfs -lzpool
CFLAGS+= -DDEBUG=1
#DEBUG_FLAGS+= -g