Create zap for root vdev
And add it to the AVZ, this is not backwards compatible with older pools due to an assertion in spa_sync() that verifies the number of ZAPs of all vdevs matches the number of ZAPs in the AVZ. Granted, the assertion only applies to #DEBUG builds - still, a feature flag is introduced to avoid the assertion, com.klarasystems:vdev_zaps_v2 Notably, this allows to get/set properties on the root vdev: % zpool set user:prop=value <pool> root-0 Before this commit, it was already possible to get/set properties on top-level vdevs with the syntax <type>-<vdev_id> (e.g. mirror-0): % zpool set user:prop=value <pool> mirror-0 This syntax also applies to the root vdev as it is is of type 'root' with a vdev_id of 0, root-0. The keyword 'root' as an alias for 'root-0'. The following tests have been added: - zpool get all properties from root vdev - zpool set a property on root vdev - verify root vdev ZAP is created Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Wing <rob.wing@klarasystems.com> Sponsored-by: Seagate Technology Submitted-by: Klara, Inc. Closes #14405
This commit is contained in:
parent
71d191ef25
commit
3e4ed4213d
|
@ -7630,6 +7630,9 @@ mos_leak_vdev(vdev_t *vd)
|
|||
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);
|
||||
|
|
|
@ -10001,33 +10001,33 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
get_callback_vdev_width_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;
|
||||
|
||||
/* Adjust the column widths for the vdev properties */
|
||||
ret = vdev_expand_proplist(zhp, vdevname, &cbp->cb_proplist);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
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);
|
||||
char *vdevname;
|
||||
const char *type;
|
||||
int ret;
|
||||
|
||||
/* Display the properties */
|
||||
/*
|
||||
* 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);
|
||||
|
||||
(void) vdev_expand_proplist(zhp, vdevname, &cbp->cb_proplist);
|
||||
|
||||
ret = get_callback_vdev(zhp, vdevname, data);
|
||||
|
||||
free(vdevname);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -10042,7 +10042,6 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||
|
||||
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 */
|
||||
|
@ -10119,6 +10118,7 @@ zpool_do_get(int argc, char **argv)
|
|||
int ret;
|
||||
int c, i;
|
||||
char *propstr = NULL;
|
||||
char *vdev = NULL;
|
||||
|
||||
cb.cb_first = B_TRUE;
|
||||
|
||||
|
@ -10216,10 +10216,17 @@ found:
|
|||
} 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 */
|
||||
|
@ -10264,6 +10271,9 @@ found:
|
|||
else
|
||||
zprop_free_list(cb.cb_proplist);
|
||||
|
||||
if (vdev != NULL)
|
||||
free(vdev);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -10365,6 +10375,7 @@ zpool_do_set(int argc, char **argv)
|
|||
{
|
||||
set_cbdata_t cb = { 0 };
|
||||
int error;
|
||||
char *vdev = NULL;
|
||||
|
||||
current_prop_type = ZFS_TYPE_POOL;
|
||||
if (argc > 1 && argv[1][0] == '-') {
|
||||
|
@ -10413,13 +10424,20 @@ zpool_do_set(int argc, char **argv)
|
|||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -10427,6 +10445,9 @@ zpool_do_set(int argc, char **argv)
|
|||
error = for_each_pool(1, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
||||
B_FALSE, set_callback, &cb);
|
||||
|
||||
if (vdev != NULL)
|
||||
free(vdev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
@ -816,6 +816,7 @@ typedef struct zpool_load_policy {
|
|||
#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"
|
||||
|
|
|
@ -277,6 +277,7 @@ struct vdev {
|
|||
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.
|
||||
|
|
|
@ -79,6 +79,7 @@ typedef enum spa_feature {
|
|||
SPA_FEATURE_HEAD_ERRLOG,
|
||||
SPA_FEATURE_BLAKE3,
|
||||
SPA_FEATURE_BLOCK_CLONING,
|
||||
SPA_FEATURE_AVZ_V2,
|
||||
SPA_FEATURES
|
||||
} spa_feature_t;
|
||||
|
||||
|
|
|
@ -595,7 +595,7 @@
|
|||
<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'/>
|
||||
|
@ -5808,7 +5808,8 @@
|
|||
<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'/>
|
||||
|
@ -8694,8 +8695,8 @@
|
|||
</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'/>
|
||||
|
@ -8772,7 +8773,7 @@
|
|||
<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'/>
|
||||
|
|
|
@ -2859,6 +2859,7 @@ zpool_vdev_is_interior(const char *name)
|
|||
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);
|
||||
|
||||
|
|
|
@ -1927,9 +1927,8 @@ for_each_vdev_cb(void *zhp, nvlist_t *nv, pool_vdev_iter_f func,
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -858,6 +858,22 @@ by user and group.
|
|||
\*[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
|
||||
|
|
|
@ -731,6 +731,12 @@ zpool_feature_init(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -3044,6 +3044,12 @@ vdev_count_verify_zaps(vdev_t *vd)
|
|||
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,
|
||||
|
@ -8626,6 +8632,11 @@ spa_avz_build(vdev_t *vd, uint64_t avz, dmu_tx_t *tx)
|
|||
{
|
||||
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));
|
||||
|
|
|
@ -397,7 +397,9 @@ vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value)
|
|||
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;
|
||||
|
@ -898,6 +900,14 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
|
|||
(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.
|
||||
*/
|
||||
|
@ -3347,6 +3357,12 @@ vdev_construct_zaps(vdev_t *vd, dmu_tx_t *tx)
|
|||
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);
|
||||
|
@ -5683,12 +5699,17 @@ vdev_props_set_sync(void *arg, dmu_tx_t *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)) {
|
||||
|
@ -5891,7 +5912,9 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
|
||||
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;
|
||||
|
|
|
@ -573,6 +573,12 @@ vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats,
|
|||
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);
|
||||
|
|
|
@ -394,7 +394,7 @@ tags = ['functional', 'cli_root', 'zpool_export']
|
|||
|
||||
[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]
|
||||
|
@ -482,7 +482,7 @@ tags = ['functional', 'cli_root', 'zpool_scrub']
|
|||
|
||||
[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]
|
||||
|
|
|
@ -178,6 +178,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
|
|||
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 \
|
||||
|
@ -1032,6 +1033,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
|||
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 \
|
||||
|
@ -1146,6 +1148,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
|||
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 \
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#
|
||||
# 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
|
||||
)
|
|
@ -0,0 +1,62 @@
|
|||
#!/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"
|
|
@ -104,5 +104,6 @@ if is_linux || is_freebsd; then
|
|||
"feature@head_errlog"
|
||||
"feature@blake3"
|
||||
"feature@block_cloning"
|
||||
"feature@vdev_zaps_v2"
|
||||
)
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/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"
|
|
@ -34,6 +34,10 @@ function get_top_vd_zap # dsk conf
|
|||
{
|
||||
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
|
||||
{
|
||||
|
@ -54,6 +58,15 @@ function assert_zap_common # pool vd lvl zapobj
|
|||
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
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#
|
||||
# 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
|
||||
|
@ -35,6 +35,7 @@ log_must zpool create -f $TESTPOOL $DISK
|
|||
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"
|
||||
|
|
|
@ -36,6 +36,7 @@ conf="$TESTDIR/vz002"
|
|||
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"
|
||||
|
|
|
@ -37,6 +37,7 @@ conf="$TESTDIR/vz003"
|
|||
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"
|
||||
|
|
|
@ -40,6 +40,7 @@ log_must zpool create -f $TESTPOOL $DISK
|
|||
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
|
||||
|
|
|
@ -37,6 +37,7 @@ log_must zpool create -f $TESTPOOL $DISK
|
|||
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
|
||||
|
|
|
@ -39,6 +39,7 @@ conf="$TESTDIR/vz006"
|
|||
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"
|
||||
|
|
|
@ -39,6 +39,7 @@ conf="$TESTDIR/vz007"
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue