Skip snapshot in zfs_iter_mounted()
[freebsd.git] / tests / zfs-tests / tests / functional / cli_root / zfs_unmount / zfs_unmount_nested.ksh
1 #!/bin/ksh -p
2 #
3 # CDDL HEADER START
4 #
5 # This file and its contents are supplied under the terms of the
6 # Common Development and Distribution License ("CDDL"), version 1.0.
7 # You may only use this file in accordance with the terms of version
8 # 1.0 of the CDDL.
9 #
10 # A full copy of the text of the CDDL should have accompanied this
11 # source.  A copy is of the CDDL is also available via the Internet
12 # at http://www.illumos.org/license/CDDL.
13 #
14 # CDDL HEADER END
15 #
16
17 #
18 # Copyright (c) 2018 Datto Inc.
19 #
20
21 . $STF_SUITE/include/libtest.shlib
22
23 #
24 # DESCRIPTION:
25 #       zfs unmount should work on nested datasets
26 #
27 # STRATEGY:
28 #       1. Create a set of nested datasets
29 #       2. Unmount a nested dataset and make sure it is unmounted
30 #       3. Ensure the dataset deeper than the one above is also unmounted
31 #       4. Ensure the datasets shallower than the unmounted one is still mounted
32 #       5. Repeat from step 2 with other mountpoint values and shallower nesting
33 #
34
35 verify_runnable "both"
36
37 function nesting_cleanup
38 {
39         log_must zfs destroy -fR $TESTPOOL/a
40         log_must zfs destroy -fR $TESTPOOL/b
41         log_must zfs destroy -fR $TESTPOOL/c
42         log_must zfs destroy -fR $TESTPOOL/d
43 }
44
45 log_onexit nesting_cleanup
46
47 set -A test_depths 30 16 3
48 typeset mountpoint=/$TESTPOOL/mnt
49
50 dsA32=$(printf 'a/%.0s' {1..32})"a"
51 log_must zfs create -p $TESTPOOL/$dsA32
52
53 dsB32=$(printf 'b/%.0s' {1..32})"b"
54 log_must zfs create -o mountpoint=none -p $TESTPOOL/$dsB32
55 # FreeBSD's mount command ignores the mountpoint property.
56 if ! is_freebsd; then
57         log_mustnot mount -t zfs $TESTPOOL/$dsB32 /mnt
58 fi
59
60 dsC32=$(printf 'c/%.0s' {1..32})"c"
61 log_must zfs create -o mountpoint=legacy -p $TESTPOOL/$dsC32
62 log_must mount -t zfs $TESTPOOL/$dsC32 /mnt
63
64 dsD32=$(printf 'd/%.0s' {1..32})"d"
65 log_must zfs create -o mountpoint=$mountpoint -p $TESTPOOL/$dsD32
66
67
68 for d in ${test_depths[@]}; do
69         # default mountpoint
70         ds_pre=$(printf 'a/%.0s' {1..$(($d-2))})"a"
71         ds=$(printf 'a/%.0s' {1..$(($d-1))})"a"
72         ds_post=$(printf 'a/%.0s' {1..$(($d))})"a"
73         if ! ismounted $TESTPOOL/$ds_pre; then
74                 log_fail "$TESTPOOL/$ds_pre (pre) not initially mounted"
75         fi
76         if ! ismounted $TESTPOOL/$ds; then
77                 log_fail "$TESTPOOL/$ds not initially mounted"
78         fi
79         if ! ismounted $TESTPOOL/$ds_post; then
80                 log_fail "$TESTPOOL/$ds_post (post) not initially mounted"
81         fi
82
83         log_must zfs snapshot $TESTPOOL/$ds@snap
84         # force snapshot mount in .zfs
85         log_must ls /$TESTPOOL/$ds/.zfs/snapshot/snap
86         log_must_nostderr zfs unmount $TESTPOOL/$ds
87
88         if ! ismounted $TESTPOOL/$ds_pre; then
89                 log_fail "$ds_pre is not mounted"
90         fi
91         if ismounted $TESTPOOL/$ds; then
92                 log_fail "$ds is mounted"
93         fi
94         if ismounted $TESTPOOL/$ds_post; then
95                 log_fail "$ds_post (post) is mounted"
96         fi
97
98
99         # mountpoint=none
100         ds_pre=$(printf 'b/%.0s' {1..$(($d-2))})"b"
101         ds=$(printf 'b/%.0s' {1..$(($d-1))})"b"
102         ds_post=$(printf 'b/%.0s' {1..$(($d))})"b"
103         if ! ismounted $TESTPOOL/$ds_pre; then
104                 log_fail "$TESTPOOL/$ds_pre (pre) not initially mounted"
105         fi
106         if ! ismounted $TESTPOOL/$ds; then
107                 log_fail "$TESTPOOL/$ds not initially mounted"
108         fi
109         if ! ismounted $TESTPOOL/$ds_post; then
110                 log_fail "$TESTPOOL/$ds_post (post) not initially mounted"
111         fi
112
113         log_must zfs snapshot $TESTPOOL/$ds@snap
114         # force snapshot mount in .zfs
115         log_must ls /$TESTPOOL/$ds/.zfs/snapshot/snap
116         log_must_nostderr zfs unmount $TESTPOOL/$ds
117
118         if ! ismounted $TESTPOOL/$ds_pre; then
119                 log_fail "$TESTPOOL/$ds_pre (pre) not mounted"
120         fi
121         if ismounted $TESTPOOL/$ds; then
122                 log_fail "$TESTPOOL/$ds is mounted"
123         fi
124         if ismounted $TESTPOOL/$ds_post; then
125                 log_fail "$TESTPOOL/$ds_post (post) is mounted"
126         fi
127
128
129         # mountpoint=legacy
130         ds_pre=$(printf 'c/%.0s' {1..$(($d-2))})"c"
131         ds=$(printf 'c/%.0s' {1..$(($d-1))})"c"
132         ds_post=$(printf 'c/%.0s' {1..$(($d))})"c"
133         if ! ismounted $TESTPOOL/$ds_pre; then
134                 log_fail "$TESTPOOL/$ds_pre (pre) not initially mounted"
135         fi
136         if ! ismounted $TESTPOOL/$ds; then
137                 log_fail "$TESTPOOL/$ds not initially mounted"
138         fi
139         if ! ismounted $TESTPOOL/$ds_post; then
140                 log_fail "$TESTPOOL/$ds_post (post) not initially mounted"
141         fi
142
143         log_must zfs snapshot $TESTPOOL/$ds@snap
144         # force snapshot mount in .zfs
145         log_must ls /$TESTPOOL/$ds/.zfs/snapshot/snap
146         log_must_nostderr zfs unmount $TESTPOOL/$ds
147
148         if ! ismounted $TESTPOOL/$ds_pre; then
149                 log_fail "$TESTPOOL/$ds_pre (pre) not mounted"
150         fi
151         if ismounted $TESTPOOL/$ds; then
152                 log_fail "$TESTPOOL/$ds is mounted"
153         fi
154         if ismounted $TESTPOOL/$ds_post; then
155                 log_fail "$TESTPOOL/$ds_post (post) is mounted"
156         fi
157
158
159         # mountpoint=/testpool/mnt
160         ds_pre=$(printf 'd/%.0s' {1..$(($d-2))})"d"
161         ds=$(printf 'd/%.0s' {1..$(($d-1))})"d"
162         ds_post=$(printf 'd/%.0s' {1..$(($d))})"d"
163         if ! ismounted $TESTPOOL/$ds_pre; then
164                 log_fail "$TESTPOOL/$ds_pre (pre) not initially mounted"
165         fi
166         if ! ismounted $TESTPOOL/$ds; then
167                 log_fail "$TESTPOOL/$ds not initially mounted"
168         fi
169         if ! ismounted $TESTPOOL/$ds_post; then
170                 log_fail "$TESTPOOL/$ds_post (post) not initially mounted"
171         fi
172
173         log_must zfs snapshot $TESTPOOL/$ds@snap
174         # force snapshot mount in .zfs
175         log_must ls /$TESTPOOL/$ds/.zfs/snapshot/snap
176         log_must_nostderr zfs unmount $TESTPOOL/$ds
177
178         if ! ismounted $TESTPOOL/$ds_pre; then
179                 log_fail "$ds_pre is not mounted"
180         fi
181         if ismounted $TESTPOOL/$ds; then
182                 log_fail "$ds is mounted"
183         fi
184         if ismounted $TESTPOOL/$ds_post; then
185                 log_fail "$ds_post (post) is mounted"
186         fi
187 done
188
189 log_must rmdir $mountpoint # remove the mountpoint we created
190 log_must zpool export $TESTPOOL
191 log_must zpool import $TESTPOOL
192
193 log_pass "Verified nested dataset are unmounted."