summaryrefslogtreecommitdiff
path: root/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_010_pos.ksh
blob: cd471999e0c0c5ff462900974fbc526b5237e2a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/bin/ksh
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.

# A full copy of the text of the CDDL should have accompanied this
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#

#
# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
#

. $STF_SUITE/include/libtest.shlib

#
# DESCRIPTION:
#	Verify 'zfs list -t all -o name,origin,clones' prints the correct
#	clone information
#
# STRATEGY:
#	1. Create datasets
#	2. Create recursive snapshots and their clones
#	3. Verify zfs clones property displays right information for different
#	   cases
#

verify_runnable "both"

function local_cleanup
{
	typeset -i i=1
	for ds in $datasets; do
                datasetexists $ds/$TESTCLONE.$i && \
		    log_must zfs destroy -rf $ds/$TESTCLONE.$i
                datasetexists $ds && log_must zfs destroy -Rf $ds
		((i=i+1))
	done
}

# Set up filesystem with clones
function setup_ds
{
	typeset -i i=1
	# create nested datasets
	log_must zfs create -p $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3

	# verify dataset creation
	for ds in $datasets; do
		datasetexists $ds || log_fail "Create $ds dataset fail."
	done

	# create recursive nested snapshot
	log_must zfs snapshot -r $TESTPOOL/$TESTFS1@snap
	for ds in $datasets; do
		datasetexists $ds@snap || \
		    log_fail "Create $ds@snap snapshot fail."
	done
	for ds in $datasets; do
		for fs in $datasets; do
			log_must zfs clone $ds@snap $fs/$TESTCLONE.$i
		done
		((i=i+1))
	done
}

# Verify clone list
function verify_clones
{
	typeset -i no_clones=$1
	typeset unexpected=$2
	typeset clone_snap=$3
	typeset -i i=1
	for ds in $datasets; do
		if [[ -n $clone_snap ]]; then
			clone_snap=/$TESTCLONE.$i
		fi
		snapshot=$(echo "$names" | grep $ds$clone_snap@snap)
		actual_clone=$(zfs list -t all -o clones $snapshot | tail -1)
		save=$IFS
		IFS=','
		typeset -a clones=()
		for token in $actual_clone; do
			clones=( "${clones[@]}" "$token" )
		done
		IFS=$save
		[[ ${#clones[*]} -ne $no_clones ]] && \
		    log_fail "$snapshot has unexpected number of clones" \
		        " ${#clones[*]}"
		expected_clone=""
		unexpected_clone=""
		if [[ $unexpected -eq 1 ]]; then
			for fs in $datasets; do
				if [[ $fs == $ds ]]; then
					if [[ -z $clone_snap ]]; then
						unexpected_clone=$fs/$TESTCLONE.$i
						(for match in ${clones[@]};do
						[[ $match != $unexpected_clone ]] && \
						    exit 0; done) || log_fail \
					            "Unexpected clones of the snapshot"
					else
						expected_clone=$fs
						unexpected_clone=$fs/$TESTCLONE.$i
						(for match in ${clones[@]};do
						[[ $match == $expected_clone ]] && \
						    [[ $match != $unexpected_clone ]] \
						    && exit 0; done) || log_fail \
						    "Unexpected clones of the snapshot"
					fi
				else
					expected_clone=$fs/$TESTCLONE.$i
					(for match in ${clones[@]};do
					[[ $match == $expected_clone ]] && \
					    exit 0; done) || log_fail \
					    "Unexpected clones of the snapshot"
				fi
			done
		else
			for fs in $datasets; do
				expected_clone=$fs/$TESTCLONE.$i
				(for match in ${clones[@]};do
				[[ $match == $expected_clone ]] && exit 0; \
				    done) || log_fail "Unexpected clones" \
				    " of the snapshot"
			done
		fi
		((i=i+1))
	done
}


log_onexit local_cleanup
datasets="$TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1/$TESTFS2
    $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3"

typeset -a d_clones
typeset -a deferred_snaps
typeset -i i
i=1
log_must setup_ds

log_note "Verify zfs clone propery for multiple clones"
names=$(zfs list -rt all -o name $TESTPOOL)
log_must verify_clones 3 0

log_note "verfify clone property for clone deletion"
i=1
for ds in $datasets; do
	log_must zfs destroy $ds/$TESTCLONE.$i
	((i=i+1))
done
names=$(zfs list -rt all -o name $TESTPOOL)
i=1
log_must verify_clones 2 1

log_must local_cleanup
log_must setup_ds

log_note "verify zfs deferred destroy on clones property"
i=1
names=$(zfs list -rt all -o name $TESTPOOL)
for ds in $datasets; do
	log_must zfs destroy -d $ds@snap
	deferred_snaps=( "${deferred_snaps[@]}" "$ds@snap" )
	((i=i+1))
done
log_must verify_clones 3 0

log_note "verify zfs deferred destroy by destroying clones on clones property"
d_clones=()
i=1
for ds in $datasets; do
	for fs in $datasets; do
		log_must zfs destroy $fs/$TESTCLONE.$i
		d_clones=( "${d_clones[@]}" "$fs/$TESTCLONE.$i" )
	done
	((i=i+1))
done
names=$(zfs list -rtall -o name $TESTPOOL)
for snap in ${deferred_snaps[@]}; do
	status=$(echo "$names" | grep $snap)
	[[ -z $status ]] || \
	    log_fail "$snap exist after deferred destroy"
done
for dclone in ${d_clones[@]}; do
	log_note "D CLONE = $dclone"
	status=$(echo "$names" | grep $dclone)
	[[ -z $status ]] || \
	    log_fail "$dclone exist after deferred destroy"
done

log_must local_cleanup
log_must setup_ds
log_note "verify clone property for zfs promote"
i=1
for ds in $datasets; do
	log_must zfs promote $ds/$TESTCLONE.$i
	((i=i+1))
done
names=$(zfs list -rt all -o name,clones $TESTPOOL)
log_must verify_clones 3 1 $TESTCLONE
i=1
for ds in $datasets; do
	log_must zfs promote $ds
	((i=i+1))
done
log_must local_cleanup

log_note "verify clone list truncated correctly"
typeset -i j=200
i=1
fs=$TESTPOOL/$TESTFS1
log_must zfs create $fs
log_must zfs snapshot $fs@snap
while((i < 7)); do
	log_must zfs clone $fs@snap $fs/$TESTCLONE$(python -c 'print "x" * 200').$i
	((i=i+1))
	((j=j+200))
done
clone_list=$(zfs list -o clones $fs@snap)
char_count=$(echo "$clone_list" | tail -1 | wc | awk '{print $3}')
[[ $char_count -eq 1024 ]] || \
    log_fail "Clone list not truncated correctly. Unexpected character count" \
        "$char_count"

log_pass "'zfs list -o name,origin,clones prints the correct clone information."