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# Copyright 2019 Joyent, Inc.
21#
22
23. $STF_SUITE/include/libtest.shlib
24. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
25
26#
27# DESCRIPTION:
28#	Verify 'zpool trim' partial trim.
29#
30# STRATEGY:
31#	1. Create a pool on a single disk and mostly fill it.
32#	2. Expand the pool to create new unallocated metaslabs.
33#	3. Run 'zpool trim' to only TRIM allocated space maps.
34#	4. Verify the disk is least 90% of its original size.
35#	5. Run 'zpool trim' to perform a full TRIM.
36#	6. Verify the disk is less than 10% of its original size.
37
38function cleanup
39{
40	if poolexists $TESTPOOL; then
41		destroy_pool $TESTPOOL
42	fi
43
44	if [[ -d "$TESTDIR" ]]; then
45		rm -rf "$TESTDIR"
46	fi
47
48	log_must set_tunable32 zfs_trim_metaslab_skip 0
49	log_must set_tunable32 zfs_trim_extent_bytes_min $trim_extent_bytes_min
50	log_must set_tunable32 zfs_vdev_min_ms_count $vdev_min_ms_count
51}
52log_onexit cleanup
53
54LARGESIZE=$((MINVDEVSIZE * 4))
55LARGEFILE="$TESTDIR/largefile"
56
57# The minimum number of metaslabs is increased in order to simulate the
58# behavior of partial trimming on a more typically sized 1TB disk.
59typeset vdev_min_ms_count=$(get_tunable zfs_vdev_min_ms_count)
60log_must set_tunable32 zfs_vdev_min_ms_count 64
61
62# Minimum trim size is decreased to verify all trim sizes.
63typeset trim_extent_bytes_min=$(get_tunable zfs_trim_extent_bytes_min)
64log_must set_tunable32 zfs_trim_extent_bytes_min 4096
65
66log_must mkdir "$TESTDIR"
67log_must truncate -s $LARGESIZE "$LARGEFILE"
68log_must zpool create $TESTPOOL "$LARGEFILE"
69# log_must mkfile $(( floor(LARGESIZE * 0.80) )) /$TESTPOOL/file
70fsize=$(( floor(LARGESIZE * 0.80) ))
71cnt=$((fsize / 1048576))
72log_must dd if=/dev/urandom of=/$TESTPOOL/file bs=1048576 count=$cnt
73sync_all_pools
74
75new_size=$(du "$LARGEFILE" | cut -f1)
76new_size=$((new_size * 512))
77log_must test $new_size -le $LARGESIZE
78log_must test $new_size -gt $(( floor(LARGESIZE * 0.70) ))
79
80# Expand the pool to create new unallocated metaslabs.
81log_must zpool export $TESTPOOL
82log_must dd if=/dev/urandom of=$LARGEFILE conv=notrunc \
83    seek=$((LARGESIZE / (1024 * 1024))) bs=$((1024 * 1024)) \
84    count=$((3 * LARGESIZE / (1024 * 1024)))
85log_must zpool import -d $TESTDIR $TESTPOOL
86log_must zpool online -e $TESTPOOL "$LARGEFILE"
87
88new_size=$(du "$LARGEFILE" | cut -f1)
89new_size=$((new_size * 512))
90log_must test $new_size -gt $((4 * floor(LARGESIZE * 0.70) ))
91
92# Perform a partial trim, we expect it to skip most of the new metaslabs
93# which have never been used and therefore do not need be trimmed.
94log_must set_tunable32 zfs_trim_metaslab_skip 1
95log_must zpool trim $TESTPOOL
96log_must set_tunable32 zfs_trim_metaslab_skip 0
97
98sync_all_pools
99while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
100	sleep 0.5
101done
102
103new_size=$(du "$LARGEFILE" | cut -f1)
104new_size=$((new_size * 512))
105log_must test $new_size -gt $LARGESIZE
106
107# Perform a full trim, all metaslabs will be trimmed the pool vdev
108# size will be reduced but not down to its original size due to the
109# space usage of the new metaslabs.
110log_must zpool trim $TESTPOOL
111
112sync_all_pools
113while [[ "$(trim_progress $TESTPOOL $LARGEFILE)" -lt "100" ]]; do
114	sleep 0.5
115done
116
117new_size=$(du "$LARGEFILE" | cut -f1)
118new_size=$((new_size * 512))
119log_must test $new_size -le $(( 2.1 * LARGESIZE))
120log_must test $new_size -gt $(( floor(LARGESIZE * 0.70) ))
121
122log_pass "Manual 'zpool trim' successfully partially trimmed pool"
123