1#!/bin/ksh -p
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright (c) 2018, 2020 by Delphix. All rights reserved.
15#
16
17# DESCRIPTION
18# Verify zfs destroy test for clones with the livelist feature
19# enabled.
20
21# STRATEGY
22# 1. One clone with an empty livelist
23#	- create the clone, check that livelist exists
24#	- delete the clone, check that livelist is eventually
25#	  destroyed
26# 2. One clone with populated livelist
27#	- create the clone, check that livelist exists
28#	- write multiple files to the clone
29#	- delete the clone, check that livelist is eventually
30#	  destroyed
31# 3. Multiple clones with empty livelists
32#	- same as 1. but with multiple clones
33# 4. Multiple clones with populated livelists
34#	- same as 2. but with multiple clones
35# 5. Clone of clone with populated livelists with promote
36
37. $STF_SUITE/include/libtest.shlib
38. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib
39
40function cleanup
41{
42	datasetexists $TESTPOOL/$TESTFS1 && destroy_dataset $TESTPOOL/$TESTFS1 -R
43	# reset the livelist sublist size to its original value
44	set_tunable64 LIVELIST_MAX_ENTRIES $ORIGINAL_MAX
45	log_must zfs inherit compression $TESTPOOL
46}
47
48function clone_write_file
49{
50	log_must mkfile 1m /$TESTPOOL/$1/$2
51	sync_pool $TESTPOOL
52}
53
54function test_one_empty
55{
56	clone_dataset $TESTFS1 snap $TESTCLONE
57
58	log_must zfs destroy $TESTPOOL/$TESTCLONE
59	check_livelist_gone
60}
61
62function test_one
63{
64	clone_dataset $TESTFS1 snap $TESTCLONE
65
66	clone_write_file $TESTCLONE $TESTFILE0
67	clone_write_file $TESTCLONE $TESTFILE1
68	clone_write_file $TESTCLONE $TESTFILE2
69	log_must rm /$TESTPOOL/$TESTCLONE/$TESTFILE0
70	log_must rm /$TESTPOOL/$TESTCLONE/$TESTFILE2
71	check_livelist_exists $TESTCLONE
72
73	log_must zfs destroy $TESTPOOL/$TESTCLONE
74	check_livelist_gone
75}
76
77function test_multiple_empty
78{
79	clone_dataset $TESTFS1 snap $TESTCLONE
80	clone_dataset $TESTFS1 snap $TESTCLONE1
81	clone_dataset $TESTFS1 snap $TESTCLONE2
82
83	log_must zfs destroy $TESTPOOL/$TESTCLONE
84	log_must zfs destroy $TESTPOOL/$TESTCLONE1
85	log_must zfs destroy $TESTPOOL/$TESTCLONE2
86	check_livelist_gone
87}
88
89function test_multiple
90{
91	clone_dataset $TESTFS1 snap $TESTCLONE
92	clone_dataset $TESTFS1 snap $TESTCLONE1
93	clone_dataset $TESTFS1 snap $TESTCLONE2
94
95	clone_write_file $TESTCLONE $TESTFILE0
96
97	clone_write_file $TESTCLONE1 $TESTFILE0
98	clone_write_file $TESTCLONE1 $TESTFILE1
99	clone_write_file $TESTCLONE1 $TESTFILE2
100
101	clone_write_file $TESTCLONE2 $TESTFILE0
102	log_must rm /$TESTPOOL/$TESTCLONE2/$TESTFILE0
103	clone_write_file $TESTCLONE2 $TESTFILE1
104	log_must rm /$TESTPOOL/$TESTCLONE2/$TESTFILE1
105
106	check_livelist_exists $TESTCLONE
107	check_livelist_exists $TESTCLONE1
108	check_livelist_exists $TESTCLONE2
109
110	log_must zfs destroy $TESTPOOL/$TESTCLONE
111	log_must zfs destroy $TESTPOOL/$TESTCLONE1
112	log_must zfs destroy $TESTPOOL/$TESTCLONE2
113	check_livelist_gone
114}
115
116function test_promote
117{
118	clone_dataset $TESTFS1 snap $TESTCLONE
119
120	log_must zfs promote $TESTPOOL/$TESTCLONE
121	check_livelist_gone
122	log_must zfs destroy -R $TESTPOOL/$TESTCLONE
123}
124
125function test_clone_clone_promote
126{
127	log_must zfs create $TESTPOOL/fs
128	log_must dd if=/dev/zero of=/$TESTPOOL/fs/file bs=128k count=100
129	log_must zfs snapshot $TESTPOOL/fs@snap
130	log_must zfs clone $TESTPOOL/fs@snap $TESTPOOL/clone
131	log_must dd if=/dev/zero of=/$TESTPOOL/clone/clonefile bs=128k count=10
132	log_must zfs snapshot $TESTPOOL/clone@csnap
133	log_must zfs clone $TESTPOOL/clone@csnap $TESTPOOL/cloneclone
134
135	check_livelist_exists clone
136	check_livelist_exists cloneclone
137
138	# Promote should remove both clones' livelists
139	log_must zfs promote $TESTPOOL/cloneclone
140	check_livelist_gone
141
142	# This destroy should not use a livelist
143	log_must zfs destroy $TESTPOOL/clone
144	log_must zdb -bcc $TESTPOOL
145}
146
147ORIGINAL_MAX=$(get_tunable LIVELIST_MAX_ENTRIES)
148
149log_onexit cleanup
150# You might think that setting compression=off for $TESTFS1 would be
151# sufficient. You would be mistaken.
152# You need compression=off for whatever the parent of $TESTFS1 is,
153# and $TESTFS1.
154log_must zfs set compression=off $TESTPOOL
155log_must zfs create $TESTPOOL/$TESTFS1
156log_must mkfile 20m /$TESTPOOL/$TESTFS1/atestfile
157log_must zfs snapshot $TESTPOOL/$TESTFS1@snap
158
159# set a small livelist entry size to more easily test multiple entry livelists
160set_tunable64 LIVELIST_MAX_ENTRIES 20
161
162test_one_empty
163test_one
164test_multiple_empty
165test_multiple
166test_promote
167test_clone_clone_promote
168
169log_pass "Clone with the livelist feature enabled could be destroyed," \
170	"also could be promoted and destroyed as expected."
171