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 && zfs destroy -R $TESTPOOL/$TESTFS1
43	# reset the livelist sublist size to its original value
44	set_tunable64 LIVELIST_MAX_ENTRIES $ORIGINAL_MAX
45}
46
47function clone_write_file
48{
49	log_must mkfile 1m /$TESTPOOL/$1/$2
50	log_must zpool sync $TESTPOOL
51}
52
53function test_one_empty
54{
55	clone_dataset $TESTFS1 snap $TESTCLONE
56
57	log_must zfs destroy $TESTPOOL/$TESTCLONE
58	check_livelist_gone
59}
60
61function test_one
62{
63	clone_dataset $TESTFS1 snap $TESTCLONE
64
65	clone_write_file $TESTCLONE $TESTFILE0
66	clone_write_file $TESTCLONE $TESTFILE1
67	clone_write_file $TESTCLONE $TESTFILE2
68	log_must rm /$TESTPOOL/$TESTCLONE/$TESTFILE0
69	log_must rm /$TESTPOOL/$TESTCLONE/$TESTFILE2
70	check_livelist_exists $TESTCLONE
71
72	log_must zfs destroy $TESTPOOL/$TESTCLONE
73	check_livelist_gone
74}
75
76function test_multiple_empty
77{
78	clone_dataset $TESTFS1 snap $TESTCLONE
79	clone_dataset $TESTFS1 snap $TESTCLONE1
80	clone_dataset $TESTFS1 snap $TESTCLONE2
81
82	log_must zfs destroy $TESTPOOL/$TESTCLONE
83	log_must zfs destroy $TESTPOOL/$TESTCLONE1
84	log_must zfs destroy $TESTPOOL/$TESTCLONE2
85	check_livelist_gone
86}
87
88function test_multiple
89{
90	clone_dataset $TESTFS1 snap $TESTCLONE
91	clone_dataset $TESTFS1 snap $TESTCLONE1
92	clone_dataset $TESTFS1 snap $TESTCLONE2
93
94	clone_write_file $TESTCLONE $TESTFILE0
95
96	clone_write_file $TESTCLONE1 $TESTFILE0
97	clone_write_file $TESTCLONE1 $TESTFILE1
98	clone_write_file $TESTCLONE1 $TESTFILE2
99
100	clone_write_file $TESTCLONE2 $TESTFILE0
101	log_must rm /$TESTPOOL/$TESTCLONE2/$TESTFILE0
102	clone_write_file $TESTCLONE2 $TESTFILE1
103	log_must rm /$TESTPOOL/$TESTCLONE2/$TESTFILE1
104
105	check_livelist_exists $TESTCLONE
106	check_livelist_exists $TESTCLONE1
107	check_livelist_exists $TESTCLONE2
108
109	log_must zfs destroy $TESTPOOL/$TESTCLONE
110	log_must zfs destroy $TESTPOOL/$TESTCLONE1
111	log_must zfs destroy $TESTPOOL/$TESTCLONE2
112	check_livelist_gone
113}
114
115function test_promote
116{
117	clone_dataset $TESTFS1 snap $TESTCLONE
118
119	log_must zfs promote $TESTPOOL/$TESTCLONE
120	check_livelist_gone
121	log_must zfs destroy -R $TESTPOOL/$TESTCLONE
122}
123
124function test_clone_clone_promote
125{
126	log_must zfs create $TESTPOOL/fs
127	log_must dd if=/dev/zero of=/$TESTPOOL/fs/file bs=128k count=100
128	log_must zfs snapshot $TESTPOOL/fs@snap
129	log_must zfs clone $TESTPOOL/fs@snap $TESTPOOL/clone
130	log_must dd if=/dev/zero of=/$TESTPOOL/clone/clonefile bs=128k count=10
131	log_must zfs snapshot $TESTPOOL/clone@csnap
132	log_must zfs clone $TESTPOOL/clone@csnap $TESTPOOL/cloneclone
133
134	check_livelist_exists clone
135	check_livelist_exists cloneclone
136
137	# Promote should remove both clones' livelists
138	log_must zfs promote $TESTPOOL/cloneclone
139	check_livelist_gone
140
141	# This destroy should not use a livelist
142	log_must zfs destroy $TESTPOOL/clone
143	log_must zdb -bcc $TESTPOOL
144}
145
146ORIGINAL_MAX=$(get_tunable LIVELIST_MAX_ENTRIES)
147
148log_onexit cleanup
149log_must zfs create $TESTPOOL/$TESTFS1
150log_must mkfile 20m /$TESTPOOL/$TESTFS1/atestfile
151log_must zfs snapshot $TESTPOOL/$TESTFS1@snap
152
153# set a small livelist entry size to more easily test multiple entry livelists
154set_tunable64 LIVELIST_MAX_ENTRIES 20
155
156test_one_empty
157test_one
158test_multiple_empty
159test_multiple
160test_promote
161test_clone_clone_promote
162
163log_pass "Clone with the livelist feature enabled could be destroyed," \
164	"also could be promoted and destroyed as expected."
165