1#!/bin/ksh
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) 2012, 2016 by Delphix. All rights reserved.
15#
16
17# DESCRIPTION
18#	zfs destroy <dataset@snap1,snap2..> can destroy a list of multiple
19#	snapshots from the same datasets
20#
21# STRATEGY
22#	1. Create multiple snapshots for the same datset
23#	2. Run zfs destroy for these snapshots for a mix of valid and
24#	   invalid snapshot names
25#	3. Run zfs destroy for snapshots from different datasets and
26#	   pools
27
28. $STF_SUITE/include/libtest.shlib
29. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy.cfg
30
31function cleanup
32{
33	datasetexists $TESTPOOL/$TESTFS1 && zfs destroy -R $TESTPOOL/$TESTFS1
34	datasetexists $TESTPOOL/$TESTFS2 && zfs destroy -R $TESTPOOL/$TESTFS2
35	poolexists $TESTPOOL2 && zpool destroy $TESTPOOL2
36	rm -rf $VIRTUAL_DISK
37}
38
39log_assert "zfs destroy for multiple snapshot is handled correctly"
40log_onexit cleanup
41
42zfs create $TESTPOOL/$TESTFS1
43typeset -i i=1
44snaplist=""
45log_note "zfs destroy on valid snapshot names"
46for i in 1 2 3 4 5; do
47	log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i
48	snaplist=$snaplist,snap$i
49done
50snaplist=${snaplist#,}
51log_must zfs destroy $TESTPOOL/$TESTFS1@$snaplist
52for i in 1 2 3 4 5; do
53	log_mustnot snapexists $TESTPOOL/$TESFS1@snap$i
54done
55
56log_note "zfs destroy with all bogus snapshot names"
57log_mustnot zfs destroy $TESTPOOL/$TESTFS1@snap12,snap21,sna@pple1@,s""nappy2
58
59log_note "zfs destroy with some bogus snapshot names"
60for i in 1 2 3; do
61	log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i
62done
63log_must zfs destroy $TESTPOOL/$TESTFS1@snap1,snap2,snapple1,snappy2,snap3
64for i in 1 2 3; do
65	log_mustnot snapexists $TESTPOOL/$TESTFS1@snap$i
66done
67
68log_note "zfs destroy with some snapshot names having special characters"
69for i in 1 2 3; do
70	log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i
71done
72log_must zfs destroy $TESTPOOL/$TESTFS1@snap1,@,snap2,,,,snap3,
73for i in 1 2 3; do
74	log_mustnot snapexists $TESTPOOL/$TESTFS1@snap$i
75done
76log_note "zfs destroy for too many snapshots"
77snaplist=""
78for i in {1..100}; do
79	log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i
80	snaplist=$snaplist,snap$i
81done
82snaplist=${snaplist#,}
83log_must zfs destroy $TESTPOOL/$TESTFS1@$snaplist
84for i in {1..100}; do
85	log_mustnot snapexists $TESTPOOL/$TESTFS1@snap$i
86done
87log_note "zfs destroy multiple snapshots with hold"
88snaplist=""
89for i in 1 2 3 4 5; do
90	log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i
91	log_must zfs hold keep $TESTPOOL/$TESTFS1@snap$i
92	snaplist=$snaplist,snap$i
93done
94snaplist=${snaplist#,}
95log_mustnot zfs destroy $TESTPOOL/$TESTFS1@$snaplist
96for i in 1 2 3 4 5; do
97	log_must zfs release keep $TESTPOOL/$TESTFS1@snap$i
98done
99log_must zfs destroy $TESTPOOL/$TESTFS1@$snaplist
100
101log_note "zfs destroy for multiple snapshots having clones"
102for i in 1 2 3 4 5; do
103	log_must zfs snapshot $TESTPOOL/$TESTFS1@snap$i
104done
105snaplist=""
106for i in 1 2 3 4 5; do
107	log_must zfs clone $TESTPOOL/$TESTFS1@snap$i $TESTPOOL/$TESTFS1/clone$i
108	snaplist=$snaplist,snap$i
109done
110snaplist=${snaplist#,}
111log_mustnot zfs destroy $TESTPOOL/$TESTFS1@$snaplist
112for i in 1 2 3 4 5; do
113	log_must snapexists $TESTPOOL/$TESTFS1@snap$i
114	log_must zfs destroy $TESTPOOL/$TESTFS1/clone$i
115done
116
117log_note "zfs destroy for snapshots for different datasets"
118log_must zfs create $TESTPOOL/$TESTFS2
119log_must zfs snapshot $TESTPOOL/$TESTFS2@fs2snap
120log_must zfs create $TESTPOOL/$TESTFS1/$TESTFS2
121log_must zfs snapshot $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
122
123long_arg=$TESTPOOL/$TESTFS1@snap1,$TESTPOOL/$TESTFS2@fs2snap,
124long_arg=$long_arg$TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
125log_must zfs destroy $long_arg
126log_mustnot snapexists $TESTPOOL/$TESTFS1@snap1
127log_must snapexists $TESTPOOL/$TESTFS2@fs2snap
128log_must snapexists $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
129
130log_must zfs destroy $TESTPOOL/$TESTFS1@fs2snap,fs12snap,snap2
131log_must snapexists $TESTPOOL/$TESTFS2@fs2snap
132log_must snapexists $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
133log_mustnot snapexists $TESTPOOL/$TESTFS1@snap2
134
135log_must zfs destroy $TESTPOOL/$TESTFS2@fs2snap,fs12snap,snap3
136log_mustnot snapexists $TESTPOOL/$TESTFS2@fs2snap
137log_must snapexists $TESTPOOL/$TESTFS1/$TESTFS2@fs12snap
138log_must snapexists $TESTPOOL/$TESTFS1@snap3
139
140log_note "zfs destroy for snapshots from different pools"
141VIRTUAL_DISK=/var/tmp/disk
142log_must mkfile $MINVDEVSIZE $VIRTUAL_DISK
143log_must zpool create $TESTPOOL2 $VIRTUAL_DISK
144log_must poolexists $TESTPOOL2
145
146log_must zfs create $TESTPOOL2/$TESTFS1
147log_must zfs snapshot $TESTPOOL2/$TESTFS1@snap
148long_arg=$TESTPOOL2/$TESTFS1@snap,$TESTPOOL/$TESTFS1@snap3,
149long_arg=$long_arg$TESTPOOL/$TESTFS1@snap5
150log_must zfs destroy $long_arg
151log_mustnot snapexists $TESTPOOL2/$TESTFS1@snap
152log_must snapexists $TESTPOOL/$TESTFS1@snap3
153log_must snapexists $TESTPOOL/$TESTFS1@snap5
154
155log_must zfs snapshot $TESTPOOL2/$TESTFS1@snap
156log_must zfs destroy $TESTPOOL2/$TESTFS1@snap5,snap3,snap
157log_mustnot snapexists $TESTPOOL2/$TESTFS1@snap
158log_must snapexists $TESTPOOL/$TESTFS1@snap3
159log_must snapexists $TESTPOOL/$TESTFS1@snap5
160
161log_pass "zfs destroy for multiple snapshots passes"
162