Skip to content

Commit 7895c6e

Browse files
author
Paul Dagnelie
committed
Add more DDT tests
The new Fast Dedup feature has a lot of moving parts, and only some of them have tests. We have some tests for prefetch and quota, and a generic ZAP shrinking test, but we don't have anything for the pruning command or specific to DDT zap shrinking. Here we add a couple small new tests for zpool ddtprune and DDT-specific ZAP shrinking. Sponsored-by: Klara, Inc. Sponsored-by: iXsystems, Inc. Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
1 parent a44f423 commit 7895c6e

File tree

5 files changed

+183
-1
lines changed

5 files changed

+183
-1
lines changed

cmd/zdb/zdb.c

+2
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,8 @@ dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
20592059
if (dump_opt['D'] < 3)
20602060
return;
20612061

2062+
(void) printf("%s: object=%llu\n", name,
2063+
(u_longlong_t)ddt->ddt_object[type][class]);
20622064
zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]);
20632065

20642066
if (dump_opt['D'] < 4)

tests/runfiles/common.run

+1-1
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ tags = ['functional', 'deadman']
683683
[tests/functional/dedup]
684684
tests = ['dedup_fdt_create', 'dedup_fdt_import', 'dedup_legacy_create',
685685
'dedup_legacy_import', 'dedup_legacy_fdt_upgrade',
686-
'dedup_legacy_fdt_mixed', 'dedup_quota']
686+
'dedup_legacy_fdt_mixed', 'dedup_quota', 'dedup_prune', 'dedup_zap_shrink']
687687
pre =
688688
post =
689689
tags = ['functional', 'dedup']

