Allow for '-o feature@<feature>=disabled' on the command line

Sometimes it is desirable to specifically disable one or several
features directly on the 'zpool create' command line.

$ zpool create -o feature@<feature>=disabled ...

Original-patch-by: Turbo Fredriksson <turbo@bayour.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes #3460 
Closes #5142 
Closes #5324
This commit is contained in:
LOLi 2016-10-26 01:17:47 +02:00 committed by Brian Behlendorf
parent 16fa68f07d
commit e4010f2719
7 changed files with 136 additions and 22 deletions

View File

@ -920,6 +920,7 @@ errout:
* -m Set default mountpoint for the root dataset. By default it's * -m Set default mountpoint for the root dataset. By default it's
* '/<pool>' * '/<pool>'
* -o Set property=value. * -o Set property=value.
* -o Set feature@feature=enabled|disabled.
* -d Don't automatically enable all supported pool features * -d Don't automatically enable all supported pool features
* (individual features can be enabled with -o). * (individual features can be enabled with -o).
* -O Set fsproperty=value in the pool's root file system * -O Set fsproperty=value in the pool's root file system
@ -1188,22 +1189,26 @@ zpool_do_create(int argc, char **argv)
/* /*
* Hand off to libzfs. * Hand off to libzfs.
*/ */
if (enable_all_pool_feat) {
spa_feature_t i; spa_feature_t i;
for (i = 0; i < SPA_FEATURES; i++) { for (i = 0; i < SPA_FEATURES; i++) {
char propname[MAXPATHLEN]; char propname[MAXPATHLEN];
char *propval;
zfeature_info_t *feat = &spa_feature_table[i]; zfeature_info_t *feat = &spa_feature_table[i];
(void) snprintf(propname, sizeof (propname), (void) snprintf(propname, sizeof (propname),
"feature@%s", feat->fi_uname); "feature@%s", feat->fi_uname);
/* /*
* Skip feature if user specified it manually * Only features contained in props will be enabled:
* on the command line. * remove from the nvlist every ZFS_FEATURE_DISABLED
* value and add every missing ZFS_FEATURE_ENABLED if
* enable_all_pool_feat is set.
*/ */
if (nvlist_exists(props, propname)) if (!nvlist_lookup_string(props, propname, &propval)) {
continue; if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
(void) nvlist_remove_all(props,
propname);
} else if (enable_all_pool_feat) {
ret = add_prop_list(propname, ret = add_prop_list(propname,
ZFS_FEATURE_ENABLED, &props, B_TRUE); ZFS_FEATURE_ENABLED, &props, B_TRUE);
if (ret != 0) if (ret != 0)

View File

@ -502,10 +502,11 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
} }
(void) nvpair_value_string(elem, &strval); (void) nvpair_value_string(elem, &strval);
if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) { if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0 &&
strcmp(strval, ZFS_FEATURE_DISABLED) != 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"property '%s' can only be set to " "property '%s' can only be set to "
"'enabled'"), propname); "'enabled' or 'disabled'"), propname);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf); (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error; goto error;
} }

View File

@ -41,8 +41,9 @@ zpool \- configures ZFS storage pools
.LP .LP
.nf .nf
\fBzpool create\fR [\fB-fnd\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR] \fBzpool create\fR [\fB-fnd\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-o\fR feature@\fIfeature=value\fR]
... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] [\fB-t\fR \fItname\fR] \fIpool\fR \fIvdev\fR ... ... [\fB-O\fR \fIfile-system-property=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR]
... [\fB-t\fR \fItname\fR] \fIpool\fR \fIvdev\fR ...
.fi .fi
.LP .LP
@ -877,7 +878,7 @@ Clears device errors in a pool. If no arguments are specified, all device errors
.sp .sp
.ne 2 .ne 2
.na .na
\fB\fBzpool create\fR [\fB-fnd\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] [\fB-t\fR \fItname\fR] \fIpool\fR \fIvdev\fR ...\fR \fB\fBzpool create\fR [\fB-fnd\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-o\fR feature@\fIfeature=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] [\fB-t\fR \fItname\fR] \fIpool\fR \fIvdev\fR ...\fR
.ad .ad
.sp .6 .sp .6
.RS 4n .RS 4n
@ -930,6 +931,18 @@ Do not enable any features on the new pool. Individual features can be enabled b
Sets the given pool properties. See the "Properties" section for a list of valid properties that can be set. Sets the given pool properties. See the "Properties" section for a list of valid properties that can be set.
.RE .RE
.sp
.ne 2
.na
\fB\fB-o\fR feature@\fIfeature=value\fR [\fB-o\fR feature@\fIfeature=value\fR] ...\fR
.ad
.sp .6
.RS 4n
Sets the given pool feature. See \fBzpool-features(5)\fR for a list of valid features that can be set.
.sp
Value can be either \fBdisabled\fR or \fBenabled\fR.
.RE
.sp .sp
.ne 2 .ne 2
.na .na

