aboutsummaryrefslogtreecommitdiff
path: root/cddl
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2018-08-11 04:26:29 +0000
committerKyle Evans <kevans@FreeBSD.org>2018-08-11 04:26:29 +0000
commit14b841d4a8e6c25d964f5e3bbda379a1541a27ec (patch)
tree01beba21222007fffb9203b614973505da4d8169 /cddl
parent6eeb282e0017163803f12ad57945e00f76c109f8 (diff)
parenta04ed7615ed26cc2c22286b2f4c624dce23a758f (diff)
downloadsrc-14b841d4a8e6c25d964f5e3bbda379a1541a27ec.tar.gz
src-14b841d4a8e6c25d964f5e3bbda379a1541a27ec.zip
MFH @ r337607, in preparation for boarding
Notes
Notes: svn path=/projects/bectl/; revision=337608
Diffstat (limited to 'cddl')
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh125
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh.out7
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh113
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.c166
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs.856
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c29
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool-features.718
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool.831
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c155
-rw-r--r--cddl/contrib/opensolaris/cmd/ztest/ztest.c166
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c2
-rw-r--r--cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c3
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h16
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c36
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c128
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c7
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h1
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c16
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c7
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c58
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c96
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c11
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c40
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c37
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h4
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h3
-rw-r--r--cddl/lib/libdtrace/Makefile1
-rw-r--r--cddl/lib/libdtrace/ip.d3
-rw-r--r--cddl/lib/libdtrace/udplite.d77
-rw-r--r--cddl/lib/libzfs/Makefile1
-rw-r--r--cddl/lib/libzfs_core/Makefile1
-rw-r--r--cddl/lib/libzpool/Makefile1
-rw-r--r--cddl/sbin/zfs/Makefile1
-rw-r--r--cddl/sbin/zpool/Makefile1
-rw-r--r--cddl/usr.bin/zinject/Makefile1
-rw-r--r--cddl/usr.bin/zstreamdump/Makefile1
-rw-r--r--cddl/usr.bin/ztest/Makefile1
-rw-r--r--cddl/usr.sbin/dtrace/tests/common/ip/Makefile4
-rwxr-xr-xcddl/usr.sbin/dtrace/tests/tools/exclude.sh1
-rw-r--r--cddl/usr.sbin/dwatch/libexec/Makefile3
-rw-r--r--cddl/usr.sbin/dwatch/libexec/udplite89
-rw-r--r--cddl/usr.sbin/zdb/Makefile1
-rw-r--r--cddl/usr.sbin/zfsd/Makefile.common1
-rw-r--r--cddl/usr.sbin/zhack/Makefile1
45 files changed, 1381 insertions, 144 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh
new file mode 100755
index 000000000000..902d278a8388
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh
@@ -0,0 +1,125 @@
+#!/usr/bin/env ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {ip,udplite}:::{send,receive} of IPv4 UDP-Lite to a local address.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on rpcbind.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test sends a UDP-Lite message using perl and checks that at least the
+# following counts were traced:
+#
+# 1 x ip:::send (UDPLite sent to UDP-Lite port 33434)
+# 1 x udplite:::send (UDPLite sent to UDP-Lite port 33434)
+# 1 x ip:::receive (UDP-Lite received)
+# 1 x udplite:::receive (UDP-Lite received)
+#
+# A udplite:::receive event is expected even if the received UDP-Lite packet
+# elicits an ICMP PORT_UNREACHABLE message since there is no UDP-Lite
+# socket for receiving the packet.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+port=33434
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Type => SOCK_DGRAM,
+ Proto => "udplite",
+ PeerAddr => "$local",
+ PeerPort => $port);
+ die "Could not create UDP-Lite socket $local port $port" unless \$s;
+ send \$s, "Hello", 0;
+ close \$s;
+ sleep(2);
+EOPERL
+
+$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = udplitesend = ipreceive = udplitereceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_UDPLITE/
+{
+ ipsend++;
+}
+
+udplite:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ udplitesend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_UDPLITE/
+{
+ ipreceive++;
+}
+
+udplite:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ udplitereceive++;
+}
+
+END
+{
+ printf("Minimum UDP-Lite events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 1 ? "yes" : "no");
+ printf("udplite:::send - %s\n", udplitesend >= 1 ? "yes" : "no");
+ printf("udplite:::receive - %s\n", udplitereceive >= 1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh.out
new file mode 100644
index 000000000000..b5970ffa57fb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudplite.ksh.out
@@ -0,0 +1,7 @@
+Minimum UDP-Lite events seen
+
+ip:::send - yes
+ip:::receive - yes
+udplite:::send - yes
+udplite:::receive - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh
new file mode 100755
index 000000000000..8837112d5d78
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh
@@ -0,0 +1,113 @@
+#!/usr/bin/env ksh93
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {udplite,ip}:::{send,receive} of IPv4 UDP-Lite to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on rpcbind.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test sends a UDP-Lite message using perl and checks that at least the
+# following counts were traced:
+#
+# 1 x ip:::send (UDP-Lite sent to UDP-Lite port 33434)
+# 1 x udplite:::send (UDP-Lite sent to UDP-Lite port 33434)
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+port=33434
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Type => SOCK_DGRAM,
+ Proto => "udplite",
+ PeerAddr => "$dest",
+ PeerPort => $port);
+ die "Could not create UDP-Lite socket $dest port $port" unless \$s;
+ send \$s, "Hello", 0;
+ close \$s;
+ sleep(2);
+EOPERL
+
+$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = udplitesend = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_UDPLITE/
+{
+ ipsend++;
+}
+
+udplite:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+ udplitesend++;
+}
+
+END
+{
+ printf("Minimum UDPLite events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+ printf("udplite:::send - %s\n", udplitesend >= 1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh.out
new file mode 100644
index 000000000000..66e39e736e23
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudplite.ksh.out
@@ -0,0 +1,5 @@
+Minimum UDP-Lite events seen
+
+ip:::send - yes
+udplite:::send - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
index 9231fd8c1038..3c72caf1e466 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
@@ -108,6 +108,7 @@ static uint64_t *zopt_object = NULL;
static unsigned zopt_objects = 0;
static libzfs_handle_t *g_zfs;
static uint64_t max_inflight = 1000;
+static int leaked_objects = 0;
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *);
@@ -774,7 +775,6 @@ verify_spacemap_refcounts(spa_t *spa)
static void
dump_spacemap(objset_t *os, space_map_t *sm)
{
- uint64_t alloc, offset, entry;
char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
"INVALID", "INVALID", "INVALID", "INVALID" };
@@ -791,41 +791,73 @@ dump_spacemap(objset_t *os, space_map_t *sm)
/*
* Print out the freelist entries in both encoded and decoded form.
*/
- alloc = 0;
- for (offset = 0; offset < space_map_length(sm);
- offset += sizeof (entry)) {
- uint8_t mapshift = sm->sm_shift;
+ uint8_t mapshift = sm->sm_shift;
+ int64_t alloc = 0;
+ uint64_t word;
+ for (uint64_t offset = 0; offset < space_map_length(sm);
+ offset += sizeof (word)) {
VERIFY0(dmu_read(os, space_map_object(sm), offset,
- sizeof (entry), &entry, DMU_READ_PREFETCH));
- if (SM_DEBUG_DECODE(entry)) {
+ sizeof (word), &word, DMU_READ_PREFETCH));
+ if (sm_entry_is_debug(word)) {
(void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
- (u_longlong_t)(offset / sizeof (entry)),
- ddata[SM_DEBUG_ACTION_DECODE(entry)],
- (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
- (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
+ (u_longlong_t)(offset / sizeof (word)),
+ ddata[SM_DEBUG_ACTION_DECODE(word)],
+ (u_longlong_t)SM_DEBUG_TXG_DECODE(word),
+ (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(word));
+ continue;
+ }
+
+ uint8_t words;
+ char entry_type;
+ uint64_t entry_off, entry_run, entry_vdev = SM_NO_VDEVID;
+
+ if (sm_entry_is_single_word(word)) {
+ entry_type = (SM_TYPE_DECODE(word) == SM_ALLOC) ?
+ 'A' : 'F';
+ entry_off = (SM_OFFSET_DECODE(word) << mapshift) +
+ sm->sm_start;
+ entry_run = SM_RUN_DECODE(word) << mapshift;
+ words = 1;
} else {
- (void) printf("\t [%6llu] %c range:"
- " %010llx-%010llx size: %06llx\n",
- (u_longlong_t)(offset / sizeof (entry)),
- SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
- (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
- mapshift) + sm->sm_start),
- (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
- mapshift) + sm->sm_start +
- (SM_RUN_DECODE(entry) << mapshift)),
- (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
- if (SM_TYPE_DECODE(entry) == SM_ALLOC)
- alloc += SM_RUN_DECODE(entry) << mapshift;
- else
- alloc -= SM_RUN_DECODE(entry) << mapshift;
+ /* it is a two-word entry so we read another word */
+ ASSERT(sm_entry_is_double_word(word));
+
+ uint64_t extra_word;
+ offset += sizeof (extra_word);
+ VERIFY0(dmu_read(os, space_map_object(sm), offset,
+ sizeof (extra_word), &extra_word,
+ DMU_READ_PREFETCH));
+
+ ASSERT3U(offset, <=, space_map_length(sm));
+
+ entry_run = SM2_RUN_DECODE(word) << mapshift;
+ entry_vdev = SM2_VDEV_DECODE(word);
+ entry_type = (SM2_TYPE_DECODE(extra_word) == SM_ALLOC) ?
+ 'A' : 'F';
+ entry_off = (SM2_OFFSET_DECODE(extra_word) <<
+ mapshift) + sm->sm_start;
+ words = 2;
}
+
+ (void) printf("\t [%6llu] %c range:"
+ " %010llx-%010llx size: %06llx vdev: %06llu words: %u\n",
+ (u_longlong_t)(offset / sizeof (word)),
+ entry_type, (u_longlong_t)entry_off,
+ (u_longlong_t)(entry_off + entry_run),
+ (u_longlong_t)entry_run,
+ (u_longlong_t)entry_vdev, words);
+
+ if (entry_type == 'A')
+ alloc += entry_run;
+ else
+ alloc -= entry_run;
}
- if (alloc != space_map_allocated(sm)) {
- (void) printf("space_map_object alloc (%llu) INCONSISTENT "
- "with space map summary (%llu)\n",
- (u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc);
+ if ((uint64_t)alloc != space_map_allocated(sm)) {
+ (void) printf("space_map_object alloc (%lld) INCONSISTENT "
+ "with space map summary (%lld)\n",
+ (longlong_t)space_map_allocated(sm), (longlong_t)alloc);
}
}
@@ -1155,7 +1187,7 @@ dump_ddt(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
while ((error = ddt_object_walk(ddt, type, class, &walk, &dde)) == 0)
dump_dde(ddt, &dde, walk);
- ASSERT(error == ENOENT);
+ ASSERT3U(error, ==, ENOENT);
(void) printf("\n");
}
@@ -1957,9 +1989,12 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
if (dump_opt['d'] > 4) {
error = zfs_obj_to_path(os, object, path, sizeof (path));
- if (error != 0) {
+ if (error == ESTALE) {
+ (void) snprintf(path, sizeof (path), "on delete queue");
+ } else if (error != 0) {
+ leaked_objects++;
(void) snprintf(path, sizeof (path),
- "\?\?\?<object#%llu>", (u_longlong_t)object);
+ "path not found, possibly leaked");
}
(void) printf("\tpath %s\n", path);
}
@@ -2289,6 +2324,12 @@ dump_dir(objset_t *os)
}
ASSERT3U(object_count, ==, usedobjs);
+
+ if (leaked_objects != 0) {
+ (void) printf("%d potentially leaked objects detected\n",
+ leaked_objects);
+ leaked_objects = 0;
+ }
}
static void
@@ -3002,7 +3043,7 @@ zdb_claim_removing(spa_t *spa, zdb_cb_t *zcb)
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
spa_vdev_removal_t *svr = spa->spa_vdev_removal;
- vdev_t *vd = svr->svr_vdev;
+ vdev_t *vd = vdev_lookup_top(spa, svr->svr_vdev_id);
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
for (uint64_t msi = 0; msi < vd->vdev_ms_count; msi++) {
@@ -3018,13 +3059,17 @@ zdb_claim_removing(spa_t *spa, zdb_cb_t *zcb)
svr->svr_allocd_segs, SM_ALLOC));
/*
- * Clear everything past what has been synced,
- * because we have not allocated mappings for it yet.
+ * Clear everything past what has been synced unless
+ * it's past the spacemap, because we have not allocated
+ * mappings for it yet.
*/
- range_tree_clear(svr->svr_allocd_segs,
- vdev_indirect_mapping_max_offset(vim),
- msp->ms_sm->sm_start + msp->ms_sm->sm_size -
- vdev_indirect_mapping_max_offset(vim));
+ uint64_t vim_max_offset =
+ vdev_indirect_mapping_max_offset(vim);
+ uint64_t sm_end = msp->ms_sm->sm_start +
+ msp->ms_sm->sm_size;
+ if (sm_end > vim_max_offset)
+ range_tree_clear(svr->svr_allocd_segs,
+ vim_max_offset, sm_end - vim_max_offset);
}
zcb->zcb_removing_size +=
@@ -3097,15 +3142,14 @@ typedef struct checkpoint_sm_exclude_entry_arg {
} checkpoint_sm_exclude_entry_arg_t;
static int
-checkpoint_sm_exclude_entry_cb(maptype_t type, uint64_t offset, uint64_t size,
- void *arg)
+checkpoint_sm_exclude_entry_cb(space_map_entry_t *sme, void *arg)
{
checkpoint_sm_exclude_entry_arg_t *cseea = arg;
vdev_t *vd = cseea->cseea_vd;
- metaslab_t *ms = vd->vdev_ms[offset >> vd->vdev_ms_shift];
- uint64_t end = offset + size;
+ metaslab_t *ms = vd->vdev_ms[sme->sme_offset >> vd->vdev_ms_shift];
+ uint64_t end = sme->sme_offset + sme->sme_run;
- ASSERT(type == SM_FREE);
+ ASSERT(sme->sme_type == SM_FREE);
/*
* Since the vdev_checkpoint_sm exists in the vdev level
@@ -3123,7 +3167,7 @@ checkpoint_sm_exclude_entry_cb(maptype_t type, uint64_t offset, uint64_t size,
* metaslab boundaries. So if needed we could add code
* that handles metaslab-crossing segments in the future.
*/
- VERIFY3U(offset, >=, ms->ms_start);
+ VERIFY3U(sme->sme_offset, >=, ms->ms_start);
VERIFY3U(end, <=, ms->ms_start + ms->ms_size);
/*
@@ -3131,10 +3175,10 @@ checkpoint_sm_exclude_entry_cb(maptype_t type, uint64_t offset, uint64_t size,
* also verify that the entry is there to begin with.
*/
mutex_enter(&ms->ms_lock);
- range_tree_remove(ms->ms_allocatable, offset, size);
+ range_tree_remove(ms->ms_allocatable, sme->sme_offset, sme->sme_run);
mutex_exit(&ms->ms_lock);
- cseea->cseea_checkpoint_size += size;
+ cseea->cseea_checkpoint_size += sme->sme_run;
return (0);
}
@@ -4109,15 +4153,14 @@ typedef struct verify_checkpoint_sm_entry_cb_arg {
#define ENTRIES_PER_PROGRESS_UPDATE 10000
static int
-verify_checkpoint_sm_entry_cb(maptype_t type, uint64_t offset, uint64_t size,
- void *arg)
+verify_checkpoint_sm_entry_cb(space_map_entry_t *sme, void *arg)
{
verify_checkpoint_sm_entry_cb_arg_t *vcsec = arg;
vdev_t *vd = vcsec->vcsec_vd;
- metaslab_t *ms = vd->vdev_ms[offset >> vd->vdev_ms_shift];
- uint64_t end = offset + size;
+ metaslab_t *ms = vd->vdev_ms[sme->sme_offset >> vd->vdev_ms_shift];
+ uint64_t end = sme->sme_offset + sme->sme_run;
- ASSERT(type == SM_FREE);
+ ASSERT(sme->sme_type == SM_FREE);
if ((vcsec->vcsec_entryid % ENTRIES_PER_PROGRESS_UPDATE) == 0) {
(void) fprintf(stderr,
@@ -4131,7 +4174,7 @@ verify_checkpoint_sm_entry_cb(maptype_t type, uint64_t offset, uint64_t size,
/*
* See comment in checkpoint_sm_exclude_entry_cb()
*/
- VERIFY3U(offset, >=, ms->ms_start);
+ VERIFY3U(sme->sme_offset, >=, ms->ms_start);
VERIFY3U(end, <=, ms->ms_start + ms->ms_size);
/*
@@ -4140,7 +4183,7 @@ verify_checkpoint_sm_entry_cb(maptype_t type, uint64_t offset, uint64_t size,
* their respective ms_allocateable trees should not contain them.
*/
mutex_enter(&ms->ms_lock);
- range_tree_verify(ms->ms_allocatable, offset, size);
+ range_tree_verify(ms->ms_allocatable, sme->sme_offset, sme->sme_run);
mutex_exit(&ms->ms_lock);
return (0);
@@ -4386,7 +4429,7 @@ verify_checkpoint(spa_t *spa)
DMU_POOL_ZPOOL_CHECKPOINT, sizeof (uint64_t),
sizeof (uberblock_t) / sizeof (uint64_t), &checkpoint);
- if (error == ENOENT) {
+ if (error == ENOENT && !dump_opt['L']) {
/*
* If the feature is active but the uberblock is missing
* then we must be in the middle of discarding the
@@ -4409,7 +4452,7 @@ verify_checkpoint(spa_t *spa)
error = 3;
}
- if (error == 0)
+ if (error == 0 && !dump_opt['L'])
verify_checkpoint_blocks(spa);
return (error);
@@ -4514,7 +4557,7 @@ dump_zpool(spa_t *spa)
if (dump_opt['h'])
dump_history(spa);
- if (rc == 0 && !dump_opt['L'])
+ if (rc == 0)
rc = verify_checkpoint(spa);
if (rc != 0) {
@@ -4907,19 +4950,18 @@ zdb_embedded_block(char *thing)
words + 8, words + 9, words + 10, words + 11,
words + 12, words + 13, words + 14, words + 15);
if (err != 16) {
- (void) printf("invalid input format\n");
+ (void) fprintf(stderr, "invalid input format\n");
exit(1);
}
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) {
- (void) fprintf(stderr, "%s: failed to allocate %llu bytes\n",
- __func__, SPA_MAXBLOCKSIZE);
+ (void) fprintf(stderr, "out of memory\n");
exit(1);
}
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) {
- (void) printf("decode failed: %u\n", err);
+ (void) fprintf(stderr, "decode failed: %u\n", err);
free(buf);
exit(1);
}
@@ -5372,5 +5414,5 @@ main(int argc, char **argv)
libzfs_fini(g_zfs);
kernel_fini();
- return (0);
+ return (error);
}
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
index 51ac88086250..f6e9bbb57972 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -28,6 +28,7 @@
.\" Copyright (c) 2016 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org>
.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved.
+.\" Copyright 2018 Joyent, Inc.
.\"
.\" $FreeBSD$
.\"
@@ -319,7 +320,8 @@ namespace. For example:
.Pp
where the maximum length of a dataset name is
.Dv MAXNAMELEN
-(256 bytes).
+(256 bytes)
+and the maximum amount of nesting allowed in a path is 50 levels deep.
.Pp
A dataset can be one of the following:
.Bl -hang -width 12n
@@ -546,6 +548,13 @@ property. Compression can be turned on by running:
.Qq Nm Cm set compression=on Ar dataset
The default value is
.Cm off .
+.It Sy createtxg
+The transaction group (txg) in which the dataset was created.
+Bookmarks have the same
+.Sy createtxg
+as the snapshot they are initially tied to.
+This property is suitable for ordering a list of snapshots,
+e.g. for incremental send and receive.
.It Sy creation
The time this dataset was created.
.It Sy clones
@@ -573,6 +582,14 @@ This value is only available when a
.Sy filesystem_limit
has
been set somewhere in the tree under which the dataset resides.
+.It Sy guid
+The 64 bit GUID of this dataset or bookmark which does not change over its
+entire lifetime.
+When a snapshot is sent to another pool, the received snapshot has the same
+GUID.
+Thus, the
+.Sy guid
+is suitable to identify a snapshot across pools.
.It Sy logicalreferenced
The amount of space that is
.Qq logically
@@ -1311,7 +1328,7 @@ The default value is
Limits the amount of space a dataset can consume. This property enforces a hard
limit on the amount of space used. This hard limit does not include space used
by descendents, including file systems and snapshots.
-.It Sy refreservation Ns = Ns Ar size | Cm none
+.It Sy refreservation Ns = Ns Ar size | Cm none | Cm auto
The minimum amount of space guaranteed to a dataset, not including its
descendents. When the amount of space used is below this value, the dataset is
treated as if it were taking up the amount of space specified by
@@ -1327,6 +1344,18 @@ is set, a snapshot is only allowed if there is enough free pool space outside
of this reservation to accommodate the current number of "referenced" bytes in
the dataset.
.Pp
+If
+.Sy refreservation
+is set to
+.Sy auto ,
+a volume is thick provisioned or not sparse.
+.Sy refreservation Ns = Cm auto
+is only supported on volumes.
+See
+.Sy volsize
+in the Native Properties
+section for more information about sparse volumes.
+.Pp
This property can also be referred to by its shortened column name,
.Sy refreserv .
.It Sy reservation Ns = Ns Ar size | Cm none
@@ -1459,18 +1488,33 @@ on how the volume is used. These effects can also occur when the volume size is
changed while it is in use (particularly when shrinking the size). Extreme care
should be used when adjusting the volume size.
.Pp
-Though not recommended, a "sparse volume" (also known as "thin provisioning")
+Though not recommended, a "sparse volume" (also known as "thin provisioned")
can be created by specifying the
.Fl s
option to the
.Qq Nm Cm create Fl V
-command, or by changing the reservation after the volume has been created. A
-"sparse volume" is a volume where the reservation is less then the volume size.
+command, or by changing the value of the
+.Sy refreservation
+property, or
+.Sy reservation
+property on pool version 8 or earlier
+.Pc
+after the volume has been created.
+A "sparse volume" is a volume where the value of
+.Sy refreservation
+is less then the size of the volume plus the space required to store its
+metadata.
Consequently, writes to a sparse volume can fail with
.Sy ENOSPC
when the pool is low on space. For a sparse volume, changes to
.Sy volsize
-are not reflected in the reservation.
+are not reflected in the
+.Sy refreservation .
+A volume that is not sparse is said to be "thick provisioned".
+A sparse volume can become thick provisioned by setting
+.Sy refreservation
+to
+.Sy auto .
.It Sy volmode Ns = Ns Cm default | geom | dev | none
This property specifies how volumes should be exposed to the OS.
Setting it to
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index d571d3f9c527..bbf2d4ba262b 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -72,6 +72,7 @@
#include <aclutils.h>
#include <directory.h>
#include <idmap.h>
+#include <libshare.h>
#endif
#include "zfs_iter.h"
@@ -6221,6 +6222,17 @@ share_mount(int op, int argc, char **argv)
return (0);
qsort(dslist, count, sizeof (void *), libzfs_dataset_cmp);
+#ifdef illumos
+ sa_init_selective_arg_t sharearg;
+ sharearg.zhandle_arr = dslist;
+ sharearg.zhandle_len = count;
+ if ((ret = zfs_init_libshare_arg(zfs_get_handle(dslist[0]),
+ SA_INIT_SHARE_API_SELECTIVE, &sharearg)) != SA_OK) {
+ (void) fprintf(stderr,
+ gettext("Could not initialize libshare, %d"), ret);
+ return (ret);
+ }
+#endif
for (i = 0; i < count; i++) {
if (verbose)
@@ -7026,11 +7038,28 @@ zfs_do_diff(int argc, char **argv)
return (err != 0);
}
+/*
+ * zfs remap <filesystem | volume>
+ *
+ * Remap the indirect blocks in the given fileystem or volume.
+ */
static int
zfs_do_remap(int argc, char **argv)
{
const char *fsname;
int err = 0;
+ int c;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "")) != -1) {
+ switch (c) {
+ case '?':
+ (void) fprintf(stderr,
+ gettext("invalid option '%c'\n"), optopt);
+ usage(B_FALSE);
+ }
+ }
+
if (argc != 2) {
(void) fprintf(stderr, gettext("wrong number of arguments\n"));
usage(B_FALSE);
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
index cc4e7c35b032..4e6b63514456 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
@@ -482,6 +482,24 @@ This feature becomes
when the "zpool remove" command is
used on a top-level vdev, and will never return to being
.Sy enabled .
+.It Sy spacemap_v2
+.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:spacemap_v2"
+.It GUID Ta com.delphix:spacemap_v2
+.It READ\-ONLY COMPATIBLE Ta yes
+.It DEPENDENCIES Ta none
+.El
+.Pp
+This feature enables the use of the new space map encoding which
+consists of two words (instead of one) whenever it is advantageous.
+The new encoding allows space maps to represent large regions of
+space more efficiently on-disk while also increasing their maximum
+addressable offset.
+.Pp
+This feature becomes
+.Sy active
+as soon as it is enabled and will
+never return to being
+.Sy enabled .
.It Sy large_blocks
.Bl -column "READ\-ONLY COMPATIBLE" "org.open-zfs:large_block"
.It GUID Ta org.open-zfs:large_block
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
index b0c21436308a..d5a8d97b1435 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
@@ -121,6 +121,11 @@
.Ar pool | id
.Op Ar newpool
.Nm
+.Cm initialize
+.Op Fl cs
+.Ar pool
+.Op Ar device Ns ...
+.Nm
.Cm iostat
.Op Fl T Cm d Ns | Ns Cm u
.Op Fl v
@@ -1437,6 +1442,32 @@ to fully rewind.
.El
.It Xo
.Nm
+.Cm initialize
+.Op Fl cs
+.Ar pool
+.Op Ar device Ns ...
+.Xc
+Begins initializing by writing to all unallocated regions on the specified
+devices, or all eligible devices in the pool if no individual devices are
+specified.
+Only leaf data or log devices may be initialized.
+.Bl -tag -width Ds
+.It Fl c, -cancel
+Cancel initializing on the specified devices, or all eligible devices if none
+are specified.
+If one or more target devices are invalid or are not currently being
+initialized, the command will fail and no cancellation will occur on any device.
+.It Fl s -suspend
+Suspend initializing on the specified devices, or all eligible devices if none
+are specified.
+If one or more target devices are invalid or are not currently being
+initialized, the command will fail and no suspension will occur on any device.
+Initializing can then be resumed by running
+.Nm zpool Cm initialize
+with no flags on the relevant target devices.
+.El
+.It Xo
+.Nm
.Cm iostat
.Op Fl T Cm d Ns | Ns Cm u
.Op Fl v
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index cb0c777bb76c..1a81991c1d25 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -87,6 +87,7 @@ static int zpool_do_detach(int, char **);
static int zpool_do_replace(int, char **);
static int zpool_do_split(int, char **);
+static int zpool_do_initialize(int, char **);
static int zpool_do_scrub(int, char **);
static int zpool_do_import(int, char **);
@@ -136,6 +137,7 @@ typedef enum {
HELP_ONLINE,
HELP_REPLACE,
HELP_REMOVE,
+ HELP_INITIALIZE,
HELP_SCRUB,
HELP_STATUS,
HELP_UPGRADE,
@@ -187,6 +189,7 @@ static zpool_command_t command_table[] = {
{ "replace", zpool_do_replace, HELP_REPLACE },
{ "split", zpool_do_split, HELP_SPLIT },
{ NULL },
+ { "initialize", zpool_do_initialize, HELP_INITIALIZE },
{ "scrub", zpool_do_scrub, HELP_SCRUB },
{ NULL },
{ "import", zpool_do_import, HELP_IMPORT },
@@ -261,6 +264,8 @@ get_usage(zpool_help_t idx)
return (gettext("\tremove [-nps] <pool> <device> ...\n"));
case HELP_REOPEN:
return (gettext("\treopen <pool>\n"));
+ case HELP_INITIALIZE:
+ return (gettext("\tinitialize [-cs] <pool> [<device> ...]\n"));
case HELP_SCRUB:
return (gettext("\tscrub [-s | -p] <pool> ...\n"));
case HELP_STATUS:
@@ -1650,6 +1655,43 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
"resilvering" : "repairing");
}
+ if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE ||
+ vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED ||
+ vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) &&
+ !vs->vs_scan_removing) {
+ char zbuf[1024];
+ char tbuf[256];
+ struct tm zaction_ts;
+
+ time_t t = vs->vs_initialize_action_time;
+ int initialize_pct = 100;
+ if (vs->vs_initialize_state != VDEV_INITIALIZE_COMPLETE) {
+ initialize_pct = (vs->vs_initialize_bytes_done * 100 /
+ (vs->vs_initialize_bytes_est + 1));
+ }
+
+ (void) localtime_r(&t, &zaction_ts);
+ (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts);
+
+ switch (vs->vs_initialize_state) {
+ case VDEV_INITIALIZE_SUSPENDED:
+ (void) snprintf(zbuf, sizeof (zbuf),
+ ", suspended, started at %s", tbuf);
+ break;
+ case VDEV_INITIALIZE_ACTIVE:
+ (void) snprintf(zbuf, sizeof (zbuf),
+ ", started at %s", tbuf);
+ break;
+ case VDEV_INITIALIZE_COMPLETE:
+ (void) snprintf(zbuf, sizeof (zbuf),
+ ", completed at %s", tbuf);
+ break;
+ }
+
+ (void) printf(gettext(" (%d%% initialized%s)"),
+ initialize_pct, zbuf);
+ }
+
(void) printf("\n");
for (c = 0; c < children; c++) {
@@ -4238,6 +4280,119 @@ zpool_do_scrub(int argc, char **argv)
return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
}
+static void
+zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
+{
+ uint_t children = 0;
+ nvlist_t **child;
+ uint_t i;
+
+ (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ &child, &children);
+
+ if (children == 0) {
+ char *path = zpool_vdev_name(g_zfs, zhp, nvroot, B_FALSE);
+ fnvlist_add_boolean(res, path);
+ free(path);
+ return;
+ }
+
+ for (i = 0; i < children; i++) {
+ zpool_collect_leaves(zhp, child[i], res);
+ }
+}
+
+/*
+ * zpool initialize [-cs] <pool> [<vdev> ...]
+ * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
+ * if none specified.
+ *
+ * -c Cancel. Ends active initializing.
+ * -s Suspend. Initializing can then be restarted with no flags.
+ */
+int
+zpool_do_initialize(int argc, char **argv)
+{
+ int c;
+ char *poolname;
+ zpool_handle_t *zhp;
+ nvlist_t *vdevs;
+ int err = 0;
+
+ struct option long_options[] = {
+ {"cancel", no_argument, NULL, 'c'},
+ {"suspend", no_argument, NULL, 's'},
+ {0, 0, 0, 0}
+ };
+
+ pool_initialize_func_t cmd_type = POOL_INITIALIZE_DO;
+ while ((c = getopt_long(argc, argv, "cs", long_options, NULL)) != -1) {
+ switch (c) {
+ case 'c':
+ if (cmd_type != POOL_INITIALIZE_DO) {
+ (void) fprintf(stderr, gettext("-c cannot be "
+ "combined with other options\n"));
+ usage(B_FALSE);
+ }
+ cmd_type = POOL_INITIALIZE_CANCEL;
+ break;
+ case 's':
+ if (cmd_type != POOL_INITIALIZE_DO) {
+ (void) fprintf(stderr, gettext("-s cannot be "
+ "combined with other options\n"));
+ usage(B_FALSE);
+ }
+ cmd_type = POOL_INITIALIZE_SUSPEND;
+ break;
+ case '?':
+ if (optopt != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid option '%c'\n"), optopt);
+ } else {
+ (void) fprintf(stderr,
+ gettext("invalid option '%s'\n"),
+ argv[optind - 1]);
+ }
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ usage(B_FALSE);
+ return (-1);
+ }
+
+ poolname = argv[0];
+ zhp = zpool_open(g_zfs, poolname);
+ if (zhp == NULL)
+ return (-1);
+
+ vdevs = fnvlist_alloc();
+ if (argc == 1) {
+ /* no individual leaf vdevs specified, so add them all */
+ nvlist_t *config = zpool_get_config(zhp, NULL);
+ nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
+ ZPOOL_CONFIG_VDEV_TREE);
+ zpool_collect_leaves(zhp, nvroot, vdevs);
+ } else {
+ int i;
+ for (i = 1; i < argc; i++) {
+ fnvlist_add_boolean(vdevs, argv[i]);
+ }
+ }
+
+ err = zpool_initialize(zhp, cmd_type, vdevs);
+
+ fnvlist_free(vdevs);
+ zpool_close(zhp);
+
+ return (err);
+}
+
typedef struct status_cbdata {
int cb_count;
boolean_t cb_allpools;
diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
index 834a2852ef1f..af8bd1867dae 100644
--- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c
+++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2017 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.
@@ -104,6 +104,7 @@
#include <sys/zil_impl.h>
#include <sys/vdev_impl.h>
#include <sys/vdev_file.h>
+#include <sys/vdev_initialize.h>
#include <sys/spa_impl.h>
#include <sys/metaslab_impl.h>
#include <sys/dsl_prop.h>
@@ -195,6 +196,7 @@ extern uint64_t zfs_deadman_synctime_ms;
extern int metaslab_preload_limit;
extern boolean_t zfs_compressed_arc_enabled;
extern boolean_t zfs_abd_scatter_enabled;
+extern boolean_t zfs_force_some_double_word_sm_entries;
static ztest_shared_opts_t *ztest_shared_opts;
static ztest_shared_opts_t ztest_opts;
@@ -347,6 +349,7 @@ ztest_func_t ztest_spa_upgrade;
ztest_func_t ztest_device_removal;
ztest_func_t ztest_remap_blocks;
ztest_func_t ztest_spa_checkpoint_create_discard;
+ztest_func_t ztest_initialize;
uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
@@ -390,7 +393,8 @@ ztest_info_t ztest_info[] = {
&ztest_opts.zo_vdevtime },
{ ztest_device_removal, 1, &zopt_sometimes },
{ ztest_remap_blocks, 1, &zopt_sometimes },
- { ztest_spa_checkpoint_create_discard, 1, &zopt_rarely }
+ { ztest_spa_checkpoint_create_discard, 1, &zopt_rarely },
+ { ztest_initialize, 1, &zopt_sometimes }
};
#define ZTEST_FUNCS (sizeof (ztest_info) / sizeof (ztest_info_t))
@@ -437,6 +441,7 @@ static ztest_ds_t *ztest_ds;
static kmutex_t ztest_vdev_lock;
static kmutex_t ztest_checkpoint_lock;
+static boolean_t ztest_device_removal_active = B_FALSE;
/*
* The ztest_name_lock protects the pool and dataset namespace used by
@@ -2881,7 +2886,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
* value. Don't bother trying to attach while we are in the middle
* of removal.
*/
- if (spa->spa_vdev_removal != NULL) {
+ if (ztest_device_removal_active) {
spa_config_exit(spa, SCL_ALL, FTAG);
mutex_exit(&ztest_vdev_lock);
return;
@@ -3056,16 +3061,49 @@ ztest_device_removal(ztest_ds_t *zd, uint64_t id)
spa_t *spa = ztest_spa;
vdev_t *vd;
uint64_t guid;
+ int error;
mutex_enter(&ztest_vdev_lock);
+ if (ztest_device_removal_active) {
+ mutex_exit(&ztest_vdev_lock);
+ return;
+ }
+
+ /*
+ * Remove a random top-level vdev and wait for removal to finish.
+ */
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
vd = vdev_lookup_top(spa, ztest_random_vdev_top(spa, B_FALSE));
guid = vd->vdev_guid;
spa_config_exit(spa, SCL_VDEV, FTAG);
- (void) spa_vdev_remove(spa, guid, B_FALSE);
+ error = spa_vdev_remove(spa, guid, B_FALSE);
+ if (error == 0) {
+ ztest_device_removal_active = B_TRUE;
+ mutex_exit(&ztest_vdev_lock);
+
+ while (spa->spa_vdev_removal != NULL)
+ txg_wait_synced(spa_get_dsl(spa), 0);
+ } else {
+ mutex_exit(&ztest_vdev_lock);
+ return;
+ }
+
+ /*
+ * The pool needs to be scrubbed after completing device removal.
+ * Failure to do so may result in checksum errors due to the
+ * strategy employed by ztest_fault_inject() when selecting which
+ * offset are redundant and can be damaged.
+ */
+ error = spa_scan(spa, POOL_SCAN_SCRUB);
+ if (error == 0) {
+ while (dsl_scan_scrubbing(spa_get_dsl(spa)))
+ txg_wait_synced(spa_get_dsl(spa), 0);
+ }
+ mutex_enter(&ztest_vdev_lock);
+ ztest_device_removal_active = B_FALSE;
mutex_exit(&ztest_vdev_lock);
}
@@ -3204,7 +3242,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
* that the metaslab_class space increased (because it decreases
* when the device removal completes).
*/
- if (spa->spa_vdev_removal != NULL) {
+ if (ztest_device_removal_active) {
spa_config_exit(spa, SCL_STATE, spa);
mutex_exit(&ztest_vdev_lock);
mutex_exit(&ztest_checkpoint_lock);
@@ -4985,6 +5023,18 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
boolean_t islog = B_FALSE;
mutex_enter(&ztest_vdev_lock);
+
+ /*
+ * Device removal is in progress, fault injection must be disabled
+ * until it completes and the pool is scrubbed. The fault injection
+ * strategy for damaging blocks does not take in to account evacuated
+ * blocks which may have already been damaged.
+ */
+ if (ztest_device_removal_active) {
+ mutex_exit(&ztest_vdev_lock);
+ return;
+ }
+
maxfaults = MAXFAULTS();
leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
mirror_save = zs->zs_mirrors;
@@ -5330,6 +5380,12 @@ ztest_scrub(ztest_ds_t *zd, uint64_t id)
{
spa_t *spa = ztest_spa;
+ /*
+ * Scrub in progress by device removal.
+ */
+ if (ztest_device_removal_active)
+ return;
+
(void) spa_scan(spa, POOL_SCAN_SCRUB);
(void) poll(NULL, 0, 100); /* wait a moment, then force a restart */
(void) spa_scan(spa, POOL_SCAN_SCRUB);
@@ -5418,6 +5474,97 @@ ztest_spa_rename(ztest_ds_t *zd, uint64_t id)
rw_exit(&ztest_name_lock);
}
+static vdev_t *
+ztest_random_concrete_vdev_leaf(vdev_t *vd)
+{
+ if (vd == NULL)
+ return (NULL);
+
+ if (vd->vdev_children == 0)
+ return (vd);
+
+ vdev_t *eligible[vd->vdev_children];
+ int eligible_idx = 0, i;
+ for (i = 0; i < vd->vdev_children; i++) {
+ vdev_t *cvd = vd->vdev_child[i];
+ if (cvd->vdev_top->vdev_removing)
+ continue;
+ if (cvd->vdev_children > 0 ||
+ (vdev_is_concrete(cvd) && !cvd->vdev_detached)) {
+ eligible[eligible_idx++] = cvd;
+ }
+ }
+ VERIFY(eligible_idx > 0);
+
+ uint64_t child_no = ztest_random(eligible_idx);
+ return (ztest_random_concrete_vdev_leaf(eligible[child_no]));
+}
+
+/* ARGSUSED */
+void
+ztest_initialize(ztest_ds_t *zd, uint64_t id)
+{
+ spa_t *spa = ztest_spa;
+ int error = 0;
+
+ mutex_enter(&ztest_vdev_lock);
+
+ spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+ /* Random leaf vdev */
+ vdev_t *rand_vd = ztest_random_concrete_vdev_leaf(spa->spa_root_vdev);
+ if (rand_vd == NULL) {
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+ mutex_exit(&ztest_vdev_lock);
+ return;
+ }
+
+ /*
+ * The random vdev we've selected may change as soon as we
+ * drop the spa_config_lock. We create local copies of things
+ * we're interested in.
+ */
+ uint64_t guid = rand_vd->vdev_guid;
+ char *path = strdup(rand_vd->vdev_path);
+ boolean_t active = rand_vd->vdev_initialize_thread != NULL;
+
+ zfs_dbgmsg("vd %p, guid %llu", rand_vd, guid);
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+
+ uint64_t cmd = ztest_random(POOL_INITIALIZE_FUNCS);
+ error = spa_vdev_initialize(spa, guid, cmd);
+ switch (cmd) {
+ case POOL_INITIALIZE_CANCEL:
+ if (ztest_opts.zo_verbose >= 4) {
+ (void) printf("Cancel initialize %s", path);
+ if (!active)
+ (void) printf(" failed (no initialize active)");
+ (void) printf("\n");
+ }
+ break;
+ case POOL_INITIALIZE_DO:
+ if (ztest_opts.zo_verbose >= 4) {
+ (void) printf("Start initialize %s", path);
+ if (active && error == 0)
+ (void) printf(" failed (already active)");
+ else if (error != 0)
+ (void) printf(" failed (error %d)", error);
+ (void) printf("\n");
+ }
+ break;
+ case POOL_INITIALIZE_SUSPEND:
+ if (ztest_opts.zo_verbose >= 4) {
+ (void) printf("Suspend initialize %s", path);
+ if (!active)
+ (void) printf(" failed (no initialize active)");
+ (void) printf("\n");
+ }
+ break;
+ }
+ free(path);
+ mutex_exit(&ztest_vdev_lock);
+}
+
/*
* Verify pool integrity by running zdb.
*/
@@ -5868,7 +6015,6 @@ ztest_run(ztest_shared_t *zs)
*/
kernel_init(FREAD | FWRITE);
VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
- spa->spa_debug = B_TRUE;
metaslab_preload_limit = ztest_random(20) + 1;
ztest_spa = spa;
@@ -6025,7 +6171,6 @@ ztest_freeze(void)
kernel_init(FREAD | FWRITE);
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
VERIFY3U(0, ==, ztest_dataset_open(0));
- spa->spa_debug = B_TRUE;
ztest_spa = spa;
/*
@@ -6096,7 +6241,6 @@ ztest_freeze(void)
VERIFY3U(0, ==, ztest_dataset_open(0));
ztest_dataset_close(0);
- spa->spa_debug = B_TRUE;
ztest_spa = spa;
txg_wait_synced(spa_get_dsl(spa), 0);
ztest_reguid(NULL, 0);
@@ -6397,6 +6541,12 @@ main(int argc, char **argv)
dprintf_setup(&argc, argv);
zfs_deadman_synctime_ms = 300000;
+ /*
+ * As two-word space map entries may not come up often (especially
+ * if pool and vdev sizes are small) we want to force at least some
+ * of them so the feature get tested.
+ */
+ zfs_force_some_double_word_sm_entries = B_TRUE;
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
ASSERT3S(ztest_fd_rand, >=, 0);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
index 3bf6196ad034..492fb937cba2 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -343,13 +343,13 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_func, "void(@)" },
{ "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN,
DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
+#ifdef illumos
{ "msgdsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGDSIZE,
DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "size_t(mblk_t *)" },
{ "msgsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGSIZE,
DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "size_t(mblk_t *)" },
-#ifdef illumos
{ "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED,
DT_ATTR_EVOLCMN, DT_VERS_1_0,
&dt_idops_func, "int(genunix`kmutex_t *)" },
diff --git a/cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c b/cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
index 7cece36ced1b..b687a2f5761a 100644
--- a/cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
+++ b/cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
@@ -10,6 +10,7 @@
*/
/*
* Copyright (c) 2014, Joyent, Inc.
+ * Copyright (c) 2017 by Delphix. All rights reserved.
*/
#include <stdio.h>
@@ -394,8 +395,10 @@ nvlist_print_json(FILE *fp, nvlist_t *nvl)
}
case DATA_TYPE_UNKNOWN:
+ case DATA_TYPE_DONTCARE:
return (-1);
}
+
}
FPRINTF(fp, "}");
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index d518abb86644..4f8a68e4d296 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -137,6 +137,9 @@ typedef enum zfs_error {
EZFS_NO_CHECKPOINT, /* pool has no checkpoint */
EZFS_DEVRM_IN_PROGRESS, /* a device is currently being removed */
EZFS_VDEV_TOO_BIG, /* a device is too big to be used */
+ EZFS_TOOMANY, /* argument list too long */
+ EZFS_INITIALIZING, /* currently initializing */
+ EZFS_NO_INITIALIZE, /* no active initialize */
EZFS_UNKNOWN
} zfs_error_t;
@@ -262,6 +265,8 @@ typedef struct splitflags {
* Functions to manipulate pool and vdev state
*/
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t);
+extern int zpool_initialize(zpool_handle_t *, pool_initialize_func_t,
+ nvlist_t *);
extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
extern int zpool_reguid(zpool_handle_t *);
extern int zpool_reopen(zpool_handle_t *);
@@ -838,6 +843,17 @@ extern int zmount(const char *, const char *, int, char *, char *, int, char *,
#endif
extern int zfs_remap_indirects(libzfs_handle_t *hdl, const char *);
+/* Allow consumers to initialize libshare externally for optimal performance */
+extern int zfs_init_libshare_arg(libzfs_handle_t *, int, void *);
+/*
+ * For most consumers, zfs_init_libshare_arg is sufficient on its own, and
+ * zfs_uninit_libshare is unnecessary. zfs_uninit_libshare should only be called
+ * if the caller has already initialized libshare for one set of zfs handles,
+ * and wishes to share or unshare filesystems outside of that set. In that case,
+ * the caller should uninitialize libshare, and then re-initialize it with the
+ * new handles being shared or unshared.
+ */
+extern void zfs_uninit_libshare(libzfs_handle_t *);
#ifdef __cplusplus
}
#endif
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
index 277e99e103cc..7bbb68328f29 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
@@ -26,7 +26,7 @@
* Portions Copyright 2007 Ramprakash Jelari
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
- * Copyright (c) 2014, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
*/
@@ -166,6 +166,11 @@ changelist_postfix(prop_changelist_t *clp)
char shareopts[ZFS_MAXPROPLEN];
int errors = 0;
libzfs_handle_t *hdl;
+#ifdef illumos
+ size_t num_datasets = 0, i;
+ zfs_handle_t **zhandle_arr;
+ sa_init_selective_arg_t sharearg;
+#endif
/*
* If we're changing the mountpoint, attempt to destroy the underlying
@@ -192,8 +197,33 @@ changelist_postfix(prop_changelist_t *clp)
hdl = cn->cn_handle->zfs_hdl;
assert(hdl != NULL);
zfs_uninit_libshare(hdl);
- }
+#ifdef illumos
+ /*
+ * For efficiencies sake, we initialize libshare for only a few
+ * shares (the ones affected here). Future initializations in
+ * this process should just use the cached initialization.
+ */
+ for (cn = uu_list_last(clp->cl_list); cn != NULL;
+ cn = uu_list_prev(clp->cl_list, cn)) {
+ num_datasets++;
+ }
+
+ zhandle_arr = zfs_alloc(hdl,
+ num_datasets * sizeof (zfs_handle_t *));
+ for (i = 0, cn = uu_list_last(clp->cl_list); cn != NULL;
+ cn = uu_list_prev(clp->cl_list, cn)) {
+ zhandle_arr[i++] = cn->cn_handle;
+ zfs_refresh_properties(cn->cn_handle);
+ }
+ assert(i == num_datasets);
+ sharearg.zhandle_arr = zhandle_arr;
+ sharearg.zhandle_len = num_datasets;
+ errors = zfs_init_libshare_arg(hdl, SA_INIT_SHARE_API_SELECTIVE,
+ &sharearg);
+ free(zhandle_arr);
+#endif
+ }
/*
* We walk the datasets in reverse, because we want to mount any parent
* datasets before mounting the children. We walk all datasets even if
@@ -218,7 +248,9 @@ changelist_postfix(prop_changelist_t *clp)
continue;
cn->cn_needpost = B_FALSE;
+#ifndef illumos
zfs_refresh_properties(cn->cn_handle);
+#endif
if (ZFS_IS_VOLUME(cn->cn_handle))
continue;
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index 2f25631c5e22..34d49768e49b 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
@@ -50,7 +50,9 @@
#include <pwd.h>
#include <grp.h>
#include <stddef.h>
+#ifdef illumos
#include <idmap.h>
+#endif
#include <sys/dnode.h>
#include <sys/spa.h>
@@ -785,15 +787,13 @@ typedef struct mnttab_node {
static int
libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
{
- const mnttab_node_t *mtn1 = arg1;
- const mnttab_node_t *mtn2 = arg2;
+ const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
+ const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
int rv;
rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
- if (rv == 0)
- return (0);
- return (rv > 0 ? 1 : -1);
+ return (AVL_ISIGN(rv));
}
void
@@ -1407,7 +1407,6 @@ badlabel:
switch (prop) {
case ZFS_PROP_RESERVATION:
- case ZFS_PROP_REFRESERVATION:
if (intval > volsize) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' is greater than current "
@@ -1418,6 +1417,17 @@ badlabel:
}
break;
+ case ZFS_PROP_REFRESERVATION:
+ if (intval > volsize && intval != UINT64_MAX) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' is greater than current "
+ "volume size"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ goto error;
+ }
+ break;
+
case ZFS_PROP_VOLSIZE:
if (intval % blocksize != 0) {
zfs_nicenum(blocksize, buf,
@@ -1519,6 +1529,61 @@ zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
return (1);
}
+/*
+ * Helper for 'zfs {set|clone} refreservation=auto'. Must be called after
+ * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinal value.
+ * Return codes must match zfs_add_synthetic_resv().
+ */
+static int
+zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
+{
+ uint64_t volsize;
+ uint64_t resvsize;
+ zfs_prop_t prop;
+ nvlist_t *props;
+
+ if (!ZFS_IS_VOLUME(zhp)) {
+ return (0);
+ }
+
+ if (zfs_which_resv_prop(zhp, &prop) != 0) {
+ return (-1);
+ }
+
+ if (prop != ZFS_PROP_REFRESERVATION) {
+ return (0);
+ }
+
+ if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) {
+ /* No value being set, so it can't be "auto" */
+ return (0);
+ }
+ if (resvsize != UINT64_MAX) {
+ /* Being set to a value other than "auto" */
+ return (0);
+ }
+
+ props = fnvlist_alloc();
+
+ fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+ zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
+
+ if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
+ &volsize) != 0) {
+ volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
+ }
+
+ resvsize = zvol_volsize_to_reservation(volsize, props);
+ fnvlist_free(props);
+
+ (void) nvlist_remove_all(nvl, zfs_prop_to_name(prop));
+ if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) {
+ (void) no_memory(zhp->zfs_hdl);
+ return (-1);
+ }
+ return (1);
+}
+
void
zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
char *errbuf)
@@ -1685,6 +1750,12 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
goto error;
}
}
+
+ if (added_resv != 1 &&
+ (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) {
+ goto error;
+ }
+
/*
* Check how many properties we're setting and allocate an array to
* store changelist pointers for postfix().
@@ -2711,6 +2782,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
break;
case ZFS_PROP_GUID:
+ case ZFS_PROP_CREATETXG:
/*
* GUIDs are stored as numbers, but they are identifiers.
* We don't want them to be pretty printed, because pretty
@@ -3376,8 +3448,22 @@ zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
{
int prefix;
char *path_copy;
+ char errbuf[1024];
int rc = 0;
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot create '%s'"), path);
+
+ /*
+ * Check that we are not passing the nesting limit
+ * before we start creating any ancestors.
+ */
+ if (dataset_nestcheck(path) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "maximum name nesting depth exceeded"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+
if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
return (-1);
@@ -3413,6 +3499,12 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
if (!zfs_validate_name(hdl, path, type, B_TRUE))
return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ if (dataset_nestcheck(path) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "maximum name nesting depth exceeded"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+
/* validate parents exist */
if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
return (-1);
@@ -3715,6 +3807,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
if (props) {
zfs_type_t type;
+
if (ZFS_IS_VOLUME(zhp)) {
type = ZFS_TYPE_VOLUME;
} else {
@@ -3723,6 +3816,10 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
if ((props = zfs_valid_proplist(hdl, type, props, zoned,
zhp, zhp->zpool_hdl, errbuf)) == NULL)
return (-1);
+ if (zfs_fix_auto_resv(zhp, props) == -1) {
+ nvlist_free(props);
+ return (-1);
+ }
}
ret = lzc_clone(target, zhp->zfs_name, props);
@@ -3839,12 +3936,24 @@ zfs_remap_indirects(libzfs_handle_t *hdl, const char *fs)
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot remap filesystem '%s' "), fs);
+ "cannot remap dataset '%s'"), fs);
err = lzc_remap(fs);
if (err != 0) {
- (void) zfs_standard_error(hdl, err, errbuf);
+ switch (err) {
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error(hdl, err, errbuf);
+ break;
+ }
}
return (err);
@@ -4196,6 +4305,7 @@ zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
errbuf));
}
}
+
if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
} else {
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c
index 840c814ff4c0..c36067389585 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2015, 2017 by Delphix. All rights reserved.
* Copyright 2016 Joyent, Inc.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
*/
@@ -101,7 +101,10 @@ get_stats_for_obj(differ_info_t *di, const char *dsname, uint64_t obj,
return (0);
}
- if (di->zerr == EPERM) {
+ if (di->zerr == ESTALE) {
+ (void) snprintf(pn, maxlen, "(on_delete_queue)");
+ return (0);
+ } else if (di->zerr == EPERM) {
(void) snprintf(di->errbuf, sizeof (di->errbuf),
dgettext(TEXT_DOMAIN,
"The sys_config privilege or diff delegated permission "
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
index 522a7e63f051..bdb9ffeadf75 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
@@ -207,7 +207,6 @@ void namespace_clear(libzfs_handle_t *);
*/
extern int zfs_init_libshare(libzfs_handle_t *, int);
-extern void zfs_uninit_libshare(libzfs_handle_t *);
extern int zfs_parse_options(char *, zfs_share_proto_t);
extern int zfs_unshare_proto(zfs_handle_t *,
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
index 8af6351d9f37..664f6b42df9e 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
@@ -33,7 +33,7 @@
* ZFS label of each device. If we successfully read the label, then we
* organize the configuration information in the following hierarchy:
*
- * pool guid -> toplevel vdev guid -> label txg
+ * pool guid -> toplevel vdev guid -> label txg
*
* Duplicate entries matching this same tuple will be discarded. Once we have
* examined every device, we pick the best label txg config for each toplevel
@@ -245,7 +245,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
ne->ne_next = pl->names;
pl->names = ne;
- nvlist_free(config);
return (0);
}
@@ -265,7 +264,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
&top_guid) != 0 ||
nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0) {
- nvlist_free(config);
return (0);
}
@@ -280,7 +278,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
if (pe == NULL) {
if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) {
- nvlist_free(config);
return (-1);
}
pe->pe_guid = pool_guid;
@@ -299,7 +296,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
if (ve == NULL) {
if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) {
- nvlist_free(config);
return (-1);
}
ve->ve_guid = top_guid;
@@ -319,15 +315,12 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
if (ce == NULL) {
if ((ce = zfs_alloc(hdl, sizeof (config_entry_t))) == NULL) {
- nvlist_free(config);
return (-1);
}
ce->ce_txg = txg;
- ce->ce_config = config;
+ ce->ce_config = fnvlist_dup(config);
ce->ce_next = ve->ve_configs;
ve->ve_configs = ce;
- } else {
- nvlist_free(config);
}
/*
@@ -1396,9 +1389,7 @@ skipdir:
&this_guid) == 0 &&
iarg->guid == this_guid;
}
- if (!matched) {
- nvlist_free(config);
- } else {
+ if (matched) {
/*
* use the non-raw path for the config
*/
@@ -1408,6 +1399,7 @@ skipdir:
config) != 0)
config_failed = B_TRUE;
}
+ nvlist_free(config);
}
free(slice->rn_name);
free(slice);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
index 433fea3ef51d..6bca98816f7c 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
@@ -272,12 +272,7 @@ zfs_snapshot_compare(const void *larg, const void *rarg)
lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
- if (lcreate < rcreate)
- return (-1);
- else if (lcreate > rcreate)
- return (+1);
- else
- return (0);
+ return (AVL_CMP(lcreate, rcreate));
}
int
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
index 84b716794ac3..d8723d37d385 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
@@ -579,6 +579,7 @@ zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
#ifdef illumos
static sa_handle_t (*_sa_init)(int);
+static sa_handle_t (*_sa_init_arg)(int, void *);
static void (*_sa_fini)(sa_handle_t);
static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
static int (*_sa_enable_share)(sa_share_t, char *);
@@ -620,6 +621,8 @@ _zfs_init_libshare(void)
if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
_sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
+ _sa_init_arg = (sa_handle_t (*)(int, void *))dlsym(libshare,
+ "sa_init_arg");
_sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
_sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
dlsym(libshare, "sa_find_share");
@@ -639,14 +642,15 @@ _zfs_init_libshare(void)
char *, char *))dlsym(libshare, "sa_zfs_process_share");
_sa_update_sharetab_ts = (void (*)(sa_handle_t))
dlsym(libshare, "sa_update_sharetab_ts");
- if (_sa_init == NULL || _sa_fini == NULL ||
- _sa_find_share == NULL || _sa_enable_share == NULL ||
- _sa_disable_share == NULL || _sa_errorstr == NULL ||
- _sa_parse_legacy_options == NULL ||
+ if (_sa_init == NULL || _sa_init_arg == NULL ||
+ _sa_fini == NULL || _sa_find_share == NULL ||
+ _sa_enable_share == NULL || _sa_disable_share == NULL ||
+ _sa_errorstr == NULL || _sa_parse_legacy_options == NULL ||
_sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
_sa_zfs_process_share == NULL ||
_sa_update_sharetab_ts == NULL) {
_sa_init = NULL;
+ _sa_init_arg = NULL;
_sa_fini = NULL;
_sa_disable_share = NULL;
_sa_enable_share = NULL;
@@ -670,8 +674,8 @@ _zfs_init_libshare(void)
* service value is which part(s) of the API to initialize and is a
* direct map to the libshare sa_init(service) interface.
*/
-int
-zfs_init_libshare(libzfs_handle_t *zhandle, int service)
+static int
+zfs_init_libshare_impl(libzfs_handle_t *zhandle, int service, void *arg)
{
#ifdef illumos
/*
@@ -694,11 +698,11 @@ zfs_init_libshare(libzfs_handle_t *zhandle, int service)
if (_sa_needs_refresh != NULL &&
_sa_needs_refresh(zhandle->libzfs_sharehdl)) {
zfs_uninit_libshare(zhandle);
- zhandle->libzfs_sharehdl = _sa_init(service);
+ zhandle->libzfs_sharehdl = _sa_init_arg(service, arg);
}
if (zhandle && zhandle->libzfs_sharehdl == NULL)
- zhandle->libzfs_sharehdl = _sa_init(service);
+ zhandle->libzfs_sharehdl = _sa_init_arg(service, arg);
if (zhandle->libzfs_sharehdl == NULL)
return (SA_NO_MEMORY);
@@ -706,6 +710,18 @@ zfs_init_libshare(libzfs_handle_t *zhandle, int service)
return (SA_OK);
}
+int
+zfs_init_libshare(libzfs_handle_t *zhandle, int service)
+{
+ return (zfs_init_libshare_impl(zhandle, service, NULL));
+}
+
+int
+zfs_init_libshare_arg(libzfs_handle_t *zhandle, int service, void *arg)
+{
+ return (zfs_init_libshare_impl(zhandle, service, arg));
+}
+
/*
* zfs_uninit_libshare(zhandle)
@@ -817,9 +833,9 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
ZFS_MAXPROPLEN, B_FALSE) != 0 ||
strcmp(shareopts, "off") == 0)
continue;
-
#ifdef illumos
- ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API);
+ ret = zfs_init_libshare_arg(hdl, SA_INIT_ONE_SHARE_FROM_HANDLE,
+ zhp);
if (ret != SA_OK) {
(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
@@ -930,6 +946,7 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
sa_share_t share;
int err;
char *mntpt;
+
/*
* Mountpoint could get trashed if libshare calls getmntany
* which it does during API initialization, so strdup the
@@ -937,8 +954,14 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
*/
mntpt = zfs_strdup(hdl, mountpoint);
- /* make sure libshare initialized */
- if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
+ /*
+ * make sure libshare initialized, initialize everything because we
+ * don't know what other unsharing may happen later. Functions up the
+ * stack are allowed to initialize instead a subset of shares at the
+ * time the set is known.
+ */
+ if ((err = zfs_init_libshare_arg(hdl, SA_INIT_ONE_SHARE_FROM_NAME,
+ (void *)name)) != SA_OK) {
free(mntpt); /* don't need the copy anymore */
return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
@@ -1289,6 +1312,9 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
int i;
int ret = -1;
int flags = (force ? MS_FORCE : 0);
+#ifdef illumos
+ sa_init_selective_arg_t sharearg;
+#endif
namelen = strlen(zhp->zpool_name);
@@ -1363,6 +1389,14 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
* At this point, we have the entire list of filesystems, so sort it by
* mountpoint.
*/
+#ifdef illumos
+ sharearg.zhandle_arr = datasets;
+ sharearg.zhandle_len = used;
+ ret = zfs_init_libshare_arg(hdl, SA_INIT_SHARE_API_SELECTIVE,
+ &sharearg);
+ if (ret != 0)
+ goto out;
+#endif
qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
/*
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index 1eec116b9fa7..392ed3cfa868 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -1981,6 +1981,100 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
}
}
+static int
+xlate_init_err(int err)
+{
+ switch (err) {
+ case ENODEV:
+ return (EZFS_NODEVICE);
+ case EINVAL:
+ case EROFS:
+ return (EZFS_BADDEV);
+ case EBUSY:
+ return (EZFS_INITIALIZING);
+ case ESRCH:
+ return (EZFS_NO_INITIALIZE);
+ }
+ return (err);
+}
+
+/*
+ * Begin, suspend, or cancel the initialization (initializing of all free
+ * blocks) for the given vdevs in the given pool.
+ */
+int
+zpool_initialize(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
+ nvlist_t *vds)
+{
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ nvlist_t *errlist;
+
+ /* translate vdev names to guids */
+ nvlist_t *vdev_guids = fnvlist_alloc();
+ nvlist_t *guids_to_paths = fnvlist_alloc();
+ boolean_t spare, cache;
+ nvlist_t *tgt;
+ nvpair_t *elem;
+
+ for (elem = nvlist_next_nvpair(vds, NULL); elem != NULL;
+ elem = nvlist_next_nvpair(vds, elem)) {
+ char *vd_path = nvpair_name(elem);
+ tgt = zpool_find_vdev(zhp, vd_path, &spare, &cache, NULL);
+
+ if ((tgt == NULL) || cache || spare) {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot initialize '%s'"),
+ vd_path);
+ int err = (tgt == NULL) ? EZFS_NODEVICE :
+ (spare ? EZFS_ISSPARE : EZFS_ISL2CACHE);
+ fnvlist_free(vdev_guids);
+ fnvlist_free(guids_to_paths);
+ return (zfs_error(hdl, err, msg));
+ }
+
+ uint64_t guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
+ fnvlist_add_uint64(vdev_guids, vd_path, guid);
+
+ (void) snprintf(msg, sizeof (msg), "%llu", guid);
+ fnvlist_add_string(guids_to_paths, msg, vd_path);
+ }
+
+ int err = lzc_initialize(zhp->zpool_name, cmd_type, vdev_guids,
+ &errlist);
+ fnvlist_free(vdev_guids);
+
+ if (err == 0) {
+ fnvlist_free(guids_to_paths);
+ return (0);
+ }
+
+ nvlist_t *vd_errlist = NULL;
+ if (errlist != NULL) {
+ vd_errlist = fnvlist_lookup_nvlist(errlist,
+ ZPOOL_INITIALIZE_VDEVS);
+ }
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "operation failed"));
+
+ for (elem = nvlist_next_nvpair(vd_errlist, NULL); elem != NULL;
+ elem = nvlist_next_nvpair(vd_errlist, elem)) {
+ int64_t vd_error = xlate_init_err(fnvpair_value_int64(elem));
+ char *path = fnvlist_lookup_string(guids_to_paths,
+ nvpair_name(elem));
+ (void) zfs_error_fmt(hdl, vd_error, "cannot initialize '%s'",
+ path);
+ }
+
+ fnvlist_free(guids_to_paths);
+ if (vd_errlist != NULL)
+ return (-1);
+
+ return (zpool_standard_error(hdl, err, msg));
+}
+
#ifdef illumos
/*
* This provides a very minimal check whether a given string is likely a
@@ -2836,7 +2930,7 @@ zpool_vdev_attach(zpool_handle_t *zhp,
case EBUSY:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy, "
- "or pool has removing/removed vdevs"),
+ "or device removal is in progress"),
new_disk);
(void) zfs_error(hdl, EZFS_BADDEV, msg);
break;
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
index a0e06c032791..2368fda9f681 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
@@ -489,15 +489,10 @@ typedef struct fsavl_node {
static int
fsavl_compare(const void *arg1, const void *arg2)
{
- const fsavl_node_t *fn1 = arg1;
- const fsavl_node_t *fn2 = arg2;
+ const fsavl_node_t *fn1 = (const fsavl_node_t *)arg1;
+ const fsavl_node_t *fn2 = (const fsavl_node_t *)arg2;
- if (fn1->fn_guid > fn2->fn_guid)
- return (+1);
- else if (fn1->fn_guid < fn2->fn_guid)
- return (-1);
- else
- return (0);
+ return (AVL_CMP(fn1->fn_guid, fn2->fn_guid));
}
/*
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
index 822c3af26ad0..faf00486751c 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2018 Joyent, Inc.
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright (c) 2017 Datto Inc.
@@ -254,6 +254,13 @@ libzfs_error_description(libzfs_handle_t *hdl)
return (dgettext(TEXT_DOMAIN, "device removal in progress"));
case EZFS_VDEV_TOO_BIG:
return (dgettext(TEXT_DOMAIN, "device exceeds supported size"));
+ case EZFS_TOOMANY:
+ return (dgettext(TEXT_DOMAIN, "argument list too long"));
+ case EZFS_INITIALIZING:
+ return (dgettext(TEXT_DOMAIN, "currently initializing"));
+ case EZFS_NO_INITIALIZE:
+ return (dgettext(TEXT_DOMAIN, "there is no active "
+ "initialization"));
case EZFS_UNKNOWN:
return (dgettext(TEXT_DOMAIN, "unknown error"));
default:
@@ -1227,6 +1234,7 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
const char *propname;
char *value;
boolean_t isnone = B_FALSE;
+ boolean_t isauto = B_FALSE;
if (type == ZFS_TYPE_POOL) {
proptype = zpool_prop_get_type(prop);
@@ -1262,8 +1270,9 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
(void) nvpair_value_string(elem, &value);
if (strcmp(value, "none") == 0) {
isnone = B_TRUE;
- } else if (zfs_nicestrtonum(hdl, value, ivalp)
- != 0) {
+ } else if (strcmp(value, "auto") == 0) {
+ isauto = B_TRUE;
+ } else if (zfs_nicestrtonum(hdl, value, ivalp) != 0) {
goto error;
}
} else if (datatype == DATA_TYPE_UINT64) {
@@ -1293,6 +1302,31 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
*ivalp = UINT64_MAX;
}
+
+ /*
+ * Special handling for setting 'refreservation' to 'auto'. Use
+ * UINT64_MAX to tell the caller to use zfs_fix_auto_resv().
+ * 'auto' is only allowed on volumes.
+ */
+ if (isauto) {
+ switch (prop) {
+ case ZFS_PROP_REFRESERVATION:
+ if ((type & ZFS_TYPE_VOLUME) == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s=auto' only allowed on "
+ "volumes"), nvpair_name(elem));
+ goto error;
+ }
+ *ivalp = UINT64_MAX;
+ break;
+ default:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'auto' is invalid value for '%s'"),
+ nvpair_name(elem));
+ goto error;
+ }
+ }
+
break;
case PROP_TYPE_INDEX:
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 3dda53395a1f..61fb4af24194 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
@@ -1085,3 +1085,40 @@ lzc_channel_program_nosync(const char *pool, const char *program,
return (lzc_channel_program_impl(pool, program, B_FALSE, timeout,
memlimit, argnvl, outnvl));
}
+
+/*
+ * Changes initializing state.
+ *
+ * vdevs should be a list of (<key>, guid) where guid is a uint64 vdev GUID.
+ * The key is ignored.
+ *
+ * If there are errors related to vdev arguments, per-vdev errors are returned
+ * in an nvlist with the key "vdevs". Each error is a (guid, errno) pair where
+ * guid is stringified with PRIu64, and errno is one of the following as
+ * an int64_t:
+ * - ENODEV if the device was not found
+ * - EINVAL if the devices is not a leaf or is not concrete (e.g. missing)
+ * - EROFS if the device is not writeable
+ * - EBUSY start requested but the device is already being initialized
+ * - ESRCH cancel/suspend requested but device is not being initialized
+ *
+ * If the errlist is empty, then return value will be:
+ * - EINVAL if one or more arguments was invalid
+ * - Other spa_open failures
+ * - 0 if the operation succeeded
+ */
+int
+lzc_initialize(const char *poolname, pool_initialize_func_t cmd_type,
+ nvlist_t *vdevs, nvlist_t **errlist)
+{
+ int error;
+ nvlist_t *args = fnvlist_alloc();
+ fnvlist_add_uint64(args, ZPOOL_INITIALIZE_COMMAND, (uint64_t)cmd_type);
+ fnvlist_add_nvlist(args, ZPOOL_INITIALIZE_VDEVS, vdevs);
+
+ error = lzc_ioctl(ZFS_IOC_POOL_INITIALIZE, poolname, args, errlist);
+
+ fnvlist_free(args);
+
+ return (error);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
index 0eaa89cc1e9e..24781cb0fd68 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
@@ -31,6 +31,8 @@
#include <libnvpair.h>
#include <sys/param.h>
#include <sys/types.h>
+#include <sys/fs/zfs.h>
+
#ifdef __cplusplus
extern "C" {
@@ -56,6 +58,8 @@ int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **);
int lzc_bookmark(nvlist_t *, nvlist_t **);
int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **);
int lzc_destroy_bookmarks(nvlist_t *, nvlist_t **);
+int lzc_initialize(const char *, pool_initialize_func_t, nvlist_t *,
+ nvlist_t **);
int lzc_snaprange_space(const char *, const char *, uint64_t *);
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 060d9a094ba1..e93ca2f4ad7b 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
@@ -670,6 +670,9 @@ extern zoneid_t getzoneid(void);
#define root_mount_wait() do { } while (0)
#define root_mounted() (1)
+#define noinline __attribute__((noinline))
+#define likely(x) __builtin_expect((x), 1)
+
struct file {
void *dummy;
};
diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile
index c33a8c2dd882..13cf557ad53e 100644
--- a/cddl/lib/libdtrace/Makefile
+++ b/cddl/lib/libdtrace/Makefile
@@ -56,6 +56,7 @@ DSRCS= errno.d \
tcp.d \
socket.d \
udp.d \
+ udplite.d \
unistd.d
FILES= ${DSRCS}
diff --git a/cddl/lib/libdtrace/ip.d b/cddl/lib/libdtrace/ip.d
index d413a300284c..f591a965af68 100644
--- a/cddl/lib/libdtrace/ip.d
+++ b/cddl/lib/libdtrace/ip.d
@@ -167,6 +167,8 @@ inline short IPPROTO_IPCOMP = 108;
inline short IPPROTO_SCTP = 132;
#pragma D binding "1.5" IPPROTO_RAW
inline short IPPROTO_RAW = 255;
+#pragma D binding "1.13" IPPROTO_UDPLITE
+inline short IPPROTO_UDPLITE = 136;
inline uint8_t INP_IPV4 = 0x01;
inline uint8_t INP_IPV6 = 0x02;
@@ -193,6 +195,7 @@ inline string protocols[int proto] =
proto == IPPROTO_PIM ? "PIM" :
proto == IPPROTO_IPCOMP ? "IPCOMP" :
proto == IPPROTO_SCTP ? "SCTP" :
+ proto == IPPROTO_UDPLITE ? "UDPLITE" :
proto == IPPROTO_RAW ? "RAW" :
"<unknown>";
diff --git a/cddl/lib/libdtrace/udplite.d b/cddl/lib/libdtrace/udplite.d
new file mode 100644
index 000000000000..e41a6faa36a8
--- /dev/null
+++ b/cddl/lib/libdtrace/udplite.d
@@ -0,0 +1,77 @@
+/*
+ * 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>
+ * Copyright (c) 2018 Michael Tuexen <tuexen@FreeBSD.org>
+ */
+
+#pragma D depends_on library ip.d
+#pragma D depends_on module kernel
+#pragma D depends_on provider udplite
+
+/*
+ * udplitesinfo contains stable UDPLite details.
+ */
+typedef struct udplitesinfo {
+ uintptr_t udplites_addr;
+ uint16_t udplites_lport; /* local port */
+ uint16_t udplites_rport; /* remote port */
+ string udplites_laddr; /* local address, as a string */
+ string udplites_raddr; /* remote address, as a string */
+} udplitesinfo_t;
+
+/*
+ * udpliteinfo is the UDPLite header fields.
+ */
+typedef struct udpliteinfo {
+ uint16_t udplite_sport; /* source port */
+ uint16_t udplite_dport; /* destination port */
+ uint16_t udplite_coverage; /* checksum coverage */
+ uint16_t udplite_checksum; /* headers + data checksum */
+ struct udplitehdr *udplite_hdr; /* raw UDPLite header */
+} udpliteinfo_t;
+
+#pragma D binding "1.13" translator
+translator udplitesinfo_t < struct inpcb *p > {
+ udplites_addr = (uintptr_t)p;
+ udplites_lport = p == NULL ? 0 : ntohs(p->inp_inc.inc_ie.ie_lport);
+ udplites_rport = p == NULL ? 0 : ntohs(p->inp_inc.inc_ie.ie_fport);
+ udplites_laddr = p == NULL ? "<unknown>" :
+ p->inp_vflag == INP_IPV4 ?
+ inet_ntoa(&p->inp_inc.inc_ie.ie_dependladdr.id46_addr.ia46_addr4.s_addr) :
+ inet_ntoa6(&p->inp_inc.inc_ie.ie_dependladdr.id6_addr);
+ udplites_raddr = p == NULL ? "<unknown>" :
+ p->inp_vflag == INP_IPV4 ?
+ inet_ntoa(&p->inp_inc.inc_ie.ie_dependfaddr.id46_addr.ia46_addr4.s_addr) :
+ inet_ntoa6(&p->inp_inc.inc_ie.ie_dependfaddr.id6_addr);
+};
+
+#pragma D binding "1.13" translator
+translator udpliteinfo_t < struct udphdr *p > {
+ udplite_sport = p == NULL ? 0 : ntohs(p->uh_sport);
+ udplite_dport = p == NULL ? 0 : ntohs(p->uh_dport);
+ udplite_coverage = p == NULL ? 0 : ntohs(p->uh_ulen);
+ udplite_checksum = p == NULL ? 0 : ntohs(p->uh_sum);
+ udplite_hdr = (struct udplitehdr *)p;
+};
diff --git a/cddl/lib/libzfs/Makefile b/cddl/lib/libzfs/Makefile
index c873f3e80d77..73013bdd887c 100644
--- a/cddl/lib/libzfs/Makefile
+++ b/cddl/lib/libzfs/Makefile
@@ -50,7 +50,6 @@ CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
diff --git a/cddl/lib/libzfs_core/Makefile b/cddl/lib/libzfs_core/Makefile
index 0df1d0c8920b..6728f63104fb 100644
--- a/cddl/lib/libzfs_core/Makefile
+++ b/cddl/lib/libzfs_core/Makefile
@@ -25,7 +25,6 @@ CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
diff --git a/cddl/lib/libzpool/Makefile b/cddl/lib/libzpool/Makefile
index 920cf865aa45..c3e64911ebd8 100644
--- a/cddl/lib/libzpool/Makefile
+++ b/cddl/lib/libzpool/Makefile
@@ -47,7 +47,6 @@ CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
diff --git a/cddl/sbin/zfs/Makefile b/cddl/sbin/zfs/Makefile
index 9d6075e6ad8f..f07b7a33b41e 100644
--- a/cddl/sbin/zfs/Makefile
+++ b/cddl/sbin/zfs/Makefile
@@ -19,7 +19,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libumem/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
LIBADD= jail nvpair uutil zfs_core zfs
diff --git a/cddl/sbin/zpool/Makefile b/cddl/sbin/zpool/Makefile
index 723bb754503a..0276258dcaf5 100644
--- a/cddl/sbin/zpool/Makefile
+++ b/cddl/sbin/zpool/Makefile
@@ -23,7 +23,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/cmd/stat/common
diff --git a/cddl/usr.bin/zinject/Makefile b/cddl/usr.bin/zinject/Makefile
index 1cc403fbbd1f..5cfd7e29edb0 100644
--- a/cddl/usr.bin/zinject/Makefile
+++ b/cddl/usr.bin/zinject/Makefile
@@ -15,7 +15,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs/
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
diff --git a/cddl/usr.bin/zstreamdump/Makefile b/cddl/usr.bin/zstreamdump/Makefile
index d6b5e30972c8..7f759caa74e2 100644
--- a/cddl/usr.bin/zstreamdump/Makefile
+++ b/cddl/usr.bin/zstreamdump/Makefile
@@ -13,7 +13,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile
index 367512999c41..4631ae2c6210 100644
--- a/cddl/usr.bin/ztest/Makefile
+++ b/cddl/usr.bin/ztest/Makefile
@@ -14,7 +14,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
diff --git a/cddl/usr.sbin/dtrace/tests/common/ip/Makefile b/cddl/usr.sbin/dtrace/tests/common/ip/Makefile
index 805c31f6cde4..c47aac901cb4 100644
--- a/cddl/usr.sbin/dtrace/tests/common/ip/Makefile
+++ b/cddl/usr.sbin/dtrace/tests/common/ip/Makefile
@@ -13,12 +13,16 @@ ${PACKAGE}FILES= \
tst.ipv4localtcp.ksh.out \
tst.ipv4localudp.ksh \
tst.ipv4localudp.ksh.out \
+ tst.ipv4localudplite.ksh \
+ tst.ipv4localudplite.ksh.out \
tst.ipv4remoteicmp.ksh \
tst.ipv4remoteicmp.ksh.out \
tst.ipv4remotetcp.ksh \
tst.ipv4remotetcp.ksh.out \
tst.ipv4remoteudp.ksh \
tst.ipv4remoteudp.ksh.out \
+ tst.ipv4remoteudplite.ksh \
+ tst.ipv4remoteudplite.ksh.out \
tst.ipv6localicmp.ksh \
tst.ipv6localicmp.ksh.out \
tst.ipv6remoteicmp.ksh \
diff --git a/cddl/usr.sbin/dtrace/tests/tools/exclude.sh b/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
index f7d856940d17..1a4d8bd7cdb9 100755
--- a/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
+++ b/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
@@ -119,6 +119,7 @@ exclude SKIP common/builtinvar/tst.ipl1.d
# These tests rely on being able to find a host via broadcast pings.
exclude EXFAIL common/ip/tst.ipv4remotetcp.ksh
exclude EXFAIL common/ip/tst.ipv4remoteudp.ksh
+exclude EXFAIL common/ip/tst.ipv4remoteudplite.ksh
exclude EXFAIL common/ip/tst.ipv6remoteicmp.ksh
exclude EXFAIL common/ip/tst.ipv4remoteicmp.ksh
exclude EXFAIL common/ip/tst.remotetcpstate.ksh
diff --git a/cddl/usr.sbin/dwatch/libexec/Makefile b/cddl/usr.sbin/dwatch/libexec/Makefile
index b0d3940914e0..eeba83eef3da 100644
--- a/cddl/usr.sbin/dwatch/libexec/Makefile
+++ b/cddl/usr.sbin/dwatch/libexec/Makefile
@@ -14,6 +14,7 @@ FILES= chmod \
sendrecv \
tcp \
udp \
+ udplite \
vop_create \
vop_readdir \
vop_rename \
@@ -78,6 +79,8 @@ LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-state-change
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-status
LINKS+= ${LIBEXECDIR}/dwatch/udp ${LIBEXECDIR}/dwatch/udp-receive
LINKS+= ${LIBEXECDIR}/dwatch/udp ${LIBEXECDIR}/dwatch/udp-send
+LINKS+= ${LIBEXECDIR}/dwatch/udplite ${LIBEXECDIR}/dwatch/udplite-receive
+LINKS+= ${LIBEXECDIR}/dwatch/udplite ${LIBEXECDIR}/dwatch/udplite-send
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_lookup
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_mkdir
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_mknod
diff --git a/cddl/usr.sbin/dwatch/libexec/udplite b/cddl/usr.sbin/dwatch/libexec/udplite
new file mode 100644
index 000000000000..093c0857f865
--- /dev/null
+++ b/cddl/usr.sbin/dwatch/libexec/udplite
@@ -0,0 +1,89 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_udplite(4) $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display local/remote UDP addresses/ports and bytes sent/received for UDP I/O
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+udplite) : ${PROBE:=udplite:::send, udplite:::receive} ;;
+ *) : ${PROBE:=udplite:::${PROFILE#udplite-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this string flow;
+this string local;
+this string remote;
+this u_char local6;
+this u_char recv;
+this u_char remote6;
+this uint16_t coverage;
+this uint16_t lport;
+this uint16_t rport;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * dtrace_udplite(4)
+ */
+ this->recv = probename == "receive" ? 1 : 0;
+ this->flow = this->recv ? "<-" : "->";
+
+ /*
+ * ipinfo_t *
+ */
+ this->local = this->recv ? args[2]->ip_daddr : args[2]->ip_saddr;
+ this->remote = this->recv ? args[2]->ip_saddr : args[2]->ip_daddr;
+
+ /*
+ * udpliteinfo_t *
+ */
+ this->coverage = (uint16_t)args[4]->udplite_coverage;
+ this->lport = this->recv ? args[4]->udplite_dport : args[4]->udplite_sport;
+ this->rport = this->recv ? args[4]->udplite_sport : args[4]->udplite_dport;
+
+ /*
+ * IPv6 support
+ */
+ this->local6 = strstr(this->local, ":") != NULL ? 1 : 0;
+ this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0;
+ this->local = strjoin(strjoin(this->local6 ? "[" : "",
+ this->local), this->local6 ? "]" : "");
+ this->remote = strjoin(strjoin(this->remote6 ? "[" : "",
+ this->remote), this->remote6 ? "]" : "");
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print network I/O details
+ */
+ printf("%s:%u %s %s:%u %d byte%s",
+ this->local, this->lport,
+ this->flow,
+ this->remote, this->rport,
+ this->coverage,
+ this->coverage == 1 ? "" : "s");
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
diff --git a/cddl/usr.sbin/zdb/Makefile b/cddl/usr.sbin/zdb/Makefile
index d5c7d254855a..cccfe15c823b 100644
--- a/cddl/usr.sbin/zdb/Makefile
+++ b/cddl/usr.sbin/zdb/Makefile
@@ -20,7 +20,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
diff --git a/cddl/usr.sbin/zfsd/Makefile.common b/cddl/usr.sbin/zfsd/Makefile.common
index 3b1430cea978..061a26a28343 100644
--- a/cddl/usr.sbin/zfsd/Makefile.common
+++ b/cddl/usr.sbin/zfsd/Makefile.common
@@ -28,7 +28,6 @@ INCFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
INCFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
INCFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
INCFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
-INCFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS= -g -DNEED_SOLARIS_BOOLEAN ${INCFLAGS}
diff --git a/cddl/usr.sbin/zhack/Makefile b/cddl/usr.sbin/zhack/Makefile
index 72641c1b8efb..1347111c7c17 100644
--- a/cddl/usr.sbin/zhack/Makefile
+++ b/cddl/usr.sbin/zhack/Makefile
@@ -18,7 +18,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
-CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head