diff options
Diffstat (limited to 'tests/zfs-tests/tests/functional/reservation')
27 files changed, 2526 insertions, 0 deletions
diff --git a/tests/zfs-tests/tests/functional/reservation/Makefile.am b/tests/zfs-tests/tests/functional/reservation/Makefile.am new file mode 100644 index 000000000000..8eaf09861551 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/Makefile.am @@ -0,0 +1,30 @@ +pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/reservation +dist_pkgdata_SCRIPTS = \ + setup.ksh \ + cleanup.ksh \ + reservation_001_pos.ksh \ + reservation_002_pos.ksh \ + reservation_003_pos.ksh \ + reservation_004_pos.ksh \ + reservation_005_pos.ksh \ + reservation_006_pos.ksh \ + reservation_007_pos.ksh \ + reservation_008_pos.ksh \ + reservation_009_pos.ksh \ + reservation_010_pos.ksh \ + reservation_011_pos.ksh \ + reservation_012_pos.ksh \ + reservation_013_pos.ksh \ + reservation_014_pos.ksh \ + reservation_015_pos.ksh \ + reservation_016_pos.ksh \ + reservation_017_pos.ksh \ + reservation_018_pos.ksh \ + reservation_019_pos.ksh \ + reservation_020_pos.ksh \ + reservation_021_neg.ksh \ + reservation_022_pos.ksh + +dist_pkgdata_DATA = \ + reservation.cfg \ + reservation.shlib diff --git a/tests/zfs-tests/tests/functional/reservation/cleanup.ksh b/tests/zfs-tests/tests/functional/reservation/cleanup.ksh new file mode 100755 index 000000000000..3166bd6ec16e --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/cleanup.ksh @@ -0,0 +1,34 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +default_cleanup diff --git a/tests/zfs-tests/tests/functional/reservation/reservation.cfg b/tests/zfs-tests/tests/functional/reservation/reservation.cfg new file mode 100644 index 000000000000..b4f9af938623 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation.cfg @@ -0,0 +1,44 @@ +# +# 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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013 by Delphix. All rights reserved. +# + +export RESV_DELTA=5242880 +export RESV_TOLERANCE=10485760 # Acceptable limit (10MB) diff in space stats +export RESV_SIZE=52428800 # Default reservation size (50MB) +export RESV_FREE_SPACE=52428800 # Amount of space (50MB) to leave free in a pool +export RESV_NUM_FS=10 # Number of filesystems to create +export RESV_ITER=10 # Number of iterations + +export BLOCK_SIZE=1048576 +export ENOSPC=28 + +export TESTVOL=testvol$$ +export TESTVOL2=testvol2-$$ +export TESTFILE1=file1.$$ +export TESTFILE2=file2.$$ diff --git a/tests/zfs-tests/tests/functional/reservation/reservation.shlib b/tests/zfs-tests/tests/functional/reservation/reservation.shlib new file mode 100644 index 000000000000..49ee3b992dcc --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation.shlib @@ -0,0 +1,201 @@ +# +# 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) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/reservation/reservation.cfg + +# +# Function to set the reservation property of a dataset to +# 'none' and verify that it is correctly set using both the +# "normal" 'zfs get reservation' and the '-p' option which +# gives a numerical value. +# +function zero_reservation +{ + typeset resv_val + dataset=$1 + + log_must zfs set reservation=none $dataset + + resv_val=`zfs get -H reservation $dataset | awk '{print $3}'` + if [[ $? -ne 0 ]]; then + log_fail "Unable to get reservation prop on $dataset" + elif [[ $resv_val != "none" ]]; then + log_fail "Reservation not 'none' ($resv_val) as expected" + fi + + + resv_val=`zfs get -pH reservation $dataset | awk '{print $3}'` + if [[ $? -ne 0 ]]; then + log_fail "Unable to get reservation prop on $dataset" + elif [[ $resv_val -ne 0 ]]; then + log_fail "Reservation not 0 ($resv_val) as expected" + fi + + return 0 +} + +# +# Utility function to see if two values are within a certain specified +# limit of each other. Used primarily to check that a dataset's parent +# is correctly accounting for space used/available. Need this function as +# currently there is some slop in the way space is accounted (i.e. can't +# do a direct comparison). +# +function within_limits +{ + typeset valA=$1 + typeset valB=$2 + typeset delta=$3 + + if ((valA <= valB)); then + if (((valB - valA) <= delta)); then + return 0 + fi + elif ((valB <= valA)); then + if (((valA - valB) <= delta)); then + return 0 + fi + fi + + return 1 +} + +# +# Function to create and mount multiple filesystems. The filesystem +# will be named according to the name specified with a suffix value +# taken from the loop counter. +# +function create_multiple_fs # num_fs base_fs_name base_mnt_name +{ + typeset -i iter=0 + typeset -i count=$1 + typeset FS_NAME=$2 + typeset MNT_NAME=$3 + + while (($iter < $count)); do + log_must zfs create ${FS_NAME}$iter + log_must zfs set mountpoint=${MNT_NAME}$iter ${FS_NAME}$iter + ((iter = iter + 1)) + done +} + +# +# This function compute the largest volume size which is multiple of volume +# block size (default 8K) and not greater than the largest expected volsize. +# +# $1 The largest expected volume size. +# $2 The volume block size +# +function floor_volsize #<largest_volsize> [volblksize] +{ + typeset largest_volsize=$1 + typeset volblksize=${2:-8192} + + if ((largest_volsize < volblksize)); then + log_fail "The largest_volsize must be greater than volblksize." + fi + typeset real_volsize + typeset n + + ((n = largest_volsize / volblksize)) + ((largest_volsize = volblksize * n)) + + print $largest_volsize +} + +# +# This function is a copy of a function by the same name in libzfs_dataset.c +# Its purpose is to reserve additional space for volume metadata so volumes +# don't unexpectedly run out of room. +# +# Note: This function can be used to do an estimate for a volume that has not +# yet been created. In this case, $vol is not a volume, but rather a pool in +# which a volume is going to be created. In this case, use default properties. +# +function volsize_to_reservation +{ + typeset vol=$1 + typeset volsize=$2 + + typeset -i DN_MAX_INDBLKSHIFT=17 + typeset -i SPA_BLKPTRSHIFT=7 + typeset -i SPA_DVAS_PER_BP=3 + + typeset DNODES_PER_LEVEL_SHIFT=$((DN_MAX_INDBLKSHIFT - \ + SPA_BLKPTRSHIFT)) + typeset DNODES_PER_LEVEL=$((1 << $DNODES_PER_LEVEL_SHIFT)) + + if ds_is_volume $vol; then + typeset ncopies=$(get_prop copies $vol) + typeset volblocksize=$(get_prop volblocksize $vol) + else + typeset ncopies=1 + typeset volblocksize=8192 + fi + typeset nblocks=$((volsize / volblocksize)) + + typeset numdb=7 + while ((nblocks > 1)); do + ((nblocks += DNODES_PER_LEVEL - 1)) + ((nblocks /= DNODES_PER_LEVEL)) + ((numdb += nblocks)) + done + + ((numdb *= SPA_DVAS_PER_BP < ncopies + 1 ? SPA_DVAS_PER_BP : \ + ncopies + 1)) + ((volsize *= ncopies)) + ((numdb *= 1 << DN_MAX_INDBLKSHIFT)) + ((volsize += numdb)) + echo $volsize +} + +# +# This function takes a pool name as an argument, and returns the largest (give +# or take some slop) -V value that can be used to create a volume in that pool. +# This is necessary because during volume creation, a reservation is created +# that will be larger than the value specified with -V, and potentially larger +# than the available space in the pool. See volsize_to_reservation(). +# +function largest_volsize_from_pool +{ + typeset pool=$1 + typeset poolsize=$(get_prop available $pool) + typeset volsize=$poolsize + typeset nvolsize + + while :; do + # knock 50M off the volsize each time through + ((volsize -= 50 * 1024 * 1024)) + nvolsize=$(volsize_to_reservation $pool $volsize) + nvolsize=$(floor_volsize $nvolsize) + ((nvolsize < poolsize)) && break + done + echo $volsize +} diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_001_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_001_pos.ksh new file mode 100755 index 000000000000..b8220791f1d4 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_001_pos.ksh @@ -0,0 +1,124 @@ +#!/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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# ZFS allows reservations to be set on filesystems and volumes, provided +# the reservation is less than the space available in the pool. +# +# STRATEGY: +# 1) Create a regular and sparse volume +# (filesystem already created by default_setup) +# 2) Get the space available in the pool +# 3) Set a reservation on the filesystem less than the space available. +# 4) Verify that the 'reservation' property for the filesystem has +# the correct value. +# 5) Reset the reservation to 'none' +# 6) Repeat steps 2-5 for both volume types +# + +verify_runnable "both" + +function cleanup +{ + for obj in $OBJ_LIST; do + destroy_dataset $obj + done +} + +log_onexit cleanup + +log_assert "Verify that to set a reservation on a filesystem or volume must " \ + "use value smaller than space available property of pool" + +space_avail=`get_prop available $TESTPOOL` + +if ! is_global_zone ; then + OBJ_LIST="" +else + OBJ_LIST="$TESTPOOL/$TESTVOL $TESTPOOL/$TESTVOL2" + + ((vol_set_size = space_avail / 4)) + vol_set_size=$(floor_volsize $vol_set_size) + ((sparse_vol_set_size = space_avail * 4)) + sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + + # + # Note that when creating a regular volume we are implicitly + # setting a reservation upon it (i.e. the size of the volume) + # which we reset back to zero initially. + # + log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + log_must zfs set reservation=none $TESTPOOL/$TESTVOL + log_must zfs set refreservation=none $TESTPOOL/$TESTVOL + log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 +fi + + +for obj in $TESTPOOL/$TESTFS $OBJ_LIST; do + + space_avail=`get_prop available $TESTPOOL` + resv_size_set=`expr $space_avail - $RESV_DELTA` + + # + # For a regular (non-sparse) volume the upper limit + # for reservations is not determined by the space + # available in the pool but rather by the size of + # the volume itself. + # + [[ $obj == $TESTPOOL/$TESTVOL ]] && \ + ((resv_size_set = vol_set_size - RESV_DELTA)) + + log_must zfs set reservation=$resv_size_set $obj + + resv_size_get=`get_prop reservation $obj` + if [[ $resv_size_set != $resv_size_get ]]; then + log_fail "Reservation not the expected value " \ + "($resv_size_set != $resv_size_get)" + fi + + log_must zero_reservation $obj + + new_space_avail=`get_prop available $obj` + + # + # Due to the way space is consumed and released by metadata we + # can't do an exact check here, but we do a basic sanity + # check. + # + log_must within_limits $space_avail $new_space_avail $RESV_TOLERANCE +done + +log_pass "Successfully set reservation on filesystem and volume" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_002_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_002_pos.ksh new file mode 100755 index 000000000000..8ae3593613f0 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_002_pos.ksh @@ -0,0 +1,100 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Reservation values cannot exceed the amount of space available +# in the pool. Verify that attempting to set a reservation greater +# than this value fails. +# +# STRATEGY: +# 1) Create a filesystem, regular and sparse volume +# 2) Get the space available in the pool +# 3) Attempt to set a reservation greater than the available space +# on the filesystem and verify it fails. +# 4) Verify that the reservation is still set to 'none' (or 0) on +# the filesystem. +# 5) Repeat 3-4 for regular and sparse volume +# + +verify_runnable "both" + +function cleanup +{ + for obj in $OBJ_LIST; do + datasetexists $obj && log_must_busy zfs destroy -f $obj + done + + log_must zero_reservation $TESTPOOL/$TESTFS +} + +log_onexit cleanup + +log_assert "Reservation values cannot exceed the amount of space" \ + " available in the pool" + +space_avail=`get_prop available $TESTPOOL` + +if ! is_global_zone ; then + OBJ_LIST="" +else + OBJ_LIST="$TESTPOOL/$TESTVOL $TESTPOOL/$TESTVOL2" + + ((vol_set_size = space_avail / 4)) + vol_set_size=$(floor_volsize $vol_set_size) + ((sparse_vol_set_size = space_avail * 4)) + sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + + log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + log_must zfs set reservation=none $TESTPOOL/$TESTVOL + log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 +fi + +for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do + + space_avail=`get_prop available $obj` + resv_size_set=`expr $space_avail + $RESV_DELTA` + + log_must zero_reservation $obj + log_mustnot zfs set reservation=$resv_size_set $obj + + resv_size_get=`get_prop reservation $obj` + + if (($resv_size_get != 0)); then + log_fail "Reservation value non-zero ($resv_size_get)" + fi +done + +log_pass "Attempting to set too large reservation failed as expected" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_003_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_003_pos.ksh new file mode 100755 index 000000000000..48adabe72ffd --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_003_pos.ksh @@ -0,0 +1,134 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Verify that it's possible to set a reservation on a filesystem, +# or volume multiple times, without resetting the reservation +# to none. +# +# STRATEGY: +# 1) Create a regular volume and a sparse volume +# 2) Get the space available in the pool +# 3) Set a reservation on the filesystem less than the space available. +# 4) Verify that the 'reservation' property for the filesystem has +# the correct value. +# 5) Repeat 2-4 for different reservation values +# 6) Repeat 3-5 for regular and sparse volume +# + +verify_runnable "both" + +log_assert "Verify it is possible to set reservations multiple times " \ + "on a filesystem regular and sparse volume" + +function cleanup +{ + log_must zero_reservation $TESTPOOL/$TESTFS + + for obj in $OBJ_LIST; do + datasetexists $obj && log_must zfs destroy -f $obj + done +} + +log_onexit cleanup + + +# +# Set a reservation $RESV_ITER times on a dataset and verify that +# the reservation is correctly set each time. +# +function multiple_resv { #dataset + typeset -i i=0 + + dataset=$1 + + log_must zero_reservation $dataset + space_avail=`get_prop available $TESTPOOL` + + ((resv_size = (space_avail - RESV_DELTA) / RESV_ITER)) + + # + # For regular (non-sparse) volumes the upper limit is determined + # not by the space available in the pool but rather by the size + # of the volume itself. + # + [[ $obj == $TESTPOOL/$TESTVOL ]] && \ + ((resv_size = (vol_set_size - RESV_DELTA) / RESV_ITER)) + + resv_size_set=$resv_size + + while (($i < $RESV_ITER)); do + + ((i = i + 1)) + + ((resv_size_set = resv_size * i)) + + log_must zfs set reservation=$resv_size_set $dataset + + resv_size_get=`get_prop reservation $dataset` + if [[ $resv_size_set != $resv_size_get ]]; then + log_fail "Reservation not the expected value " \ + "($resv_size_set != $resv_size_get)" + fi + done + + log_must zero_reservation $dataset +} + +space_avail=`get_prop available $TESTPOOL` + +if ! is_global_zone ; then + OBJ_LIST="" +else + OBJ_LIST="$TESTPOOL/$TESTVOL $TESTPOOL/$TESTVOL2" + + ((vol_set_size = space_avail / 4)) + vol_set_size=$(floor_volsize $vol_set_size) + ((sparse_vol_set_size = space_avail * 4)) + sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + + + log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + log_must zfs set reservation=none $TESTPOOL/$TESTVOL + log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 +fi + +for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do + multiple_resv $obj +done + +log_pass "Multiple reservations successfully set on filesystem" \ + " and both volume types" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_004_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_004_pos.ksh new file mode 100755 index 000000000000..f8342ff29488 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_004_pos.ksh @@ -0,0 +1,130 @@ +#!/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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# When a dataset which has a reservation set on it is destroyed, +# the space consumed or reserved by that dataset should be released +# back into the pool. +# +# STRATEGY: +# 1) Create a filesystem, regular and sparse volume +# 2) Get the space used and available in the pool +# 3) Set a reservation on the filesystem less than the space available. +# 4) Verify that the 'reservation' property for the filesystem has +# the correct value. +# 5) Destroy the filesystem without resetting the reservation value. +# 6) Verify that the space used and available totals for the pool have +# changed by the expected amounts (within tolerances). +# 7) Repeat steps 3-6 for a regular volume and sparse volume +# + +verify_runnable "both" + +function cleanup { + + for obj in $OBJ_LIST; do + datasetexists $obj && log_must_busy zfs destroy -f $obj + done +} + +log_assert "Verify space released when a dataset with reservation is destroyed" + +log_onexit cleanup + +log_must zfs create $TESTPOOL/$TESTFS2 + +space_avail=`get_prop available $TESTPOOL` + +if ! is_global_zone ; then + OBJ_LIST="$TESTPOOL/$TESTFS2" +else + OBJ_LIST="$TESTPOOL/$TESTFS2 \ + $TESTPOOL/$TESTVOL $TESTPOOL/$TESTVOL2" + + ((vol_set_size = space_avail / 4)) + vol_set_size=$(floor_volsize $vol_set_size) + ((sparse_vol_set_size = space_avail * 4)) + sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + + log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + log_must zfs set refreservation=none $TESTPOOL/$TESTVOL + log_must zfs set reservation=none $TESTPOOL/$TESTVOL + log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 +fi + +# re-calculate space available. +space_avail=`get_prop available $TESTPOOL` + +# Calculate a large but valid reservation value. +resv_size_set=`expr $space_avail - $RESV_DELTA` + +for obj in $OBJ_LIST ; do + + space_avail=`get_prop available $TESTPOOL` + space_used=`get_prop used $TESTPOOL` + + # + # For regular (non-sparse) volumes the upper limit is determined + # not by the space available in the pool but rather by the size + # of the volume itself. + # + [[ $obj == $TESTPOOL/$TESTVOL ]] && \ + ((resv_size_set = vol_set_size - RESV_DELTA)) + + log_must zfs set reservation=$resv_size_set $obj + + resv_size_get=`get_prop reservation $obj` + if [[ $resv_size_set != $resv_size_get ]]; then + log_fail "Reservation not the expected value " \ + "($resv_size_set != $resv_size_get)" + fi + + log_must_busy zfs destroy -f $obj + + new_space_avail=`get_prop available $TESTPOOL` + new_space_used=`get_prop used $TESTPOOL` + + # + # Recent changes to metaslab logic have caused these tests to expand + # outside of their previous tolerance. If this is discovered to be a + # bug, rather than a side effect of some interactions, the reservation + # should be halved again. + # + log_must within_limits $space_used $new_space_used $RESV_TOLERANCE + log_must within_limits $space_avail $new_space_avail $RESV_TOLERANCE +done + +log_pass "Space correctly released when dataset is destroyed" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_005_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_005_pos.ksh new file mode 100755 index 000000000000..4047fab0d7f9 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_005_pos.ksh @@ -0,0 +1,118 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# When a reservation property of a filesystem, regular volume +# or sparse volume is set to 'none' the space previously consumed by the +# reservation should be released back to the pool +# +# STRATEGY: +# 1) Create a filesystem, regular volume and sparse volume +# 2) Get the space used and available in the pool +# 3) Set a reservation on the filesystem less than the space available. +# 4) Verify that the 'reservation' property for the filesystem has +# the correct value. +# 5) Reset the reservation value back to zero (or 'none') +# 6) Verify that the space used and available totals for the pool have +# changed by the expected amounts (within tolerances). +# 7) Repeat steps 3-6 for a regular volume, sparse volume +# + +verify_runnable "both" + +log_assert "Verify space released when reservation on a dataset is set "\ + "to 'none'" + +function cleanup +{ + for obj in $OBJ_LIST; do + datasetexists $obj && log_must zfs destroy -f $obj + done +} + +log_onexit cleanup + +space_avail=`get_prop available $TESTPOOL` + +if ! is_global_zone ; then + OBJ_LIST="" +else + OBJ_LIST="$TESTPOOL/$TESTVOL $TESTPOOL/$TESTVOL2" + ((vol_set_size = space_avail / 4)) + vol_set_size=$(floor_volsize $vol_set_size) + ((sparse_vol_set_size = space_avail * 4)) + sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + + + log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + log_must zfs set reservation=none $TESTPOOL/$TESTVOL + log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 +fi + +space_avail=`get_prop available $TESTPOOL` +space_used=`get_prop used $TESTPOOL` + +# Calculate a large but valid reservation value. +resv_size_set=`expr $space_avail - $RESV_DELTA` + +for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do + + # + # For regular (non-sparse) volumes the upper limit is determined + # not by the space available in the pool but rather by the size + # of the volume itself. + # + [[ $obj == $TESTPOOL/$TESTVOL ]] && \ + ((resv_size_set = vol_set_size - RESV_DELTA)) + + log_must zfs set reservation=$resv_size_set $obj + + resv_size_get=`get_prop reservation $obj` + if [[ $resv_size_set != $resv_size_get ]]; then + log_fail "Reservation not the expected value "\ + "($resv_size_set != $resv_size_get)" + fi + + log_must zfs set reservation=none $obj + + new_space_avail=`get_prop available $TESTPOOL` + new_space_used=`get_prop used $TESTPOOL` + + log_must within_limits $space_used $new_space_used $RESV_TOLERANCE + log_must within_limits $space_avail $new_space_avail $RESV_TOLERANCE +done + +log_pass "Space correctly released when dataset reservation set to 'none'" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh new file mode 100755 index 000000000000..ec1986c4547c --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh @@ -0,0 +1,81 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Reservations (if successfully set) guarantee a minimum amount of space +# for a dataset. Unlike quotas however there should be no restrictions +# on accessing space outside of the limits of the reservation (if the +# space is available in the pool). Verify that in a filesystem with a +# reservation set that its possible to create files both within the +# reserved space and also outside. +# +# STRATEGY: +# 1) Create a filesystem +# 2) Get the space used and available in the pool +# 3) Set a reservation on the filesystem +# 4) Verify can write a file that is bigger than the reserved space +# +# i.e. we start writing within the reserved region and then continue +# for 20MB outside it. +# + +verify_runnable "both" + +function cleanup +{ + [[ -e $TESTDIR/$TESTFILE1 ]] && log_must rm -rf $TESTDIR/$TESTFILE1 + log_must zfs set reservation=none $TESTPOOL/$TESTFS +} + +log_onexit cleanup + +log_assert "Verify can create files both inside and outside reserved areas" + +space_used=`get_prop used $TESTPOOL` + +log_must zfs set reservation=$RESV_SIZE $TESTPOOL/$TESTFS + +# +# Calculate how many writes of BLOCK_SIZE it would take to fill +# up RESV_SIZE + 20971520 (20 MB). +# +fill_size=`expr $RESV_SIZE + 20971520` +write_count=`expr $fill_size / $BLOCK_SIZE` + +log_must file_write -o create -f $TESTDIR/$TESTFILE1 -b $BLOCK_SIZE \ + -c $write_count -d 0 + +log_pass "Able to create files inside and outside reserved area" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_007_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_007_pos.ksh new file mode 100755 index 000000000000..48d6b40ad05a --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_007_pos.ksh @@ -0,0 +1,128 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Setting a reservation on dataset should have no effect on any other +# dataset at the same level in the hierarchy beyond using up available +# space in the pool. +# +# STRATEGY: +# 1) Create a filesystem +# 2) Set a reservation on the filesystem +# 3) Create another filesystem at the same level +# 4) Set a reservation on the second filesystem +# 5) Destroy both the filesystems +# 6) Verify space accounted for correctly +# + +verify_runnable "both" + +log_assert "Verify reservations on data sets doesn't affect other data sets " \ + "at same level except for consuming space from common pool" + +function cleanup +{ + datasetexists $TESTPOOL/$TESTFS2 && \ + log_must zfs destroy -f $TESTPOOL/$TESTFS2 + + datasetexists $TESTPOOL/$TESTFS1 && \ + log_must zfs destroy -f $TESTPOOL/$TESTFS1 +} + +log_onexit cleanup + +space_avail=`get_prop available $TESTPOOL` +space_used=`get_prop used $TESTPOOL` + +resv_size_set=`expr $space_avail / 3` + +# +# Function which creates two datasets, sets reservations on them, +# then destroys them and ensures that space is correctly accounted +# for. +# +# Any special arguments for create are passed in via the args +# parameter. +# +function create_resv_destroy { # args1 dataset1 args2 dataset2 + + args1=$1 + dataset1=$2 + args2=$3 + dataset2=$4 + + log_must zfs create $args1 $dataset1 + + log_must zfs set reservation=$RESV_SIZE $dataset1 + + avail_aft_dset1=`get_prop available $TESTPOOL` + used_aft_dset1=`get_prop used $TESTPOOL` + + log_must zfs create $args2 $dataset2 + + log_must zfs set reservation=$RESV_SIZE $dataset2 + + # + # After destroying the second dataset the space used and + # available totals should revert back to the values they + # had after creating the first dataset. + # + log_must zfs destroy -f $dataset2 + + avail_dest_dset2=`get_prop available $TESTPOOL` + used_dest_dset2=`get_prop used $TESTPOOL` + + log_must within_limits $avail_aft_dset1 $avail_dest_dset2 $RESV_TOLERANCE + log_must within_limits $used_aft_dset1 $used_dest_dset2 $RESV_TOLERANCE + + + # After destroying the first dataset the space used and + # space available totals should revert back to the values + # they had when the pool was first created. + log_must zfs destroy -f $dataset1 + + avail_dest_dset1=`get_prop available $TESTPOOL` + used_dest_dset1=`get_prop used $TESTPOOL` + + log_must within_limits $avail_dest_dset1 $space_avail $RESV_TOLERANCE + log_must within_limits $used_dest_dset1 $space_used $RESV_TOLERANCE +} + +create_resv_destroy "" $TESTPOOL/$TESTFS1 "" $TESTPOOL/$TESTFS2 +create_resv_destroy "" $TESTPOOL/$TESTFS2 "" $TESTPOOL/$TESTFS1 + +log_pass "Verify reservations on data sets doesn't affect other data sets at" \ + " same level except for consuming space from common pool" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_008_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_008_pos.ksh new file mode 100755 index 000000000000..a0cd039b1839 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_008_pos.ksh @@ -0,0 +1,124 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Setting a reservation reserves a defined minimum amount of space for +# a dataset, and prevents other datasets using that space. Verify that +# reducing the reservation on a filesystem allows other datasets in +# the pool to use that space. +# +# STRATEGY: +# 1) Create multiple filesystems +# 2) Set reservations on all bar one of the filesystems +# 3) Fill up the one non-reserved filesystem +# 4) Reduce one of the reservations and verify can write more +# data into the non-reserved filesystem +# + +verify_runnable "both" + +log_assert "Verify reducing reservation allows other datasets to use space" + +function cleanup +{ + typeset -i loop=0 + while (($loop < $RESV_NUM_FS)); do + datasetexists $TESTPOOL/${TESTFS}$loop && \ + log_must zfs destroy -f $TESTPOOL/${TESTFS}$loop + + [[ -d ${TESTDIR}$loop ]] && log_must rm -r ${TESTDIR}$loop + + ((loop = loop + 1)) + done +} + +log_onexit cleanup + +log_must create_multiple_fs $RESV_NUM_FS $TESTPOOL/$TESTFS $TESTDIR + +space_avail=`get_prop available $TESTPOOL` +space_used=`get_prop used $TESTPOOL` + +# +# To make sure this test doesn't take too long to execute on +# large pools, we calculate a reservation setting which when +# applied to all bar one of the filesystems (RESV_NUM_FS-1) will +# ensure we have RESV_FREE_SPACE left free in the pool, which we will +# be able to quickly fill. +# +resv_space_avail=`expr $space_avail - $RESV_FREE_SPACE` +num_resv_fs=`expr $RESV_NUM_FS - 1` # Number of FS to which resv will be applied +resv_size_set=`expr $resv_space_avail / $num_resv_fs` + +# +# We set the reservations now, rather than when we created the filesystems +# to allow us to take into account space used by the filesystem metadata +# +# Note we don't set a reservation on the first filesystem we created, +# hence num=1 rather than zero below. +# +typeset -i num=1 +while (($num < $RESV_NUM_FS)); do + log_must zfs set reservation=$resv_size_set $TESTPOOL/$TESTFS$num + ((num = num + 1)) +done + +space_avail_still=`get_prop available $TESTPOOL` + +fill_size=`expr $space_avail_still + $RESV_TOLERANCE` +write_count=`expr $fill_size / $BLOCK_SIZE` + +# Now fill up the first filesystem (which doesn't have a reservation set +# and thus will use up whatever free space is left in the pool). +num=0 +log_note "Writing to $TESTDIR$num/$TESTFILE1" + +file_write -o create -f $TESTDIR$num/$TESTFILE1 -b $BLOCK_SIZE \ + -c $write_count -d 0 +ret=$? +if (($ret != $ENOSPC)); then + log_fail "Did not get ENOSPC as expected (got $ret)." +fi + +# Remove the reservation on one of the other filesystems and verify +# can write more data to the original non-reservation filesystem. +num=1 +log_must zfs set reservation=none $TESTPOOL/${TESTFS}$num +num=0 +log_must file_write -o create -f ${TESTDIR}$num/$TESTFILE2 \ + -b $(getconf PAGESIZE) -c 1000 -d 0 + +log_pass "reducing reservation allows other datasets to use space" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_009_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_009_pos.ksh new file mode 100755 index 000000000000..171577def5ef --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_009_pos.ksh @@ -0,0 +1,100 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# In pool with a full filesystem and another filesystem with a reservation +# setting the reservation on the second filesystem to 'none' should allow more +# data to be written to the first filesystem. +# +# +# STRATEGY: +# 1) Create a filesystem as a dataset +# 2) Create a filesystem at the same level +# 3) Set a reservation on the dataset filesystem +# 4) Fill up the filesystem +# 5) Set the reservation on the dataset filesystem to 'none' +# 6) Verify we can write more data to the first filesystem +# + +verify_runnable "both" + +log_assert "Setting top level dataset reservation to 'none' allows more data " \ + "to be written to top level filesystem" + +function cleanup +{ + log_must rm -rf $TESTDIR/$TESTFILE1 + log_must rm -rf $TESTDIR/$TESTFILE2 + log_must zfs destroy -f $TESTPOOL/$TESTFS1 +} + +log_onexit cleanup + +log_must zfs create $TESTPOOL/$TESTFS1 + +space_avail=`get_prop available $TESTPOOL` + +# +# To make sure this test doesn't take too long to execute on +# large pools, we calculate a reservation setting which when +# applied to the dataset will ensure we have RESV_FREE_SPACE +# left free in the pool which we can quickly fill. +# +((resv_size_set = space_avail - RESV_FREE_SPACE)) + +log_must zfs set reservation=$resv_size_set $TESTPOOL/$TESTFS1 + +space_avail_still=`get_prop available $TESTPOOL` + +fill_size=`expr $space_avail_still + $RESV_TOLERANCE` +write_count=`expr $fill_size / $BLOCK_SIZE` + +# Now fill up the filesystem (which doesn't have a reservation set +# and thus will use up whatever free space is left in the pool). +file_write -o create -f $TESTDIR/$TESTFILE1 -b $BLOCK_SIZE \ + -c $write_count -d 0 +ret=$? +if (($ret != $ENOSPC)); then + log_fail "Did not get ENOSPC as expected (got $ret)." +fi + +log_must zfs set reservation=none $TESTPOOL/$TESTFS1 + +log_must file_write -o create -f $TESTDIR/$TESTFILE2 \ + -b $(getconf PAGESIZE) -c 1000 -d 0 + +log_pass "Setting top level dataset reservation to 'none' allows more " \ + "data to be written to the top level filesystem" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_010_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_010_pos.ksh new file mode 100755 index 000000000000..2ca279a4a437 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_010_pos.ksh @@ -0,0 +1,101 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# In pool with a full filesystem and a filesystem with a reservation +# destroying another filesystem should allow more data to be written to +# the full filesystem +# +# +# STRATEGY: +# 1) Create a filesystem as dataset +# 2) Create a filesystem at the same level +# 3) Set a reservation on the dataset filesystem +# 4) Fill up the second filesystem +# 5) Destroy the dataset filesystem +# 6) Verify can write more data to the full filesystem +# + +verify_runnable "both" + +log_assert "Destroying top level filesystem with reservation allows more " \ + "data to be written to another top level filesystem" + +function cleanup +{ + datasetexists $TESTPOOL/$TESTFS1 && \ + log_must zfs destroy $TESTPOOL/$TESTFS1 + + [[ -e $TESTDIR/$TESTFILE1 ]] && log_must rm -rf $TESTDIR/$TESTFILE1 + [[ -e $TESTDIR/$TESTFILE2 ]] && log_must rm -rf $TESTDIR/$TESTFILE2 +} + +log_onexit cleanup + +log_must zfs create $TESTPOOL/$TESTFS1 + +space_avail=`get_prop available $TESTPOOL` + +# +# To make sure this test doesn't take too long to execute on +# large pools, we calculate a reservation setting which when +# applied to the dataset filesystem will ensure we have +# RESV_FREE_SPACE left free in the pool. +# +((resv_size_set = space_avail - RESV_FREE_SPACE)) + +log_must zfs set reservation=$resv_size_set $TESTPOOL/$TESTFS1 + +space_avail_still=`get_prop available $TESTPOOL` + +fill_size=`expr $space_avail_still + $RESV_TOLERANCE` +write_count=`expr $fill_size / $BLOCK_SIZE` + +# Now fill up the filesystem (which doesn't have a reservation set +# and thus will use up whatever free space is left in the pool). +file_write -o create -f $TESTDIR/$TESTFILE1 -b $BLOCK_SIZE -c $write_count -d 0 +ret=$? +if (($ret != $ENOSPC)); then + log_fail "Did not get ENOSPC as expected (got $ret)." +fi + +log_must zfs destroy -f $TESTPOOL/$TESTFS1 + +log_must file_write -o create -f $TESTDIR/$TESTFILE2 \ + -b $(getconf PAGESIZE) -c 1000 -d 0 + +log_pass "Destroying top level filesystem with reservation allows more data " \ + "to be written to another top level filesystem" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_011_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_011_pos.ksh new file mode 100755 index 000000000000..a6abe9db6a13 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_011_pos.ksh @@ -0,0 +1,75 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# ZFS has two mechanisms dealing with space for datasets, namely +# reservations and quotas. Setting one should not affect the other, +# provided the values are legal (i.e. enough space in pool etc). +# +# STRATEGY: +# 1) Create one filesystem +# 2) Get the current quota setting +# 3) Set a reservation +# 4) Verify that the quota value remains unchanged +# + +verify_runnable "both" + +log_assert "Verify reservation settings do not affect quota settings" + +function cleanup +{ + log_must zero_reservation $TESTPOOL/$TESTFS +} + +log_onexit cleanup + +space_avail=`get_prop available $TESTPOOL` + +((resv_size_set = (space_avail - RESV_DELTA) / 2)) + +fs_quota=`zfs get quota $TESTPOOL/$TESTFS` + +log_must zfs set reservation=$resv_size_set $TESTPOOL/$TESTFS + +new_fs_quota=`zfs get quota $TESTPOOL/$TESTFS` + +if [[ $fs_quota != $new_fs_quota ]]; then + log_fail "Quota value on $TESTFS has changed " \ + "($fs_quota != $new_fs_quota)" +fi + +log_pass "Quota settings unaffected by reservation settings" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_012_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_012_pos.ksh new file mode 100755 index 000000000000..5ab0952b1910 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_012_pos.ksh @@ -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 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) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# A reservation guarantees a certain amount of space for a dataset. +# Nothing else which happens in the same pool should affect that +# space, i.e. even if the rest of the pool fills up the reserved +# space should still be accessible. +# +# STRATEGY: +# 1) Create 2 filesystems +# 2) Set a reservation on one filesystem +# 3) Fill up the other filesystem (which does not have a reservation +# set) until all space is consumed +# 4) Verify can still write to the filesystem which has a reservation +# + +verify_runnable "both" + +log_assert "Verify reservations protect space" + +function cleanup +{ + log_must zfs destroy -f $TESTPOOL/$TESTFS2 + log_must zero_reservation $TESTPOOL/$TESTFS + + [[ -e $TESTDIR/$TESTFILE2 ]] && log_must rm -rf $TESTDIR/$TESTFILE2 + [[ -d $TESTDIR2 ]] && log_must rm -rf $TESTDIR2 +} + +log_onexit cleanup + +log_must zfs create $TESTPOOL/$TESTFS2 +log_must zfs set mountpoint=$TESTDIR2 $TESTPOOL/$TESTFS2 + +space_avail=`get_prop available $TESTPOOL` + +((resv_size_set = space_avail - RESV_FREE_SPACE)) + +log_must zfs set reservation=$resv_size_set $TESTPOOL/$TESTFS + +((write_count = (RESV_FREE_SPACE + RESV_TOLERANCE) / BLOCK_SIZE)) + +file_write -o create -f $TESTDIR2/$TESTFILE1 -b $BLOCK_SIZE -c $write_count \ + -d 0 +ret=$? +if [[ $ret != $ENOSPC ]]; then + log_fail "Did not get ENOSPC (got $ret) for non-reserved filesystem" +fi + +((write_count = (RESV_FREE_SPACE - RESV_TOLERANCE) / BLOCK_SIZE)) +log_must file_write -o create -f $TESTDIR/$TESTFILE2 -b $BLOCK_SIZE -c \ + $write_count -d 0 + +log_pass "Reserved space preserved correctly" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_013_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_013_pos.ksh new file mode 100755 index 000000000000..6a80bb575dc4 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_013_pos.ksh @@ -0,0 +1,112 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Reservation properties on data objects should be preserved when the +# pool within which they are contained is exported and then re-imported. +# +# +# STRATEGY: +# 1) Create a filesystem as dataset +# 2) Create another filesystem at the same level +# 3) Create a regular volume at the same level +# 4) Create a sparse volume at the same level +# 5) Create a filesystem within the dataset filesystem +# 6) Set reservations on all filesystems +# 7) Export the pool +# 8) Re-import the pool +# 9) Verify that the reservation settings are correct +# + +verify_runnable "global" + +log_assert "Reservation properties preserved across exports and imports" + +function cleanup +{ + for obj in $OBJ_LIST; do + datasetexists $obj && log_must zfs destroy -f $obj + done + + log_must zero_reservation $TESTPOOL/$TESTFS +} +log_onexit cleanup + +OBJ_LIST="$TESTPOOL/$TESTFS1/$TESTFS2 $TESTPOOL/$TESTFS1 $TESTPOOL/$TESTVOL \ + $TESTPOOL/$TESTVOL2" + +log_must zfs create $TESTPOOL/$TESTFS1 +log_must zfs create $TESTPOOL/$TESTFS1/$TESTFS2 + +space_avail=$(get_prop available $TESTPOOL) +[[ $? -ne 0 ]] && \ + log_fail "Unable to get space available property for $TESTPOOL" + +typeset -il resv_set=space_avail/5 +resv_set=$(floor_volsize $resv_set) +typeset -il sparse_vol_set_size=space_avail*5 +sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + +# When initially created, a regular volume's reservation property is set +# equal to its size (unlike a sparse volume), so we don't need to set it +# explicitly later on +log_must zfs create -V $resv_set $TESTPOOL/$TESTVOL +log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 + +log_must zfs set reservation=$resv_set $TESTPOOL/$TESTFS +log_must zfs set reservation=$resv_set $TESTPOOL/$TESTFS1 +log_must zfs set reservation=$resv_set $TESTPOOL/$TESTFS1/$TESTFS2 +log_must zfs set reservation=$resv_set $TESTPOOL/$TESTVOL2 + +log_must zpool export $TESTPOOL +log_must zpool import $TESTPOOL + +for obj in $TESTPOOL/$TESTFS $OBJ_LIST; do + + if [[ $obj == $TESTPOOL/$TESTVOL ]]; then + expected=$(volsize_to_reservation $obj $resv_set) + found=$(get_prop refreservation $obj) + else + expected=$resv_set + found=$(get_prop reservation $obj) + fi + + [[ $found != $expected ]] && \ + log_fail "Reservation property for $obj incorrect. Expected " \ + "$expected but got $found." +done + +log_pass "Reservation properties preserved across exports and imports" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_014_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_014_pos.ksh new file mode 100755 index 000000000000..e8bd91d00e68 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_014_pos.ksh @@ -0,0 +1,116 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# A reservation cannot exceed the quota on a dataset +# +# STRATEGY: +# 1) Create a filesystem and volume +# 2) Set a quota on the filesystem +# 3) Attempt to set a reservation larger than the quota. Verify +# that the attempt fails. +# 4) Repeat 2-3 for volume +# + +verify_runnable "both" + +log_assert "Verify cannot set reservation larger than quota" + +function cleanup +{ + # + # Note we don't destroy $TESTFS as it's used by other tests + for obj in $OBJ_LIST ; do + datasetexists $obj && log_must zfs destroy -f $obj + done + + log_must zero_reservation $TESTPOOL/$TESTFS +} +log_onexit cleanup + +space_avail=`get_prop available $TESTPOOL` + +if ! is_global_zone ; then + OBJ_LIST="" +else + OBJ_LIST="$TESTPOOL/$TESTVOL $TESTPOOL/$TESTVOL2" + + ((vol_set_size = space_avail / 4)) + vol_set_size=$(floor_volsize $vol_set_size) + ((sparse_vol_set_size = space_avail * 4)) + sparse_vol_set_size=$(floor_volsize $sparse_vol_set_size) + + log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + log_must zfs create -s -V $sparse_vol_set_size $TESTPOOL/$TESTVOL2 +fi + +for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do + + space_avail=`get_prop available $obj` + ((quota_set_size = space_avail / 3)) + + # + # Volumes do not support quota so only need to explicitly + # set quotas for filesystems. + # + # The maximum reservation value that can be set on a volume + # is determined by the quota set on its parent filesystems or + # the amount of space in the pool, whichever is smaller. + # + if [[ $obj == $TESTPOOL/$TESTFS ]]; then + log_must zfs set quota=$quota_set_size $obj + ((resv_set_size = quota_set_size + RESV_SIZE)) + elif [[ $obj == $TESTPOOL/$TESTVOL || $obj == $TESTPOOL/$TESTVOL2 ]] + then + resv_set_size=`expr $space_avail + $RESV_DELTA` + fi + + orig_quota=`get_prop quota $obj` + + log_mustnot zfs set reservation=$resv_set_size $obj + new_quota=`get_prop quota $obj` + + if [[ $orig_quota != $new_quota ]]; then + log_fail "Quota value changed from $orig_quota " \ + "to $new_quota" + fi + + if [[ $obj == $TESTPOOL/$TESTFS ]]; then + log_must zfs set quota=none $obj + fi +done + +log_pass "As expected cannot set reservation larger than quota" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_015_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_015_pos.ksh new file mode 100755 index 000000000000..d67f8c7ec2f6 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_015_pos.ksh @@ -0,0 +1,99 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# In pool with a full filesystem and a regular volume with an implicit +# reservation, setting the reservation on the volume to 'none' should allow +# more data to be written to the filesystem. +# +# +# STRATEGY: +# 1) Create a regular non-sparse volume (which implicitly sets the reservation +# property to a value equal to the volume size) +# 2) Create a filesystem at the same level +# 3) Fill up the filesystem +# 4) Set the reservation on the volume to 'none' +# 5) Verify can write more data to the filesystem +# + +verify_runnable "global" + +log_assert "Setting volume reservation to 'none' allows more data to be " \ + "written to top level filesystem" + +function cleanup +{ + datasetexists $TESTPOOL/$TESTVOL && \ + log_must zfs destroy $TESTPOOL/$TESTVOL + + [[ -e $TESTDIR/$TESTFILE1 ]] && log_must rm -rf $TESTDIR/$TESTFILE1 + [[ -e $TESTDIR/$TESTFILE2 ]] && log_must rm -rf $TESTDIR/$TESTFILE2 +} +log_onexit cleanup + +space_avail=$(largest_volsize_from_pool $TESTPOOL) + +# +# To make sure this test doesn't take too long to execute on +# large pools, we calculate a volume size which when applied +# to the volume will ensure we have RESV_FREE_SPACE +# left free in the pool which we can quickly fill. +# +((resv_size_set = space_avail - RESV_FREE_SPACE)) +resv_size_set=$(floor_volsize $resv_size_set) + +log_must zfs create -V $resv_size_set $TESTPOOL/$TESTVOL + +space_avail_still=`get_prop available $TESTPOOL` + +fill_size=$((space_avail_still + $RESV_TOLERANCE)) +write_count=$((fill_size / BLOCK_SIZE)) + +# Now fill up the filesystem (which doesn't have a reservation set +# and thus will use up whatever free space is left in the pool). +file_write -o create -f $TESTDIR/$TESTFILE1 -b $BLOCK_SIZE -c $write_count -d 0 +ret=$? +if (($ret != $ENOSPC)); then + log_fail "Did not get ENOSPC as expected (got $ret)." +fi + +log_must zfs set refreservation=none $TESTPOOL/$TESTVOL + +log_must file_write -o create -f $TESTDIR/$TESTFILE2 \ + -b $(getconf PAGESIZE) -c 1000 -d 0 + +log_pass "Setting top level volume reservation to 'none' allows more " \ + "data to be written to the top level filesystem" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_016_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_016_pos.ksh new file mode 100755 index 000000000000..cbb1db658b33 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_016_pos.ksh @@ -0,0 +1,98 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# In pool with a full filesystem and a regular volume (with implicit +# reservation) destroying the volume should allow more data to be written +# to the filesystem +# +# +# STRATEGY: +# 1) Create a regular (non-sparse) volume +# 2) Create a filesystem at the same level +# 3) Fill up the filesystem +# 4) Destroy the volume +# 5) Verify can write more data to the filesystem +# + +verify_runnable "global" + +log_assert "Destroying a regular volume with reservation allows more data to" \ + " be written to top level filesystem" + +function cleanup +{ + datasetexists $TESTPOOL/$TESTVOL && \ + log_must zfs destroy $TESTPOOL/$TESTVOL + + [[ -e $TESTDIR/$TESTFILE1 ]] && log_must rm -rf $TESTDIR/$TESTFILE1 + [[ -e $TESTDIR/$TESTFILE2 ]] && log_must rm -rf $TESTDIR/$TESTFILE2 +} +log_onexit cleanup + +space_avail=$(largest_volsize_from_pool $TESTPOOL) + +# +# To make sure this test doesn't take too long to execute on +# large pools, we calculate a volume size which will ensure we +# have RESV_FREE_SPACE left free in the pool. +# +((vol_set_size = space_avail - RESV_FREE_SPACE)) +vol_set_size=$(floor_volsize $vol_set_size) + +# Creating a regular volume implicitly sets its reservation +# property to the same value. +log_must zfs create -V $vol_set_size $TESTPOOL/$TESTVOL + +space_avail_still=$(get_prop available $TESTPOOL) +fill_size=$((space_avail_still + $RESV_TOLERANCE)) +write_count=$((fill_size / BLOCK_SIZE)) + +# Now fill up the filesystem (which doesn't have a reservation set +# and thus will use up whatever free space is left in the pool). +file_write -o create -f $TESTDIR/$TESTFILE1 -b $BLOCK_SIZE -c $write_count -d 0 +ret=$? +if (($ret != $ENOSPC)); then + log_fail "Did not get ENOSPC as expected (got $ret)." +fi + +log_must zfs destroy -f $TESTPOOL/$TESTVOL + +log_must file_write -o create -f $TESTDIR/$TESTFILE2 \ + -b $(getconf PAGESIZE) -c 1000 -d 0 + +log_pass "Destroying volume with reservation allows more data to be written " \ + "to top level filesystem" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_017_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_017_pos.ksh new file mode 100755 index 000000000000..bb3af67d24d3 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_017_pos.ksh @@ -0,0 +1,101 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# For a sparse volume changes to the volsize are not reflected in the +# reservation. +# +# STRATEGY: +# 1) Create a regular and sparse volume +# 2) Get the space available in the pool +# 3) Set reservation with various sizes on the regular and sparse volumes +# 4) Verify that the 'reservation' property for the regular volume has +# the correct value. +# 5) Verify that the 'reservation' property for the sparse volume is set to +# 'none' +# + +verify_runnable "global" + +function cleanup +{ + typeset vol + + for vol in $regvol $sparsevol; do + destroy_dataset $vol + done +} +log_onexit cleanup + +log_assert "Verify that the volsize changes of sparse volumes are not " \ + "reflected in the reservation." +log_onexit cleanup + +# Create a regular and sparse volume for testing. +regvol=$TESTPOOL/$TESTVOL +sparsevol=$TESTPOOL/$TESTVOL2 +log_must zfs create -V 64M $regvol +log_must zfs create -s -V 64M $sparsevol + +typeset vsize=$(get_prop available $TESTPOOL) +typeset iterate=10 +typeset regreserv +typeset sparsereserv +typeset volblocksize=$(get_prop volblocksize $regvol) +typeset blknum=0 +typeset randomblknum +((blknum = vsize / volblocksize)) + +while ((iterate > 1)); do + ((randomblknum = 1 + RANDOM % blknum)) + # Make sure volsize is a multiple of volume block size + ((vsize = randomblknum * volblocksize)) + log_must zfs set volsize=$vsize $regvol + log_must zfs set volsize=$vsize $sparsevol + vsize=$(volsize_to_reservation $regvol $vsize) + regreserv=$(get_prop refreservation $regvol) + sparsereserv=$(get_prop reservation $sparsevol) + ((sparsereserv == vsize)) && \ + log_fail "volsize changes of sparse volume is reflected in " \ + "reservation (expected $vsize, got $sparsereserv)." + ((regreserv != vsize)) && \ + log_fail "volsize changes of regular volume is not reflected " \ + "in reservation (expected $vsize, got $regreserv)." + ((iterate = iterate - 1)) +done + +log_pass "The volsize changes of sparse volumes are not reflected in the " \ + "reservation" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_018_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_018_pos.ksh new file mode 100755 index 000000000000..0969a6877316 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_018_pos.ksh @@ -0,0 +1,72 @@ +#!/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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Verify that reservation doesn't inherit its value from parent. +# +# STRATEGY: +# 1) Create a filesystem tree +# 2) Set reservation for parents +# 3) Verify that the 'reservation' for descendent doesnot inherit the value. +# + +verify_runnable "both" + +function cleanup +{ + datasetexists $fs_child && log_must zfs destroy $fs_child + log_must zfs set reservation=$reserv_val $fs +} + +log_onexit cleanup + +log_assert "Verify that reservation doesnot inherit its value from parent." + +fs=$TESTPOOL/$TESTFS +fs_child=$TESTPOOL/$TESTFS/$TESTFS + +space_avail=$(get_prop available $fs) +reserv_val=$(get_prop reservation $fs) +typeset reservsize=$space_avail +((reservsize = reservsize / 2)) +log_must zfs set reservation=$reservsize $fs + +log_must zfs create $fs_child +rsv_space=$(get_prop reservation $fs_child) +[[ $rsv_space == $reservsize ]] && \ + log_fail "The reservation of child dataset inherits its value from parent." + +log_pass "reservation doesnot inherit its value from parent as expected." diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_019_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_019_pos.ksh new file mode 100755 index 000000000000..45da06a9f42f --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_019_pos.ksh @@ -0,0 +1,63 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# A thin provisioned volume can become thick provisioned with 'zfs set +# refreservation=auto'. +# +# STRATEGY: +# 1) Create a sparse value. +# 2) Use zfs set refreservation=auto to make it thick provisioned. +# 3) Verify that refreservation is now the size predicted by +# volsize_to_reservation(). +# + +verify_runnable "global" + +function cleanup +{ + destroy_dataset "$TESTPOOL/$TESTVOL" "-f" +} + +log_onexit cleanup + +log_assert "A thin provisioned volume can become thick provisioned with" \ + "'zfs set refreservation=auto'." + +space_avail=$(get_prop available $TESTPOOL) +(( vol_size = (space_avail / 2) & ~(1024 * 1024 - 1) )) + +vol=$TESTPOOL/$TESTVOL + +# Create sparse vol and verify +log_must zfs create -V $vol_size -s $vol +resv=$(get_prop refreservation $vol) +log_must test $resv -eq 0 + +# Set refreservation +log_must zfs set refreservation=auto $vol + +# Verify +resv=$(get_prop refreservation $vol) +expected=$(volsize_to_reservation $vol $vol_size) +log_must test $resv -eq $expected + +log_pass "Setting refreservation=auto set refreservation to expected value" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_020_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_020_pos.ksh new file mode 100755 index 000000000000..68d46d0a0eea --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_020_pos.ksh @@ -0,0 +1,64 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Cloning a thick provisioned volume results in a sparse volume +# +# STRATEGY: +# 1) Create a thick provisioned volume. +# 2) Snapshot and clone it. +# 3) Verify that the clone is sparse. +# + +verify_runnable "global" + +function cleanup +{ + # Destroy first vol and descendants in one go. + destroy_dataset "$TESTPOOL/$TESTVOL" "-Rf" +} + +log_onexit cleanup + +log_assert "Cloning a thick provisioned volume results in a sparse volume" + +space_avail=$(get_prop available $TESTPOOL) +(( vol_size = (space_avail / 4) & ~(1024 * 1024 - 1) )) + +vol=$TESTPOOL/$TESTVOL +snap=$vol@clone +vol2=$TESTPOOL/$TESTVOL2 + +# Create sparse vol and verify +log_must zfs create -V $vol_size $vol +resv=$(get_prop refreservation $vol) +expected=$(volsize_to_reservation $vol $vol_size) +log_must test $resv -eq $expected + +# Clone it +log_must zfs snapshot $snap +log_must zfs clone $snap $vol2 + +# Verify +resv=$(get_prop refreservation $vol2) +log_must test $resv -eq 0 + +log_pass "Cloning a thick provisioned volume results in a sparse volume" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_021_neg.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_021_neg.ksh new file mode 100755 index 000000000000..c99a82c5db71 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_021_neg.ksh @@ -0,0 +1,72 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# The use of refreservation=auto on a filesystem does not change the +# refreservation and results in an error. +# +# STRATEGY: +# 1) Create a filesystem +# 2) Verify that zfs set refreservation=auto fails without changing +# refreservation from none. +# 3) Set refreservation to a valid value. +# 4) Verify that zfs set refreservation=auto fails without changing +# refreservation from the previous value. +# + +verify_runnable "both" + +fs=$TESTPOOL/$TESTFS/$(basename $0).$$ + +function cleanup +{ + destroy_dataset "$fs" "-f" +} + +log_onexit cleanup + +log_assert "refreservation=auto on a filesystem generates an error without" \ + "changing refreservation" + +space_avail=$(get_prop available $TESTPOOL) +(( fs_size = space_avail / 4 )) + +# Create a filesystem with no refreservation +log_must zfs create $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq 0 + +# Verify that refreservation=auto fails without altering refreservation +log_mustnot zfs set refreservation=auto $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq 0 + +# Set refreservation and verify +log_must zfs set refreservation=$fs_size $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq $fs_size + +# Verify that refreservation=auto fails without altering refreservation +log_mustnot zfs set refreservation=auto $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq $fs_size + +log_pass "refreservation=auto does not work on filesystems, as expected" diff --git a/tests/zfs-tests/tests/functional/reservation/reservation_022_pos.ksh b/tests/zfs-tests/tests/functional/reservation/reservation_022_pos.ksh new file mode 100755 index 000000000000..879dc5da5a85 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/reservation_022_pos.ksh @@ -0,0 +1,82 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Cloning a volume with -o refreservation=auto creates a thick provisioned +# volume +# +# STRATEGY: +# 1) Create a sparse volume. +# 2) Snapshot and clone it, using clone -o refreservation=auto. +# 3) Verify that the clone has refreservation that matches the size predicted by +# volsize_to_reservation(). +# 4) Snapshot this second volume and clone it, using clone -o +# refreservation=auto. +# 5) Verify that the second clone has refreservation that matches the size +# predicted by volsize_to_reservation(). +# + +verify_runnable "global" + +function cleanup +{ + # Destroy first vol and descendants in one go. + destroy_dataset "$TESTPOOL/$TESTVOL" "-Rf" +} + +log_onexit cleanup + +log_assert "Cloning a volume with -o refreservation=auto creates a thick" \ + "provisioned volume" + +space_avail=$(get_prop available $TESTPOOL) +(( vol_size = (space_avail / 4) & ~(1024 * 1024 - 1) )) + +vol=$TESTPOOL/$TESTVOL +vol2=$TESTPOOL/$TESTVOL2 +vol3=$TESTPOOL/$TESTVOL2-again + +# Create sparse vol and verify +log_must zfs create -s -V $vol_size $vol +resv=$(get_prop refreservation $vol) +log_must test $resv -eq 0 + +# Clone it +snap=$vol@clone +log_must zfs snapshot $snap +log_must zfs clone -o refreservation=auto $snap $vol2 + +# Verify it is thick provisioned +resv=$(get_prop refreservation $vol2) +expected=$(volsize_to_reservation $vol2 $vol_size) +log_must test $resv -eq $expected + +# Clone the thick provisioned volume +snap=$vol2@clone +log_must zfs snapshot $snap +log_must zfs clone -o refreservation=auto $snap $vol3 + +# Verify new newest clone is also thick provisioned +resv=$(get_prop refreservation $vol3) +expected=$(volsize_to_reservation $vol3 $vol_size) +log_must test $resv -eq $expected + +log_pass "Cloning a thick provisioned volume results in a sparse volume" diff --git a/tests/zfs-tests/tests/functional/reservation/setup.ksh b/tests/zfs-tests/tests/functional/reservation/setup.ksh new file mode 100755 index 000000000000..c39034783555 --- /dev/null +++ b/tests/zfs-tests/tests/functional/reservation/setup.ksh @@ -0,0 +1,35 @@ +#!/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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2013 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +default_setup_noexit ${DISKS%% *} +log_pass |