View File

@ -250,7 +250,8 @@ tests = [
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg', 'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_024_pos', 'zpool_create_024_pos',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos', 'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
'zpool_create_features_003_pos', 'zpool_create_features_004_neg'] 'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
'zpool_create_features_005_pos']
# DISABLED: # DISABLED:
# zpool_destroy_001_pos - failure should be investigated # zpool_destroy_001_pos - failure should be investigated

View File

@ -30,4 +30,5 @@ dist_pkgdata_SCRIPTS = \
zpool_create_features_001_pos.ksh \ zpool_create_features_001_pos.ksh \
zpool_create_features_002_pos.ksh \ zpool_create_features_002_pos.ksh \
zpool_create_features_003_pos.ksh \ zpool_create_features_003_pos.ksh \
zpool_create_features_004_neg.ksh zpool_create_features_004_neg.ksh \
zpool_create_features_005_pos.ksh

View File

@ -39,7 +39,7 @@
verify_runnable "global" verify_runnable "global"
properties="\ properties="\
feature@async_destroy=disabled \ feature@async_destroy=disable \
feature@async_destroy=active \ feature@async_destroy=active \
feature@xxx_fake_xxx=enabled \ feature@xxx_fake_xxx=enabled \
unsupported@some_feature=inactive \ unsupported@some_feature=inactive \

View File

@ -0,0 +1,93 @@
#!/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 http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2012 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_create/zpool_create.shlib
################################################################################
#
# Specifically disabling a feature, all other features should be enabled.
#
# 1. Loop through all existing features:
# a. Create a new pool with '-o feature@XXX=disabled'.
# b. Verify that every other feature is 'enabled' or 'active'.
#
################################################################################
verify_runnable "global"
function cleanup
{
datasetexists $TESTPOOL && log_must $ZPOOL destroy $TESTPOOL
}
function check_features
{
typeset feature="${1}"
${ZPOOL} get all ${TESTPOOL} | $GREP feature@ | while read line; do
set -- $(echo "${line}")
if [[ "feature@${feature}" == "${2}" ]]; then
# Failure passed feature must be disabled.
if [[ "${3}" != "disabled" ]]; then
return 1;
fi
else
# Failure other features must be enabled or active.
if [[ "${3}" != "enabled" && "${3}" != "active" ]]; then
return 2;
fi
fi
done
# All features enabled or active except the expected one.
return 0
}
log_onexit cleanup
# Several representative features are tested to keep the test time short.
# The features 'extensible_dataset' and 'enabled_txg' are intentionally
# excluded because other features depend on them.
set -A features \
"hole_birth" \
"large_blocks" \
"large_dnode" \
"userobj_accounting"
typeset -i i=0
while (( $i < ${#features[*]} )); do
log_assert "'zpool create' creates pools with ${features[i]} disabled"
log_must $ZPOOL create -f -o "feature@${features[i]}=disabled" \
$TESTPOOL $DISKS
log_must check_features "${features[i]}"
log_must $ZPOOL destroy -f $TESTPOOL
(( i = i+1 ))
done
log_pass "'zpool create -o feature@feature=disabled' disables features"