aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zpool/zpool_main.c33
-rw-r--r--lib/libzfs/libzfs_pool.c5
-rw-r--r--man/man8/zpool.819
-rw-r--r--tests/runfiles/linux.run3
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am3
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_004_neg.ksh2
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_005_pos.ksh93
7 files changed, 136 insertions, 22 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c
index 3431ec67a..b6702f22c 100644
--- a/cmd/zpool/zpool_main.c
+++ b/cmd/zpool/zpool_main.c
@@ -920,6 +920,7 @@ errout:
* -m Set default mountpoint for the root dataset. By default it's
* '/<pool>'
* -o Set property=value.
+ * -o Set feature@feature=enabled|disabled.
* -d Don't automatically enable all supported pool features
* (individual features can be enabled with -o).
* -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.
*/
- if (enable_all_pool_feat) {
- spa_feature_t i;
- for (i = 0; i < SPA_FEATURES; i++) {
- char propname[MAXPATHLEN];
- zfeature_info_t *feat = &spa_feature_table[i];
-
- (void) snprintf(propname, sizeof (propname),
- "feature@%s", feat->fi_uname);
+ spa_feature_t i;
+ for (i = 0; i < SPA_FEATURES; i++) {
+ char propname[MAXPATHLEN];
+ char *propval;
+ zfeature_info_t *feat = &spa_feature_table[i];
- /*
- * Skip feature if user specified it manually
- * on the command line.
- */
- if (nvlist_exists(props, propname))
- continue;
+ (void) snprintf(propname, sizeof (propname),
+ "feature@%s", feat->fi_uname);
+ /*
+ * Only features contained in props will be enabled:
+ * 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_lookup_string(props, propname, &propval)) {
+ if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
+ (void) nvlist_remove_all(props,
+ propname);
+ } else if (enable_all_pool_feat) {
ret = add_prop_list(propname,
ZFS_FEATURE_ENABLED, &props, B_TRUE);
if (ret != 0)
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
index 0641c1844..6727a77e7 100644
--- a/lib/libzfs/libzfs_pool.c
+++ b/lib/libzfs/libzfs_pool.c
@@ -502,10 +502,11 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
}
(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,
"property '%s' can only be set to "
- "'enabled'"), propname);
+ "'enabled' or 'disabled'"), propname);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
diff --git a/man/man8/zpool.8 b/man/man8/zpool.8
index 351817569..43dccc05a 100644
--- a/man/man8/zpool.8
+++ b/man/man8/zpool.8
@@ -41,8 +41,9 @@ zpool \- configures ZFS storage pools
.LP
.nf
-\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 ...
+\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 ...
.fi
.LP
@@ -877,7 +878,7 @@ Clears device errors in a pool. If no arguments are specified, all device errors
.sp
.ne 2
.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
.sp .6
.RS 4n
@@ -933,6 +934,18 @@ Sets the given pool properties. See the "Properties" section for a list of valid
.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
+.ne 2
+.na
\fB\fB-O\fR \fIfile-system-property=value\fR\fR
.ad
.br
diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run
index bfda141f5..9d63d6853 100644
--- a/tests/runfiles/linux.run
+++ b/tests/runfiles/linux.run
@@ -250,7 +250,8 @@ tests = [
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_024_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:
# zpool_destroy_001_pos - failure should be investigated
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am
index a9ffbee03..8cfc5bd00 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am
@@ -30,4 +30,5 @@ dist_pkgdata_SCRIPTS = \
zpool_create_features_001_pos.ksh \
zpool_create_features_002_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
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_004_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_004_neg.ksh
index a52e86251..2b465d5a4 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_004_neg.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_004_neg.ksh
@@ -39,7 +39,7 @@
verify_runnable "global"
properties="\
-feature@async_destroy=disabled \
+feature@async_destroy=disable \
feature@async_destroy=active \
feature@xxx_fake_xxx=enabled \
unsupported@some_feature=inactive \
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_005_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_005_pos.ksh
new file mode 100755
index 000000000..488f11c9b
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_005_pos.ksh
@@ -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"