Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for '-o feature@<feature>=disable' on the command line. #3465

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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