| # |
| # 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 2009 Sun Microsystems, Inc. All rights reserved. |
| # Use is subject to license terms. |
| # |
| |
| # |
| # Copyright (c) 2014, 2016 by Delphix. All rights reserved. |
| # |
| |
| . $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[*]} |
| |
| # |
| # Firstly, set the property value to dataset. Then checking if the property |
| # value is equal with the expected value, according to the expected result. |
| # |
| # $1 property value |
| # $2 property name |
| # $3 dataset |
| # $4 expected result |
| # |
| function set_n_check_prop |
| { |
| typeset expect_value=$1 |
| typeset prop=$2 |
| typeset dataset=$3 |
| typeset expect_result=${4:-true} |
| |
| typeset old_value="" |
| typeset cur_value="" |
| |
| [[ -n $prop ]] && old_value=$(get_prop $prop $dataset) |
| |
| if [[ $expect_result == true ]]; then |
| [[ -z $prop || -z $dataset ]] && \ |
| log_fail "property or dataset isn't defined." |
| |
| log_must zfs set $prop=$expect_value $dataset |
| if [[ $expect_value == "gzip-6" ]]; then |
| expect_value="gzip" |
| fi |
| |
| [[ -n $prop ]] && cur_value=$(get_prop $prop $dataset) |
| |
| case $prop in |
| reservation|reserv|quota ) |
| if [[ $expect_value == "none" ]]; then |
| [[ $cur_value != "0" ]] && \ |
| log_fail "The '$dataset' '$prop' value \ |
| '$cur_value' is not expected." |
| elif [[ $cur_value != $expect_value ]]; then |
| log_fail "The '$dataset' '$prop' value '$cur_value' \ |
| does not equal the expected value '$expect_value'." |
| fi |
| ;; |
| * ) |
| if [[ $cur_value != $expect_value ]]; then |
| log_fail "The '$dataset' '$prop' value '$cur_value' \ |
| does not equal the expected value '$expect_value'." |
| fi |
| ;; |
| esac |
| |
| else |
| log_mustnot zfs set $prop=$expect_value $dataset |
| |
| [[ -n $prop ]] && cur_value=$(get_prop $prop $dataset) |
| |
| wait_freeing |
| |
| if [[ "$expect_value" != "" && "$cur_value" != "$old_value" ]]; |
| then |
| log_fail "The '$dataset' '$prop' value '$cur_value' \ |
| should equal with '$old_value'." |
| fi |
| fi |
| } |
| |
| # |
| # Cleanup all the user properties of the pool and the dataset reside it. |
| # |
| # $1 pool name |
| # |
| function cleanup_user_prop |
| { |
| typeset pool=$1 |
| typeset dtst=$(zfs list -H -r -o name -t filesystem,volume $pool) |
| |
| typeset user_prop |
| for dt in $dtst; do |
| user_prop=$(zfs get -H -o property all $dtst | grep ":") |
| |
| typeset prop |
| for prop in $user_prop; do |
| zfs inherit $prop $dt |
| (($? != 0)) && log_must zfs inherit $prop $dt |
| done |
| 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 property value |
| # |
| # $1 user defined property name length |
| # |
| function user_property_value |
| { |
| typeset -i len=${1:-100} |
| |
| typeset value=$(random_string ALL_CHAR $len) |
| |
| echo "$value" |
| } |
| |
| # |
| # Check if the user property is identical to the expected value. |
| # |
| # $1 dataset |
| # $2 user property |
| # $3 expected value |
| # |
| function check_user_prop |
| { |
| typeset dtst=$1 |
| typeset user_prop="$2" |
| typeset expect_value="$3" |
| typeset value=$(zfs get -p -H -o value "$user_prop" $dtst 2>&1) |
| |
| if [[ "$expect_value" == "$value" ]]; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| # |
| # Get source of the dataset |
| # |
| function get_source |
| { |
| typeset prop=$1 |
| typeset dataset=$2 |
| typeset source |
| |
| source=$(zfs get -H -o source $prop $dataset) |
| if (($? != 0)); then |
| log_fail "Unable to get $prop source for dataset $dataset" |
| fi |
| |
| echo "$source" |
| } |
| |
| # |
| # Verify property $2 is set from source $4 on dataset $1 and has value $3. |
| # |
| # $1 checked dataset |
| # $2 user property |
| # $3 property value |
| # $4 source |
| # |
| # Returns: 0 if both expected source and value match, 1 otherwise |
| # |
| function check_prop_source |
| { |
| typeset dataset="$1" |
| typeset prop="$2" |
| typeset value="$3" |
| typeset source="$4" |
| typeset chk_value=$(get_prop "$prop" "$dataset") |
| typeset chk_source=$(get_source "$prop" "$dataset") |
| |
| if [[ "$chk_value" != "$value" || "$chk_source" != "$source" ]] |
| then |
| log_note "expected (value '$value', source '$source'), got \ |
| (value '$chk_value', source '$chk_source')" |
| return 1 |
| else |
| return 0 |
| fi |
| } |
| |
| # |
| # Verify target dataset $1 inherit property $2 from dataset $3. |
| # |
| # $1 checked dataset |
| # $2 property |
| # $3 inherited dataset |
| # |
| # Returns: 0 if property has expected value and is inherited, 1 otherwise |
| # |
| function check_prop_inherit |
| { |
| typeset checked_dtst="$1" |
| typeset prop="$2" |
| typeset inherited_dtst="$3" |
| typeset inherited_value=$(get_prop "$prop" "$inherited_dtst") |
| typeset value=$(get_prop "$prop" "$checked_dtst") |
| typeset source=$(get_source "$prop" "$checked_dtst") |
| |
| if [[ "$value" != "$inherited_value" || \ |
| "$source" != "inherited from $inherited_dtst" ]] |
| then |
| return 1 |
| else |
| return 0 |
| fi |
| } |
| |
| # |
| # Verify property $2 received value on dataset $1 has value $3 |
| # |
| # $1 checked dataset |
| # $2 property name |
| # $3 checked value |
| # |
| # Returns: 0 if property has expected value and is received, 1 otherwise |
| # |
| function check_prop_received |
| { |
| typeset dataset="$1" |
| typeset prop="$2" |
| typeset value="$3" |
| |
| received=$(zfs get -H -o received "$prop" "$dataset") |
| if (($? != 0)); then |
| log_fail "Unable to get $prop received value for dataset " \ |
| "$dataset" |
| fi |
| if [[ "$received" == "$value" ]] |
| then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| # |
| # Verify user property $2 is not set on dataset $1 |
| # |
| # $1 checked dataset |
| # $2 property name |
| # |
| # Returns: 0 if property is missing (not set), 1 otherwise |
| # |
| function check_prop_missing |
| { |
| typeset dataset="$1" |
| typeset prop="$2" |
| |
| value=$(zfs get -H -o value "$prop" "$dataset") |
| if (($? != 0)); then |
| log_fail "Unable to get $prop value for dataset $dataset" |
| fi |
| if [[ "-" == "$value" ]] |
| then |
| return 0 |
| else |
| return 1 |
| fi |
| } |