Skip to content

Commit

Permalink
Allow for '-o feature@<feature>=disabled' on the command line.
Browse files Browse the repository at this point in the history
Sometimes it is desired to specifically disable a feature
directly on the 'zpool create' command line.

Signed-off-by: Turbo Fredriksson <turbo@bayour.com>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
  • Loading branch information
loli10K committed Oct 24, 2016
1 parent 9523b15 commit b994fcf
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 22 deletions.
33 changes: 19 additions & 14 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ zpool_do_labelclear(int argc, char **argv)
* -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
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions lib/libzfs/libzfs_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

This comment has been minimized.

Copy link
@behlendorf

behlendorf Oct 24, 2016

Contributor

[cstyle] 4 space indent for continued lines. Like this:

+           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;
}
Expand Down
19 changes: 16 additions & 3 deletions man/man8/zpool.8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
.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
.ne 2
.na
Expand Down
3 changes: 2 additions & 1 deletion tests/runfiles/linux.run
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ tests = [
'zpool_create_018_pos', 'zpool_create_019_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,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
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/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 features is in the 'enabled' state.
#
################################################################################

verify_runnable "global"

function cleanup
{
datasetexists $TESTPOOL && log_must $ZPOOL destroy $TESTPOOL
}

function check_features
{
feature="${1}"
feature_set=false
other_feature_set=false

${ZPOOL} get all ${TESTPOOL} | \
grep feature@ | \
while read line; do
set -- $(echo "${line}")

if [[ "${3}" == "enabled" || "${3}" == "active" ]]; then
if [[ "feature@${feature}" == "${2}" ]]; then
feature_set=true
else
other_feature_set=true
fi
fi
done

if [[ "${feature_set}" == "true" ]]; then
# This is a success
if [[ "${other_feature_set}" == "true" ]]; then
# .. but if _any_ of the other features is enabled,
# it's a failure!
return 0
else
# All good - feature is enabled, all other disabled.
return 1
fi
else
# Feature is not set - failure.
return 1
fi
}

log_onexit cleanup

for feature in async_destroy bookmarks embedded_data empty_bpobj enabled_txg \
extensible_dataset filesystem_limits hole_birth large_blocks \
lz4_compress spacemap_histogram large_dnode userobj_accounting \
sha512 skein edonr
do
log_assert "'zpool create' creates pools with ${feature} disabled"

log_must $ZPOOL create -f -o "feature@${feature}=disabled" $TESTPOOL $DISKS
check_features ${feature}
log_must $ZPOOL destroy -f $TESTPOOL

log_pass "'zpool create' creates pools with ${feature} disabled"
done

0 comments on commit b994fcf

Please sign in to comment.