tests/zfs-tests/tests/Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,9 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
14441444
functional/dedup/dedup_legacy_import.ksh \
14451445
functional/dedup/dedup_legacy_fdt_upgrade.ksh \
14461446
functional/dedup/dedup_legacy_fdt_mixed.ksh \
1447+
functional/dedup/dedup_prune.ksh \
14471448
functional/dedup/dedup_quota.ksh \
1449+
functional/dedup/dedup_zap_shrink.ksh \
14481450
functional/delegate/cleanup.ksh \
14491451
functional/delegate/setup.ksh \
14501452
functional/delegate/zfs_allow_001_pos.ksh \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/bin/ksh -p
2+
# CDDL HEADER START
3+
#
4+
# The contents of this file are subject to the terms of the
5+
# Common Development and Distribution License (the "License").
6+
# You may not use this file except in compliance with the License.
7+
#
8+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9+
# or https://opensource.org/licenses/CDDL-1.0.
10+
# See the License for the specific language governing permissions
11+
# and limitations under the License.
12+
#
13+
# When distributing Covered Code, include this CDDL HEADER in each
14+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15+
# If applicable, add the following below this CDDL HEADER, with the
16+
# fields enclosed by brackets "[]" replaced with your own identifying
17+
# information: Portions Copyright [yyyy] [name of copyright owner]
18+
#
19+
# CDDL HEADER END
20+
#
21+
22+
#
23+
# Copyright (c) 2025, Klara Inc.
24+
#
25+
26+
# DESCRIPTION:
27+
# Verify that zpool ddtprune successfully reduces the number of entries
28+
# in the DDT.
29+
#
30+
# STRATEGY:
31+
# 1. Create a pool with dedup=on
32+
# 2. Add duplicate entries to the DDT
33+
# 3. Verify ddtprune doesn't remove duplicate entries
34+
# 4. Convert some entries to non-duplicate
35+
# 5. Verify ddtprune removes non-duplicate entries
36+
#
37+
38+
. $STF_SUITE/include/libtest.shlib
39+
. $STF_SUITE/tests/functional/events/events_common.kshlib
40+
41+
verify_runnable "both"
42+
43+
log_assert "Verify DDT pruning correctly removes non-duplicate entries"
44+
45+
# We set the dedup log txg interval to 1, to get a log flush every txg,
46+
# effectively disabling the log. Without this it's hard to predict when
47+
# entries appear in the DDT ZAP
48+
log_must save_tunable DEDUP_LOG_TXG_MAX
49+
log_must set_tunable32 DEDUP_LOG_TXG_MAX 1
50+
51+
function cleanup
52+
{
53+
if poolexists $TESTPOOL ; then
54+
destroy_pool $TESTPOOL
55+
fi
56+
log_must restore_tunable DEDUP_LOG_TXG_MAX
57+
}
58+
59+
function ddt_entries
60+
{
61+
typeset -i entries=$(zpool status -D $TESTPOOL | \
62+
grep "dedup: DDT entries" | awk '{print $4}')
63+
64+
echo ${entries}
65+
}
66+
67+
log_onexit cleanup
68+
69+
log_must zpool create -f -o feature@block_cloning=disabled $TESTPOOL $DISKS
70+
71+
log_must zfs create -o recordsize=512 -o dedup=on $TESTPOOL/$TESTFS
72+
typeset mountpoint=$(get_prop mountpoint $TESTPOOL/$TESTFS)
73+
log_must dd if=/dev/urandom of=$mountpoint/f1 bs=512k count=1
74+
log_must cp $mountpoint/f1 $mountpoint/f2
75+
sync_pool $TESTPOOL
76+
entries=$(ddt_entries)
77+
log_note "ddt entries before: $entries"
78+
79+
log_must zpool ddtprune -p 100 $TESTPOOL
80+
sync_pool $TESTPOOL
81+
new_entries=$(ddt_entries)
82+
[[ "$entries" -eq "$new_entries" ]] || \
83+
log_fail "DDT entries changed from $entries to $new_entries"
84+
85+
log_must truncate -s 128k $mountpoint/f2
86+
sync_pool $TESTPOOL
87+
sleep 1
88+
log_must zpool ddtprune -p 100 $TESTPOOL
89+
sync_pool $TESTPOOL
90+
91+
new_entries=$(ddt_entries)
92+
[[ "$((entries / 4))" -eq "$new_entries" ]] || \
93+
log_fail "DDT entries did not shrink enough: $entries -> $new_entries"
94+
95+
96+
log_pass "DDT pruning correctly removes non-duplicate entries"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#! /bin/ksh -p
2+
#
3+
# CDDL HEADER START
4+
#
5+
# The contents of this file are subject to the terms of the
6+
# Common Development and Distribution License (the "License").
7+
# You may not use this file except in compliance with the License.
8+
#
9+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10+
# or https://opensource.org/licenses/CDDL-1.0.
11+
# See the License for the specific language governing permissions
12+
# and limitations under the License.
13+
#
14+
# When distributing Covered Code, include this CDDL HEADER in each
15+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16+
# If applicable, add the following below this CDDL HEADER, with the
17+
# fields enclosed by brackets "[]" replaced with your own identifying
18+
# information: Portions Copyright [yyyy] [name of copyright owner]
19+
#
20+
# CDDL HEADER END
21+
#
22+
23+
#
24+
# Copyright (c) 2024, 2025, Klara Inc.
25+
#
26+
27+
. $STF_SUITE/include/libtest.shlib
28+
29+
#
30+
# DESCRIPTION:
31+
# Create a large number of entries in the DDT. Then remove all entries and
32+
# check that the DDT zap was shrunk. Use zdb to check that the zap object
33+
# contains only one leaf block using zdb.
34+
#
35+
36+
verify_runnable "global"
37+
38+
log_assert "Create a large number of entries in the DDT. " \
39+
"Ensure DDT ZAP object shrank after removing entries."
40+
41+
# We set the dedup log txg interval to 1, to get a log flush every txg,
42+
# effectively disabling the log. Without this it's hard to predict when
43+
# entries appear in the DDT ZAP
44+
log_must save_tunable DEDUP_LOG_TXG_MAX
45+
log_must set_tunable32 DEDUP_LOG_TXG_MAX 1
46+
47+
function cleanup
48+
{
49+
if poolexists $TESTPOOL ; then
50+
destroy_pool $TESTPOOL
51+
fi
52+
log_must restore_tunable DEDUP_LOG_TXG_MAX
53+
}
54+
55+
log_onexit cleanup
56+
57+
log_must create_pool $TESTPOOL $DISKS
58+
log_must zfs create -o dedup=sha256 -o recordsize=512 $TESTPOOL/$TESTFS
59+
typeset mountpoint=$(get_prop mountpoint $TESTPOOL/$TESTFS)
60+
61+
log_must dd if=/dev/urandom of=$mountpoint/file bs=512k count=1
62+
sync_pool $TESTPOOL
63+
64+
zap_obj=$(zdb -DDD $TESTPOOL | grep "DDT-sha256-zap-unique" | sed -n 's/.*object=//p')
65+
66+
nleafs=$(zdb -dddd $TESTPOOL "$zap_obj" | grep "Leaf blocks:" | awk -F\: '{print($2);}')
67+
log_must test 1 -lt $nleafs
68+
69+
nleafs_old=$nleafs
70+
71+
log_must truncate -s 512 $mountpoint/file
72+
sync_pool $TESTPOOL
73+
nleafs=$(zdb -dddd $TESTPOOL "$zap_obj" | grep "Leaf blocks:" | awk -F\: '{print($2);}')
74+
log_must test $nleafs -lt $nleafs_old
75+
76+
log_must zpool export $TESTPOOL
77+
log_must zpool import $TESTPOOL
78+
79+
nleafs=$(zdb -dddd $TESTPOOL "$zap_obj" | grep "Leaf blocks:" | awk -F\: '{print($2);}')
80+
log_must test $nleafs -lt $nleafs_old
81+
82+
log_pass "ZAP object shrank after removing entries."

0 commit comments

Comments
 (0)