1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or https://opensource.org/licenses/CDDL-1.0.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27
28#
29# Copyright (c) 2016 by Delphix. All rights reserved.
30# Copyright (c) 2018, Datto, Inc. All rights reserved.
31#
32
33. $STF_SUITE/include/libtest.shlib
34. $STF_SUITE/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib
35
36#
37# DESCRIPTION:
38#	Invoke "zfs mount <filesystem>" with a filesystem mountpoint that is
39#	identical to an existing one.  It will fail with a return code of 1
40#	when overlay=off.  Place a file in the directory to ensure the failure.
41#	Also test overlay=on (default) in which case the mount will not fail.
42#
43# STRATEGY:
44#	1. Prepare an existing mounted filesystem.
45#	2. Setup a new filesystem with overlay=off and make sure that it is
46#	   unmounted.
47#	3. Place a file in the mount point folder.
48#	4. Mount the new filesystem using the various combinations
49#	   - zfs set mountpoint=<identical path> <filesystem>
50#	   - zfs set mountpoint=<top path> <filesystem>
51#	5. Verify that mount failed with return code of 1.
52#	6. For Linux, also set overlay=on and verify the mount is
53#	   allowed.
54#
55
56verify_runnable "both"
57
58function cleanup
59{
60	log_must force_unmount $TESTPOOL/$TESTFS
61
62	datasetexists $TESTPOOL/$TESTFS1 && \
63		cleanup_filesystem $TESTPOOL $TESTFS1
64
65	[[ -d $TESTDIR ]] && \
66		log_must rm -rf $TESTDIR
67	log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
68	log_must force_unmount $TESTPOOL/$TESTFS
69
70	return 0
71}
72
73typeset -i ret=0
74
75log_assert "Verify that 'zfs $mountcmd <filesystem>'" \
76	"where the mountpoint is identical or on top of an existing one" \
77	"will fail with return code 1 when overlay=off."
78
79log_onexit cleanup
80
81unmounted $TESTPOOL/$TESTFS || \
82	log_must force_unmount $TESTPOOL/$TESTFS
83
84[[ -d $TESTDIR ]] && \
85	log_must rm -rf $TESTDIR
86
87typeset -i MAXDEPTH=3
88typeset -i depth=0
89typeset mtpt=$TESTDIR
90
91while (( depth < MAXDEPTH )); do
92	mtpt=$mtpt/$depth
93	(( depth = depth + 1))
94done
95
96log_must zfs set mountpoint=$mtpt $TESTPOOL/$TESTFS
97log_must ismounted $TESTPOOL/$TESTFS
98
99log_must zfs set overlay=off $TESTPOOL/$TESTFS
100if ! is_illumos; then
101	touch $mtpt/file.1
102	log_must ls -l $mtpt | grep file
103fi
104
105mounted $TESTPOOL/$TESTFS || \
106	log_unresolved "Filesystem $TESTPOOL/$TESTFS is unmounted"
107
108log_must zfs create -o overlay=off $TESTPOOL/$TESTFS1
109
110unmounted $TESTPOOL/$TESTFS1 || \
111	log_must force_unmount $TESTPOOL/$TESTFS1
112
113while [[ $depth -gt 0 ]] ; do
114	(( depth == MAXDEPTH )) && \
115		log_note "Verify that 'zfs $mountcmd <filesystem>'" \
116		"with a mountpoint that is identical to an existing one" \
117		"will fail with return code 1."
118
119	log_must zfs set mountpoint=$mtpt $TESTPOOL/$TESTFS1
120	log_note "zfs $mountcmd $TESTPOOL/$TESTFS1"
121
122	log_mustnot zfs $mountcmd $TESTPOOL/$TESTFS1
123
124	if ! is_illumos; then
125		# Test the overlay=on feature which allows
126		# mounting of non-empty directory.
127		log_must zfs set overlay=on $TESTPOOL/$TESTFS1
128		log_must zfs $mountcmd $TESTPOOL/$TESTFS1
129		log_must force_unmount $TESTPOOL/$TESTFS1
130		log_must zfs set overlay=off $TESTPOOL/$TESTFS1
131	fi
132
133	unmounted $TESTPOOL/$TESTFS1 || \
134		log_fail "Filesystem $TESTPOOL/$TESTFS1 is mounted."
135
136	mtpt=${mtpt%/*}
137
138	(( depth == MAXDEPTH )) && \
139		log_note "Verify that 'zfs $mountcmd <filesystem>'" \
140		"with a mountpoint on top of an existing one" \
141		"will fail with return code 1."
142	(( depth = depth - 1 ))
143done
144
145log_pass "'zfs $mountcmd <filesystem>'" \
146	"with a mountpoint that is identical or on top of an existing one" \
147	"will fail with return code 1."
148