mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Add support for zpool user properties
Usage:
zpool set org.freebsd:comment="this is my pool" poolname
Tests are based on zfs_set's user property tests.
Also stop truncating property values at MAXNAMELEN, use ZFS_MAXPROPLEN.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Mateusz Piotrowski <mateusz.piotrowski@klarasystems.com>
Sponsored-by: Beckhoff Automation GmbH & Co. KG.
Sponsored-by: Klara Inc.
Closes #11680
This commit is contained in:
@@ -1149,10 +1149,13 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/cli_root/zpool_set/setup.ksh \
|
||||
functional/cli_root/zpool/setup.ksh \
|
||||
functional/cli_root/zpool_set/vdev_set_001_pos.ksh \
|
||||
functional/cli_root/zpool_set/zpool_set_common.kshlib \
|
||||
functional/cli_root/zpool_set/zpool_set_001_pos.ksh \
|
||||
functional/cli_root/zpool_set/zpool_set_002_neg.ksh \
|
||||
functional/cli_root/zpool_set/zpool_set_003_neg.ksh \
|
||||
functional/cli_root/zpool_set/zpool_set_ashift.ksh \
|
||||
functional/cli_root/zpool_set/user_property_001_pos.ksh \
|
||||
functional/cli_root/zpool_set/user_property_002_neg.ksh \
|
||||
functional/cli_root/zpool_set/zpool_set_features.ksh \
|
||||
functional/cli_root/zpool_split/cleanup.ksh \
|
||||
functional/cli_root/zpool_split/setup.ksh \
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
#!/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 https://opensource.org/licenses/CDDL-1.0.
|
||||
# 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 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2016 by Delphix. All rights reserved.
|
||||
# Copyright (c) 2023 by Klara Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_set/zpool_set_common.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# ZFS can set any valid user-defined pool property.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Combine all kind of valid characters into a valid user-defined
|
||||
# property name.
|
||||
# 2. Random get a string as the value.
|
||||
# 3. Verify all the valid user-defined pool properties can be set to a
|
||||
# pool.
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
log_assert "ZFS can set any valid user-defined pool property."
|
||||
log_onexit cleanup_user_prop $TESTPOOL
|
||||
|
||||
typeset -a names=()
|
||||
typeset -a values=()
|
||||
|
||||
# Longest property name (255 bytes, which is the 256-byte limit minus 1 byte
|
||||
# for the null byte)
|
||||
names+=("$(awk 'BEGIN { printf "x:"; while (c++ < (256 - 2 - 1)) printf "a" }')")
|
||||
values+=("long-property-name")
|
||||
# Longest property value (the limits are 1024 on FreeBSD and 4096 on Linux, so
|
||||
# pick the right one; the longest value can use limit minus 1 bytes for the
|
||||
# null byte)
|
||||
if is_linux; then
|
||||
typeset ZFS_MAXPROPLEN=4096
|
||||
else
|
||||
typeset ZFS_MAXPROPLEN=1024
|
||||
fi
|
||||
names+=("long:property:value")
|
||||
values+=("$(awk -v max="$ZFS_MAXPROPLEN" 'BEGIN { while (c++ < (max - 1)) printf "A" }')")
|
||||
# Valid property names
|
||||
for i in {1..10}; do
|
||||
typeset -i len
|
||||
((len = RANDOM % 32))
|
||||
names+=("$(valid_user_property $len)")
|
||||
((len = RANDOM % 512))
|
||||
values+=("$(user_property_value $len)")
|
||||
done
|
||||
|
||||
typeset -i i=0
|
||||
while ((i < ${#names[@]})); do
|
||||
typeset name="${names[$i]}"
|
||||
typeset value="${values[$i]}"
|
||||
|
||||
log_must eval "zpool set $name='$value' $TESTPOOL"
|
||||
log_must eval "check_user_prop $TESTPOOL $name '$value'"
|
||||
|
||||
((i += 1))
|
||||
done
|
||||
|
||||
log_pass "ZFS can set any valid user-defined pool property passed."
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#!/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 https://opensource.org/licenses/CDDL-1.0.
|
||||
# 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 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2016 by Delphix. All rights reserved.
|
||||
# Copyright (c) 2023 by Klara Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_set/zpool_set_common.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# ZFS can handle any invalid user-defined pool property.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Combine all kind of invalid user pool property names.
|
||||
# 2. Random get a string as the value.
|
||||
# 3. Verify all the invalid user-defined pool properties can not be set
|
||||
# to the pool.
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
log_assert "ZFS can handle any invalid user pool property."
|
||||
log_onexit cleanup_user_prop $TESTPOOL
|
||||
|
||||
typeset -a names=()
|
||||
typeset -a values=()
|
||||
|
||||
# Too long property name (256 bytes, which is the 256-byte limit minus 1 byte
|
||||
# for the null byte plus 1 byte to reach back over the limit)
|
||||
names+=("$(awk 'BEGIN { printf "x:"; while (c++ < (256 - 2 - 1 + 1)) printf "a" }')")
|
||||
values+=("too-long-property-name")
|
||||
# Too long property value (the limits are 1024 on FreeBSD and 4096 on Linux, so
|
||||
# pick the right one; the too long value is, e.g., the limit minus 1 bytes for the
|
||||
# null byte plus 1 byte to reach back over the limit)
|
||||
if is_linux; then
|
||||
typeset ZFS_MAXPROPLEN=4096
|
||||
else
|
||||
typeset ZFS_MAXPROPLEN=1024
|
||||
fi
|
||||
names+=("too:long:property:value")
|
||||
values+=("$(awk -v max="$ZFS_MAXPROPLEN" 'BEGIN { while (c++ < (max - 1 + 1)) printf "A" }')")
|
||||
# Invalid property names
|
||||
for i in {1..10}; do
|
||||
typeset -i len
|
||||
((len = RANDOM % 32))
|
||||
names+=("$(invalid_user_property $len)")
|
||||
((len = RANDOM % 512))
|
||||
values+=("$(user_property_value $len)")
|
||||
done
|
||||
|
||||
typeset -i i=0
|
||||
while ((i < ${#names[@]})); do
|
||||
typeset name="${names[$i]}"
|
||||
typeset value="${values[$i]}"
|
||||
|
||||
log_mustnot zpool set $name=$value $TESTPOOL
|
||||
log_mustnot check_user_prop $TESTPOOL \"$name\" \"$value\"
|
||||
|
||||
((i += 1))
|
||||
done
|
||||
|
||||
log_pass "ZFS can handle invalid user pool property passed."
|
||||
@@ -0,0 +1,178 @@
|
||||
#
|
||||
# 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 https://opensource.org/licenses/CDDL-1.0.
|
||||
# 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 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2014, 2016 by Delphix. All rights reserved.
|
||||
# Copyright (c) 2023 by Klara Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
set -A VALID_NAME_CHAR a b c d e f g h i j k l m n o p q r s t u v w x y z \
|
||||
0 1 2 3 4 5 6 7 8 9 ':' '-' '.' '_'
|
||||
set -A INVALID_NAME_CHAR A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
|
||||
'`' '~' '!' '@' '#' '$' '%' '^' '&' '(' ')' '+' '=' '|' "\\" '{' '[' ']' \
|
||||
'}' ';' '"' '<' ',' '>' '?' '/' ' '
|
||||
set -A ALL_CHAR ${VALID_NAME_CHAR[*]} ${INVALID_NAME_CHAR[*]}
|
||||
|
||||
#
|
||||
# Cleanup all the user properties of the pool.
|
||||
#
|
||||
# $1 pool name
|
||||
#
|
||||
function cleanup_user_prop
|
||||
{
|
||||
typeset pool=$1
|
||||
|
||||
typeset user_prop
|
||||
user_prop=$(zpool get -H -o property all $pool | grep ":")
|
||||
|
||||
typeset prop
|
||||
for prop in $user_prop; do
|
||||
zpool set $prop="" $pool ||
|
||||
log_must zpool set $prop="" $pool
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Random select character from the specified character set and combine into a
|
||||
# random string
|
||||
#
|
||||
# $1 character set name
|
||||
# $2 String length
|
||||
#
|
||||
function random_string
|
||||
{
|
||||
typeset char_set=${1:-VALID_NAME_CHAR}
|
||||
typeset -i len=${2:-5}
|
||||
|
||||
eval typeset -i count=\${#$char_set[@]}
|
||||
|
||||
# No consumers want an empty string.
|
||||
((len == 0)) && len=3
|
||||
|
||||
typeset str
|
||||
typeset -i i=0
|
||||
while ((i < len)); do
|
||||
typeset -i ind
|
||||
((ind = RANDOM % count))
|
||||
eval str=\${str}\${$char_set[\$ind]}
|
||||
|
||||
((i += 1))
|
||||
done
|
||||
|
||||
echo "$str"
|
||||
}
|
||||
|
||||
#
|
||||
# Get valid user-defined property name
|
||||
#
|
||||
# $1 user-defined property name length
|
||||
#
|
||||
function valid_user_property
|
||||
{
|
||||
typeset -i sumlen=${1:-10}
|
||||
((sumlen < 2 )) && sumlen=2
|
||||
typeset -i len
|
||||
((len = RANDOM % sumlen))
|
||||
typeset part1 part2
|
||||
|
||||
while true; do
|
||||
part1="$(random_string VALID_NAME_CHAR $len)"
|
||||
if [[ "$part1" == "-"* ]]; then
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
((len = sumlen - (len + 1)))
|
||||
|
||||
while true; do
|
||||
part2="$(random_string VALID_NAME_CHAR $len)"
|
||||
if [[ -z $part1 && -z $part2 ]]; then
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
echo "${part1}:${part2}"
|
||||
}
|
||||
|
||||
#
|
||||
# Get invalid user-defined property name
|
||||
#
|
||||
# $1 user-defined property name length
|
||||
#
|
||||
function invalid_user_property
|
||||
{
|
||||
typeset -i sumlen=${1:-10}
|
||||
((sumlen == 0)) && sumlen=1
|
||||
typeset -i len
|
||||
((len = RANDOM % sumlen))
|
||||
|
||||
typeset part1 part2
|
||||
while true; do
|
||||
part1="$(random_string VALID_NAME_CHAR $len)"
|
||||
((len = sumlen - len))
|
||||
part2="$(random_string INVALID_NAME_CHAR $len)"
|
||||
|
||||
# Avoid $part1 is *:* and $part2 is "=*"
|
||||
if [[ "$part1" == *":"* && "$part2" == "="* ]]; then
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
echo "${part1}${part2}"
|
||||
}
|
||||
|
||||
#
|
||||
# Get user-defined property value
|
||||
#
|
||||
# $1 user-defined property name length
|
||||
#
|
||||
function user_property_value
|
||||
{
|
||||
typeset -i len=${1:-100}
|
||||
|
||||
random_string ALL_CHAR $len
|
||||
}
|
||||
|
||||
#
|
||||
# Check if the user-defined property is identical to the expected value.
|
||||
#
|
||||
# $1 pool
|
||||
# $2 user property
|
||||
# $3 expected value
|
||||
#
|
||||
function check_user_prop
|
||||
{
|
||||
typeset pool=$1
|
||||
typeset user_prop="$2"
|
||||
typeset expect_value="$3"
|
||||
typeset value=$(zpool get -p -H -o value "$user_prop" $pool 2>&1)
|
||||
|
||||
[ "$expect_value" = "$value" ]
|
||||
}
|
||||
Reference in New Issue
Block a user