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 http://www.opensolaris.org/os/licensing.
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 (c) 2020 by Delphix. All rights reserved.
25#
26
27. $STF_SUITE/include/libtest.shlib
28
29#
30# DESCRIPTION:
31# Verify that 'zfs set sharenfs=on', 'zfs share', and 'zfs unshare' can
32# run concurrently. The test creates 50 filesystem and 50 threads.
33# Each thread will run through the test strategy in parallel.
34#
35# STRATEGY:
36# 1. Verify that the file system is not shared.
37# 2. Enable the 'sharenfs' property
38# 3. Invoke 'zfs unshare' and verify filesystem is no longer shared
39# 4. Invoke 'zfs share'.
40# 4. Verify that the file system is shared.
41# 5. Verify that a shared filesystem cannot be shared again.
42# 6. Verify that share -a succeeds.
43#
44
45verify_runnable "global"
46
47function cleanup
48{
49	wait
50	for fs in $(seq 0 50)
51	do
52		log_must zfs set sharenfs=off $TESTPOOL/$TESTFS1/$fs
53		log_must zfs set sharenfs=off $TESTPOOL/$TESTFS2/$fs
54		log_must zfs set sharenfs=off $TESTPOOL/$TESTFS3/$fs
55		unshare_fs $TESTPOOL/$TESTFS1/$fs
56		unshare_fs $TESTPOOL/$TESTFS2/$fs
57		unshare_fs $TESTPOOL/$TESTFS3/$fs
58
59		if mounted $TESTPOOL/$TESTFS1/$fs; then
60			log_must zfs unmount $TESTPOOL/$TESTFS1/$fs
61		fi
62		if mounted $TESTPOOL/$TESTFS2/$fs; then
63			log_must zfs unmount $TESTPOOL/$TESTFS2/$fs
64		fi
65		if mounted $TESTPOOL/$TESTFS3/$fs; then
66			log_must zfs unmount $TESTPOOL/$TESTFS3/$fs
67		fi
68
69		datasetexists $TESTPOOL/$TESTFS1/$fs && \
70			destroy_dataset $TESTPOOL/$TESTFS1/$fs -f
71		datasetexists $TESTPOOL/$TESTFS2/$fs && \
72			destroy_dataset $TESTPOOL/$TESTFS2/$fs -f
73		datasetexists $TESTPOOL/$TESTFS3/$fs && \
74			destroy_dataset $TESTPOOL/$TESTFS3/$fs -f
75	done
76
77	log_must zfs share -a
78}
79
80function create_filesystems
81{
82	for fs in $(seq 0 50)
83	do
84		log_must zfs create -p $TESTPOOL/$TESTFS1/$fs
85		log_must zfs create -p $TESTPOOL/$TESTFS2/$fs
86		log_must zfs create -p $TESTPOOL/$TESTFS3/$fs
87	done
88}
89
90#
91# Main test routine.
92#
93# Given a file system this routine will attempt
94# share the mountpoint and then verify it has been shared.
95#
96function test_share # filesystem
97{
98	typeset filesystem=$1
99	typeset mntp=$(get_prop mountpoint $filesystem)
100
101	not_shared $mntp || \
102	    log_fail "File system $filesystem is already shared."
103
104	zfs set sharenfs=on $filesystem || \
105		log_fail "zfs set sharenfs=on $filesystem failed."
106	is_shared $mntp || \
107	    log_fail "File system $filesystem is not shared (set sharenfs)."
108
109	#
110	# Verify 'zfs share' works as well.
111	#
112	zfs unshare $filesystem || \
113		log_fail "zfs unshare $filesystem failed."
114	is_shared $mntp && \
115	    log_fail "File system $filesystem is still shared."
116
117	zfs share $filesystem || \
118		log_fail "zfs share $filesystem failed."
119	is_shared $mntp || \
120	    log_fail "file system $filesystem is not shared (zfs share)."
121
122	#log_note "Sharing a shared file system fails."
123	zfs share $filesystem && \
124		log_fail "zfs share $filesystem did not fail"
125	return 0
126}
127
128#
129# Set the main process id so that we know to capture
130# failures from child processes and allow the parent process
131# to report the failure.
132#
133set_main_pid $$
134log_assert "Verify that 'zfs share' succeeds as root."
135log_onexit cleanup
136
137create_filesystems
138
139child_pids=()
140for fs in $(seq 0 50)
141do
142	test_share $TESTPOOL/$TESTFS1/$fs &
143	child_pids+=($!)
144	log_note "$TESTPOOL/$TESTFS1/$fs ==> $!"
145	test_share $TESTPOOL/$TESTFS2/$fs &
146	child_pids+=($!)
147	log_note "$TESTPOOL/$TESTFS2/$fs ==> $!"
148	test_share $TESTPOOL/$TESTFS3/$fs &
149	child_pids+=($!)
150	log_note "$TESTPOOL/$TESTFS3/$fs ==> $!"
151done
152wait_for_children "${child_pids[@]}" ||
153	log_fail "multithreaded share test failed"
154
155log_note "Verify 'zfs share -a' succeeds."
156
157#
158# Unshare each of the file systems.
159#
160child_pids=()
161for fs in $(seq 0 50)
162do
163	unshare_fs $TESTPOOL/$TESTFS1/$fs &
164	child_pids+=($!)
165	unshare_fs $TESTPOOL/$TESTFS2/$fs &
166	child_pids+=($!)
167	unshare_fs $TESTPOOL/$TESTFS3/$fs &
168	child_pids+=($!)
169done
170wait_for_children "${child_pids[@]}" ||
171	log_fail "multithreaded unshare failed"
172
173#
174# Try a zfs share -a and verify all file systems are shared.
175#
176log_must zfs share -a
177
178#
179# We need to unset __ZFS_POOL_EXCLUDE so that we include all file systems
180# in the os-specific zfs exports file. This will be reset by the next test.
181#
182unset __ZFS_POOL_EXCLUDE
183
184for fs in $(seq 0 50)
185do
186	is_shared $TESTPOOL/$TESTFS1/$fs || \
187	    log_fail "File system $TESTPOOL/$TESTFS1/$fs is not shared"
188	is_shared $TESTPOOL/$TESTFS2/$fs || \
189	    log_fail "File system $TESTPOOL/$TESTFS2/$fs is not shared"
190	is_shared $TESTPOOL/$TESTFS3/$fs || \
191	    log_fail "File system $TESTPOOL/$TESTFS3/$fs is not shared"
192
193	is_exported $TESTPOOL/$TESTFS1/$fs || \
194	    log_fail "File system $TESTPOOL/$TESTFS1/$fs is not exported"
195	is_exported $TESTPOOL/$TESTFS2/$fs || \
196	    log_fail "File system $TESTPOOL/$TESTFS2/$fs is not exported"
197	is_exported $TESTPOOL/$TESTFS3/$fs || \
198	    log_fail "File system $TESTPOOL/$TESTFS3/$fs is not exported"
199done
200
201log_pass "'zfs share [ -a ] <filesystem>' succeeds as root."
202