1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# This file and its contents are supplied under the terms of the
6# Common Development and Distribution License ("CDDL"), version 1.0.
7# You may only use this file in accordance with the terms of version
8# 1.0 of the CDDL.
9#
10# A full copy of the text of the CDDL should have accompanied this
11# source.  A copy of the CDDL is also available via the Internet at
12# http://www.illumos.org/license/CDDL.
13#
14# CDDL HEADER END
15#
16
17#
18# Copyright (c) 2019 by Tim Chase. All rights reserved.
19# Copyright (c) 2019 Lawrence Livermore National Security, LLC.
20#
21
22. $STF_SUITE/include/libtest.shlib
23. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
24
25#
26# DESCRIPTION:
27#	Verify 'zpool trim' partial trim.
28#
29# STRATEGY:
30#	1. Create a pool on a single disk and mostly fill it.
31#	2. Expand the pool to create new unallocated metaslabs.
32#	3. Run 'zpool trim' to only TRIM allocated space maps.
33#	4. Verify the disk is least 90% of its original size.
34#	5. Run 'zpool trim' to perform a full TRIM.
35#	6. Verify the disk is less than 10% of its original size.
36
37function cleanup
38{
39	if poolexists $TESTPOOL; then
40		destroy_pool $TESTPOOL
41	fi
42
43	if [[ -d "$TESTDIR" ]]; then
44		rm -rf "$TESTDIR"
45	fi
46
47	log_must set_tunable64 TRIM_METASLAB_SKIP 0
48	log_must set_tunable64 TRIM_EXTENT_BYTES_MIN $trim_extent_bytes_min
49	log_must set_tunable64 VDEV_MIN_MS_COUNT $vdev_min_ms_count
50}
51log_onexit cleanup
52
53LARGESIZE=$((MINVDEVSIZE * 4))
54LARGEFILE="$TESTDIR/largefile"
55
56# The minimum number of metaslabs is increased in order to simulate the
57# behavior of partial trimming on a more typically sized 1TB disk.
58typeset vdev_min_ms_count=$(get_tunable VDEV_MIN_MS_COUNT)
59log_must set_tunable64 VDEV_MIN_MS_COUNT 64
60
61# Minimum trim size is decreased to verify all trim sizes.
62typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN)
63log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096
64
65log_must mkdir "$TESTDIR"
66log_must truncate -s $LARGESIZE "$LARGEFILE"
67log_must zpool create $TESTPOOL "$LARGEFILE"
68log_must mkfile $(( floor(LARGESIZE * 0.80) )) /$TESTPOOL/file
69log_must zpool sync
70
71new_size=$(du -B1 "$LARGEFILE" | cut -f1)
72log_must test $new_size -le $LARGESIZE
73log_must test $new_size -gt $(( floor(LARGESIZE * 0.70) ))
74
75# Expand the pool to create new unallocated metaslabs.
76log_must zpool export $TESTPOOL
77log_must dd if=/dev/urandom of=$LARGEFILE conv=notrunc,nocreat \
78    seek=$((LARGESIZE / (1024 * 1024))) bs=$((1024 * 1024)) \
79    count=$((3 * LARGESIZE / (1024 * 1024)))
80log_must zpool import -d $TESTDIR $TESTPOOL
81log_must zpool online -e $TESTPOOL "$LARGEFILE"
82
83new_size=$(du -B1 "$LARGEFILE" | cut -f1)
84log_must test $new_size -gt $((4 * floor(LARGESIZE * 0.70) ))
85
86# Perform a partial trim, we expect it to skip most of the new metaslabs
87# which have never been used and therefore do not need be trimmed.
88log_must set_tunable64 TRIM_METASLAB_SKIP 1
89log_must zpool trim $TESTPOOL
90log_must set_tunable64 TRIM_METASLAB_SKIP 0
91
92log_must zpool sync
93while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
94	sleep 0.5
95done
96
97new_size=$(du -B1 "$LARGEFILE" | cut -f1)
98log_must test $new_size -gt $LARGESIZE
99
100# Perform a full trim, all metaslabs will be trimmed the pool vdev
101# size will be reduced but not down to its original size due to the
102# space usage of the new metaslabs.
103log_must zpool trim $TESTPOOL
104
105log_must zpool sync
106while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
107	sleep 0.5
108done
109
110new_size=$(du -B1 "$LARGEFILE" | cut -f1)
111log_must test $new_size -le $(( 2 * LARGESIZE))
112log_must test $new_size -gt $(( floor(LARGESIZE * 0.70) ))
113
114log_pass "Manual 'zpool trim' successfully partially trimmed pool"
115