Skip to content

Commit

Permalink
Allow for '-o feature@<feature>=disable' 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
Closes #3460, #5142
  • Loading branch information
FransUrbo committed Oct 9, 2016
1 parent 7515f8f commit 9c9119d
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 5 deletions.
71 changes: 69 additions & 2 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,64 @@ add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
return (add_prop_list(propname, propval, props, B_TRUE));
}

static boolean_t
setup_prop_list(const char *propname, char *propval, nvlist_t **props,
int call)
{
spa_feature_t i;
char *prop;

if ((strcmp(propval, "disable") == 0 ||
strcmp(propval, "disabled") == 0)) {
/*
* Because we've choosen to disable (a) feature(s) we first
* need to make sure we enable ALL features...
* I.e. default=enabled
*/
if (call == 0) {
for (i = 0; i < SPA_FEATURES; i++) {
/* String WITH the 'feature@' part */
prop = safe_malloc(
strlen(spa_feature_table[i].fi_uname)
+ 9);

strcpy(prop, "feature@");
strcat(prop, spa_feature_table[i].fi_uname);
prop[strlen(prop)] = '\0';

if (!nvlist_exists(*props,
spa_feature_table[i].fi_uname) ||
!nvlist_exists(*props, prop)) {
if (add_prop_list(prop,
ZFS_FEATURE_ENABLED, props,
B_TRUE))
return (B_TRUE);
}
}
}


/*
* ... then we disable all BUT the one(s) we choosed to
* disable.
*/
for (i = 0; i < SPA_FEATURES; i++) {
/* String WITH the 'feature@' part */
prop = safe_malloc(
strlen(spa_feature_table[i].fi_uname) + 9);

strcpy(prop, "feature@");
strcat(prop, spa_feature_table[i].fi_uname);
prop[strlen(prop)] = '\0';

if (strcmp(prop, propname) == 0)
(void) nvlist_remove_all(*props, prop);
}
}

return (B_FALSE);
}

/*
* zpool add [-fgLnP] [-o property=value] <pool> <vdev> ...
*
Expand Down Expand Up @@ -920,6 +978,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=value.
* -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 All @@ -939,7 +998,7 @@ zpool_do_create(int argc, char **argv)
nvlist_t *nvroot = NULL;
char *poolname;
char *tname = NULL;
int ret = 1;
int ret = 1, call = 0;
char *altroot = NULL;
char *mountpoint = NULL;
nvlist_t *fsprops = NULL;
Expand Down Expand Up @@ -980,7 +1039,15 @@ zpool_do_create(int argc, char **argv)
*propval = '\0';
propval++;

if (add_prop_list(optarg, propval, &props, B_TRUE))
if (zpool_prop_feature(optarg)) {
if (setup_prop_list(optarg, propval, &props,
call))
goto errout;
else
enable_all_pool_feat = B_FALSE;
call++;
} else if (add_prop_list(optarg, propval, &props,
B_TRUE))
goto errout;

/*
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 \fBdisable\fR or \fBenable\fR.
.RE

.sp
.ne 2
.na
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/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
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 9c9119d

Please sign in to comment.