mos_obj_refd(space_map_object(ms->ms_sm));
}
+ if (vd->vdev_root_zap != 0)
+ mos_obj_refd(vd->vdev_root_zap);
+
if (vd->vdev_top_zap != 0) {
mos_obj_refd(vd->vdev_top_zap);
mos_leak_vdev_top_zap(vd);
}
static int
-get_callback_vdev_width_cb(void *zhp_data, nvlist_t *nv, void *data)
+get_callback_vdev_cb(void *zhp_data, nvlist_t *nv, void *data)
{
zpool_handle_t *zhp = zhp_data;
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
- char *vdevname = zpool_vdev_name(g_zfs, zhp, nv,
- cbp->cb_vdevs.cb_name_flags);
+ char *vdevname;
+ const char *type;
int ret;
- /* Adjust the column widths for the vdev properties */
- ret = vdev_expand_proplist(zhp, vdevname, &cbp->cb_proplist);
-
- return (ret);
-}
+ /*
+ * zpool_vdev_name() transforms the root vdev name (i.e., root-0) to the
+ * pool name for display purposes, which is not desired. Fallback to
+ * zpool_vdev_name() when not dealing with the root vdev.
+ */
+ type = fnvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE);
+ if (zhp != NULL && strcmp(type, "root") == 0)
+ vdevname = strdup("root-0");
+ else
+ vdevname = zpool_vdev_name(g_zfs, zhp, nv,
+ cbp->cb_vdevs.cb_name_flags);
-static int
-get_callback_vdev_cb(void *zhp_data, nvlist_t *nv, void *data)
-{
- zpool_handle_t *zhp = zhp_data;
- zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
- char *vdevname = zpool_vdev_name(g_zfs, zhp, nv,
- cbp->cb_vdevs.cb_name_flags);
- int ret;
+ (void) vdev_expand_proplist(zhp, vdevname, &cbp->cb_proplist);
- /* Display the properties */
ret = get_callback_vdev(zhp, vdevname, data);
+ free(vdevname);
+
return (ret);
}
if (cbp->cb_type == ZFS_TYPE_VDEV) {
if (strcmp(cbp->cb_vdevs.cb_names[0], "all-vdevs") == 0) {
- for_each_vdev(zhp, get_callback_vdev_width_cb, data);
for_each_vdev(zhp, get_callback_vdev_cb, data);
} else {
/* Adjust column widths for vdev properties */
int ret;
int c, i;
char *propstr = NULL;
+ char *vdev = NULL;
cb.cb_first = B_TRUE;
} else if (are_all_pools(1, argv)) {
/* The first arg is a pool name */
if ((argc == 2 && strcmp(argv[1], "all-vdevs") == 0) ||
+ (argc == 2 && strcmp(argv[1], "root") == 0) ||
are_vdevs_in_pool(argc - 1, argv + 1, argv[0],
&cb.cb_vdevs)) {
+
+ if (strcmp(argv[1], "root") == 0)
+ vdev = strdup("root-0");
+ else
+ vdev = strdup(argv[1]);
+
/* ... and the rest are vdev names */
- cb.cb_vdevs.cb_names = argv + 1;
+ cb.cb_vdevs.cb_names = &vdev;
cb.cb_vdevs.cb_names_count = argc - 1;
cb.cb_type = ZFS_TYPE_VDEV;
argc = 1; /* One pool to process */
else
zprop_free_list(cb.cb_proplist);
+ if (vdev != NULL)
+ free(vdev);
+
return (ret);
}
{
set_cbdata_t cb = { 0 };
int error;
+ char *vdev = NULL;
current_prop_type = ZFS_TYPE_POOL;
if (argc > 1 && argv[1][0] == '-') {
/* argv[1], when supplied, is vdev name */
if (argc == 2) {
- if (!are_vdevs_in_pool(1, argv + 1, argv[0], &cb.cb_vdevs)) {
+
+ if (strcmp(argv[1], "root") == 0)
+ vdev = strdup("root-0");
+ else
+ vdev = strdup(argv[1]);
+
+ if (!are_vdevs_in_pool(1, &vdev, argv[0], &cb.cb_vdevs)) {
(void) fprintf(stderr, gettext(
"cannot find '%s' in '%s': device not in pool\n"),
- argv[1], argv[0]);
+ vdev, argv[0]);
+ free(vdev);
return (EINVAL);
}
- cb.cb_vdevs.cb_names = argv + 1;
+ cb.cb_vdevs.cb_names = &vdev;
cb.cb_vdevs.cb_names_count = 1;
cb.cb_type = ZFS_TYPE_VDEV;
}
error = for_each_pool(1, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
B_FALSE, set_callback, &cb);
+ if (vdev != NULL)
+ free(vdev);
+
return (error);
}
#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read"
#define ZPOOL_CONFIG_FEATURE_STATS "feature_stats" /* not stored on disk */
#define ZPOOL_CONFIG_ERRATA "errata" /* not stored on disk */
+#define ZPOOL_CONFIG_VDEV_ROOT_ZAP "com.klarasystems:vdev_zap_root"
#define ZPOOL_CONFIG_VDEV_TOP_ZAP "com.delphix:vdev_zap_top"
#define ZPOOL_CONFIG_VDEV_LEAF_ZAP "com.delphix:vdev_zap_leaf"
#define ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS "com.delphix:has_per_vdev_zaps"
kthread_t *vdev_open_thread; /* thread opening children */
kthread_t *vdev_validate_thread; /* thread validating children */
uint64_t vdev_crtxg; /* txg when top-level was added */
+ uint64_t vdev_root_zap;
/*
* Top-level vdev state.
SPA_FEATURE_HEAD_ERRLOG,
SPA_FEATURE_BLAKE3,
SPA_FEATURE_BLOCK_CLONING,
+ SPA_FEATURE_AVZ_V2,
SPA_FEATURES
} spa_feature_t;
<elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='spa_feature_table' size='2128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='spa_feature_table' size='2184' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_deleg_perm_tab' size='512' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<enumerator name='SPA_FEATURE_HEAD_ERRLOG' value='35'/>
<enumerator name='SPA_FEATURE_BLAKE3' value='36'/>
<enumerator name='SPA_FEATURE_BLOCK_CLONING' value='37'/>
- <enumerator name='SPA_FEATURES' value='38'/>
+ <enumerator name='SPA_FEATURE_AVZ_V2' value='38'/>
+ <enumerator name='SPA_FEATURES' value='39'/>
</enum-decl>
<typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
<qualified-type-def type-id='22cce67b' const='yes' id='d2816df0'/>
</function-decl>
</abi-instr>
<abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='17024' id='9944fffc'>
- <subrange length='38' type-id='7359adad' id='aa4ccdac'/>
+ <array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='17472' id='dd432c71'>
+ <subrange length='39' type-id='7359adad' id='ae4a9561'/>
</array-type-def>
<enum-decl name='zfeature_flags' id='6db816a4'>
<underlying-type type-id='9cac1fee'/>
<pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
- <var-decl name='spa_feature_table' type-id='9944fffc' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
+ <var-decl name='spa_feature_table' type-id='dd432c71' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
<function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='80f4b756'/>
strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 ||
strncmp(name,
VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 ||
+ strncmp(name, VDEV_TYPE_ROOT, strlen(VDEV_TYPE_ROOT)) == 0 ||
strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
return (B_TRUE);
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
return (ret);
- /* Don't run our function on root or indirect vdevs */
- if ((strcmp(type, VDEV_TYPE_ROOT) != 0) &&
- (strcmp(type, VDEV_TYPE_INDIRECT) != 0)) {
+ /* Don't run our function on indirect vdevs */
+ if (strcmp(type, VDEV_TYPE_INDIRECT) != 0) {
ret |= func(zhp, nv, data);
}
\*[instant-never]
\*[remount-upgrade]
.
+.feature com.klarasystems vdev_zaps_v2 no
+This feature creates a ZAP object for the root vdev.
+.Pp
+This feature becomes active after the next
+.Nm zpool Cm import
+or
+.Nm zpool reguid .
+.
+Properties can be retrieved or set on the root vdev using
+.Nm zpool Cm get
+and
+.Nm zpool Cm set
+with
+.Sy root
+as the vdev name which is an alias for
+.Sy root-0 .
.feature org.openzfs zilsaxattr yes extensible_dataset
This feature enables
.Sy xattr Ns = Ns Sy sa
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
+ zfeature_register(SPA_FEATURE_AVZ_V2,
+ "com.klarasystems:vdev_zaps_v2", "vdev_zaps_v2",
+ "Support for root vdev ZAP.",
+ ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL,
+ sfeatures);
+
zfs_mod_list_supported_free(sfeatures);
}
spa_t *spa = vd->vdev_spa;
uint64_t total = 0;
+ if (spa_feature_is_active(vd->vdev_spa, SPA_FEATURE_AVZ_V2) &&
+ vd->vdev_root_zap != 0) {
+ total++;
+ ASSERT0(zap_lookup_int(spa->spa_meta_objset,
+ spa->spa_all_vdev_zaps, vd->vdev_root_zap));
+ }
if (vd->vdev_top_zap != 0) {
total++;
ASSERT0(zap_lookup_int(spa->spa_meta_objset,
{
spa_t *spa = vd->vdev_spa;
+ if (vd->vdev_root_zap != 0 &&
+ spa_feature_is_active(spa, SPA_FEATURE_AVZ_V2)) {
+ VERIFY0(zap_add_int(spa->spa_meta_objset, avz,
+ vd->vdev_root_zap, tx));
+ }
if (vd->vdev_top_zap != 0) {
VERIFY0(zap_add_int(spa->spa_meta_objset, avz,
vd->vdev_top_zap, tx));
uint64_t objid;
int err;
- if (vd->vdev_top_zap != 0) {
+ if (vd->vdev_root_zap != 0) {
+ objid = vd->vdev_root_zap;
+ } else if (vd->vdev_top_zap != 0) {
objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
objid = vd->vdev_leaf_zap;
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_CREATE_TXG,
&vd->vdev_crtxg);
+ if (vd->vdev_ops == &vdev_root_ops &&
+ (alloctype == VDEV_ALLOC_LOAD ||
+ alloctype == VDEV_ALLOC_SPLIT ||
+ alloctype == VDEV_ALLOC_ROOTPOOL)) {
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_VDEV_ROOT_ZAP,
+ &vd->vdev_root_zap);
+ }
+
/*
* If we're a top-level vdev, try to load the allocation parameters.
*/
vdev_zap_allocation_data(vd, tx);
}
}
+ if (vd->vdev_ops == &vdev_root_ops && vd->vdev_root_zap == 0 &&
+ spa_feature_is_enabled(vd->vdev_spa, SPA_FEATURE_AVZ_V2)) {
+ if (!spa_feature_is_active(vd->vdev_spa, SPA_FEATURE_AVZ_V2))
+ spa_feature_incr(vd->vdev_spa, SPA_FEATURE_AVZ_V2, tx);
+ vd->vdev_root_zap = vdev_create_link_zap(vd, tx);
+ }
for (uint64_t i = 0; i < vd->vdev_children; i++) {
vdev_construct_zaps(vd->vdev_child[i], tx);
/*
* Set vdev property values in the vdev props mos object.
*/
- if (vd->vdev_top_zap != 0) {
+ if (vd->vdev_root_zap != 0) {
+ objid = vd->vdev_root_zap;
+ } else if (vd->vdev_top_zap != 0) {
objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
objid = vd->vdev_leaf_zap;
} else {
- panic("vdev not top or leaf");
+ /*
+ * XXX: implement vdev_props_set_check()
+ */
+ panic("vdev not root/top/leaf");
}
switch (prop = vdev_name_to_prop(propname)) {
nvlist_lookup_nvlist(innvl, ZPOOL_VDEV_PROPS_GET_PROPS, &nvprops);
- if (vd->vdev_top_zap != 0) {
+ if (vd->vdev_root_zap != 0) {
+ objid = vd->vdev_root_zap;
+ } else if (vd->vdev_top_zap != 0) {
objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
objid = vd->vdev_leaf_zap;
vd->vdev_top_zap);
}
+ if (vd->vdev_ops == &vdev_root_ops && vd->vdev_root_zap != 0 &&
+ spa_feature_is_active(vd->vdev_spa, SPA_FEATURE_AVZ_V2)) {
+ fnvlist_add_uint64(nv, ZPOOL_CONFIG_VDEV_ROOT_ZAP,
+ vd->vdev_root_zap);
+ }
+
if (vd->vdev_resilver_deferred) {
ASSERT(vd->vdev_ops->vdev_op_leaf);
ASSERT(spa->spa_resilver_deferred);
[tests/functional/cli_root/zpool_get]
tests = ['zpool_get_001_pos', 'zpool_get_002_pos', 'zpool_get_003_pos',
- 'zpool_get_004_neg', 'zpool_get_005_pos']
+ 'zpool_get_004_neg', 'zpool_get_005_pos', 'vdev_get_001_pos']
tags = ['functional', 'cli_root', 'zpool_get']
[tests/functional/cli_root/zpool_history]
[tests/functional/cli_root/zpool_set]
tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg',
- 'zpool_set_ashift', 'zpool_set_features']
+ 'zpool_set_ashift', 'zpool_set_features', 'vdev_set_001_pos']
tags = ['functional', 'cli_root', 'zpool_set']
[tests/functional/cli_root/zpool_split]
functional/cli_root/zpool_expand/zpool_expand.cfg \
functional/cli_root/zpool_export/zpool_export.cfg \
functional/cli_root/zpool_export/zpool_export.kshlib \
+ functional/cli_root/zpool_get/vdev_get.cfg \
functional/cli_root/zpool_get/zpool_get.cfg \
functional/cli_root/zpool_get/zpool_get_parsable.cfg \
functional/cli_root/zpool_import/blockfiles/cryptv0.dat.bz2 \
functional/cli_root/zpool_export/zpool_export_004_pos.ksh \
functional/cli_root/zpool_get/cleanup.ksh \
functional/cli_root/zpool_get/setup.ksh \
+ functional/cli_root/zpool_get/vdev_get_001_pos.ksh \
functional/cli_root/zpool_get/zpool_get_001_pos.ksh \
functional/cli_root/zpool_get/zpool_get_002_pos.ksh \
functional/cli_root/zpool_get/zpool_get_003_pos.ksh \
functional/cli_root/zpool_set/cleanup.ksh \
functional/cli_root/zpool_set/setup.ksh \
functional/cli_root/zpool/setup.ksh \
+ functional/cli_root/zpool_set/vdev_set_001_pos.ksh \
functional/cli_root/zpool_set/zpool_set_001_pos.ksh \
functional/cli_root/zpool_set/zpool_set_002_neg.ksh \
functional/cli_root/zpool_set/zpool_set_003_neg.ksh \
--- /dev/null
+#
+# 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 https://opensource.org/licenses/CDDL-1.0.
+# 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) 2022, Klara Inc.
+#
+
+# Set the expected properties of a vdev
+typeset -a properties=(
+ capacity
+ state
+ guid
+ asize
+ psize
+ ashift
+ size
+ free
+ allocated
+ comment
+ expandsize
+ fragmentation
+ bootsize
+ parity
+ path
+ devid
+ physpath
+ encpath
+ fru
+ parent
+ children
+ numchildren
+ read_errors
+ write_errors
+ checksum_errors
+ initialize_errors
+ null_ops
+ read_ops
+ write_ops
+ free_ops
+ claim_ops
+ trim_ops
+ null_bytes
+ read_bytes
+ write_bytes
+ free_bytes
+ claim_bytes
+ trim_bytes
+ removing
+ allocating
+ failfast
+ checksum_n
+ checksum_t
+ io_n
+ io_t
+)
--- /dev/null
+#!/bin/ksh -p
+#
+# 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 https://opensource.org/licenses/CDDL-1.0.
+# 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) 2022, Klara Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_get/vdev_get.cfg
+
+#
+# DESCRIPTION:
+#
+# zpool get <pool> root works as expected
+#
+# STRATEGY:
+#
+# 1. use zpool get to retrieve properties from root vdev
+# 2. verify expected properties match detected properties
+#
+
+log_assert "zpool get all on root vdev"
+
+EXPECT="$(zpool get -H all ${TESTPOOL} root | wc -l)"
+if [ $? -ne 0 ]; then
+ log_fail "cannot retrieve properties from root vdev"
+fi
+
+i=0;
+while [ $i -lt "${#properties[@]}" ]
+do
+ log_must zpool get -H "${properties[$i]}" "$TESTPOOL" root
+ i=$(($i+1))
+done
+
+EXPECT=$((EXPECT))
+if [ $i -gt $EXPECT ]; then
+ log_fail "found vdev properties not in vdev_get.cfg: $i/$EXPECT."
+elif [ $i -lt $EXPECT ]; then
+ log_fail "expected properties not found in vdev_get.cfg: $i/$EXPECT."
+fi
+
+log_pass "zpool get all on root vdev"
"feature@head_errlog"
"feature@blake3"
"feature@block_cloning"
+ "feature@vdev_zaps_v2"
)
fi
--- /dev/null
+#!/bin/ksh -p
+#
+# 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 https://opensource.org/licenses/CDDL-1.0.
+# 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) 2022, Klara Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+#
+# zpool set comment property on root vdev
+#
+# STRATEGY:
+# 1. set a property on root vdev
+# 2. verify the property is set
+#
+
+log_assert "zpool set comment property on root vdev"
+
+log_must zpool set comment="openzfs" ${TESTPOOL} root
+
+COMMENT="$(zpool get -H -o value comment ${TESTPOOL} root)"
+if [ $? -ne 0 ]; then
+ log_fail "cant retrieve comment property from root vdev"
+fi
+
+if [ "$COMMENT" != "openzfs" ]; then
+ log_fail "unexpected value for comment property: $COMMENT != \"openzfs\""
+fi
+
+log_pass "zpool set comment property on root vdev"
{
get_conf_section "$1" "$2" | awk '/com.delphix:vdev_zap_top: [0-9]+/ {print $2}'
}
+function get_root_vd_zap # conf
+{
+ awk '/com.klarasystems:vdev_zap_root: [0-9]+/ {print $2}' "$1"
+}
function assert_has_sentinel # conf
{
fi
}
+function assert_root_zap # pool conf
+{
+ typeset pool=$1
+ typeset conf=$2
+
+ root_zap=$(get_root_vd_zap $conf)
+ assert_zap_common $pool "root vdev" "root" $root_zap
+}
+
function assert_top_zap # pool vd conf
{
typeset pool=$1
#
# Strategy:
# 1. Create a pool with one disk.
-# 2. Verify that the disk has a top and leaf ZAP in its config and the MOS.
+# 2. Verify that the disk has a root, top and leaf ZAP in its config and the MOS.
#
. $STF_SUITE/include/libtest.shlib
conf="$TESTDIR/vz001"
log_must eval "zdb -PC $TESTPOOL > $conf"
+assert_root_zap $TESTPOOL "$conf"
assert_top_zap $TESTPOOL $DISK "$conf"
assert_leaf_zap $TESTPOOL $DISK "$conf"
assert_has_sentinel "$conf"
log_must eval "zdb -PC $TESTPOOL > $conf"
assert_has_sentinel "$conf"
+assert_root_zap $TESTPOOL "$conf"
for DISK in $DISKS; do
assert_top_zap $TESTPOOL $DISK "$conf"
assert_leaf_zap $TESTPOOL $DISK "$conf"
log_must eval "zdb -PC $TESTPOOL > $conf"
assert_has_sentinel "$conf"
+assert_root_zap $TESTPOOL "$conf"
assert_top_zap $TESTPOOL "type: 'mirror'" "$conf"
for DISK in $DISKS; do
assert_leaf_zap $TESTPOOL $DISK "$conf"
conf="$TESTDIR/vz004"
log_must eval "zdb -PC $TESTPOOL > $conf"
assert_has_sentinel "$conf"
+assert_root_zap $TESTPOOL "$conf"
orig_top=$(get_top_vd_zap $DISK $conf)
orig_leaf=$(get_leaf_vd_zap $DISK $conf)
assert_zap_common $TESTPOOL $DISK "top" $orig_top
conf="$TESTDIR/vz005"
log_must eval "zdb -PC $TESTPOOL > $conf"
assert_has_sentinel "$conf"
+assert_root_zap $TESTPOOL "$conf"
orig_top=$(get_top_vd_zap $DISK $conf)
orig_leaf=$(get_leaf_vd_zap $DISK $conf)
assert_zap_common $TESTPOOL $DISK "top" $orig_top
log_must eval "zdb -PC $TESTPOOL > $conf"
assert_has_sentinel "$conf"
+assert_root_zap $TESTPOOL "$conf"
orig_top=$(get_top_vd_zap ${DISK_ARR[1]} $conf)
assert_zap_common $TESTPOOL ${DISK_ARR[1]} "top" $orig_top
assert_leaf_zap $TESTPOOL ${DISK_ARR[1]} "$conf"
log_must eval "zdb -PC $TESTPOOL > $conf"
assert_has_sentinel "$conf"
+assert_root_zap $TESTPOOL "$conf"
orig_top=$(get_top_vd_zap "type: 'mirror'" $conf)
orig_leaf0=$(get_leaf_vd_zap ${DISK_ARR[0]} $conf)
orig_leaf1=$(get_leaf_vd_zap ${DISK_ARR[1]} $conf)