aboutsummaryrefslogtreecommitdiff
path: root/cddl
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
commitd1d015864103b253b3fcb2f72a0da5b0cfeb31b6 (patch)
tree22b131dceb13c3df96da594fbaadb693504797c7 /cddl
parent12d4083451fc39b3e831d4ea0bfa67d3b32cfb54 (diff)
parentb6f49c23a36f329cbf1e7f28078e17fd87f0e245 (diff)
downloadsrc-d1d015864103b253b3fcb2f72a0da5b0cfeb31b6.tar.gz
src-d1d015864103b253b3fcb2f72a0da5b0cfeb31b6.zip
Merge from head
Notes
Notes: svn path=/projects/bmake/; revision=255263
Diffstat (limited to 'cddl')
-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/fbtprovider/tst.functionentry.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d9
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl2
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl29
-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.BadAlign.d7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal.ksh4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.temporal2.ksh4
-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_AGG.bad.d (renamed from cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast1.d)3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c20
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d4
-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/err.D_PROTO_LEN.bad.d10
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_AGG.bad.d (renamed from cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast2.d)4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d9
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.const.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c33
-rw-r--r--cddl/contrib/opensolaris/cmd/zhack/zhack.c3
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c75
-rw-r--r--cddl/contrib/opensolaris/cmd/ztest/ztest.c79
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_create.c190
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_error.c7
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_impl.h10
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_open.c13
-rw-r--r--cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c57
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c6
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c2
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c6
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h2
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c23
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c4
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c51
-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/libzfs/common/libzfs.h5
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c143
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c6
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c16
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c146
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c88
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c60
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h3
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/kernel.c6
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h46
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c15
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h2
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c112
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c6
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c8
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/util.c4
-rw-r--r--cddl/lib/drti/Makefile8
-rw-r--r--cddl/lib/libdtrace/Makefile3
-rw-r--r--cddl/lib/libdtrace/ip.d285
-rw-r--r--cddl/lib/libdtrace/nfs.d76
-rw-r--r--cddl/lib/libdtrace/nfssrv.d54
-rw-r--r--cddl/lib/libdtrace/tcp.d203
-rw-r--r--cddl/lib/libdtrace/udp.d75
-rw-r--r--cddl/lib/libzpool/Makefile6
-rw-r--r--cddl/usr.bin/ztest/Makefile5
-rw-r--r--cddl/usr.sbin/zdb/Makefile5
77 files changed, 2001 insertions, 506 deletions
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 ea746948e5ef..68e35889eca0 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,9 +23,8 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
- */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
/*
* ASSERTION:
@@ -38,20 +37,19 @@
*/
/*
- * 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.
+ * 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.
*/
#pragma D option bufpolicy=ring
-#pragma D option bufsize=80
+#pragma D option bufsize=40
#pragma D option quiet
int n;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d
index 78e107eed492..e625cd9996d4 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d
@@ -36,12 +36,12 @@
#pragma D option quiet
#pragma D option statusrate=10ms
-fbt::ioctl:entry
+fbt::kern_ioctl:entry
{
printf("Entering the ioctl function\n");
}
-fbt::ioctl:return
+fbt::kern_ioctl:return
{
printf("Returning from ioctl function\n");
exit(0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d
index 6d1b8a8fab69..f0338ec57133 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d
@@ -36,7 +36,7 @@
#pragma D option quiet
#pragma D option statusrate=10ms
-fbt::ioctl:return
+fbt::kern_ioctl:return
{
printf("The function return value is stored in %u\n", arg1);
exit(0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d
index c2c7bf04d002..5a26459a2eef 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d
@@ -36,13 +36,13 @@
#pragma D option quiet
#pragma D option statusrate=10ms
-fbt::ioctl:entry
+fbt::kern_ioctl:entry
{
printf("Entering the ioctl function\n");
printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
}
-fbt::ioctl:return
+fbt::kern_ioctl:return
{
printf("Returning from ioctl function\n");
printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d
index be2c0d6a6169..2ee8080305ba 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d
@@ -41,12 +41,12 @@ BEGIN
self->traceme = 1;
}
-fbt::ioctl:entry
+fbt::kern_ioctl:entry
{
printf("Entering the function\n");
}
-fbt::ioctl:return
+fbt::kern_ioctl:return
{
printf("The offset = %u\n", arg0);
exit(0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d
index 240744bff38f..1e8ae16e0970 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d
@@ -36,14 +36,14 @@
#pragma D option quiet
#pragma D option statusrate=10ms
-fbt::ioctl:entry
+fbt::kern_ioctl:entry
{
printf("Entering the ioctl function\n");
printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
exit(0);
}
-fbt::ioctl:return
+fbt::kern_ioctl:return
{
printf("Returning from ioctl function\n");
printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d
index cadbaa00f925..3fb54227b050 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d
@@ -36,7 +36,7 @@
#pragma D option quiet
#pragma D option statusrate=10ms
-fbt::ioctl:return
+fbt::kern_ioctl:return
/arg1 == 0/
{
printf("%s %x returned 0", probefunc, arg0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d
index 67ef106fac0c..8dbb0abe39c0 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d
@@ -36,7 +36,7 @@
#pragma D option quiet
#pragma D option statusrate=10ms
-fbt::ioctl:entry
+fbt::kern_ioctl:entry
{
self->traceme = 1;
}
@@ -47,7 +47,7 @@ fbt:::entry
printf("called %s\n", probefunc);
}
-fbt::ioctl:return
+fbt::kern_ioctl:return
/self->traceme/
{
self->traceme = 0;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d
index 392c18a6df89..0f23737d38f6 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.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.
+ */
#pragma D option quiet
@@ -36,3 +38,8 @@ BEGIN
printf("%s\n", strjoin("", ""));
exit(0);
}
+
+BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
index 128263eaec22..ccc247dec514 100755
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
@@ -73,7 +73,7 @@ die "Could not determine local IP address" if $local eq "";
# Find the first remote host that responds to an icmp echo,
# which isn't a local address.
#
-open PING, "/sbin/ping -ns $Broadcast{$local} 56 $MAXHOSTS |" or
+open PING, "/sbin/ping -n -s 56 -c $MAXHOSTS $Broadcast{$local} |" or
die "Couldn't run ping: $!\n";
while (<PING>) {
if (/bytes from (.*): / and not defined $Broadcast{$1}) {
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
index 837ca3c799d2..35bea8e58fa1 100755
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
@@ -48,7 +48,9 @@ my $MULTICAST = "FF02::1"; # IPv6 multicast address
#
my $local = "";
my $remote = "";
+my $interf = "";
my %Local;
+my %Addr;
my $up;
open IFCONFIG, '/sbin/ifconfig -a inet6 |'
or die "Couldn't run ifconfig: $!\n";
@@ -59,27 +61,34 @@ while (<IFCONFIG>) {
$up = 1 if /^[a-z].*<UP,/;
$up = 0 if /^[a-z].*<,/;
+ if (m:(\S+\d+)\: :) {
+ $interf = $1;
+ }
+
# assume output is "inet6 ...":
- if (m:inet6 (\S+)/:) {
+ if (m:inet6 (\S+) :) {
my $addr = $1;
$Local{$addr} = 1;
- $local = $addr if $up and $local eq "";
+ $Addr{$interf} = $addr;
$up = 0;
+ $interf = "";
}
}
close IFCONFIG;
-exit 1 if $local eq "";
#
# Find the first remote host that responds to an icmp echo,
-# which isn't a local address.
+# which isn't a local address. Try each IPv6-enabled interface.
#
-open PING, "/sbin/ping -ns -A inet6 $MULTICAST 56 $MAXHOSTS |" or
- die "Couldn't run ping: $!\n";
-while (<PING>) {
- if (/bytes from (.*): / and not defined $Local{$1}) {
- $remote = $1;
- last;
+foreach $interf (split(' ', `ifconfig -l -u inet6`)) {
+ next if $interf =~ /lo[0-9]+/;
+ open PING, "/sbin/ping6 -n -s 56 -c $MAXHOSTS $MULTICAST\%$interf |" or next;
+ while (<PING>) {
+ if (/bytes from (.*), / and not defined $Local{$1}) {
+ $remote = $1;
+ $local = $Addr{$interf};
+ last;
+ }
}
}
close PING;
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 25ae061ec074..35f0391ba87d 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,9 +24,7 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-
-#
-# Copyright (c) 2012 by Delphix. All rights reserved.
+# ident "%Z%%M% %I% %E% SMI"
#
if [ $# != 1 ]; then
@@ -51,13 +49,13 @@ tick-1s
tick-1s
/(i % 2) == 0/
{
- system("dtrace -c date -n 'pid\$target::main:entry' >/dev/null");
+ system("dtrace -c date -ln 'pid\$target::main:entry' >/dev/null");
}
tick-1s
/(i % 2) == 1/
{
- system("dtrace -c date -n 'pid\$target::main:return' >/dev/null");
+ system("dtrace -c date -ln 'pid\$target::main:return' >/dev/null");
}
EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d
index ab4106dbeef8..3923cd910a14 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.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: This test reproduces the alignment error.
@@ -39,9 +41,10 @@
BEGIN
{
- x = (int *) 64;
+ x = (int *)64;
y = *x;
trace(y);
+ exit(0);
}
ERROR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d
index 324f40113ae8..6c79bfa42016 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.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: D pointers do not allow invalid pointer accesses.
@@ -44,6 +46,7 @@ BEGIN
y = (int *) (x - 3300778156056);
*y = 3;
trace(*y);
+ exit(0);
}
ERROR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d
index 39bd1140bdf1..66c203061d00 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.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: D pointers do not allow invalid pointer accesses.
@@ -39,9 +41,10 @@
BEGIN
{
- y = (int *) (-33007);
+ y = (int *)-33007;
*y = 3;
trace(*y);
+ exit(0);
}
ERROR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d
index 9d6b144086b8..f5f49e966fcf 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.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: Demonstrating valid memory access.
@@ -40,10 +42,11 @@
BEGIN
{
x = (int *)alloca(sizeof (int));
- printf("Address x: %x\n", (int) x);
- y = (int *) (x - 2);
+ printf("Address x: %x\n", (int)x);
+ y = (int *)(x - 2);
*y = 3;
- printf("Address y: %x\tValue: %d\n", (int) y, *y);
+ printf("Address y: %x\tValue: %d\n", (int)y, *y);
+ exit(0);
}
ERROR
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
index 9a0aed0678cf..f09c71fa59c7 100644
--- 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
@@ -73,8 +73,8 @@ if [ "$status" -ne 0 ]; then
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
+# so use sed to remove the blank line.
+sed '$d' $file > $file.2
sort -n $file.2 | diff $file.2 -
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
index 4e8d592d81d6..05b078a7d216 100644
--- 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
@@ -89,8 +89,8 @@ if [ "$status" -ne 0 ]; then
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
+# so use sed to remove the blank line.
+sed '$d' $file > $file.2
sort -n $file.2 | diff $file.2 -
status=$?
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
new file mode 100644
index 000000000000..f06edcb5a4ec
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh
@@ -0,0 +1,197 @@
+#
+# 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/pointers/tst.assigncast1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_AGG.bad.d
index 0567123f3a8b..5479d00126a7 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast1.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_AGG.bad.d
@@ -19,7 +19,8 @@
BEGIN
{
- *((int *)alloca(4)) = 1;
+ @ = count();
+ print(@);
}
BEGIN
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
index 902f07272dd0..4f45885d42a3 100644
--- 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
@@ -20,10 +20,15 @@
*/
/*
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
BEGIN
{
print((void)`p0);
}
+
+BEGIN
+{
+ exit(0);
+}
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
index a1d3be1f62d3..368caebacb81 100644
--- 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
@@ -20,10 +20,15 @@
*/
/*
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
BEGIN
{
print();
}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d
new file mode 100644
index 000000000000..f96af108cbea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+enum simpson {
+ homer,
+ marge,
+ bart,
+ lisa,
+ maggie,
+ snowball_ii,
+ santas_little_helper
+};
+
+BEGIN
+{
+ print(bart);
+ print((enum simpson)4);
+ print(snowball_ii);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d.out
new file mode 100644
index 000000000000..979a5b72d716
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.enum.d.out
@@ -0,0 +1,4 @@
+enum simpson bart
+enum simpson maggie
+enum simpson snowball_ii
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d
index 7426d19e1b31..beb1c50bba38 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.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:
@@ -39,7 +41,7 @@
*/
-#pragma D option bufsize=16
+#pragma D option bufsize=32
#pragma D option bufpolicy=ring
#pragma D option statusrate=1nsec
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
index e2e9505fb598..013a9e7c7897 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
@@ -26,26 +26,24 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
#include <unistd.h>
-#ifndef __FreeBSD__
-#include <sys/uadmin.h>
-#endif
int
main(int argc, char **argv)
{
-#ifdef __FreeBSD__
- return (1);
-#else
+ int val = 1;
+
while (1) {
- if (uadmin(A_SDTTEST, 0, 0) < 0) {
- perror("uadmin");
- return (1);
- }
+ if (sysctlbyname("debug.dtracetest.sdttest", NULL, NULL, &val,
+ sizeof(val)))
+ err(1, "sysctlbyname");
sleep(1);
}
return (0);
-#endif
}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
index 0523de0951ed..e965b05f2405 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
@@ -43,7 +43,7 @@ ERROR
exit(1);
}
-sdt:::test
+test:::sdttest
/arg0 != 1 || arg1 != 2 || arg2 != 3 || arg3 != 4 || arg4 != 5 || arg5 != 6 ||
arg6 != 7/
{
@@ -54,7 +54,7 @@ sdt:::test
exit(1);
}
-sdt:::test
+test:::sdttest
{
exit(0);
}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d
index f660e9a8f3cf..5ac7957ced85 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.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:
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 99539f903eb6..6b91efd9114b 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,10 +24,7 @@
* Use is subject to license terms.
*/
-/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
- */
-
+#pragma ident "%Z%%M% %I% %E% SMI"
/*
* ASSERTION:
* Verify the behavior of speculations with changes in specsize.
@@ -38,7 +35,7 @@
*/
#pragma D option quiet
-#pragma D option specsize=48
+#pragma D option specsize=40
BEGIN
{
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d
index a1ec95ccb4f5..68c11950b51c 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d
@@ -24,8 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
/*
* ASSERTION:
@@ -39,3 +40,8 @@ BEGIN
trace();
}
+
+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/trace/err.D_TRACE_AGG.bad.d
index 6282e7ae15a3..b29b9f179964 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.assigncast2.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_AGG.bad.d
@@ -19,8 +19,8 @@
BEGIN
{
- this->a = alloca(4);
- *((int *)this->a) = 1;
+ @ = count();
+ trace(@);
}
BEGIN
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d
index eb9f194a73f4..ed044b2236fb 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.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:
@@ -37,3 +39,8 @@ BEGIN
{
trace((void)`kmem_flags);
}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.const.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.const.d
new file mode 100644
index 000000000000..dae3d9041ed3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.const.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.
+ */
+
+/*
+ * Make sure we can scope types with modifiers.
+ */
+
+BEGIN
+{
+ trace((D`int *)0);
+ trace((const D`int *)0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index 611740c756e8..3779b2996fb7 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -28,6 +28,7 @@
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
#include <assert.h>
@@ -56,6 +57,7 @@
#include <sys/fs/zfs.h>
#include <sys/types.h>
#include <time.h>
+#include <err.h>
#include <libzfs.h>
#include <libzfs_core.h>
@@ -3529,6 +3531,12 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
int rv = 0;
int error;
+ if (sd->sd_recursive &&
+ zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) != 0) {
+ zfs_close(zhp);
+ return (0);
+ }
+
error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
if (error == -1)
nomem();
@@ -5233,8 +5241,7 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
continue;
}
if (holding) {
- if (zfs_hold(zhp, delim+1, tag, recursive,
- B_FALSE, -1) != 0)
+ if (zfs_hold(zhp, delim+1, tag, recursive, -1) != 0)
++errors;
} else {
if (zfs_release(zhp, delim+1, tag, recursive) != 0)
@@ -5601,8 +5608,8 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
(void) fprintf(stderr, gettext("cannot share '%s': "
"legacy share\n"), zfs_get_name(zhp));
- (void) fprintf(stderr, gettext("use share(1M) to "
- "share this filesystem, or set "
+ (void) fprintf(stderr, gettext("to "
+ "share this filesystem set "
"sharenfs property on\n"));
return (1);
}
@@ -5618,7 +5625,7 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
(void) fprintf(stderr, gettext("cannot %s '%s': "
"legacy mountpoint\n"), cmdname, zfs_get_name(zhp));
- (void) fprintf(stderr, gettext("use %s(1M) to "
+ (void) fprintf(stderr, gettext("use %s(8) to "
"%s this filesystem\n"), cmdname, cmdname);
return (1);
}
@@ -6056,8 +6063,10 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
strcmp(smbshare_prop, "off") == 0) {
(void) fprintf(stderr, gettext("cannot unshare "
"'%s': legacy share\n"), path);
+#ifdef illumos
(void) fprintf(stderr, gettext("use "
"unshare(1M) to unshare this filesystem\n"));
+#endif
} else if (!zfs_is_shared(zhp)) {
(void) fprintf(stderr, gettext("cannot unshare '%s': "
"not currently shared\n"), path);
@@ -6076,7 +6085,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
(void) fprintf(stderr, gettext("cannot unmount "
"'%s': legacy mountpoint\n"),
zfs_get_name(zhp));
- (void) fprintf(stderr, gettext("use umount(1M) "
+ (void) fprintf(stderr, gettext("use umount(8) "
"to unmount this filesystem\n"));
} else {
ret = zfs_unmountall(zhp, flags);
@@ -6298,9 +6307,11 @@ unshare_unmount(int op, int argc, char **argv)
(void) fprintf(stderr, gettext("cannot "
"unshare '%s': legacy share\n"),
zfs_get_name(zhp));
+#ifdef illumos
(void) fprintf(stderr, gettext("use "
"unshare(1M) to unshare this "
"filesystem\n"));
+#endif
ret = 1;
} else if (!zfs_is_shared(zhp)) {
(void) fprintf(stderr, gettext("cannot "
@@ -6318,7 +6329,7 @@ unshare_unmount(int op, int argc, char **argv)
"unmount '%s': legacy "
"mountpoint\n"), zfs_get_name(zhp));
(void) fprintf(stderr, gettext("use "
- "umount(1M) to unmount this "
+ "umount(8) to unmount this "
"filesystem\n"));
ret = 1;
} else if (!zfs_is_mounted(zhp, NULL)) {
@@ -6504,12 +6515,12 @@ manual_mount(int argc, char **argv)
}
} else {
(void) fprintf(stderr, gettext("filesystem '%s' cannot be "
- "mounted using 'mount -F zfs'\n"), dataset);
+ "mounted using 'mount -t zfs'\n"), dataset);
(void) fprintf(stderr, gettext("Use 'zfs set mountpoint=%s' "
"instead.\n"), path);
- (void) fprintf(stderr, gettext("If you must use 'mount -F zfs' "
- "or /etc/vfstab, use 'zfs set mountpoint=legacy'.\n"));
- (void) fprintf(stderr, gettext("See zfs(1M) for more "
+ (void) fprintf(stderr, gettext("If you must use 'mount -t zfs' "
+ "or /etc/fstab, use 'zfs set mountpoint=legacy'.\n"));
+ (void) fprintf(stderr, gettext("See zfs(8) for more "
"information.\n"));
ret = 1;
}
diff --git a/cddl/contrib/opensolaris/cmd/zhack/zhack.c b/cddl/contrib/opensolaris/cmd/zhack/zhack.c
index d80b3a013d3e..1eb87136f2db 100644
--- a/cddl/contrib/opensolaris/cmd/zhack/zhack.c
+++ b/cddl/contrib/opensolaris/cmd/zhack/zhack.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
/*
@@ -153,7 +154,7 @@ import_pool(const char *target, boolean_t readonly)
g_importargs.poolname = g_pool;
pools = zpool_search_import(g_zfs, &g_importargs);
- if (pools == NULL || nvlist_next_nvpair(pools, NULL) == NULL) {
+ if (nvlist_empty(pools)) {
if (!g_importargs.can_be_active) {
g_importargs.can_be_active = B_TRUE;
if (zpool_search_import(g_zfs, &g_importargs) != NULL ||
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index 7e0fa18e9f7c..0dcf11b92046 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -25,6 +25,7 @@
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
*/
#include <solaris.h>
@@ -804,6 +805,7 @@ zpool_do_create(int argc, char **argv)
goto errout;
break;
case 'm':
+ /* Equivalent to -O mountpoint=optarg */
mountpoint = optarg;
break;
case 'o':
@@ -842,8 +844,18 @@ zpool_do_create(int argc, char **argv)
*propval = '\0';
propval++;
- if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
+ /*
+ * Mountpoints are checked and then added later.
+ * Uniquely among properties, they can be specified
+ * more than once, to avoid conflict with -m.
+ */
+ if (0 == strcmp(optarg,
+ zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
+ mountpoint = propval;
+ } else if (add_prop_list(optarg, propval, &fsprops,
+ B_FALSE)) {
goto errout;
+ }
break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
@@ -961,6 +973,18 @@ zpool_do_create(int argc, char **argv)
}
}
+ /*
+ * Now that the mountpoint's validity has been checked, ensure that
+ * the property is set appropriately prior to creating the pool.
+ */
+ if (mountpoint != NULL) {
+ ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
+ mountpoint, &fsprops, B_FALSE);
+ if (ret != 0)
+ goto errout;
+ }
+
+ ret = 1;
if (dryrun) {
/*
* For a dry run invocation, print out a basic message and run
@@ -995,21 +1019,19 @@ zpool_do_create(int argc, char **argv)
if (nvlist_exists(props, propname))
continue;
- if (add_prop_list(propname, ZFS_FEATURE_ENABLED,
- &props, B_TRUE) != 0)
+ ret = add_prop_list(propname,
+ ZFS_FEATURE_ENABLED, &props, B_TRUE);
+ if (ret != 0)
goto errout;
}
}
+
+ ret = 1;
if (zpool_create(g_zfs, poolname,
nvroot, props, fsprops) == 0) {
zfs_handle_t *pool = zfs_open(g_zfs, poolname,
ZFS_TYPE_FILESYSTEM);
if (pool != NULL) {
- if (mountpoint != NULL)
- verify(zfs_prop_set(pool,
- zfs_prop_to_name(
- ZFS_PROP_MOUNTPOINT),
- mountpoint) == 0);
if (zfs_mount(pool, NULL, 0) == 0)
ret = zfs_shareall(pool);
zfs_close(pool);
@@ -1274,12 +1296,13 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
int namewidth, int depth, boolean_t isspare)
{
nvlist_t **child;
- uint_t c, children;
+ uint_t c, vsc, children;
pool_scan_stat_t *ps = NULL;
vdev_stat_t *vs;
char rbuf[6], wbuf[6], cbuf[6];
char *vname;
uint64_t notpresent;
+ uint64_t ashift;
spare_cbdata_t cb;
const char *state;
@@ -1288,7 +1311,7 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
children = 0;
verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
- (uint64_t **)&vs, &c) == 0);
+ (uint64_t **)&vs, &vsc) == 0);
state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
if (isspare) {
@@ -1342,6 +1365,10 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
(void) printf(gettext("unsupported feature(s)"));
break;
+ case VDEV_AUX_ASHIFT_TOO_BIG:
+ (void) printf(gettext("unsupported minimum blocksize"));
+ break;
+
case VDEV_AUX_SPARED:
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
&cb.cb_guid) == 0);
@@ -1384,6 +1411,12 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
(void) printf(gettext("corrupted data"));
break;
}
+ } else if (children == 0 && !isspare &&
+ VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
+ vs->vs_configured_ashift < vs->vs_physical_ashift) {
+ (void) printf(
+ gettext(" block size: %dB configured, %dB native"),
+ 1 << vs->vs_configured_ashift, 1 << vs->vs_physical_ashift);
}
(void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
@@ -2096,8 +2129,10 @@ zpool_do_import(int argc, char **argv)
errno = 0;
searchguid = strtoull(argv[0], &endptr, 10);
- if (errno != 0 || *endptr != '\0')
+ if (errno != 0 || *endptr != '\0') {
searchname = argv[0];
+ searchguid = 0;
+ }
found_config = NULL;
/*
@@ -3976,7 +4011,7 @@ print_dedup_stats(nvlist_t *config)
/*
* If the pool was faulted then we may not have been able to
- * obtain the config. Otherwise, if have anything in the dedup
+ * obtain the config. Otherwise, if we have anything in the dedup
* table continue processing the stats.
*/
if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
@@ -4247,6 +4282,15 @@ status_callback(zpool_handle_t *zhp, void *data)
"'zpool clear'.\n"));
break;
+ case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
+ (void) printf(gettext("status: One or more devices are "
+ "configured to use a non-native block size.\n"
+ "\tExpect reduced performance.\n"));
+ (void) printf(gettext("action: Replace affected devices with "
+ "devices that support the\n\tconfigured block size, or "
+ "migrate data to a properly configured\n\tpool.\n"));
+ break;
+
default:
/*
* The remaining errors can't actually be generated, yet.
@@ -5323,10 +5367,9 @@ main(int argc, char **argv)
* 'freeze' is a vile debugging abomination, so we treat
* it as such.
*/
- char buf[16384];
- int fd = open(ZFS_DEV, O_RDWR);
- (void) strcpy((void *)buf, argv[2]);
- return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
+ zfs_cmd_t zc = { 0 };
+ (void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name));
+ return (!!zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc));
} else {
(void) fprintf(stderr, gettext("unrecognized "
"command '%s'\n"), cmdname);
diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
index ef776a4c7b3f..b6dcf09963a1 100644
--- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c
+++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
@@ -20,9 +20,10 @@
*/
/*
* 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.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
/*
@@ -185,6 +186,7 @@ static const ztest_shared_opts_t ztest_opts_defaults = {
extern uint64_t metaslab_gang_bang;
extern uint64_t metaslab_df_alloc_threshold;
+extern uint64_t zfs_deadman_synctime;
static ztest_shared_opts_t *ztest_shared_opts;
static ztest_shared_opts_t ztest_opts;
@@ -364,7 +366,7 @@ ztest_info_t ztest_info[] = {
{ ztest_fault_inject, 1, &zopt_sometimes },
{ ztest_ddt_repair, 1, &zopt_sometimes },
{ ztest_dmu_snapshot_hold, 1, &zopt_sometimes },
- { ztest_reguid, 1, &zopt_sometimes },
+ { ztest_reguid, 1, &zopt_rarely },
{ ztest_spa_rename, 1, &zopt_rarely },
{ ztest_scrub, 1, &zopt_rarely },
{ ztest_spa_upgrade, 1, &zopt_rarely },
@@ -767,6 +769,16 @@ ztest_kill(ztest_shared_t *zs)
{
zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(ztest_spa));
zs->zs_space = metaslab_class_get_space(spa_normal_class(ztest_spa));
+
+ /*
+ * Before we kill off ztest, make sure that the config is updated.
+ * See comment above spa_config_sync().
+ */
+ mutex_enter(&spa_namespace_lock);
+ spa_config_sync(ztest_spa, B_FALSE, B_FALSE);
+ mutex_exit(&spa_namespace_lock);
+
+ zfs_dbgmsg_print(FTAG);
(void) kill(getpid(), SIGKILL);
}
@@ -2731,7 +2743,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
uint64_t leaf, top;
uint64_t ashift = ztest_get_ashift();
uint64_t oldguid, pguid;
- size_t oldsize, newsize;
+ uint64_t oldsize, newsize;
char oldpath[MAXPATHLEN], newpath[MAXPATHLEN];
int replacing;
int oldvd_has_siblings = B_FALSE;
@@ -2890,8 +2902,8 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
if (error != expected_error && expected_error != EBUSY) {
fatal(0, "attach (%s %llu, %s %llu, %d) "
"returned %d, expected %d",
- oldpath, (longlong_t)oldsize, newpath,
- (longlong_t)newsize, replacing, error, expected_error);
+ oldpath, oldsize, newpath,
+ newsize, replacing, error, expected_error);
}
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
@@ -3605,6 +3617,9 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
else
dmu_tx_hold_write(tx, bigobj, bigoff, bigsize);
+ /* This accounts for setting the checksum/compression. */
+ dmu_tx_hold_bonus(tx, bigobj);
+
txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
if (txg == 0) {
umem_free(packbuf, packsize);
@@ -4509,7 +4524,7 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
*/
tmp_cb = list_head(&zcl.zcl_callbacks);
if (tmp_cb != NULL &&
- tmp_cb->zcd_txg > txg - ZTEST_COMMIT_CALLBACK_THRESH) {
+ (txg - ZTEST_COMMIT_CALLBACK_THRESH) > tmp_cb->zcd_txg) {
fatal(0, "Commit callback threshold exceeded, oldest txg: %"
PRIu64 ", open txg: %" PRIu64 "\n", tmp_cb->zcd_txg, txg);
}
@@ -4713,7 +4728,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
error = user_release_one(fullname, tag);
if (error)
- fatal(0, "user_release_one(%s)", fullname, tag);
+ fatal(0, "user_release_one(%s, %s) = %d", fullname, tag, error);
VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT);
@@ -4755,6 +4770,14 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
ASSERT(leaves >= 1);
/*
+ * Grab the name lock as reader. There are some operations
+ * which don't like to have their vdevs changed while
+ * they are in progress (i.e. spa_change_guid). Those
+ * operations will have grabbed the name lock as writer.
+ */
+ (void) rw_rdlock(&ztest_name_lock);
+
+ /*
* We need SCL_STATE here because we're going to look at vd0->vdev_tsd.
*/
spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
@@ -4783,7 +4806,14 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
if (vd0 != NULL && vd0->vdev_top->vdev_islog)
islog = B_TRUE;
- if (vd0 != NULL && maxfaults != 1) {
+ /*
+ * If the top-level vdev needs to be resilvered
+ * then we only allow faults on the device that is
+ * resilvering.
+ */
+ if (vd0 != NULL && maxfaults != 1 &&
+ (!vdev_resilver_needed(vd0->vdev_top, NULL, NULL) ||
+ vd0->vdev_resilver_txg != 0)) {
/*
* Make vd0 explicitly claim to be unreadable,
* or unwriteable, or reach behind its back
@@ -4814,6 +4844,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
if (sav->sav_count == 0) {
spa_config_exit(spa, SCL_STATE, FTAG);
+ (void) rw_unlock(&ztest_name_lock);
return;
}
vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)];
@@ -4827,6 +4858,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
}
spa_config_exit(spa, SCL_STATE, FTAG);
+ (void) rw_unlock(&ztest_name_lock);
/*
* If we can tolerate two or more faults, or we're dealing
@@ -5292,16 +5324,33 @@ static void *
ztest_deadman_thread(void *arg)
{
ztest_shared_t *zs = arg;
- int grace = 300;
- hrtime_t delta;
+ spa_t *spa = ztest_spa;
+ hrtime_t delta, total = 0;
- delta = (zs->zs_thread_stop - zs->zs_thread_start) / NANOSEC + grace;
+ for (;;) {
+ delta = (zs->zs_thread_stop - zs->zs_thread_start) /
+ NANOSEC + zfs_deadman_synctime;
- (void) poll(NULL, 0, (int)(1000 * delta));
+ (void) poll(NULL, 0, (int)(1000 * delta));
- fatal(0, "failed to complete within %d seconds of deadline", grace);
+ /*
+ * If the pool is suspended then fail immediately. Otherwise,
+ * check to see if the pool is making any progress. If
+ * vdev_deadman() discovers that there hasn't been any recent
+ * I/Os then it will end up aborting the tests.
+ */
+ if (spa_suspended(spa)) {
+ fatal(0, "aborting test after %llu seconds because "
+ "pool has transitioned to a suspended state.",
+ zfs_deadman_synctime);
+ return (NULL);
+ }
+ vdev_deadman(spa->spa_root_vdev);
- return (NULL);
+ total += zfs_deadman_synctime;
+ (void) printf("ztest has been running for %lld seconds\n",
+ total);
+ }
}
static void
@@ -5615,6 +5664,7 @@ ztest_run(ztest_shared_t *zs)
zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(spa));
zs->zs_space = metaslab_class_get_space(spa_normal_class(spa));
+ zfs_dbgmsg_print(FTAG);
umem_free(tid, ztest_opts.zo_threads * sizeof (thread_t));
@@ -6030,6 +6080,7 @@ main(int argc, char **argv)
(void) setvbuf(stdout, NULL, _IOLBF, 0);
dprintf_setup(&argc, argv);
+ zfs_deadman_synctime = 300;
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
ASSERT3S(ztest_fd_rand, >=, 0);
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c
index a4f3df34e8cf..239d166f4412 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_create.c
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c
@@ -24,13 +24,15 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include <sys/sysmacros.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <ctf_impl.h>
+#include <sys/debug.h>
/*
* This static string is used as the template for initially populating a
@@ -167,6 +169,51 @@ ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
}
/*
+ * Only types of dyanmic CTF containers contain reference counts. These
+ * containers are marked RD/WR. Because of that we basically make this a no-op
+ * for compatability with non-dynamic CTF sections. This is also a no-op for
+ * types which are not dynamic types. It is the responsibility of the caller to
+ * make sure it is a valid type. We help that caller out on debug builds.
+ *
+ * Note that the reference counts are not maintained for types that are not
+ * within this container. In other words if we have a type in a parent, that
+ * will not have its reference count increased. On the flip side, the parent
+ * will not be allowed to remove dynamic types if it has children.
+ */
+static void
+ctf_ref_inc(ctf_file_t *fp, ctf_id_t tid)
+{
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
+
+ if (dtd == NULL)
+ return;
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return;
+
+ dtd->dtd_ref++;
+}
+
+/*
+ * Just as with ctf_ref_inc, this is a no-op on non-writeable containers and the
+ * caller should ensure that this is already a valid type.
+ */
+static void
+ctf_ref_dec(ctf_file_t *fp, ctf_id_t tid)
+{
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
+
+ if (dtd == NULL)
+ return;
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return;
+
+ ASSERT(dtd->dtd_ref >= 1);
+ dtd->dtd_ref--;
+}
+
+/*
* If the specified CTF container is writable and has been modified, reload
* this container with the updated type definitions. In order to make this
* code and the rest of libctf as simple as possible, we perform updates by
@@ -180,6 +227,10 @@ ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
* ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
* constant for the caller, so after ctf_bufopen() returns, we use bcopy to
* swap the interior of the old and new ctf_file_t's, and then free the old.
+ *
+ * Note that the lists of dynamic types stays around and the resulting container
+ * is still writeable. Furthermore, the reference counts that are on the dtd's
+ * are still valid.
*/
int
ctf_update(ctf_file_t *fp)
@@ -432,6 +483,7 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
ctf_dmdef_t *dmd, *nmd;
size_t len;
+ int kind, i;
for (p = *q; p != NULL; p = p->dtd_hash) {
if (p != dtd)
@@ -443,7 +495,8 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
if (p != NULL)
*q = p->dtd_hash;
- switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
+ kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
+ switch (kind) {
case CTF_K_STRUCT:
case CTF_K_UNION:
case CTF_K_ENUM:
@@ -454,14 +507,33 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
ctf_free(dmd->dmd_name, len);
fp->ctf_dtstrlen -= len;
}
+ if (kind != CTF_K_ENUM)
+ ctf_ref_dec(fp, dmd->dmd_type);
nmd = ctf_list_next(dmd);
ctf_free(dmd, sizeof (ctf_dmdef_t));
}
break;
case CTF_K_FUNCTION:
+ ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
+ for (i = 0; i < CTF_INFO_VLEN(dtd->dtd_data.ctt_info); i++)
+ if (dtd->dtd_u.dtu_argv[i] != 0)
+ ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]);
ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
break;
+ case CTF_K_ARRAY:
+ ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
+ ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
+ break;
+ case CTF_K_TYPEDEF:
+ ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
+ break;
+ case CTF_K_POINTER:
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
+ break;
}
if (dtd->dtd_name) {
@@ -495,7 +567,9 @@ ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type)
* Discard all of the dynamic type definitions that have been added to the
* container since the last call to ctf_update(). We locate such types by
* scanning the list and deleting elements that have type IDs greater than
- * ctf_dtoldid, which is set by ctf_update(), above.
+ * ctf_dtoldid, which is set by ctf_update(), above. Note that to work properly
+ * with our reference counting schemes, we must delete the dynamic list in
+ * reverse.
*/
int
ctf_discard(ctf_file_t *fp)
@@ -508,11 +582,11 @@ ctf_discard(ctf_file_t *fp)
if (!(fp->ctf_flags & LCTF_DIRTY))
return (0); /* no update required */
- for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
+ for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
if (dtd->dtd_type <= fp->ctf_dtoldid)
continue; /* skip types that have been committed */
- ntd = ctf_list_next(dtd);
+ ntd = ctf_list_prev(dtd);
ctf_dtd_delete(fp, dtd);
}
@@ -614,6 +688,8 @@ ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
return (CTF_ERR); /* errno is set for us */
+ ctf_ref_inc(fp, ref);
+
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
dtd->dtd_data.ctt_type = (ushort_t)ref;
@@ -645,16 +721,29 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
{
ctf_dtdef_t *dtd;
ctf_id_t type;
+ ctf_file_t *fpd;
if (arp == NULL)
return (ctf_set_errno(fp, EINVAL));
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
+ ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
+ ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
return (CTF_ERR); /* errno is set for us */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
dtd->dtd_data.ctt_size = 0;
dtd->dtd_u.dtu_arr = *arp;
+ ctf_ref_inc(fp, arp->ctr_contents);
+ ctf_ref_inc(fp, arp->ctr_index);
return (type);
}
@@ -662,6 +751,7 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
int
ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
{
+ ctf_file_t *fpd;
ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
if (!(fp->ctf_flags & LCTF_RDWR))
@@ -670,8 +760,22 @@ ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
return (ctf_set_errno(fp, ECTF_BADID));
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
+ ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
+ ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
+ ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
fp->ctf_flags |= LCTF_DIRTY;
dtd->dtd_u.dtu_arr = *arp;
+ ctf_ref_inc(fp, arp->ctr_contents);
+ ctf_ref_inc(fp, arp->ctr_index);
return (0);
}
@@ -683,7 +787,9 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
ctf_dtdef_t *dtd;
ctf_id_t type;
uint_t vlen;
+ int i;
ctf_id_t *vdat = NULL;
+ ctf_file_t *fpd;
if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
(ctc->ctc_argc != 0 && argv == NULL))
@@ -696,6 +802,18 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
if (vlen > CTF_MAX_VLEN)
return (ctf_set_errno(fp, EOVERFLOW));
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, ctc->ctc_return) == NULL &&
+ ctf_dtd_lookup(fp, ctc->ctc_return) == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ for (i = 0; i < ctc->ctc_argc; i++) {
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, argv[i]) == NULL &&
+ ctf_dtd_lookup(fp, argv[i]) == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+ }
+
if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
return (ctf_set_errno(fp, EAGAIN));
@@ -707,6 +825,10 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
+ ctf_ref_inc(fp, ctc->ctc_return);
+ for (i = 0; i < ctc->ctc_argc; i++)
+ ctf_ref_inc(fp, argv[i]);
+
bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc);
if (ctc->ctc_flags & CTF_FUNC_VARARG)
vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
@@ -825,8 +947,11 @@ ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
{
ctf_dtdef_t *dtd;
ctf_id_t type;
+ ctf_file_t *fpd;
- if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
+ fpd = fp;
+ if (ref == CTF_ERR || (ctf_lookup_by_id(&fpd, ref) == NULL &&
+ ctf_dtd_lookup(fp, ref) == NULL))
return (ctf_set_errno(fp, EINVAL));
if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
@@ -834,6 +959,7 @@ ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
dtd->dtd_data.ctt_type = (ushort_t)ref;
+ ctf_ref_inc(fp, ref);
return (type);
}
@@ -1008,6 +1134,45 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
if (s != NULL)
fp->ctf_dtstrlen += strlen(s) + 1;
+ ctf_ref_inc(fp, type);
+ fp->ctf_flags |= LCTF_DIRTY;
+ return (0);
+}
+
+/*
+ * This removes a type from the dynamic section. This will fail if the type is
+ * referenced by another type. Note that the CTF ID is never reused currently by
+ * CTF. Note that if this container is a parent container then we just outright
+ * refuse to remove the type. There currently is no notion of searching for the
+ * ctf_dtdef_t in parent containers. If there is, then this constraint could
+ * become finer grained.
+ */
+int
+ctf_delete_type(ctf_file_t *fp, ctf_id_t type)
+{
+ ctf_file_t *fpd;
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ /*
+ * We want to give as useful an errno as possible. That means that we
+ * want to distinguish between a type which does not exist and one for
+ * which the type is not dynamic.
+ */
+ fpd = fp;
+ if (ctf_lookup_by_id(&fpd, type) == NULL &&
+ ctf_dtd_lookup(fp, type) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (dtd == NULL)
+ return (ctf_set_errno(fp, ECTF_NOTDYN));
+
+ if (dtd->dtd_ref != 0 || fp->ctf_refcnt > 1)
+ return (ctf_set_errno(fp, ECTF_REFERENCED));
+
+ ctf_dtd_delete(fp, dtd);
fp->ctf_flags |= LCTF_DIRTY;
return (0);
}
@@ -1103,6 +1268,9 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
ctf_hash_t *hp;
ctf_helem_t *hep;
+ if (dst_fp == src_fp)
+ return (src_type);
+
if (!(dst_fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(dst_fp, ECTF_RDONLY));
@@ -1313,6 +1481,14 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
if (errs)
return (CTF_ERR); /* errno is set for us */
+
+ /*
+ * Now that we know that we can't fail, we go through and bump
+ * all the reference counts on the member types.
+ */
+ for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ dmd != NULL; dmd = ctf_list_next(dmd))
+ ctf_ref_inc(dst_fp, dmd->dmd_type);
break;
}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_error.c b/cddl/contrib/opensolaris/common/ctf/ctf_error.c
index 888c6c848b3f..fe3d0de0cb93 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_error.c
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_error.c
@@ -23,8 +23,9 @@
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012, Joyent, Inc.
+ */
#include <ctf_impl.h>
@@ -73,6 +74,8 @@ static const char *const _ctf_errlist[] = {
"Limit on number of dynamic types reached", /* ECTF_FULL */
"Duplicate member name definition", /* ECTF_DUPMEMBER */
"Conflicting type is already defined", /* ECTF_CONFLICT */
+ "Type has outstanding references", /* ECTF_REFERENCED */
+ "Type is not a dynamic type" /* ECTF_NOTDYN */
};
static const int _ctf_nerr = sizeof (_ctf_errlist) / sizeof (_ctf_errlist[0]);
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_impl.h b/cddl/contrib/opensolaris/common/ctf/ctf_impl.h
index 99990806a32e..f56fa6a00548 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_impl.h
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_impl.h
@@ -24,12 +24,13 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
#ifndef _CTF_IMPL_H
#define _CTF_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/sysmacros.h>
@@ -149,6 +150,7 @@ typedef struct ctf_dtdef {
char *dtd_name; /* name associated with definition (if any) */
ctf_id_t dtd_type; /* type identifier for this definition */
ctf_type_t dtd_data; /* type node (see <sys/ctf.h>) */
+ int dtd_ref; /* recfount for dyanmic types */
union {
ctf_list_t dtu_members; /* struct, union, or enum */
ctf_arinfo_t dtu_arr; /* array */
@@ -269,7 +271,9 @@ enum {
ECTF_DTFULL, /* CTF type is full (no more members allowed) */
ECTF_FULL, /* CTF container is full */
ECTF_DUPMEMBER, /* duplicate member name definition */
- ECTF_CONFLICT /* conflicting type definition present */
+ ECTF_CONFLICT, /* conflicting type definition present */
+ ECTF_REFERENCED, /* type has outstanding references */
+ ECTF_NOTDYN /* type is not a dynamic type */
};
extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *,
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_open.c b/cddl/contrib/opensolaris/common/ctf/ctf_open.c
index e49a4cb32934..2148389fff80 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_open.c
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_open.c
@@ -24,8 +24,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, Joyent, Inc. All rights reserved.
+ */
#include <ctf_impl.h>
#include <sys/mman.h>
@@ -810,8 +811,12 @@ ctf_close(ctf_file_t *fp)
if (fp->ctf_parent != NULL)
ctf_close(fp->ctf_parent);
- for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
- ntd = ctf_list_next(dtd);
+ /*
+ * Note, to work properly with reference counting on the dynamic
+ * section, we must delete the list in reverse.
+ */
+ for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
+ ntd = ctf_list_prev(dtd);
ctf_dtd_delete(fp, dtd);
}
diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c
index 6cd003663cac..0df44cfda938 100644
--- a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c
+++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c
@@ -216,6 +216,7 @@ ctf_fdopen(int fd, int *errp)
{
ctf_sect_t ctfsect, symsect, strsect;
ctf_file_t *fp = NULL;
+ size_t shstrndx, shnum;
struct stat64 st;
ssize_t nbytes;
@@ -278,11 +279,10 @@ ctf_fdopen(int fd, int *errp)
#else
uchar_t order = ELFDATA2LSB;
#endif
- GElf_Half i, n;
GElf_Shdr *sp;
void *strs_map;
- size_t strs_mapsz;
+ size_t strs_mapsz, i;
char *strs;
if (hdr.e32.e_ident[EI_DATA] != order)
@@ -298,11 +298,38 @@ ctf_fdopen(int fd, int *errp)
ehdr_to_gelf(&e32, &hdr.e64);
}
- if (hdr.e64.e_shstrndx >= hdr.e64.e_shnum)
+ shnum = hdr.e64.e_shnum;
+ shstrndx = hdr.e64.e_shstrndx;
+
+ /* Extended ELF sections */
+ if ((shstrndx == SHN_XINDEX) || (shnum == 0)) {
+ if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
+ Elf32_Shdr x32;
+
+ if (pread64(fd, &x32, sizeof (x32),
+ hdr.e64.e_shoff) != sizeof (x32))
+ return (ctf_set_open_errno(errp,
+ errno));
+
+ shnum = x32.sh_size;
+ shstrndx = x32.sh_link;
+ } else {
+ Elf64_Shdr x64;
+
+ if (pread64(fd, &x64, sizeof (x64),
+ hdr.e64.e_shoff) != sizeof (x64))
+ return (ctf_set_open_errno(errp,
+ errno));
+
+ shnum = x64.sh_size;
+ shstrndx = x64.sh_link;
+ }
+ }
+
+ if (shstrndx >= shnum)
return (ctf_set_open_errno(errp, ECTF_CORRUPT));
- n = hdr.e64.e_shnum;
- nbytes = sizeof (GElf_Shdr) * n;
+ nbytes = sizeof (GElf_Shdr) * shnum;
if ((sp = malloc(nbytes)) == NULL)
return (ctf_set_open_errno(errp, errno));
@@ -314,7 +341,7 @@ ctf_fdopen(int fd, int *errp)
if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Shdr *sp32;
- nbytes = sizeof (Elf32_Shdr) * n;
+ nbytes = sizeof (Elf32_Shdr) * shnum;
if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
@@ -322,7 +349,7 @@ ctf_fdopen(int fd, int *errp)
return (ctf_set_open_errno(errp, errno));
}
- for (i = 0; i < n; i++)
+ for (i = 0; i < shnum; i++)
shdr_to_gelf(&sp32[i], &sp[i]);
free(sp32);
@@ -336,14 +363,14 @@ ctf_fdopen(int fd, int *errp)
* Now mmap the section header strings section so that we can
* perform string comparison on the section names.
*/
- strs_mapsz = sp[hdr.e64.e_shstrndx].sh_size +
- (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
+ strs_mapsz = sp[shstrndx].sh_size +
+ (sp[shstrndx].sh_offset & ~_PAGEMASK);
strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
- fd, sp[hdr.e64.e_shstrndx].sh_offset & _PAGEMASK);
+ fd, sp[shstrndx].sh_offset & _PAGEMASK);
strs = (char *)strs_map +
- (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
+ (sp[shstrndx].sh_offset & ~_PAGEMASK);
if (strs_map == MAP_FAILED) {
free(sp);
@@ -354,15 +381,15 @@ ctf_fdopen(int fd, int *errp)
* Iterate over the section header array looking for the CTF
* section and symbol table. The strtab is linked to symtab.
*/
- for (i = 0; i < n; i++) {
+ for (i = 0; i < shnum; i++) {
const GElf_Shdr *shp = &sp[i];
const GElf_Shdr *lhp = &sp[shp->sh_link];
- if (shp->sh_link >= hdr.e64.e_shnum)
+ if (shp->sh_link >= shnum)
continue; /* corrupt sh_link field */
- if (shp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size ||
- lhp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size)
+ if (shp->sh_name >= sp[shstrndx].sh_size ||
+ lhp->sh_name >= sp[shstrndx].sh_size)
continue; /* corrupt sh_name field */
if (shp->sh_type == SHT_PROGBITS &&
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
index 57009935f937..64b98c4527bf 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -677,6 +677,12 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
"%s( ) may not be applied to a translated pointer\n", act);
}
+ if (dnp->dn_args->dn_kind == DT_NODE_AGG) {
+ dnerror(dnp->dn_args, istrace ? D_TRACE_AGG : D_PRINT_AGG,
+ "%s( ) may not be applied to an aggregation%s\n", act,
+ istrace ? "" : " -- did you mean printa()?");
+ }
+
dt_cg(yypcb, dnp->dn_args);
/*
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
index c9e157bafb5d..8d9e49449eca 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
@@ -2949,7 +2949,7 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
break;
timestamp = dt_buf_oldest(buf, dtp);
- /* XXX: assert(timestamp >= dtp->dt_last_timestamp); */
+ assert(timestamp >= dtp->dt_last_timestamp);
dtp->dt_last_timestamp = timestamp;
if (timestamp == buf->dtbd_timestamp) {
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
index bb779840406c..871fdd530487 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
@@ -21,6 +21,7 @@
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Use is subject to license terms.
*/
@@ -254,11 +255,6 @@ dt_decl_spec(ushort_t kind, char *name)
ddp->dd_kind = kind;
ddp->dd_name = name;
- if (name != NULL && strchr(name, '`') != NULL) {
- xyerror(D_DECL_SCOPE, "D scoping operator may not be used "
- "in a type name\n");
- }
-
return (dt_decl_check(ddp));
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
index 353f581adc7f..6bc392ff65fa 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
@@ -190,8 +190,10 @@ 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_TRACE_AGG, /* trace() argument is an aggregation */
D_PRINT_VOID, /* print() argument has void type */
D_PRINT_DYN, /* print() argument has dynamic type */
+ D_PRINT_AGG, /* print() argument is an aggregation */
D_TRACEMEM_ADDR, /* tracemem() address bad type */
D_TRACEMEM_SIZE, /* tracemem() size bad type */
D_TRACEMEM_ARGS, /* tracemem() illegal number of args */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
index eae0b016f9c9..9c9b2a6e63c6 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -1086,7 +1086,17 @@ dt_vopen(int version, int flags, int *errp,
dtfd = open("/dev/dtrace/dtrace", O_RDWR);
err = errno; /* save errno from opening dtfd */
-
+#if defined(__FreeBSD__)
+ /*
+ * Automatically load the 'dtraceall' module if we couldn't open the
+ * char device.
+ */
+ if (err == ENOENT && modfind("dtraceall") < 0) {
+ kldload("dtraceall"); /* ignore the error */
+ dtfd = open("/dev/dtrace/dtrace", O_RDWR);
+ err = errno;
+ }
+#endif
#if defined(sun)
ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
#else
@@ -1132,7 +1142,7 @@ alloc:
#if defined(sun)
dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
#else
- dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
+ dtp->dt_prcmode = DT_PROC_STOP_MAIN;
#endif
dtp->dt_linkmode = DT_LINK_KERNEL;
dtp->dt_linktype = DT_LTYP_ELF;
@@ -1153,7 +1163,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_init(dtp);
+ dt_proc_hash_create(dtp);
dtp->dt_vmax = DT_VERS_LATEST;
dtp->dt_cpp_path = strdup(_dtrace_defcpp);
dtp->dt_cpp_argv = malloc(sizeof (char *));
@@ -1167,9 +1177,8 @@ alloc:
(void) uname(&dtp->dt_uts);
if (dtp->dt_mods == NULL || dtp->dt_provs == 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)
+ dtp->dt_procs == 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++)
@@ -1581,7 +1590,7 @@ dtrace_close(dtrace_hdl_t *dtp)
int i;
if (dtp->dt_procs != NULL)
- dt_proc_fini(dtp);
+ dt_proc_hash_destroy(dtp);
while ((pgp = dt_list_next(&dtp->dt_programs)) != NULL)
dt_program_destroy(dtp, pgp);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c
index a16397174dc0..0cd556abd8f5 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c
@@ -73,10 +73,6 @@ 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++;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
index 261fc8ced4d5..ccfa3da39dfe 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
@@ -25,6 +25,9 @@
/*
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
/*
* DTrace print() action
@@ -93,6 +96,7 @@
* Print structure passed down recursively through printing algorithm.
*/
typedef struct dt_printarg {
+ dtrace_hdl_t *pa_dtp; /* libdtrace handle */
caddr_t pa_addr; /* base address of trace data */
ctf_file_t *pa_ctfp; /* CTF container */
int pa_depth; /* member depth */
@@ -303,8 +307,8 @@ dt_print_float(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
}
/*
- * A pointer is printed as a fixed-size integer. This is used both for
- * pointers and functions.
+ * A pointer is generally printed as a fixed-size integer. If we have a
+ * function pointer, we try to look up its name.
*/
static void
dt_print_ptr(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
@@ -313,8 +317,23 @@ dt_print_ptr(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
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);
+ ctf_id_t bid = ctf_type_reference(ctfp, base);
+ uint64_t pc;
+ dtrace_syminfo_t dts;
+ GElf_Sym sym;
+
+ if (bid == CTF_ERR || ctf_type_kind(ctfp, bid) != CTF_K_FUNCTION) {
+ dt_print_hex(fp, addr, size);
+ } else {
+ /* LINTED - alignment */
+ pc = *((uint64_t *)addr);
+ if (dtrace_lookup_by_addr(pap->pa_dtp, pc, &sym, &dts) != 0) {
+ dt_print_hex(fp, addr, size);
+ } else {
+ (void) fprintf(fp, "%s`%s", dts.dts_object,
+ dts.dts_name);
+ }
+ }
}
/*
@@ -459,8 +478,31 @@ 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;
+ ssize_t size;
+ caddr_t addr = pap->pa_addr + off / NBBY;
int value = 0;
+ /*
+ * The C standard says that an enum will be at most the sizeof (int).
+ * But if all the values are less than that, the compiler can use a
+ * smaller size. Thanks standards.
+ */
+ size = ctf_type_size(ctfp, base);
+ switch (size) {
+ case sizeof (uint8_t):
+ value = *(uint8_t *)addr;
+ break;
+ case sizeof (uint16_t):
+ value = *(uint16_t *)addr;
+ break;
+ case sizeof (int32_t):
+ value = *(int32_t *)addr;
+ break;
+ default:
+ (void) fprintf(fp, "<invalid enum size %u>", (uint_t)size);
+ return;
+ }
+
if ((ename = ctf_enum_name(ctfp, base, value)) != NULL)
(void) fprintf(fp, "%s", ename);
else
@@ -635,6 +677,7 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
}
/* setup the print structure and kick off the main print routine */
+ pa.pa_dtp = dtp;
pa.pa_addr = addr;
pa.pa_ctfp = dt_module_getctf(dtp, dmp);
pa.pa_nest = 0;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
index 45eb5a36da7e..d40a0ae1eb18 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
@@ -25,10 +25,6 @@
*/
/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
- */
-
-/*
* DTrace Process Control
*
* This file provides a set of routines that permit libdtrace and its clients
@@ -507,7 +503,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 = dtp->dt_procs;
+ dt_proc_hash_t *dph = dpr->dpr_hdl->dt_procs;
struct ps_prochandle *P = dpr->dpr_proc;
int pid = dpr->dpr_pid;
@@ -968,8 +964,7 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
(void) pthread_cond_init(&dpr->dpr_cv, NULL);
#if defined(sun)
- dpr->dpr_proc = Pxcreate(file, argv, dtp->dt_proc_env, &err, NULL, 0);
- if (dpr->dpr_proc == NULL) {
+ if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) {
#else
if ((err = proc_create(file, argv, pcf, child_arg,
&dpr->dpr_proc)) != 0) {
@@ -1145,75 +1140,30 @@ dt_proc_unlock(dtrace_hdl_t *dtp, struct ps_prochandle *P)
}
void
-dt_proc_init(dtrace_hdl_t *dtp)
+dt_proc_hash_create(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)
- 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;
+ sizeof (dt_proc_t *) * _dtrace_pidbuckets - 1)) != NULL) {
+ (void) pthread_mutex_init(&dtp->dt_procs->dph_lock, NULL);
+ (void) pthread_cond_init(&dtp->dt_procs->dph_cv, NULL);
- /*
- * 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;
+ dtp->dt_procs->dph_hashlen = _dtrace_pidbuckets;
+ dtp->dt_procs->dph_lrulim = _dtrace_pidlrulim;
}
- 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_fini(dtrace_hdl_t *dtp)
+dt_proc_hash_destroy(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 beae6f6d5cda..d1fc7652385d 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
@@ -24,13 +24,11 @@
* 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>
@@ -108,8 +106,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_init(dtrace_hdl_t *);
-extern void dt_proc_fini(dtrace_hdl_t *);
+extern void dt_proc_hash_create(dtrace_hdl_t *);
+extern void dt_proc_hash_destroy(dtrace_hdl_t *);
#ifdef __cplusplus
}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 274b47b5557a..0a5ca82e4c97 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -27,6 +27,7 @@
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
#ifndef _LIBZFS_H
@@ -325,6 +326,7 @@ typedef enum {
ZPOOL_STATUS_RESILVERING, /* device being resilvered */
ZPOOL_STATUS_OFFLINE_DEV, /* device online */
ZPOOL_STATUS_REMOVED_DEV, /* removed device */
+ ZPOOL_STATUS_NON_NATIVE_ASHIFT, /* (e.g. 512e dev with ashift of 9) */
/*
* Finally, the following indicates a healthy pool.
@@ -611,7 +613,8 @@ extern int zfs_send(zfs_handle_t *, const char *, const char *,
extern int zfs_promote(zfs_handle_t *);
extern int zfs_hold(zfs_handle_t *, const char *, const char *,
- boolean_t, boolean_t, int);
+ boolean_t, int);
+extern int zfs_hold_nvl(zfs_handle_t *, int, nvlist_t *);
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_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index e78bb82c61fb..e330ad220e5b 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -21,12 +21,13 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
#include <ctype.h>
@@ -1884,6 +1885,10 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
zcmd_free_nvlists(&zc);
break;
+ case ZFS_PROP_INCONSISTENT:
+ *val = zhp->zfs_dmustats.dds_inconsistent;
+ break;
+
default:
switch (zfs_prop_get_type(prop)) {
case PROP_TYPE_NUMBER:
@@ -3158,18 +3163,14 @@ static int
zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
{
struct destroydata *dd = arg;
- zfs_handle_t *szhp;
char name[ZFS_MAXNAMELEN];
int rv = 0;
(void) snprintf(name, sizeof (name),
"%s@%s", zhp->zfs_name, dd->snapname);
- szhp = make_dataset_handle(zhp->zfs_hdl, name);
- if (szhp) {
+ if (lzc_exists(name))
verify(nvlist_add_boolean(dd->nvl, name) == 0);
- zfs_close(szhp);
- }
rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
zfs_close(zhp);
@@ -3189,7 +3190,7 @@ zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
verify(nvlist_alloc(&dd.nvl, NV_UNIQUE_NAME, 0) == 0);
(void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
- if (nvlist_next_nvpair(dd.nvl, NULL) == NULL) {
+ if (nvlist_empty(dd.nvl)) {
ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
zhp->zfs_name, snapname);
@@ -3214,7 +3215,7 @@ zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
if (ret == 0)
return (0);
- if (nvlist_next_nvpair(errlist, NULL) == NULL) {
+ if (nvlist_empty(errlist)) {
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
@@ -3382,13 +3383,16 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
char name[ZFS_MAXNAMELEN];
int rv = 0;
- (void) snprintf(name, sizeof (name),
- "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
+ if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
- fnvlist_add_boolean(sd->sd_nvl, name);
+ fnvlist_add_boolean(sd->sd_nvl, name);
- rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ }
zfs_close(zhp);
+
return (rv);
}
@@ -3568,7 +3572,6 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
{
rollback_data_t cb = { 0 };
int err;
- zfs_cmd_t zc = { 0 };
boolean_t restore_resv = 0;
uint64_t old_volsize, new_volsize;
zfs_prop_t resv_prop;
@@ -3600,22 +3603,15 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
(old_volsize == zfs_prop_get_int(zhp, resv_prop));
}
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- if (ZFS_IS_VOLUME(zhp))
- zc.zc_objset_type = DMU_OST_ZVOL;
- else
- zc.zc_objset_type = DMU_OST_ZFS;
-
/*
* We rely on zfs_iter_children() to verify that there are no
* newer snapshots for the given dataset. Therefore, we can
* simply pass the name on to the ioctl() call. There is still
* an unlikely race condition where the user has taken a
* snapshot since we verified that this was the most recent.
- *
*/
- if ((err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_ROLLBACK, &zc)) != 0) {
+ err = lzc_rollback(zhp->zfs_name, NULL, 0);
+ if (err != 0) {
(void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
zhp->zfs_name);
@@ -4162,24 +4158,21 @@ struct holdarg {
const char *snapname;
const char *tag;
boolean_t recursive;
+ int error;
};
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) {
+ if (lzc_exists(name))
fnvlist_add_string(ha->nvl, name, ha->tag);
- zfs_close(szhp);
- }
if (ha->recursive)
rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
@@ -4189,14 +4182,10 @@ zfs_hold_one(zfs_handle_t *zhp, void *arg)
int
zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
- boolean_t recursive, boolean_t enoent_ok, int cleanup_fd)
+ boolean_t recursive, int cleanup_fd)
{
int ret;
struct holdarg ha;
- nvlist_t *errors;
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char errbuf[1024];
- nvpair_t *elem;
ha.nvl = fnvlist_alloc();
ha.snapname = snapname;
@@ -4204,23 +4193,44 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
ha.recursive = recursive;
(void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
- if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+ if (nvlist_empty(ha.nvl)) {
+ char errbuf[1024];
+
fnvlist_free(ha.nvl);
ret = ENOENT;
(void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot hold snapshot '%s@%s'"),
+ dgettext(TEXT_DOMAIN,
+ "cannot hold snapshot '%s@%s'"),
zhp->zfs_name, snapname);
- (void) zfs_standard_error(hdl, ret, errbuf);
+ (void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf);
return (ret);
}
- ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
+ ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl);
fnvlist_free(ha.nvl);
- if (ret == 0)
+ return (ret);
+}
+
+int
+zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds)
+{
+ int ret;
+ nvlist_t *errors;
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char errbuf[1024];
+ nvpair_t *elem;
+
+ errors = NULL;
+ ret = lzc_hold(holds, cleanup_fd, &errors);
+
+ if (ret == 0) {
+ /* There may be errors even in the success case. */
+ fnvlist_free(errors);
return (0);
+ }
- if (nvlist_next_nvpair(errors, NULL) == NULL) {
+ if (nvlist_empty(errors)) {
/* no hold-specific errors */
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot hold"));
@@ -4260,10 +4270,6 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
case EEXIST:
(void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
break;
- case ENOENT:
- if (enoent_ok)
- return (ENOENT);
- /* FALLTHROUGH */
default:
(void) zfs_standard_error(hdl,
fnvpair_value_int32(elem), errbuf);
@@ -4274,30 +4280,26 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
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;
+ nvlist_t *existing_holds;
(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 (lzc_get_holds(name, &existing_holds) != 0) {
+ ha->error = ENOENT;
+ } else if (!nvlist_exists(existing_holds, ha->tag)) {
+ ha->error = ESRCH;
+ } else {
+ nvlist_t *torelease = fnvlist_alloc();
+ fnvlist_add_boolean(torelease, ha->tag);
+ fnvlist_add_nvlist(ha->nvl, name, torelease);
+ fnvlist_free(torelease);
}
if (ha->recursive)
@@ -4312,7 +4314,7 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
{
int ret;
struct holdarg ha;
- nvlist_t *errors;
+ nvlist_t *errors = NULL;
nvpair_t *elem;
libzfs_handle_t *hdl = zhp->zfs_hdl;
char errbuf[1024];
@@ -4321,26 +4323,34 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
ha.snapname = snapname;
ha.tag = tag;
ha.recursive = recursive;
+ ha.error = 0;
(void) zfs_release_one(zfs_handle_dup(zhp), &ha);
- if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+ if (nvlist_empty(ha.nvl)) {
fnvlist_free(ha.nvl);
- ret = ENOENT;
+ ret = ha.error;
(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);
+ if (ret == ESRCH) {
+ (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
+ } else {
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ }
return (ret);
}
ret = lzc_release(ha.nvl, &errors);
fnvlist_free(ha.nvl);
- if (ret == 0)
+ if (ret == 0) {
+ /* There may be errors even in the success case. */
+ fnvlist_free(errors);
return (0);
+ }
- if (nvlist_next_nvpair(errors, NULL) == NULL) {
+ if (nvlist_empty(errors)) {
/* no hold-specific errors */
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot release"));
@@ -4535,6 +4545,11 @@ zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
return (err);
}
+/*
+ * Convert the zvol's volume size to an appropriate reservation.
+ * Note: If this routine is updated, it is necessary to update the ZFS test
+ * suite's shell version in reservation.kshlib.
+ */
uint64_t
zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
{
@@ -4590,7 +4605,7 @@ zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
} else {
(void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
+ dgettext(TEXT_DOMAIN, "cannot unjail '%s'"), zhp->zfs_name);
}
switch (zhp->zfs_type) {
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
index 278bfd4cfd8f..259d045e58a3 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
@@ -21,10 +21,10 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdio.h>
@@ -452,8 +452,12 @@ iter_dependents_cb(zfs_handle_t *zhp, void *arg)
}
ida->stack = isf.next;
}
+
if (!first && err == 0)
err = ida->func(zhp, ida->data);
+ else
+ zfs_close(zhp);
+
return (err);
}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index 9b04e08c5e8a..3ce962310f80 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -1112,7 +1112,6 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
nvlist_t *zc_fsprops = NULL;
nvlist_t *zc_props = NULL;
char msg[1024];
- char *altroot;
int ret = -1;
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
@@ -1211,21 +1210,6 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
}
}
- /*
- * If this is an alternate root pool, then we automatically set the
- * mountpoint of the root dataset to be '/'.
- */
- if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT),
- &altroot) == 0) {
- zfs_handle_t *zhp;
-
- verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL);
- verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
- "/") == 0);
-
- zfs_close(zhp);
- }
-
create_failed:
zcmd_free_nvlists(&zc);
nvlist_free(zc_props);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
index 34cb648f6214..1fc46c24e4ab 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
@@ -25,6 +25,7 @@
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
#include <assert.h>
@@ -802,6 +803,7 @@ typedef struct send_dump_data {
int outfd;
boolean_t err;
nvlist_t *fss;
+ nvlist_t *snapholds;
avl_tree_t *fsavl;
snapfilter_cb_t *filter_cb;
void *filter_cb_arg;
@@ -952,41 +954,19 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
return (0);
}
-static int
-hold_for_send(zfs_handle_t *zhp, send_dump_data_t *sdd)
+static void
+gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
{
- zfs_handle_t *pzhp;
- int error = 0;
- char *thissnap;
-
assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
- if (sdd->dryrun)
- return (0);
-
/*
- * zfs_send() only opens a cleanup_fd for sends that need it,
+ * zfs_send() only sets snapholds for sends that need them,
* e.g. replication and doall.
*/
- if (sdd->cleanup_fd == -1)
- return (0);
-
- thissnap = strchr(zhp->zfs_name, '@') + 1;
- *(thissnap - 1) = '\0';
- pzhp = zfs_open(zhp->zfs_hdl, zhp->zfs_name, ZFS_TYPE_DATASET);
- *(thissnap - 1) = '@';
-
- /*
- * It's OK if the parent no longer exists. The send code will
- * handle that error.
- */
- if (pzhp) {
- error = zfs_hold(pzhp, thissnap, sdd->holdtag,
- B_FALSE, B_TRUE, sdd->cleanup_fd);
- zfs_close(pzhp);
- }
+ if (sdd->snapholds == NULL)
+ return;
- return (error);
+ fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
}
static void *
@@ -1042,28 +1022,23 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
send_dump_data_t *sdd = arg;
progress_arg_t pa = { 0 };
pthread_t tid;
-
char *thissnap;
int err;
boolean_t isfromsnap, istosnap, fromorigin;
boolean_t exclude = B_FALSE;
+ err = 0;
thissnap = strchr(zhp->zfs_name, '@') + 1;
isfromsnap = (sdd->fromsnap != NULL &&
strcmp(sdd->fromsnap, thissnap) == 0);
if (!sdd->seenfrom && isfromsnap) {
- err = hold_for_send(zhp, sdd);
- if (err == 0) {
- sdd->seenfrom = B_TRUE;
- (void) strcpy(sdd->prevsnap, thissnap);
- sdd->prevsnap_obj = zfs_prop_get_int(zhp,
- ZFS_PROP_OBJSETID);
- } else if (err == ENOENT) {
- err = 0;
- }
+ gather_holds(zhp, sdd);
+ sdd->seenfrom = B_TRUE;
+ (void) strcpy(sdd->prevsnap, thissnap);
+ sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
zfs_close(zhp);
- return (err);
+ return (0);
}
if (sdd->seento || !sdd->seenfrom) {
@@ -1114,14 +1089,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
return (0);
}
- err = hold_for_send(zhp, sdd);
- if (err) {
- if (err == ENOENT)
- err = 0;
- zfs_close(zhp);
- return (err);
- }
-
+ gather_holds(zhp, sdd);
fromorigin = sdd->prevsnap[0] == '\0' &&
(sdd->fromorigin || sdd->replicate);
@@ -1389,7 +1357,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
avl_tree_t *fsavl = NULL;
static uint64_t holdseq;
int spa_version;
- pthread_t tid;
+ pthread_t tid = 0;
int pipefd[2];
dedup_arg_t dda = { 0 };
int featureflags = 0;
@@ -1462,11 +1430,8 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
*debugnvp = hdrnv;
else
nvlist_free(hdrnv);
- if (err) {
- fsavl_destroy(fsavl);
- nvlist_free(fss);
+ if (err)
goto stderr_out;
- }
}
if (!flags->dryrun) {
@@ -1490,8 +1455,6 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
}
free(packbuf);
if (err == -1) {
- fsavl_destroy(fsavl);
- nvlist_free(fss);
err = errno;
goto stderr_out;
}
@@ -1502,8 +1465,6 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
drr.drr_u.drr_end.drr_checksum = zc;
err = write(outfd, &drr, sizeof (drr));
if (err == -1) {
- fsavl_destroy(fsavl);
- nvlist_free(fss);
err = errno;
goto stderr_out;
}
@@ -1515,7 +1476,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
/* dump each stream */
sdd.fromsnap = fromsnap;
sdd.tosnap = tosnap;
- if (flags->dedup)
+ if (tid != 0)
sdd.outfd = pipefd[0];
else
sdd.outfd = outfd;
@@ -1552,34 +1513,69 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
err = errno;
goto stderr_out;
}
+ sdd.snapholds = fnvlist_alloc();
} else {
sdd.cleanup_fd = -1;
+ sdd.snapholds = NULL;
}
- if (flags->verbose) {
+ if (flags->verbose || sdd.snapholds != NULL) {
/*
* Do a verbose no-op dry run to get all the verbose output
- * before generating any data. Then do a non-verbose real
- * run to generate the streams.
+ * or to gather snapshot hold's before generating any data,
+ * then do a non-verbose real run to generate the streams.
*/
sdd.dryrun = B_TRUE;
err = dump_filesystems(zhp, &sdd);
- sdd.dryrun = flags->dryrun;
- sdd.verbose = B_FALSE;
- if (flags->parsable) {
- (void) fprintf(stderr, "size\t%llu\n",
- (longlong_t)sdd.size);
- } else {
- char buf[16];
- zfs_nicenum(sdd.size, buf, sizeof (buf));
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "total estimated size is %s\n"), buf);
+
+ if (err != 0)
+ goto stderr_out;
+
+ if (flags->verbose) {
+ if (flags->parsable) {
+ (void) fprintf(stderr, "size\t%llu\n",
+ (longlong_t)sdd.size);
+ } else {
+ char buf[16];
+ zfs_nicenum(sdd.size, buf, sizeof (buf));
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "total estimated size is %s\n"), buf);
+ }
+ }
+
+ /* Ensure no snaps found is treated as an error. */
+ if (!sdd.seento) {
+ err = ENOENT;
+ goto err_out;
}
+
+ /* Skip the second run if dryrun was requested. */
+ if (flags->dryrun)
+ goto err_out;
+
+ if (sdd.snapholds != NULL) {
+ err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
+ if (err != 0)
+ goto stderr_out;
+
+ fnvlist_free(sdd.snapholds);
+ sdd.snapholds = NULL;
+ }
+
+ sdd.dryrun = B_FALSE;
+ sdd.verbose = B_FALSE;
}
+
err = dump_filesystems(zhp, &sdd);
fsavl_destroy(fsavl);
nvlist_free(fss);
- if (flags->dedup) {
+ /* Ensure no snaps found is treated as an error. */
+ if (err == 0 && !sdd.seento)
+ err = ENOENT;
+
+ if (tid != 0) {
+ if (err != 0)
+ (void) pthread_cancel(tid);
(void) close(pipefd[0]);
(void) pthread_join(tid, NULL);
}
@@ -1609,12 +1605,16 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
stderr_out:
err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
err_out:
+ fsavl_destroy(fsavl);
+ nvlist_free(fss);
+ fnvlist_free(sdd.snapholds);
+
if (sdd.cleanup_fd != -1)
VERIFY(0 == close(sdd.cleanup_fd));
- if (flags->dedup) {
+ if (tid != 0) {
(void) pthread_cancel(tid);
- (void) pthread_join(tid, NULL);
(void) close(pipefd[0]);
+ (void) pthread_join(tid, NULL);
}
return (err);
}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c
index 6af5f77d24df..906883ca60d1 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
/*
@@ -72,57 +73,66 @@ static char *zfs_msgid_table[] = {
/* ARGSUSED */
static int
-vdev_missing(uint64_t state, uint64_t aux, uint64_t errs)
+vdev_missing(vdev_stat_t *vs, uint_t vsc)
{
- return (state == VDEV_STATE_CANT_OPEN &&
- aux == VDEV_AUX_OPEN_FAILED);
+ return (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ vs->vs_aux == VDEV_AUX_OPEN_FAILED);
}
/* ARGSUSED */
static int
-vdev_faulted(uint64_t state, uint64_t aux, uint64_t errs)
+vdev_faulted(vdev_stat_t *vs, uint_t vsc)
{
- return (state == VDEV_STATE_FAULTED);
+ return (vs->vs_state == VDEV_STATE_FAULTED);
}
/* ARGSUSED */
static int
-vdev_errors(uint64_t state, uint64_t aux, uint64_t errs)
+vdev_errors(vdev_stat_t *vs, uint_t vsc)
{
- return (state == VDEV_STATE_DEGRADED || errs != 0);
+ return (vs->vs_state == VDEV_STATE_DEGRADED ||
+ vs->vs_read_errors != 0 || vs->vs_write_errors != 0 ||
+ vs->vs_checksum_errors != 0);
}
/* ARGSUSED */
static int
-vdev_broken(uint64_t state, uint64_t aux, uint64_t errs)
+vdev_broken(vdev_stat_t *vs, uint_t vsc)
{
- return (state == VDEV_STATE_CANT_OPEN);
+ return (vs->vs_state == VDEV_STATE_CANT_OPEN);
}
/* ARGSUSED */
static int
-vdev_offlined(uint64_t state, uint64_t aux, uint64_t errs)
+vdev_offlined(vdev_stat_t *vs, uint_t vsc)
{
- return (state == VDEV_STATE_OFFLINE);
+ return (vs->vs_state == VDEV_STATE_OFFLINE);
}
/* ARGSUSED */
static int
-vdev_removed(uint64_t state, uint64_t aux, uint64_t errs)
+vdev_removed(vdev_stat_t *vs, uint_t vsc)
{
- return (state == VDEV_STATE_REMOVED);
+ return (vs->vs_state == VDEV_STATE_REMOVED);
+}
+
+static int
+vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)
+{
+ return (VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
+ vs->vs_configured_ashift < vs->vs_physical_ashift);
}
/*
* Detect if any leaf devices that have seen errors or could not be opened.
*/
static boolean_t
-find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
+find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
+ boolean_t ignore_replacing)
{
nvlist_t **child;
vdev_stat_t *vs;
- uint_t c, children;
- char *type;
+ uint_t c, vsc, children;
/*
* Ignore problems within a 'replacing' vdev, since we're presumably in
@@ -130,23 +140,25 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
* out again. We'll pick up the fact that a resilver is happening
* later.
*/
- verify(nvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE, &type) == 0);
- if (strcmp(type, VDEV_TYPE_REPLACING) == 0)
- return (B_FALSE);
+ if (ignore_replacing == B_TRUE) {
+ char *type;
+
+ verify(nvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE,
+ &type) == 0);
+ if (strcmp(type, VDEV_TYPE_REPLACING) == 0)
+ return (B_FALSE);
+ }
if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,
&children) == 0) {
for (c = 0; c < children; c++)
- if (find_vdev_problem(child[c], func))
+ if (find_vdev_problem(child[c], func, ignore_replacing))
return (B_TRUE);
} else {
verify(nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
- (uint64_t **)&vs, &c) == 0);
+ (uint64_t **)&vs, &vsc) == 0);
- if (func(vs->vs_state, vs->vs_aux,
- vs->vs_read_errors +
- vs->vs_write_errors +
- vs->vs_checksum_errors))
+ if (func(vs, vsc) != 0)
return (B_TRUE);
}
@@ -156,7 +168,7 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,
&children) == 0) {
for (c = 0; c < children; c++)
- if (find_vdev_problem(child[c], func))
+ if (find_vdev_problem(child[c], func, ignore_replacing))
return (B_TRUE);
}
@@ -269,15 +281,15 @@ check_status(nvlist_t *config, boolean_t isimport)
* Bad devices in non-replicated config.
*/
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_faulted))
+ find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
return (ZPOOL_STATUS_FAULTED_DEV_NR);
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_missing))
+ find_vdev_problem(nvroot, vdev_missing, B_TRUE))
return (ZPOOL_STATUS_MISSING_DEV_NR);
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_broken))
+ find_vdev_problem(nvroot, vdev_broken, B_TRUE))
return (ZPOOL_STATUS_CORRUPT_LABEL_NR);
/*
@@ -299,32 +311,38 @@ check_status(nvlist_t *config, boolean_t isimport)
/*
* Missing devices in a replicated config.
*/
- if (find_vdev_problem(nvroot, vdev_faulted))
+ if (find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
return (ZPOOL_STATUS_FAULTED_DEV_R);
- if (find_vdev_problem(nvroot, vdev_missing))
+ if (find_vdev_problem(nvroot, vdev_missing, B_TRUE))
return (ZPOOL_STATUS_MISSING_DEV_R);
- if (find_vdev_problem(nvroot, vdev_broken))
+ if (find_vdev_problem(nvroot, vdev_broken, B_TRUE))
return (ZPOOL_STATUS_CORRUPT_LABEL_R);
/*
* Devices with errors
*/
- if (!isimport && find_vdev_problem(nvroot, vdev_errors))
+ if (!isimport && find_vdev_problem(nvroot, vdev_errors, B_TRUE))
return (ZPOOL_STATUS_FAILING_DEV);
/*
* Offlined devices
*/
- if (find_vdev_problem(nvroot, vdev_offlined))
+ if (find_vdev_problem(nvroot, vdev_offlined, B_TRUE))
return (ZPOOL_STATUS_OFFLINE_DEV);
/*
* Removed device
*/
- if (find_vdev_problem(nvroot, vdev_removed))
+ if (find_vdev_problem(nvroot, vdev_removed, B_TRUE))
return (ZPOOL_STATUS_REMOVED_DEV);
/*
+ * Suboptimal, but usable, ashift configuration.
+ */
+ if (find_vdev_problem(nvroot, vdev_non_native_ashift, B_FALSE))
+ return (ZPOOL_STATUS_NON_NATIVE_ASHIFT);
+
+ /*
* Outdated, but usable, version
*/
if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION)
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
index ab23aa1ad2ec..6f4b46cf2815 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
@@ -20,7 +20,8 @@
*/
/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
/*
@@ -333,7 +334,6 @@ lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist)
nvlist_free(args);
return (error);
-
}
int
@@ -393,11 +393,17 @@ lzc_exists(const char *dataset)
* 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).
+ * Holds for snapshots which don't exist will be skipped and have an entry
+ * added to errlist, but will not cause an overall failure.
+ *
+ * The return value will be 0 if all holds, for snapshots that existed,
+ * were succesfully created.
+ *
+ * Otherwise the return value will be the errno of a (unspecified) hold that
+ * failed and no holds will be created.
+ *
+ * In all cases the errlist will have an entry for each hold that failed
+ * (name = snapshot), with its value being the error code (int32).
*/
int
lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist)
@@ -434,11 +440,17 @@ lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist)
* 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.
+ * Holds which failed to release because they didn't exist will have an entry
+ * added to errlist, but will not cause an overall failure.
+ *
+ * The return value will be 0 if the nvl holds was empty or all holds that
+ * existed, were successfully removed.
+ *
+ * Otherwise the return value will be the errno of a (unspecified) hold that
+ * failed to release and no holds will be released.
+ *
+ * In all cases the errlist will have an entry for each hold that failed to
+ * to release.
*/
int
lzc_release(nvlist_t *holds, nvlist_t **errlist)
@@ -616,3 +628,27 @@ out:
free((void*)(uintptr_t)zc.zc_nvlist_dst);
return (error);
}
+
+/*
+ * Roll back this filesystem or volume to its most recent snapshot.
+ * If snapnamebuf is not NULL, it will be filled in with the name
+ * of the most recent snapshot.
+ *
+ * Return 0 on success or an errno on failure.
+ */
+int
+lzc_rollback(const char *fsname, char *snapnamebuf, int snapnamelen)
+{
+ nvlist_t *args;
+ nvlist_t *result;
+ int err;
+
+ args = fnvlist_alloc();
+ err = lzc_ioctl(ZFS_IOC_ROLLBACK, fsname, args, &result);
+ nvlist_free(args);
+ if (err == 0 && snapnamebuf != NULL) {
+ const char *snapname = fnvlist_lookup_string(result, "target");
+ (void) strlcpy(snapnamebuf, snapname, snapnamelen);
+ }
+ return (err);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
index b10098b378c6..c55caf44f0fa 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -59,6 +59,7 @@ int lzc_send_space(const char *snapname, const char *fromsnap,
boolean_t lzc_exists(const char *dataset);
+int lzc_rollback(const char *fsname, char *snapnamebuf, int snapnamelen);
#ifdef __cplusplus
}
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
index c5c7b66142a0..71c3dceaa0f1 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
@@ -591,6 +591,12 @@ dprintf_setup(int *argc, char **argv)
dprintf_print_all = 1;
}
+int
+sysctl_handle_64(SYSCTL_HANDLER_ARGS)
+{
+ return (0);
+}
+
/*
* =========================================================================
* debug printfs
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 21075055a1d8..da153c7c1668 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
@@ -659,11 +659,55 @@ typedef uint32_t idmap_rid_t;
#define SX_SYSINIT(name, lock, desc)
+#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, \
+ intptr_t arg2, struct sysctl_req *req
+
+/*
+ * This describes the access space for a sysctl request. This is needed
+ * so that we can use the interface from the kernel or from user-space.
+ */
+struct sysctl_req {
+ struct thread *td; /* used for access checking */
+ int lock; /* wiring state */
+ void *oldptr;
+ size_t oldlen;
+ size_t oldidx;
+ int (*oldfunc)(struct sysctl_req *, const void *, size_t);
+ void *newptr;
+ size_t newlen;
+ size_t newidx;
+ int (*newfunc)(struct sysctl_req *, void *, size_t);
+ size_t validlen;
+ int flags;
+};
+
+SLIST_HEAD(sysctl_oid_list, sysctl_oid);
+
+/*
+ * This describes one "oid" in the MIB tree. Potentially more nodes can
+ * be hidden behind it, expanded by the handler.
+ */
+struct sysctl_oid {
+ struct sysctl_oid_list *oid_parent;
+ SLIST_ENTRY(sysctl_oid) oid_link;
+ int oid_number;
+ u_int oid_kind;
+ void *oid_arg1;
+ intptr_t oid_arg2;
+ const char *oid_name;
+ int (*oid_handler)(SYSCTL_HANDLER_ARGS);
+ const char *oid_fmt;
+ int oid_refcnt;
+ u_int oid_running;
+ const char *oid_descr;
+};
+
#define SYSCTL_DECL(...)
#define SYSCTL_NODE(...)
#define SYSCTL_INT(...)
#define SYSCTL_UINT(...)
#define SYSCTL_ULONG(...)
+#define SYSCTL_PROC(...)
#define SYSCTL_QUAD(...)
#define SYSCTL_UQUAD(...)
#ifdef TUNABLE_INT
@@ -675,6 +719,8 @@ typedef uint32_t idmap_rid_t;
#define TUNABLE_ULONG(...)
#define TUNABLE_QUAD(...)
+int sysctl_handle_64(SYSCTL_HANDLER_ARGS);
+
/* Errors */
#ifndef ERESTART
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
index 55dd39e3a900..82ec5fafda4a 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
@@ -47,11 +47,13 @@
*
* The value is only valid during a call to ctf_load.
*/
-char *curfile;
+static char *curfile;
#define CTF_BUF_CHUNK_SIZE (64 * 1024)
#define RES_BUF_CHUNK_SIZE (64 * 1024)
+static int ntypes = 0; /* The number of types. */
+
struct ctf_buf {
strtab_t ctb_strtab; /* string table */
caddr_t ctb_base; /* pointer to base of buffer */
@@ -1143,6 +1145,10 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
(*mpp)->ml_type = tdarr[ctm->ctm_type];
(*mpp)->ml_offset = ctm->ctm_offset;
(*mpp)->ml_size = 0;
+ if (ctm->ctm_type > ntypes) {
+ parseterminate("Invalid member type ctm_type=%d",
+ ctm->ctm_type);
+ }
}
} else {
for (i = 0, mpp = &tdp->t_members; i < vlen;
@@ -1159,6 +1165,10 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
(*mpp)->ml_offset =
(int)CTF_LMEM_OFFSET(ctlm);
(*mpp)->ml_size = 0;
+ if (ctlm->ctlm_type > ntypes) {
+ parseterminate("Invalid lmember type ctlm_type=%d",
+ ctlm->ctlm_type);
+ }
}
}
@@ -1272,9 +1282,10 @@ ctf_parse(ctf_header_t *h, caddr_t buf, symit_data_t *si, char *label)
{
tdata_t *td = tdata_new();
tdesc_t **tdarr;
- int ntypes = count_types(h, buf);
int idx, i;
+ ntypes = count_types(h, buf);
+
/* shudder */
tdarr = xcalloc(sizeof (tdesc_t *) * (ntypes + 1));
tdarr[0] = NULL;
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
index 93a540d22c60..9b2ee3d7565c 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
@@ -159,7 +159,7 @@ typedef struct ardef {
/* Auxiliary structure for structure/union tdesc_t */
typedef struct mlist {
int ml_offset; /* Offset from start of structure (in bits) */
- int ml_size; /* Member size (in bits) */
+ uint_t ml_size; /* Member size (in bits) */
char *ml_name; /* Member name */
struct tdesc *ml_type; /* Member type */
struct mlist *ml_next; /* Next member */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
index 19aeff2c7942..0738dd080f83 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* DWARF to tdata conversion
*
@@ -674,6 +672,13 @@ die_array_create(dwarf_t *dw, Dwarf_Die arr, Dwarf_Off off, tdesc_t *tdp)
tdesc_t *dimtdp;
int flags;
+ /* Check for bogus gcc DW_AT_byte_size attribute */
+ if (uval == (unsigned)-1) {
+ printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n",
+ __func__);
+ uval = 0;
+ }
+
tdp->t_size = uval;
/*
@@ -760,6 +765,12 @@ die_enum_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
tdp->t_type = ENUM;
(void) die_unsigned(dw, die, DW_AT_byte_size, &uval, DW_ATTR_REQ);
+ /* Check for bogus gcc DW_AT_byte_size attribute */
+ if (uval == (unsigned)-1) {
+ printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n",
+ __func__);
+ uval = 0;
+ }
tdp->t_size = uval;
if ((mem = die_child(dw, die)) != NULL) {
@@ -873,7 +884,7 @@ static void
die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
int type, const char *typename)
{
- Dwarf_Unsigned sz, bitsz, bitoff;
+ Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0;
Dwarf_Die mem;
mlist_t *ml, **mlastp;
iidesc_t *ii;
@@ -929,6 +940,8 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
ml->ml_name = NULL;
ml->ml_type = die_lookup_pass1(dw, mem, DW_AT_type);
+ debug(3, "die_sou_create(): ml_type = %p t_id = %d\n",
+ ml->ml_type, ml->ml_type->t_id);
if (die_mem_offset(dw, mem, DW_AT_data_member_location,
&mloff, 0)) {
@@ -956,8 +969,24 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
*mlastp = ml;
mlastp = &ml->ml_next;
+
+ /* Find the size of the largest member to work around a gcc
+ * bug. See GCC Bugzilla 35998.
+ */
+ if (maxsz < ml->ml_size)
+ maxsz = ml->ml_size;
+
} while ((mem = die_sibling(dw, mem)) != NULL);
+ /* See if we got a bogus DW_AT_byte_size. GCC will sometimes
+ * emit this.
+ */
+ if (sz == (unsigned)-1) {
+ printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n",
+ __func__);
+ tdp->t_size = maxsz / 8; /* maxsz is in bits, t_size is bytes */
+ }
+
/*
* GCC will attempt to eliminate unused types, thus decreasing the
* size of the emitted dwarf. That is, if you declare a foo_t in your
@@ -1054,7 +1083,7 @@ die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
}
if (ml->ml_size != 0 && mt->t_type == INTRINSIC &&
- mt->t_intr->intr_nbits != ml->ml_size) {
+ mt->t_intr->intr_nbits != (int)ml->ml_size) {
/*
* This member is a bitfield, and needs to reference
* an intrinsic type with the same width. If the
@@ -1370,6 +1399,13 @@ die_base_create(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, tdesc_t *tdp)
*/
(void) die_unsigned(dw, base, DW_AT_byte_size, &sz, DW_ATTR_REQ);
+ /* Check for bogus gcc DW_AT_byte_size attribute */
+ if (sz == (unsigned)-1) {
+ printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n",
+ __func__);
+ sz = 0;
+ }
+
if (tdp->t_name == NULL)
terminate("die %llu: base type without name\n", off);
@@ -1758,6 +1794,59 @@ die_resolve(dwarf_t *dw)
} while (dw->dw_nunres != 0);
}
+/*
+ * Any object containing a function or object symbol at any scope should also
+ * contain DWARF data.
+ */
+static boolean_t
+should_have_dwarf(Elf *elf)
+{
+ Elf_Scn *scn = NULL;
+ Elf_Data *data = NULL;
+ GElf_Shdr shdr;
+ GElf_Sym sym;
+ uint32_t symdx = 0;
+ size_t nsyms = 0;
+ boolean_t found = B_FALSE;
+
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ gelf_getshdr(scn, &shdr);
+
+ if (shdr.sh_type == SHT_SYMTAB) {
+ found = B_TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ terminate("cannot convert stripped objects\n");
+
+ data = elf_getdata(scn, NULL);
+ nsyms = shdr.sh_size / shdr.sh_entsize;
+
+ for (symdx = 0; symdx < nsyms; symdx++) {
+ gelf_getsym(data, symdx, &sym);
+
+ if ((GELF_ST_TYPE(sym.st_info) == STT_FUNC) ||
+ (GELF_ST_TYPE(sym.st_info) == STT_TLS) ||
+ (GELF_ST_TYPE(sym.st_info) == STT_OBJECT)) {
+ char *name;
+
+ name = elf_strptr(elf, shdr.sh_link, sym.st_name);
+
+ /* Studio emits these local symbols regardless */
+ if ((strcmp(name, "Bbss.bss") != 0) &&
+ (strcmp(name, "Ttbss.bss") != 0) &&
+ (strcmp(name, "Ddata.data") != 0) &&
+ (strcmp(name, "Ttdata.data") != 0) &&
+ (strcmp(name, "Drodata.rodata") != 0))
+ return (B_TRUE);
+ }
+ }
+
+ return (B_FALSE);
+}
+
/*ARGSUSED*/
int
dw_read(tdata_t *td, Elf *elf, char *filename __unused)
@@ -1782,8 +1871,12 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw,
&dw.dw_err)) == DW_DLV_NO_ENTRY) {
- errno = ENOENT;
- return (-1);
+ if (should_have_dwarf(elf)) {
+ errno = ENOENT;
+ return (-1);
+ } else {
+ return (0);
+ }
} else if (rc != DW_DLV_OK) {
if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
/*
@@ -1801,9 +1894,14 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err));
- if ((cu = die_sibling(&dw, NULL)) == NULL)
+ if ((cu = die_sibling(&dw, NULL)) == NULL ||
+ (((child = die_child(&dw, cu)) == NULL) &&
+ should_have_dwarf(elf))) {
terminate("file does not contain dwarf type data "
"(try compiling with -g)\n");
+ } else if (child == NULL) {
+ return (0);
+ }
dw.dw_maxoff = nxthdr - 1;
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c b/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c
index 1dca82a0d3b2..e136c94ab9b0 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c
@@ -54,7 +54,7 @@ static int faketypenumber = 100000000;
static tdesc_t *hash_table[BUCKETS];
static tdesc_t *name_table[BUCKETS];
-list_t *typedbitfldmems;
+static list_t *typedbitfldmems;
static void reset(void);
static jmp_buf resetbuf;
@@ -952,7 +952,7 @@ soudef(char *cp, stabtype_t type, tdesc_t **rtdp)
itdp = find_intrinsic(tdp);
if (itdp->t_type == INTRINSIC) {
- if (mlp->ml_size != itdp->t_intr->intr_nbits) {
+ if ((int)mlp->ml_size != itdp->t_intr->intr_nbits) {
parse_debug(4, cp, "making %d bit intrinsic "
"from %s", mlp->ml_size, tdesc_name(itdp));
mlp->ml_type = bitintrinsic(itdp, mlp->ml_size);
@@ -1173,7 +1173,7 @@ resolve_typed_bitfields_cb(void *arg, void *private __unused)
while (tdp) {
switch (tdp->t_type) {
case INTRINSIC:
- if (ml->ml_size != tdp->t_intr->intr_nbits) {
+ if ((int)ml->ml_size != tdp->t_intr->intr_nbits) {
debug(3, "making %d bit intrinsic from %s",
ml->ml_size, tdesc_name(tdp));
ml->ml_type = bitintrinsic(tdp, ml->ml_size);
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c b/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
index feb9908638af..2d6d74bc78b1 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
@@ -37,8 +37,8 @@
#include "traverse.h"
#include "memory.h"
-int (*tddescenders[])(tdesc_t *, tdtrav_data_t *);
-tdtrav_cb_f tdnops[];
+static int (*tddescenders[])(tdesc_t *, tdtrav_data_t *);
+static tdtrav_cb_f tdnops[];
void
tdtrav_init(tdtrav_data_t *tdtd, int *vgenp, tdtrav_cb_f *firstops,
@@ -111,7 +111,7 @@ tdtrav_assert(tdesc_t *node __unused, tdesc_t **nodep __unused, void *private __
return (-1);
}
-tdtrav_cb_f tdnops[] = {
+static tdtrav_cb_f tdnops[] = {
NULL,
NULL, /* intrinsic */
NULL, /* pointer */
@@ -128,7 +128,7 @@ tdtrav_cb_f tdnops[] = {
NULL /* restrict */
};
-int (*tddescenders[])(tdesc_t *, tdtrav_data_t *) = {
+static int (*tddescenders[])(tdesc_t *, tdtrav_data_t *) = {
NULL,
NULL, /* intrinsic */
tdtrav_plain, /* pointer */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/util.c b/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
index 0f36fa02decf..82dfe63ad579 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
@@ -249,8 +249,8 @@ tdesc_name(tdesc_t *tdp)
return (tdp->t_name == NULL ? "(anon)" : tdp->t_name);
}
-char *watch_address = NULL;
-int watch_length = 0;
+static char *watch_address = NULL;
+static int watch_length = 0;
void
watch_set(void *addr, int len)
diff --git a/cddl/lib/drti/Makefile b/cddl/lib/drti/Makefile
index 6e3d3a61a41d..c715809708f5 100644
--- a/cddl/lib/drti/Makefile
+++ b/cddl/lib/drti/Makefile
@@ -9,6 +9,8 @@ FILESGRP= ${LIBGRP}
FILESMODE= ${LIBMODE}
FILESDIR= ${LIBDIR}/dtrace
CLEANFILES= ${FILES}
+LIB= drti-dummy
+INTERNALLIB=
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/compat/opensolaris/include \
@@ -18,4 +20,10 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${OPENSOLARIS_SYS_DISTDIR}/uts/common \
-DPIC ${PICFLAG}
+.if make(install) && defined(LIBRARIES_ONLY)
+install:
+ ${INSTALL} -o ${FILESOWN} -g ${FILESGRP} -m ${FILESMODE} \
+ ${FILES} ${DESTDIR}${FILESDIR}
+.endif
+
.include <bsd.lib.mk>
diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile
index 4fd7faefc3d8..46f7046d874f 100644
--- a/cddl/lib/libdtrace/Makefile
+++ b/cddl/lib/libdtrace/Makefile
@@ -48,8 +48,11 @@ SRCS= dt_aggregate.c \
DSRCS= errno.d \
io.d \
+ ip.d \
psinfo.d \
signal.d \
+ tcp.d \
+ udp.d \
unistd.d
WARNS?= 1
diff --git a/cddl/lib/libdtrace/ip.d b/cddl/lib/libdtrace/ip.d
new file mode 100644
index 000000000000..b886a0ad2543
--- /dev/null
+++ b/cddl/lib/libdtrace/ip.d
@@ -0,0 +1,285 @@
+/*
+ * 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
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 Mark Johnston <markj@freebsd.org>
+ */
+
+#pragma D depends_on provider ip
+
+/*
+ * pktinfo is where packet ID info can be made available for deeper
+ * analysis if packet IDs become supported by the kernel in the future.
+ * The pkt_addr member is currently always NULL.
+ */
+typedef struct pktinfo {
+ uintptr_t pkt_addr;
+} pktinfo_t;
+
+/*
+ * csinfo is where connection state info is made available.
+ */
+typedef uint32_t zoneid_t;
+typedef struct csinfo {
+ uintptr_t cs_addr;
+ uint64_t cs_cid;
+ pid_t cs_pid;
+ zoneid_t cs_zoneid;
+} csinfo_t;
+
+/*
+ * ipinfo contains common IP info for both IPv4 and IPv6.
+ */
+typedef struct ipinfo {
+ uint8_t ip_ver; /* IP version (4, 6) */
+ uint32_t ip_plength; /* payload length */
+ string ip_saddr; /* source address */
+ string ip_daddr; /* destination address */
+} ipinfo_t;
+
+/*
+ * ifinfo contains network interface info.
+ */
+typedef struct ifinfo {
+ string if_name; /* interface name */
+ int8_t if_local; /* is delivered locally */
+ /*netstackid_t if_ipstack;*/ /* ipstack ID */
+ uintptr_t if_addr; /* pointer to raw ill_t */
+} ifinfo_t;
+
+typedef uint32_t ipaddr_t;
+typedef struct {
+ uint8_t ipha_version_and_hdr_length;
+ uint8_t ipha_type_of_service;
+ uint16_t ipha_length;
+ uint16_t ipha_ident;
+ uint16_t ipha_fragment_offset_and_flags;
+ uint8_t ipha_ttl;
+ uint8_t ipha_protocol;
+ uint16_t ipha_hdr_checksum;
+ ipaddr_t ipha_src;
+ ipaddr_t ipha_dst;
+} ipha_t;
+
+/*
+ * ipv4info is a translated version of the IPv4 header (with raw pointer).
+ * These values are NULL if the packet is not IPv4.
+ */
+typedef struct ipv4info {
+ uint8_t ipv4_ver; /* IP version (4) */
+ uint8_t ipv4_ihl; /* header length, bytes */
+ uint8_t ipv4_tos; /* type of service field */
+ uint16_t ipv4_length; /* length (header + payload) */
+ uint16_t ipv4_ident; /* identification */
+ uint8_t ipv4_flags; /* IP flags */
+ uint16_t ipv4_offset; /* fragment offset */
+ uint8_t ipv4_ttl; /* time to live */
+ uint8_t ipv4_protocol; /* next level protocol */
+ string ipv4_protostr; /* next level protocol, as a string */
+ uint16_t ipv4_checksum; /* header checksum */
+ ipaddr_t ipv4_src; /* source address */
+ ipaddr_t ipv4_dst; /* destination address */
+ string ipv4_saddr; /* source address, string */
+ string ipv4_daddr; /* destination address, string */
+ ipha_t *ipv4_hdr; /* pointer to raw header */
+} ipv4info_t;
+
+/*
+ * ipv6info is a translated version of the IPv6 header (with raw pointer).
+ * These values are NULL if the packet is not IPv6.
+ */
+typedef struct in6_addr in6_addr_t;
+typedef struct ip6_hdr ip6_t;
+typedef struct ipv6info {
+ uint8_t ipv6_ver; /* IP version (6) */
+ uint8_t ipv6_tclass; /* traffic class */
+ uint32_t ipv6_flow; /* flow label */
+ uint16_t ipv6_plen; /* payload length */
+ uint8_t ipv6_nexthdr; /* next header protocol */
+ string ipv6_nextstr; /* next header protocol, as a string */
+ uint8_t ipv6_hlim; /* hop limit */
+ in6_addr_t *ipv6_src; /* source address */
+ in6_addr_t *ipv6_dst; /* destination address */
+ string ipv6_saddr; /* source address, string */
+ string ipv6_daddr; /* destination address, string */
+ ip6_t *ipv6_hdr; /* pointer to raw header */
+} ipv6info_t;
+
+#pragma D binding "1.0" IPPROTO_IP
+inline short IPPROTO_IP = 0;
+#pragma D binding "1.0" IPPROTO_ICMP
+inline short IPPROTO_ICMP = 1;
+#pragma D binding "1.0" IPPROTO_IGMP
+inline short IPPROTO_IGMP = 2;
+#pragma D binding "1.0" IPPROTO_IPV4
+inline short IPPROTO_IPV4 = 4;
+#pragma D binding "1.0" IPPROTO_TCP
+inline short IPPROTO_TCP = 6;
+#pragma D binding "1.0" IPPROTO_UDP
+inline short IPPROTO_UDP = 17;
+#pragma D binding "1.0" IPPROTO_IPV6
+inline short IPPROTO_IPV6 = 41;
+#pragma D binding "1.0" IPPROTO_ROUTING
+inline short IPPROTO_ROUTING = 43;
+#pragma D binding "1.0" IPPROTO_FRAGMENT
+inline short IPPROTO_FRAGMENT = 44;
+#pragma D binding "1.0" IPPROTO_RSVP
+inline short IPPROTO_RSVP = 46;
+#pragma D binding "1.0" IPPROTO_GRE
+inline short IPPROTO_GRE = 47;
+#pragma D binding "1.0" IPPROTO_ESP
+inline short IPPROTO_ESP = 50;
+#pragma D binding "1.0" IPPROTO_AH
+inline short IPPROTO_AH = 51;
+#pragma D binding "1.0" IPPROTO_MOBILE
+inline short IPPROTO_MOBILE = 55;
+#pragma D binding "1.0" IPPROTO_ICMPV6
+inline short IPPROTO_ICMPV6 = 58;
+#pragma D binding "1.0" IPPROTO_DSTOPTS
+inline short IPPROTO_DSTOPTS = 60;
+#pragma D binding "1.0" IPPROTO_ETHERIP
+inline short IPPROTO_ETHERIP = 97;
+#pragma D binding "1.0" IPPROTO_PIM
+inline short IPPROTO_PIM = 103;
+#pragma D binding "1.0" IPPROTO_IPCOMP
+inline short IPPROTO_IPCOMP = 108;
+#pragma D binding "1.0" IPPROTO_SCTP
+inline short IPPROTO_SCTP = 132;
+#pragma D binding "1.0" IPPROTO_RAW
+inline short IPPROTO_RAW = 255;
+
+inline uint8_t INP_IPV4 = 0x01;
+inline uint8_t INP_IPV6 = 0x02;
+
+#pragma D binding "1.0" protocols
+inline string protocols[int proto] =
+ proto == IPPROTO_IP ? "IP" :
+ proto == IPPROTO_ICMP ? "ICMP" :
+ proto == IPPROTO_IGMP ? "IGMP" :
+ proto == IPPROTO_IPV4 ? "IPV4" :
+ proto == IPPROTO_TCP ? "TCP" :
+ proto == IPPROTO_UDP ? "UDP" :
+ proto == IPPROTO_IPV6 ? "IPV6" :
+ proto == IPPROTO_ROUTING ? "ROUTING" :
+ proto == IPPROTO_FRAGMENT ? "FRAGMENT" :
+ proto == IPPROTO_RSVP ? "RSVP" :
+ proto == IPPROTO_GRE ? "GRE" :
+ proto == IPPROTO_ESP ? "ESP" :
+ proto == IPPROTO_AH ? "AH" :
+ proto == IPPROTO_MOBILE ? "MOBILE" :
+ proto == IPPROTO_ICMPV6 ? "ICMPV6" :
+ proto == IPPROTO_DSTOPTS ? "DSTOPTS" :
+ proto == IPPROTO_ETHERIP ? "ETHERIP" :
+ proto == IPPROTO_PIM ? "PIM" :
+ proto == IPPROTO_IPCOMP ? "IPCOMP" :
+ proto == IPPROTO_SCTP ? "SCTP" :
+ proto == IPPROTO_RAW ? "RAW" :
+ "<unknown>";
+
+/*
+ * This field is always NULL according to the current definition of the ip
+ * probes.
+ */
+#pragma D binding "1.0" translator
+translator pktinfo_t < void *p > {
+ pkt_addr = NULL;
+};
+
+#pragma D binding "1.0" translator
+translator csinfo_t < void *p > {
+ cs_addr = NULL;
+ cs_cid = (uint64_t)p;
+ cs_pid = 0;
+ cs_zoneid = 0;
+};
+
+#pragma D binding "1.0" translator
+translator csinfo_t < struct inpcb *p > {
+ cs_addr = NULL;
+ cs_cid = (uint64_t)p;
+ cs_pid = 0; /* XXX */
+ cs_zoneid = 0;
+};
+
+#pragma D binding "1.0" translator
+translator ipinfo_t < uint8_t *p > {
+ ip_ver = p == NULL ? 0 : ((struct ip *)p)->ip_v;
+ ip_plength = p == NULL ? 0 :
+ ((struct ip *)p)->ip_v == 4 ?
+ ntohs(((struct ip *)p)->ip_len) - (((struct ip *)p)->ip_hl << 2):
+ ntohs(((struct ip6_hdr *)p)->ip6_ctlun.ip6_un1.ip6_un1_plen);
+ ip_saddr = p == NULL ? 0 :
+ ((struct ip *)p)->ip_v == 4 ?
+ inet_ntoa(&((struct ip *)p)->ip_src.s_addr) :
+ inet_ntoa6(&((struct ip6_hdr *)p)->ip6_src);
+ ip_daddr = p == NULL ? 0 :
+ ((struct ip *)p)->ip_v == 4 ?
+ inet_ntoa(&((struct ip *)p)->ip_dst.s_addr) :
+ inet_ntoa6(&((struct ip6_hdr *)p)->ip6_dst);
+};
+
+#pragma D binding "1.0" IFF_LOOPBACK
+inline int IFF_LOOPBACK = 0x8;
+
+#pragma D binding "1.0" translator
+translator ifinfo_t < struct ifnet *p > {
+ if_name = p->if_xname;
+ if_local = (p->if_flags & IFF_LOOPBACK) == 0 ? 0 : 1;
+ if_addr = (uintptr_t)p;
+};
+
+#pragma D binding "1.0" translator
+translator ipv4info_t < struct ip *p > {
+ ipv4_ver = p == NULL ? 0 : p->ip_v;
+ ipv4_ihl = p == NULL ? 0 : p->ip_hl;
+ ipv4_tos = p == NULL ? 0 : p->ip_tos;
+ ipv4_length = p == NULL ? 0 : ntohs(p->ip_len);
+ ipv4_ident = p == NULL ? 0 : ntohs(p->ip_id);
+ ipv4_flags = p == NULL ? 0 : (p->ip_off & 0xe000);
+ ipv4_offset = p == NULL ? 0 : p->ip_off;
+ ipv4_ttl = p == NULL ? 0 : p->ip_ttl;
+ ipv4_protocol = p == NULL ? 0 : p->ip_p;
+ ipv4_protostr = p == NULL ? "<null>" : protocols[p->ip_p];
+ ipv4_checksum = p == NULL ? 0 : ntohs(p->ip_sum);
+ ipv4_src = p == NULL ? 0 : (ipaddr_t)ntohl(p->ip_src.s_addr);
+ ipv4_dst = p == NULL ? 0 : (ipaddr_t)ntohl(p->ip_dst.s_addr);
+ ipv4_saddr = p == NULL ? 0 : inet_ntoa(&p->ip_src.s_addr);
+ ipv4_daddr = p == NULL ? 0 : inet_ntoa(&p->ip_dst.s_addr);
+ ipv4_hdr = (ipha_t *)p;
+};
+
+#pragma D binding "1.0" translator
+translator ipv6info_t < struct ip6_hdr *p > {
+ ipv6_ver = p == NULL ? 0 : (ntohl(p->ip6_ctlun.ip6_un1.ip6_un1_flow) & 0xf0000000) >> 28;
+ ipv6_tclass = p == NULL ? 0 : (ntohl(p->ip6_ctlun.ip6_un1.ip6_un1_flow) & 0x0ff00000) >> 20;
+ ipv6_flow = p == NULL ? 0 : ntohl(p->ip6_ctlun.ip6_un1.ip6_un1_flow) & 0x000fffff;
+ ipv6_plen = p == NULL ? 0 : ntohs(p->ip6_ctlun.ip6_un1.ip6_un1_plen);
+ ipv6_nexthdr = p == NULL ? 0 : p->ip6_ctlun.ip6_un1.ip6_un1_nxt;
+ ipv6_nextstr = p == NULL ? "<null>" : protocols[p->ip6_ctlun.ip6_un1.ip6_un1_nxt];
+ ipv6_hlim = p == NULL ? 0 : p->ip6_ctlun.ip6_un1.ip6_un1_hlim;
+ ipv6_src = p == NULL ? 0 : (in6_addr_t *)&p->ip6_src;
+ ipv6_dst = p == NULL ? 0 : (in6_addr_t *)&p->ip6_dst;
+ ipv6_saddr = p == NULL ? 0 : inet_ntoa6(&p->ip6_src);
+ ipv6_daddr = p == NULL ? 0 : inet_ntoa6(&p->ip6_dst);
+ ipv6_hdr = (ip6_t *)p;
+};
diff --git a/cddl/lib/libdtrace/nfs.d b/cddl/lib/libdtrace/nfs.d
index 0f936c4afc2f..be342286f1b5 100644
--- a/cddl/lib/libdtrace/nfs.d
+++ b/cddl/lib/libdtrace/nfs.d
@@ -28,11 +28,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#pragma D depends_on library ip.d
#pragma D depends_on library net.d
-#pragma D depends_on module genunix
+#pragma D depends_on module nfs
typedef struct nfsv4opinfo {
uint64_t noi_xid; /* unique transation ID */
@@ -47,50 +45,62 @@ typedef struct nfsv4cbinfo {
#pragma D binding "1.5" translator
translator conninfo_t < struct svc_req *P > {
ci_protocol = P->rq_xprt->xp_master->xp_netid == "tcp" ? "ipv4" :
+ P->rq_xprt->xp_master->xp_netid == "udp" ? "ipv4" :
P->rq_xprt->xp_master->xp_netid == "tcp6" ? "ipv6" :
+ P->rq_xprt->xp_master->xp_netid == "udp6" ? "ipv6" :
"<unknown>";
- ci_local = inet_ntoa6(&((conn_t *)P->rq_xprt->xp_xpc.
- xpc_wq->q_next->q_ptr)->connua_v6addr.connua_laddr);
-
- ci_remote = inet_ntoa6(&((conn_t *)P->rq_xprt->xp_xpc.
- xpc_wq->q_next->q_ptr)->connua_v6addr.connua_faddr);
+ ci_local = (P->rq_xprt->xp_master->xp_netid == "tcp" ||
+ P->rq_xprt->xp_master->xp_netid == "udp") ?
+ inet_ntoa(&((struct sockaddr_in *)
+ P->rq_xprt->xp_xpc.xpc_lcladdr.buf)->sin_addr.S_un.S_addr) :
+ (P->rq_xprt->xp_master->xp_netid == "tcp6" ||
+ P->rq_xprt->xp_master->xp_netid == "udp6") ?
+ inet_ntoa6(&((struct sockaddr_in6 *)
+ P->rq_xprt->xp_xpc.xpc_lcladdr.buf)->sin6_addr) :
+ "unknown";
+
+ ci_remote = (P->rq_xprt->xp_master->xp_netid == "tcp" ||
+ P->rq_xprt->xp_master->xp_netid == "udp") ?
+ inet_ntoa(&((struct sockaddr_in *)
+ P->rq_xprt->xp_xpc.xpc_rtaddr.buf)->sin_addr.S_un.S_addr) :
+ (P->rq_xprt->xp_master->xp_netid == "tcp6" ||
+ P->rq_xprt->xp_master->xp_netid == "udp6") ?
+ inet_ntoa6(&((struct sockaddr_in6 *)
+ P->rq_xprt->xp_xpc.xpc_rtaddr.buf)->sin6_addr) :
+ "unknown";
};
#pragma D binding "1.5" translator
-translator conninfo_t < struct compound_state *P > {
- ci_protocol = P->req->rq_xprt->xp_master->xp_netid == "tcp" ? "ipv4" :
- P->req->rq_xprt->xp_master->xp_netid == "tcp6" ? "ipv6" :
- "<unknown>";
+translator conninfo_t < rfs4_client_t *P > {
+ ci_protocol = (P->rc_addr.ss_family == AF_INET) ? "ipv4" : "ipv6";
- ci_local = inet_ntoa6(&((conn_t *)P->req->rq_xprt->xp_xpc.
- xpc_wq->q_next->q_ptr)->connua_v6addr.connua_laddr);
+ ci_local = "<unknown>";
- ci_remote = inet_ntoa6(&((conn_t *)P->req->rq_xprt->xp_xpc.
- xpc_wq->q_next->q_ptr)->connua_v6addr.connua_faddr);
+ ci_remote = (P->rc_addr.ss_family == AF_INET) ?
+ inet_ntoa((ipaddr_t *)
+ &((struct sockaddr_in *)&P->rc_addr)->sin_addr) :
+ inet_ntoa6(&((struct sockaddr_in6 *)&P->rc_addr)->sin6_addr);
};
#pragma D binding "1.5" translator
-translator nfsv4opinfo_t < struct compound_state *P > {
- noi_xid = P->req->rq_xprt->xp_xid;
- noi_cred = P->basecr;
- noi_curpath = (P->vp == NULL) ? "<unknown>" : P->vp->v_path;
+translator nfsv4cbinfo_t < rfs4_deleg_state_t *P > {
+ nci_curpath = (P->rds_finfo->rf_vp == NULL) ? "<unknown>" :
+ P->rds_finfo->rf_vp->v_path;
};
-#pragma D binding "1.5" translator
-translator conninfo_t < rfs4_client_t *P > {
- ci_protocol = (P->cl_addr.ss_family == AF_INET) ? "ipv4" : "ipv6";
-
- ci_local = "<unknown>";
+typedef struct nfsv3opinfo {
+ uint64_t noi_xid; /* unique transation ID */
+ cred_t *noi_cred; /* credentials for operation */
+ string noi_curpath; /* current file handle path (if any) */
+} nfsv3opinfo_t;
- ci_remote = (P->cl_addr.ss_family == AF_INET) ?
- inet_ntoa((ipaddr_t *)
- &((struct sockaddr_in *)&P->cl_addr)->sin_addr) :
- inet_ntoa6(&((struct sockaddr_in6 *)&P->cl_addr)->sin6_addr);
-};
+typedef struct nfsv3oparg nfsv3oparg_t;
#pragma D binding "1.5" translator
-translator nfsv4cbinfo_t < rfs4_deleg_state_t *P > {
- nci_curpath = (P->finfo->vp == NULL) ? "<unknown>" :
- P->finfo->vp->v_path;
+translator nfsv3opinfo_t < nfsv3oparg_t *P > {
+ noi_xid = ((struct svc_req *)arg0)->rq_xprt->xp_xid;
+ noi_cred = (cred_t *)arg1;
+ noi_curpath = (arg2 == 0 || ((vnode_t *)arg2)->v_path == NULL) ?
+ "<unknown>" : ((vnode_t *)arg2)->v_path;
};
diff --git a/cddl/lib/libdtrace/nfssrv.d b/cddl/lib/libdtrace/nfssrv.d
new file mode 100644
index 000000000000..68ac08b58cde
--- /dev/null
+++ b/cddl/lib/libdtrace/nfssrv.d
@@ -0,0 +1,54 @@
+/*
+ * 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
+ *
+ * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma D depends_on library ip.d
+#pragma D depends_on library net.d
+#pragma D depends_on module nfs.d
+#pragma D depends_on module nfssrv
+
+#pragma D binding "1.5" translator
+translator conninfo_t < struct compound_state *P > {
+ ci_protocol = P->req->rq_xprt->xp_master->xp_netid == "tcp" ? "ipv4" :
+ P->req->rq_xprt->xp_master->xp_netid == "tcp6" ? "ipv6" :
+ "<unknown>";
+
+ ci_local = inet_ntoa6(&((conn_t *)P->req->rq_xprt->xp_xpc.
+ xpc_wq->q_next->q_ptr)->connua_v6addr.connua_laddr);
+
+ ci_remote = inet_ntoa6(&((conn_t *)P->req->rq_xprt->xp_xpc.
+ xpc_wq->q_next->q_ptr)->connua_v6addr.connua_faddr);
+};
+
+#pragma D binding "1.5" translator
+translator nfsv4opinfo_t < struct compound_state *P > {
+ noi_xid = P->req->rq_xprt->xp_xid;
+ noi_cred = P->basecr;
+ noi_curpath = (P->vp == NULL) ? "<unknown>" : P->vp->v_path;
+};
diff --git a/cddl/lib/libdtrace/tcp.d b/cddl/lib/libdtrace/tcp.d
new file mode 100644
index 000000000000..271266584d48
--- /dev/null
+++ b/cddl/lib/libdtrace/tcp.d
@@ -0,0 +1,203 @@
+/*
+ * 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
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 Mark Johnston <markj@freebsd.org>
+ */
+
+#pragma D depends_on library ip.d
+#pragma D depends_on provider tcp
+
+/*
+ * Convert a TCP state value to a string.
+ */
+#pragma D binding "1.0" TCPS_CLOSED
+inline int TCPS_CLOSED = 0;
+#pragma D binding "1.0" TCPS_LISTEN
+inline int TCPS_LISTEN = 1;
+#pragma D binding "1.0" TCPS_SYN_SENT
+inline int TCPS_SYN_SENT = 2;
+#pragma D binding "1.0" TCPS_SYN_RECEIVED
+inline int TCPS_SYN_RECEIVED = 3;
+#pragma D binding "1.0" TCPS_ESTABLISHED
+inline int TCPS_ESTABLISHED = 4;
+#pragma D binding "1.0" TCPS_CLOSE_WAIT
+inline int TCPS_CLOSE_WAIT = 5;
+#pragma D binding "1.0" TCPS_FIN_WAIT_1
+inline int TCPS_FIN_WAIT_1 = 6;
+#pragma D binding "1.0" TCPS_CLOSING
+inline int TCPS_CLOSING = 7;
+#pragma D binding "1.0" TCPS_LAST_ACK
+inline int TCPS_LAST_ACK = 8;
+#pragma D binding "1.0" TCPS_FIN_WAIT_2
+inline int TCPS_FIN_WAIT_2 = 9;
+#pragma D binding "1.0" TCPS_TIME_WAIT
+inline int TCPS_TIME_WAIT = 10;
+
+/* TCP segment flags. */
+#pragma D binding "1.0" TH_FIN
+inline uint8_t TH_FIN = 0x01;
+#pragma D binding "1.0" TH_SYN
+inline uint8_t TH_SYN = 0x02;
+#pragma D binding "1.0" TH_RST
+inline uint8_t TH_RST = 0x04;
+#pragma D binding "1.0" TH_PUSH
+inline uint8_t TH_PUSH = 0x08;
+#pragma D binding "1.0" TH_ACK
+inline uint8_t TH_ACK = 0x10;
+#pragma D binding "1.0" TH_URG
+inline uint8_t TH_URG = 0x20;
+#pragma D binding "1.0" TH_ECE
+inline uint8_t TH_ECE = 0x40;
+#pragma D binding "1.0" TH_CWR
+inline uint8_t TH_CWR = 0x80;
+
+/* TCP connection state strings. */
+#pragma D binding "1.0" tcp_state_string
+inline string tcp_state_string[int32_t state] =
+ state == TCPS_CLOSED ? "state-closed" :
+ state == TCPS_LISTEN ? "state-listen" :
+ state == TCPS_SYN_SENT ? "state-syn-sent" :
+ state == TCPS_SYN_RECEIVED ? "state-syn-received" :
+ state == TCPS_ESTABLISHED ? "state-established" :
+ state == TCPS_CLOSE_WAIT ? "state-close-wait" :
+ state == TCPS_FIN_WAIT_1 ? "state-fin-wait-1" :
+ state == TCPS_CLOSING ? "state-closing" :
+ state == TCPS_LAST_ACK ? "state-last-ack" :
+ state == TCPS_FIN_WAIT_2 ? "state-fin-wait-2" :
+ state == TCPS_TIME_WAIT ? "state-time-wait" :
+ "<unknown>";
+
+/*
+ * tcpsinfo contains stable TCP details from tcp_t.
+ */
+typedef struct tcpsinfo {
+ uintptr_t tcps_addr;
+ int tcps_local; /* is delivered locally, boolean */
+ int tcps_active; /* active open (from here), boolean */
+ uint16_t tcps_lport; /* local port */
+ uint16_t tcps_rport; /* remote port */
+ string tcps_laddr; /* local address, as a string */
+ string tcps_raddr; /* remote address, as a string */
+ int32_t tcps_state; /* TCP state */
+ uint32_t tcps_iss; /* Initial sequence # sent */
+ uint32_t tcps_suna; /* sequence # sent but unacked */
+ uint32_t tcps_snxt; /* next sequence # to send */
+ uint32_t tcps_rack; /* sequence # we have acked */
+ uint32_t tcps_rnxt; /* next sequence # expected */
+ uint32_t tcps_swnd; /* send window size */
+ int32_t tcps_snd_ws; /* send window scaling */
+ uint32_t tcps_rwnd; /* receive window size */
+ int32_t tcps_rcv_ws; /* receive window scaling */
+ uint32_t tcps_cwnd; /* congestion window */
+ uint32_t tcps_cwnd_ssthresh; /* threshold for congestion avoidance */
+ uint32_t tcps_sack_fack; /* SACK sequence # we have acked */
+ uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */
+ uint32_t tcps_rto; /* round-trip timeout, msec */
+ uint32_t tcps_mss; /* max segment size */
+ int tcps_retransmit; /* retransmit send event, boolean */
+} tcpsinfo_t;
+
+/*
+ * tcplsinfo provides the old tcp state for state changes.
+ */
+typedef struct tcplsinfo {
+ int32_t tcps_state; /* previous TCP state */
+} tcplsinfo_t;
+
+/*
+ * tcpinfo is the TCP header fields.
+ */
+typedef struct tcpinfo {
+ uint16_t tcp_sport; /* source port */
+ uint16_t tcp_dport; /* destination port */
+ uint32_t tcp_seq; /* sequence number */
+ uint32_t tcp_ack; /* acknowledgment number */
+ uint8_t tcp_offset; /* data offset, in bytes */
+ uint8_t tcp_flags; /* flags */
+ uint16_t tcp_window; /* window size */
+ uint16_t tcp_checksum; /* checksum */
+ uint16_t tcp_urgent; /* urgent data pointer */
+ struct tcphdr *tcp_hdr; /* raw TCP header */
+} tcpinfo_t;
+
+#pragma D binding "1.0" translator
+translator csinfo_t < struct tcpcb *p > {
+ cs_addr = NULL;
+ cs_cid = (uint64_t)p;
+ cs_pid = 0;
+ cs_zoneid = 0;
+};
+
+#pragma D binding "1.0" translator
+translator tcpsinfo_t < struct tcpcb *p > {
+ tcps_addr = (uintptr_t)p;
+ tcps_local = -1; /* XXX */
+ tcps_active = -1; /* XXX */
+ tcps_lport = p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_lport);
+ tcps_rport = p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_fport);
+ tcps_laddr = p == NULL ? 0 :
+ p->t_inpcb->inp_vflag == INP_IPV4 ?
+ inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie46_local.ia46_addr4.s_addr) :
+ inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie6_local);
+ tcps_raddr = p == NULL ? 0 :
+ p->t_inpcb->inp_vflag == INP_IPV4 ?
+ inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie46_foreign.ia46_addr4.s_addr) :
+ inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie6_foreign);
+ tcps_state = p == NULL ? -1 : p->t_state;
+ tcps_iss = p == NULL ? 0 : p->iss;
+ tcps_suna = p == NULL ? 0 : p->snd_una;
+ tcps_snxt = p == NULL ? 0 : p->snd_nxt;
+ tcps_rack = p == NULL ? 0 : p->last_ack_sent;
+ tcps_rnxt = p == NULL ? 0 : p->rcv_nxt;
+ tcps_swnd = p == NULL ? -1 : p->snd_wnd;
+ tcps_snd_ws = p == NULL ? -1 : p->snd_scale;
+ tcps_rwnd = p == NULL ? -1 : p->rcv_wnd;
+ tcps_rcv_ws = p == NULL ? -1 : p->rcv_scale;
+ tcps_cwnd = p == NULL ? -1 : p->snd_cwnd;
+ tcps_cwnd_ssthresh = p == NULL ? -1 : p->snd_ssthresh;
+ tcps_sack_fack = p == NULL ? 0 : p->snd_fack;
+ tcps_sack_snxt = p == NULL ? 0 : p->sack_newdata;
+ tcps_rto = p == NULL ? -1 : p->t_rxtcur / 1000; /* XXX */
+ tcps_mss = p == NULL ? -1 : p->t_maxseg;
+ tcps_retransmit = -1; /* XXX */
+};
+
+#pragma D binding "1.0" translator
+translator tcpinfo_t < struct tcphdr *p > {
+ tcp_sport = p == NULL ? 0 : ntohs(p->th_sport);
+ tcp_dport = p == NULL ? 0 : ntohs(p->th_dport);
+ tcp_seq = p == NULL ? -1 : ntohl(p->th_seq);
+ tcp_ack = p == NULL ? -1 : ntohl(p->th_ack);
+ tcp_offset = p == NULL ? -1 : (p->th_off >> 2);
+ tcp_flags = p == NULL ? 0 : p->th_flags;
+ tcp_window = p == NULL ? 0 : ntohs(p->th_win);
+ tcp_checksum = p == NULL ? 0 : ntohs(p->th_sum);
+ tcp_urgent = p == NULL ? 0 : ntohs(p->th_urp);
+ tcp_hdr = (struct tcphdr *)p;
+};
+
+#pragma D binding "1.0" translator
+translator tcplsinfo_t < int s > {
+ tcps_state = s;
+};
diff --git a/cddl/lib/libdtrace/udp.d b/cddl/lib/libdtrace/udp.d
new file mode 100644
index 000000000000..5ad625de1bc6
--- /dev/null
+++ b/cddl/lib/libdtrace/udp.d
@@ -0,0 +1,75 @@
+/*
+ * 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
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 Mark Johnston <markj@FreeBSD.org>
+ */
+
+#pragma D depends_on library ip.d
+#pragma D depends_on provider udp
+
+/*
+ * udpsinfo contains stable UDP details.
+ */
+typedef struct udpsinfo {
+ uintptr_t udps_addr;
+ uint16_t udps_lport; /* local port */
+ uint16_t udps_rport; /* remote port */
+ string udps_laddr; /* local address, as a string */
+ string udps_raddr; /* remote address, as a string */
+} udpsinfo_t;
+
+/*
+ * udpinfo is the UDP header fields.
+ */
+typedef struct udpinfo {
+ uint16_t udp_sport; /* source port */
+ uint16_t udp_dport; /* destination port */
+ uint16_t udp_length; /* total length */
+ uint16_t udp_checksum; /* headers + data checksum */
+ struct udphdr *udp_hdr; /* raw UDP header */
+} udpinfo_t;
+
+#pragma D binding "1.0" translator
+translator udpsinfo_t < struct inpcb *p > {
+ udps_addr = (uintptr_t)p;
+ udps_lport = p == NULL ? 0 : ntohs(p->inp_inc.inc_ie.ie_lport);
+ udps_rport = p == NULL ? 0 : ntohs(p->inp_inc.inc_ie.ie_fport);
+ udps_laddr = p == NULL ? "" :
+ p->inp_vflag == INP_IPV4 ?
+ inet_ntoa(&p->inp_inc.inc_ie.ie_dependladdr.ie46_local.ia46_addr4.s_addr) :
+ inet_ntoa6(&p->inp_inc.inc_ie.ie_dependladdr.ie6_local);
+ udps_raddr = p == NULL ? "" :
+ p->inp_vflag == INP_IPV4 ?
+ inet_ntoa(&p->inp_inc.inc_ie.ie_dependfaddr.ie46_foreign.ia46_addr4.s_addr) :
+ inet_ntoa6(&p->inp_inc.inc_ie.ie_dependfaddr.ie6_foreign);
+};
+
+#pragma D binding "1.0" translator
+translator udpinfo_t < struct udphdr *p > {
+ udp_sport = p == NULL ? 0 : ntohs(p->uh_sport);
+ udp_dport = p == NULL ? 0 : ntohs(p->uh_dport);
+ udp_length = p == NULL ? 0 : ntohs(p->uh_ulen);
+ udp_checksum = p == NULL ? 0 : ntohs(p->uh_sum);
+ udp_hdr = p;
+};
diff --git a/cddl/lib/libzpool/Makefile b/cddl/lib/libzpool/Makefile
index b159d3af7311..848325aff849 100644
--- a/cddl/lib/libzpool/Makefile
+++ b/cddl/lib/libzpool/Makefile
@@ -64,7 +64,9 @@ NO_PROFILE=
CSTD= c99
-CFLAGS+= -DDEBUG=1
-#DEBUG_FLAGS+= -g
+# Since there are many asserts in this library, it makes no sense to compile
+# it without debugging.
+
+CFLAGS+= -g -DDEBUG=1
.include <bsd.lib.mk>
diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile
index 965300ef2976..370eacb57246 100644
--- a/cddl/usr.bin/ztest/Makefile
+++ b/cddl/usr.bin/ztest/Makefile
@@ -25,7 +25,8 @@ LDADD= -lgeom -lm -lnvpair -lumem -lzpool -lpthread -lavl -lzfs_core -lzfs \
CSTD= c99
-CFLAGS+= -DDEBUG=1
-#DEBUG_FLAGS+= -g
+# Since there are many asserts in this program, it makes no sense to compile
+# it without debugging.
+CFLAGS+= -g -DDEBUG=1
.include <bsd.prog.mk>
diff --git a/cddl/usr.sbin/zdb/Makefile b/cddl/usr.sbin/zdb/Makefile
index 806838560a7d..fa9ab98f5b3a 100644
--- a/cddl/usr.sbin/zdb/Makefile
+++ b/cddl/usr.sbin/zdb/Makefile
@@ -27,7 +27,8 @@ DPADD= ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
${LIBUUTIL} ${LIBZFS_CORE} ${LIBZFS} ${LIBZPOOL}
LDADD= -lgeom -lm -lnvpair -lpthread -lumem -luutil -lzfs_core -lzfs -lzpool
-CFLAGS+= -DDEBUG=1
-#DEBUG_FLAGS+= -g
+# Since there are many asserts in this program, it makes no sense to compile
+# it without debugging.
+CFLAGS+= -g -DDEBUG=1
.include <bsd.prog.mk>