mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-27 04:32:16 +03:00
Add TRIM support
UNMAP/TRIM support is a frequently-requested feature to help prevent performance from degrading on SSDs and on various other SAN-like storage back-ends. By issuing UNMAP/TRIM commands for sectors which are no longer allocated the underlying device can often more efficiently manage itself. This TRIM implementation is modeled on the `zpool initialize` feature which writes a pattern to all unallocated space in the pool. The new `zpool trim` command uses the same vdev_xlate() code to calculate what sectors are unallocated, the same per- vdev TRIM thread model and locking, and the same basic CLI for a consistent user experience. The core difference is that instead of writing a pattern it will issue UNMAP/TRIM commands for those extents. The zio pipeline was updated to accommodate this by adding a new ZIO_TYPE_TRIM type and associated spa taskq. This new type makes is straight forward to add the platform specific TRIM/UNMAP calls to vdev_disk.c and vdev_file.c. These new ZIO_TYPE_TRIM zios are handled largely the same way as ZIO_TYPE_READs or ZIO_TYPE_WRITEs. This makes it possible to largely avoid changing the pipieline, one exception is that TRIM zio's may exceed the 16M block size limit since they contain no data. In addition to the manual `zpool trim` command, a background automatic TRIM was added and is controlled by the 'autotrim' property. It relies on the exact same infrastructure as the manual TRIM. However, instead of relying on the extents in a metaslab's ms_allocatable range tree, a ms_trim tree is kept per metaslab. When 'autotrim=on', ranges added back to the ms_allocatable tree are also added to the ms_free tree. The ms_free tree is then periodically consumed by an autotrim thread which systematically walks a top level vdev's metaslabs. Since the automatic TRIM will skip ranges it considers too small there is value in occasionally running a full `zpool trim`. This may occur when the freed blocks are small and not enough time was allowed to aggregate them. An automatic TRIM and a manual `zpool trim` may be run concurrently, in which case the automatic TRIM will yield to the manual TRIM. Reviewed-by: Jorgen Lundman <lundman@lundman.net> Reviewed-by: Tim Chase <tim@chase2k.com> Reviewed-by: Matt Ahrens <mahrens@delphix.com> Reviewed-by: George Wilson <george.wilson@delphix.com> Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com> Contributions-by: Saso Kiselkov <saso.kiselkov@nexenta.com> Contributions-by: Tim Chase <tim@chase2k.com> Contributions-by: Chunwei Chen <tuxoko@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #8419 Closes #598
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/trim
|
||||
dist_pkgdata_SCRIPTS = \
|
||||
setup.ksh \
|
||||
cleanup.ksh \
|
||||
trim.kshlib \
|
||||
trim.cfg \
|
||||
autotrim_integrity.ksh \
|
||||
autotrim_config.ksh \
|
||||
autotrim_trim_integrity.ksh \
|
||||
trim_integrity.ksh \
|
||||
trim_config.ksh
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.kshlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.cfg
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Check various pool geometries stripe, mirror, raidz)
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool on file vdevs to trim.
|
||||
# 2. Set 'autotrim=on' on pool.
|
||||
# 3. Fill the pool to a known percentage of capacity.
|
||||
# 4. Verify the vdevs contain 75% or more allocated blocks.
|
||||
# 5. Remove all files making it possible to trim the entire pool.
|
||||
# 6. Wait for auto trim to issue trim IOs for the free blocks.
|
||||
# 7. Verify the disks contain 30% or less allocated blocks.
|
||||
# 8. Repeat for test for striped, mirrored, and RAIDZ pools.
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Set 'autotrim=on' verify pool disks were trimmed"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
if poolexists $TESTPOOL; then
|
||||
destroy_pool $TESTPOOL
|
||||
fi
|
||||
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min $trim_extent_bytes_min
|
||||
log_must set_tunable64 zfs_trim_txg_batch $trim_txg_batch
|
||||
log_must set_tunable64 zfs_vdev_min_ms_count $vdev_min_ms_count
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
# Minimum trim size is decreased to verify all trim sizes.
|
||||
typeset trim_extent_bytes_min=$(get_tunable zfs_trim_extent_bytes_min)
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min 4096
|
||||
|
||||
# Reduced zfs_trim_txg_batch to make trimming more frequent.
|
||||
typeset trim_txg_batch=$(get_tunable zfs_trim_txg_batch)
|
||||
log_must set_tunable64 zfs_trim_txg_batch 8
|
||||
|
||||
# Increased metaslabs to better simulate larger more realistic devices.
|
||||
typeset vdev_min_ms_count=$(get_tunable zfs_vdev_min_ms_count)
|
||||
log_must set_tunable64 zfs_vdev_min_ms_count 32
|
||||
|
||||
typeset VDEV_MAX_MB=$(( floor(4 * MINVDEVSIZE * 0.75 / 1024 / 1024) ))
|
||||
typeset VDEV_MIN_MB=$(( floor(4 * MINVDEVSIZE * 0.30 / 1024 / 1024) ))
|
||||
|
||||
for type in "" "mirror" "raidz2"; do
|
||||
|
||||
if [[ "$type" = "" ]]; then
|
||||
VDEVS="$TRIM_VDEV1"
|
||||
elif [[ "$type" = "mirror" ]]; then
|
||||
VDEVS="$TRIM_VDEV1 $TRIM_VDEV2"
|
||||
else
|
||||
VDEVS="$TRIM_VDEV1 $TRIM_VDEV2 $TRIM_VDEV3"
|
||||
fi
|
||||
|
||||
log_must truncate -s $((4 * MINVDEVSIZE)) $VDEVS
|
||||
log_must zpool create -f $TESTPOOL $VDEVS
|
||||
log_must zpool set autotrim=on $TESTPOOL
|
||||
|
||||
typeset availspace=$(get_prop available $TESTPOOL)
|
||||
typeset fill_mb=$(( floor(availspace * 0.90 / 1024 / 1024) ))
|
||||
|
||||
# Fill the pool, verify the vdevs are no longer sparse.
|
||||
file_write -o create -f /$TESTPOOL/file -b 1048576 -c $fill_mb -d R
|
||||
verify_vdevs "-gt" "$VDEV_MAX_MB" $VDEVS
|
||||
|
||||
# Remove the file, wait for trim, verify the vdevs are now sparse.
|
||||
log_must rm /$TESTPOOL/file
|
||||
wait_trim_io $TESTPOOL "ind" 64
|
||||
verify_vdevs "-le" "$VDEV_MIN_MB" $VDEVS
|
||||
|
||||
log_must zpool destroy $TESTPOOL
|
||||
log_must rm -f $VDEVS
|
||||
done
|
||||
|
||||
log_pass "Auto trim successfully shrunk vdevs"
|
||||
@@ -0,0 +1,87 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.kshlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.cfg
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify automatic trim pool data integrity.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool on sparse file vdevs to trim.
|
||||
# 2. Set autotrim=on to enable asynchronous pool trimming.
|
||||
# 3. Generate some interesting pool data which can be trimmed.
|
||||
# 4. Verify trim IOs of the expected type were issued for the pool.
|
||||
# 5. Verify data integrity of the pool after trim.
|
||||
# 6. Repeat test for striped, mirrored, and RAIDZ pools.
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Set 'autotrim=on' pool property verify pool data integrity"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
if poolexists $TESTPOOL; then
|
||||
destroy_pool $TESTPOOL
|
||||
fi
|
||||
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min $trim_extent_bytes_min
|
||||
log_must set_tunable64 zfs_trim_txg_batch $trim_txg_batch
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
# Minimum trim size is decreased to verify all trim sizes.
|
||||
typeset trim_extent_bytes_min=$(get_tunable zfs_trim_extent_bytes_min)
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min 4096
|
||||
|
||||
# Reduced zfs_trim_txg_batch to make trimming more frequent.
|
||||
typeset trim_txg_batch=$(get_tunable zfs_trim_txg_batch)
|
||||
log_must set_tunable64 zfs_trim_txg_batch 8
|
||||
|
||||
for type in "" "mirror" "raidz" "raidz2" "raidz3"; do
|
||||
log_must truncate -s 1G $TRIM_VDEVS
|
||||
|
||||
log_must zpool create -f $TESTPOOL $type $TRIM_VDEVS
|
||||
log_must zpool set autotrim=on $TESTPOOL
|
||||
|
||||
# Add and remove data from the pool in a random fashion in order
|
||||
# to generate a variety of interesting ranges to be auto trimmed.
|
||||
for n in {0..10}; do
|
||||
dir="/$TESTPOOL/autotrim-$((RANDOM % 5))"
|
||||
filesize=$((4096 + ((RANDOM * 691) % 131072) ))
|
||||
log_must rm -rf $dir
|
||||
log_must fill_fs $dir 10 10 $filesize 1 R
|
||||
zpool sync
|
||||
done
|
||||
log_must du -hs /$TESTPOOL
|
||||
|
||||
verify_trim_io $TESTPOOL "ind" 10
|
||||
verify_pool $TESTPOOL
|
||||
|
||||
log_must zpool destroy $TESTPOOL
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
done
|
||||
|
||||
log_pass "Automatic trim successfully validated"
|
||||
@@ -0,0 +1,93 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.kshlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.cfg
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify automatic trim and manual trim coexist correctly.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool on sparse file vdevs to trim.
|
||||
# 2. Set autotrim=on to enable asynchronous pool trimming.
|
||||
# 3. Generate some interesting pool data which can be trimmed.
|
||||
# 4. While generating data issue manual trims.
|
||||
# 4. Verify trim IOs of the expected type were issued for the pool.
|
||||
# 5. Verify data integrity of the pool after trim.
|
||||
# 6. Repeat test for striped, mirrored, and RAIDZ pools.
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Set 'autotrim=on', run 'zpool trim' and verify pool data integrity"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
if poolexists $TESTPOOL; then
|
||||
destroy_pool $TESTPOOL
|
||||
fi
|
||||
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min $trim_extent_bytes_min
|
||||
log_must set_tunable64 zfs_trim_txg_batch $trim_txg_batch
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
# Minimum trim size is decreased to verify all trim sizes.
|
||||
typeset trim_extent_bytes_min=$(get_tunable zfs_trim_extent_bytes_min)
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min 4096
|
||||
|
||||
# Reduced zfs_trim_txg_batch to make trimming more frequent.
|
||||
typeset trim_txg_batch=$(get_tunable zfs_trim_txg_batch)
|
||||
log_must set_tunable64 zfs_trim_txg_batch 8
|
||||
|
||||
for type in "" "mirror" "raidz" "raidz2" "raidz3"; do
|
||||
log_must truncate -s 1G $TRIM_VDEVS
|
||||
|
||||
log_must zpool create -f $TESTPOOL $type $TRIM_VDEVS
|
||||
log_must zpool set autotrim=on $TESTPOOL
|
||||
|
||||
# Add and remove data from the pool in a random fashion in order
|
||||
# to generate a variety of interesting ranges to be auto trimmed.
|
||||
for n in {0..10}; do
|
||||
dir="/$TESTPOOL/autotrim-$((RANDOM % 5))"
|
||||
filesize=$((4096 + ((RANDOM * 691) % 131072) ))
|
||||
log_must rm -rf $dir
|
||||
log_must fill_fs $dir 10 10 $filesize 1 R
|
||||
zpool sync
|
||||
|
||||
if [[ $((n % 4)) -eq 0 ]]; then
|
||||
log_must zpool trim $TESTPOOL
|
||||
wait_trim $TESTPOOL $TRIM_VDEVS
|
||||
fi
|
||||
done
|
||||
log_must du -hs /$TESTPOOL
|
||||
|
||||
verify_trim_io $TESTPOOL "ind" 10
|
||||
verify_pool $TESTPOOL
|
||||
|
||||
log_must zpool destroy $TESTPOOL
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
done
|
||||
|
||||
log_pass "Automatic trim and manual trim coexistence successfully validated"
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#!/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.
|
||||
#
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
if poolexists $TESTPOOL; then
|
||||
destroy_pool $TESTPOOL
|
||||
fi
|
||||
|
||||
if poolexists $TESTPOOL1; then
|
||||
destroy_pool $TESTPOOL1
|
||||
fi
|
||||
|
||||
TRIM_DIR="$TEST_BASE_DIR"
|
||||
TRIM_VDEVS="$TRIM_DIR/trim-vdev1 $TRIM_DIR/trim-vdev2 \
|
||||
$TRIM_DIR/trim-vdev3 $TRIM_DIR/trim-vdev4"
|
||||
|
||||
rm -rf $TRIM_VDEVS
|
||||
|
||||
default_cleanup
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
DISK1=${DISKS%% *}
|
||||
|
||||
typeset -i max_discard=0
|
||||
if [[ -b $DEV_RDSKDIR/$DISK1 ]]; then
|
||||
max_discard=$(lsblk -Dbn $DEV_RDSKDIR/$DISK1 | awk '{ print $4; exit }')
|
||||
fi
|
||||
|
||||
if test $max_discard -eq 0; then
|
||||
log_unsupported "DISKS do not support discard (TRIM/UNMAP)"
|
||||
fi
|
||||
|
||||
log_pass
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
TRIM_DIR="$TEST_BASE_DIR"
|
||||
TRIM_VDEV1="$TRIM_DIR/trim-vdev1"
|
||||
TRIM_VDEV2="$TRIM_DIR/trim-vdev2"
|
||||
TRIM_VDEV3="$TRIM_DIR/trim-vdev3"
|
||||
TRIM_VDEV4="$TRIM_DIR/trim-vdev4"
|
||||
TRIM_VDEVS="$TRIM_VDEV1 $TRIM_VDEV2 $TRIM_VDEV3 $TRIM_VDEV4"
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/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 (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
|
||||
|
||||
#
|
||||
# Get the actual on disk disk for the provided file.
|
||||
#
|
||||
function get_size_mb
|
||||
{
|
||||
typeset rval=$(du --block-size 1048576 -s "$1" | awk '{print $1}')
|
||||
echo -n "$rval"
|
||||
}
|
||||
|
||||
#
|
||||
# Get the number of trim IOs issued for the pool (ind or agg).
|
||||
#
|
||||
function get_trim_io
|
||||
{
|
||||
typeset pool="${1-:$TESTPOOL}"
|
||||
typeset type="${2-:ind}"
|
||||
typeset rval
|
||||
|
||||
# Sum the ind or agg columns of the trim request size histogram.
|
||||
case "$type" in
|
||||
"ind")
|
||||
rval=$(zpool iostat -pr $pool | awk \
|
||||
'$1 ~ /[0-9].*/ { sum += $12 } END { print sum }')
|
||||
echo -n "$rval"
|
||||
;;
|
||||
"agg")
|
||||
rval=$(zpool iostat -pr $pool | awk \
|
||||
'$1 ~ /[0-9].*/ { sum += $13 } END { print sum }')
|
||||
echo -n "$rval"
|
||||
;;
|
||||
*)
|
||||
log_fail "Type must be 'ind' or 'agg'"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
# Verify that trim IOs were send to devices in the pool.
|
||||
#
|
||||
function verify_trim_io
|
||||
{
|
||||
typeset pool="${1:-$TESTPOOL}"
|
||||
typeset type="${2:-ind}"
|
||||
typeset min_trim_ios=${3:-100}
|
||||
typeset ios
|
||||
|
||||
ios=$(get_trim_io $pool $type)
|
||||
if [[ $ios -ge $min_trim_ios ]]; then
|
||||
log_note "Issued $ios $type trim IOs for pool $pool"
|
||||
else
|
||||
log_fail "Too few trim IOs issued $ios/$min_trim_ios"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Run N txgs which should be enough to trim the entire pool.
|
||||
#
|
||||
function wait_trim_io # pool type txgs
|
||||
{
|
||||
typeset pool="${1-:$TESTPOOL}"
|
||||
typeset type="${2-:ind}"
|
||||
typeset txgs=${3:-10}
|
||||
typeset timeout=120
|
||||
typeset stop_time=$(( $(date +%s) + $timeout ))
|
||||
|
||||
typeset -i i=0
|
||||
while [[ $i -lt $txgs ]]; do
|
||||
if [ "$(date +%s)" -ge $stop_time ]; then
|
||||
log_fail "Exceeded trim time limit of ${timeout}s"
|
||||
return
|
||||
fi
|
||||
|
||||
zpool sync -f
|
||||
((i = i + 1))
|
||||
done
|
||||
|
||||
typeset ios=$(get_trim_io $pool $type)
|
||||
log_note "Waited for $txgs txgs, $ios $type TRIM IOs"
|
||||
}
|
||||
|
||||
#
|
||||
# Verify that file vdevs against a target value.
|
||||
#
|
||||
function verify_vdevs # op size vdevs
|
||||
{
|
||||
typeset tgt_op=$1
|
||||
typeset tgt_size=$2
|
||||
shift 2
|
||||
typeset vdevs=$@
|
||||
|
||||
for vdev in $vdevs; do
|
||||
typeset size=$(get_size_mb $vdev)
|
||||
if test $size $tgt_op $tgt_size; then
|
||||
log_note "Success $vdev is $size MB which is $tgt_op" \
|
||||
"than $tgt_size MB"
|
||||
else
|
||||
log_fail "Failure $vdev is $size MB which is not" \
|
||||
"$tgt_op than $tgt_size MB"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Wait for up to 120 seconds for trimming of the listed vdevs to complete.
|
||||
#
|
||||
function wait_trim # pool vdevs
|
||||
{
|
||||
typeset stop_time=$(( $(date +%s) + 120 ))
|
||||
typeset pool="$1"
|
||||
shift
|
||||
typeset vdevs=$@
|
||||
typeset complete
|
||||
|
||||
while [[ $complete -eq 0 ]]; do
|
||||
complete=1
|
||||
|
||||
for vdev in $vdevs; do
|
||||
if [[ "$(trim_progress $pool $vdev)" -lt "100" ]]; then
|
||||
complete=0
|
||||
break
|
||||
else
|
||||
log_must eval "trim_prog_line $pool $vdev | \
|
||||
grep complete"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$(date +%s)" -ge $stop_time ]; then
|
||||
log_fail "Exceeded trim time limit of 120s"
|
||||
fi
|
||||
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
log_note "Pool completed trim successfully."
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.kshlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.cfg
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Check various pool geometries stripe, mirror, raidz
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool on file vdevs to trim.
|
||||
# 2. Fill the pool to a known percentage of capacity.
|
||||
# 3. Verify the vdevs contain 75% or more allocated blocks.
|
||||
# 4. Remove all files making it possible to trim the entire pool.
|
||||
# 5. Manually trim the pool.
|
||||
# 6. Wait for trim to issue trim IOs for the free blocks.
|
||||
# 7. Verify the disks contain 30% or less allocated blocks.
|
||||
# 8. Repeat for test for striped, mirrored, and RAIDZ pools.
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Run 'zpool trim' verify pool disks were trimmed"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
if poolexists $TESTPOOL; then
|
||||
destroy_pool $TESTPOOL
|
||||
fi
|
||||
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min $trim_extent_bytes_min
|
||||
log_must set_tunable64 zfs_trim_txg_batch $trim_txg_batch
|
||||
log_must set_tunable64 zfs_vdev_min_ms_count $vdev_min_ms_count
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
# Minimum trim size is decreased to verify all trim sizes.
|
||||
typeset trim_extent_bytes_min=$(get_tunable zfs_trim_extent_bytes_min)
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min 4096
|
||||
|
||||
# Reduced zfs_trim_txg_batch to make trimming more frequent.
|
||||
typeset trim_txg_batch=$(get_tunable zfs_trim_txg_batch)
|
||||
log_must set_tunable64 zfs_trim_txg_batch 8
|
||||
|
||||
# Increased metaslabs to better simulate larger more realistic devices.
|
||||
typeset vdev_min_ms_count=$(get_tunable zfs_vdev_min_ms_count)
|
||||
log_must set_tunable64 zfs_vdev_min_ms_count 32
|
||||
|
||||
typeset VDEV_MAX_MB=$(( floor(4 * MINVDEVSIZE * 0.75 / 1024 / 1024) ))
|
||||
typeset VDEV_MIN_MB=$(( floor(4 * MINVDEVSIZE * 0.30 / 1024 / 1024) ))
|
||||
|
||||
for type in "" "mirror" "raidz2"; do
|
||||
|
||||
if [[ "$type" = "" ]]; then
|
||||
VDEVS="$TRIM_VDEV1"
|
||||
elif [[ "$type" = "mirror" ]]; then
|
||||
VDEVS="$TRIM_VDEV1 $TRIM_VDEV2"
|
||||
else
|
||||
VDEVS="$TRIM_VDEV1 $TRIM_VDEV2 $TRIM_VDEV3"
|
||||
fi
|
||||
|
||||
log_must truncate -s $((4 * MINVDEVSIZE)) $VDEVS
|
||||
log_must zpool create -f $TESTPOOL $type $VDEVS
|
||||
|
||||
typeset availspace=$(get_prop available $TESTPOOL)
|
||||
typeset fill_mb=$(( floor(availspace * 0.90 / 1024 / 1024) ))
|
||||
|
||||
# Fill the pool, verify the vdevs are no longer sparse.
|
||||
file_write -o create -f /$TESTPOOL/file -b 1048576 -c $fill_mb -d R
|
||||
verify_vdevs "-gt" "$VDEV_MAX_MB" $VDEVS
|
||||
|
||||
# Remove the file, issue trim, verify the vdevs are now sparse.
|
||||
log_must rm /$TESTPOOL/file
|
||||
log_must zpool trim $TESTPOOL
|
||||
wait_trim $TESTPOOL $VDEVS
|
||||
verify_vdevs "-le" "$VDEV_MIN_MB" $VDEVS
|
||||
|
||||
log_must zpool destroy $TESTPOOL
|
||||
log_must rm -f $VDEVS
|
||||
done
|
||||
|
||||
log_pass "Manual trim successfully shrunk vdevs"
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 by Tim Chase. All rights reserved.
|
||||
# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.kshlib
|
||||
. $STF_SUITE/tests/functional/trim/trim.cfg
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify manual trim pool data integrity.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool on sparse file vdevs to trim.
|
||||
# 2. Generate some interesting pool data which can be trimmed.
|
||||
# 3. Manually trim the pool.
|
||||
# 4. Verify trim IOs of the expected type were issued for the pool.
|
||||
# 5. Verify data integrity of the pool after trim.
|
||||
# 6. Repeat test for striped, mirrored, and RAIDZ pools.
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Run 'zpool trim' and verify pool data integrity"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
if poolexists $TESTPOOL; then
|
||||
destroy_pool $TESTPOOL
|
||||
fi
|
||||
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min $trim_extent_bytes_min
|
||||
log_must set_tunable64 zfs_trim_txg_batch $trim_txg_batch
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
# Minimum trim size is decreased to verify all trim sizes.
|
||||
typeset trim_extent_bytes_min=$(get_tunable zfs_trim_extent_bytes_min)
|
||||
log_must set_tunable64 zfs_trim_extent_bytes_min 4096
|
||||
|
||||
# Reduced zfs_trim_txg_batch to make trimming more frequent.
|
||||
typeset trim_txg_batch=$(get_tunable zfs_trim_txg_batch)
|
||||
log_must set_tunable64 zfs_trim_txg_batch 8
|
||||
|
||||
for type in "" "mirror" "raidz" "raidz2" "raidz3"; do
|
||||
log_must truncate -s 1G $TRIM_VDEVS
|
||||
|
||||
log_must zpool create -f $TESTPOOL $type $TRIM_VDEVS
|
||||
|
||||
# Add and remove data from the pool in a random fashion in order
|
||||
# to generate a variety of interesting ranges to be manually trimmed.
|
||||
for n in {0..10}; do
|
||||
dir="/$TESTPOOL/trim-$((RANDOM % 5))"
|
||||
filesize=$((4096 + ((RANDOM * 691) % 131072) ))
|
||||
log_must rm -rf $dir
|
||||
log_must fill_fs $dir 10 10 $filesize 1 R
|
||||
zpool sync
|
||||
done
|
||||
log_must du -hs /$TESTPOOL
|
||||
|
||||
log_must zpool trim $TESTPOOL
|
||||
wait_trim $TESTPOOL $TRIM_VDEVS
|
||||
|
||||
verify_trim_io $TESTPOOL "ind" 10
|
||||
verify_pool $TESTPOOL
|
||||
|
||||
log_must zpool destroy $TESTPOOL
|
||||
log_must rm -f $TRIM_VDEVS
|
||||
done
|
||||
|
||||
log_pass "Manual trim successfully validated"
|
||||
Reference in New Issue
Block a user