xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/delegate/delegate_common.kshlib (revision 36c970ed985ff3dd5443db4bf2aa58799028512c)
1# SPDX-License-Identifier: CDDL-1.0
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 2008 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27
28#
29# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
30# Copyright 2016 Nexenta Systems, Inc.
31# Copyright (c) 2018 George Melikov. All Rights Reserved.
32#
33
34. $STF_SUITE/include/libtest.shlib
35. $STF_SUITE/tests/functional/delegate/delegate.cfg
36
37#
38# Cleanup exist user/group.
39#
40function cleanup_user_group
41{
42	typeset i
43	for i in $STAFF1 $STAFF2 $OTHER1 $OTHER2 ; do
44		del_user $i
45	done
46	for i in $STAFF_GROUP $OTHER_GROUP ; do
47		del_group $i
48	done
49
50	return 0
51}
52
53#
54# Restore test file system to the original status.
55#
56function restore_root_datasets
57{
58	destroy_dataset "$ROOT_TESTFS" "-Rf"
59	log_must zfs create $ROOT_TESTFS
60
61	if is_global_zone ; then
62		destroy_dataset "$ROOT_TESTVOL" "-Rf"
63		log_must zfs create -V $VOLSIZE $ROOT_TESTVOL
64		block_device_wait
65	fi
66
67	return 0
68}
69
70#
71# Verify the specified user have permission on the dataset
72#
73# $1 dataset
74# $2 permissions which are separated by comma(,)
75# $3-n users
76#
77function verify_perm
78{
79	typeset dtst=$1
80	typeset permissions=$2
81	shift 2
82
83	if [[ -z $@ || -z $permissions || -z $dtst ]]; then
84		return 1
85	fi
86
87	typeset type=$(get_prop type $dtst)
88	permissions=$(echo $permissions | tr -s "," " ")
89
90	typeset user
91	for user in $@; do
92		typeset perm
93		for perm in $permissions; do
94			typeset -i ret=1
95			if [[ $type == "filesystem" ]]; then
96				check_fs_perm $user $perm $dtst
97				ret=$?
98			elif [[ $type == "volume" ]]; then
99				check_vol_perm $user $perm $dtst
100				ret=$?
101			fi
102
103			log_note "Check $type $user $perm $dtst"
104			if ((ret != 0)) ; then
105				log_note "Fail: $user should have $perm" \
106					"on $dtst"
107				return 1
108			fi
109		done
110	done
111
112	return 0
113}
114
115#
116# Verify the specified user have no permission on the dataset
117#
118# $1 dataset
119# $2 permissions which are separated by comma(,)
120# $3-n users
121#
122function verify_noperm
123{
124	typeset dtst=$1
125	typeset permissions=$2
126	shift 2
127
128	if [[ -z $@ || -z $permissions || -z $dtst ]]; then
129		return 1
130	fi
131
132	typeset type=$(get_prop type $dtst)
133	permissions=$(echo $permissions | tr -s "," " ")
134
135	typeset user
136	for user in $@; do
137		typeset perm
138		for perm in $permissions; do
139			typeset -i ret=1
140			if [[ $type == "filesystem" ]]; then
141				check_fs_perm $user $perm $dtst
142				ret=$?
143			elif [[ $type == "volume" ]]; then
144				check_vol_perm $user $perm $dtst
145				ret=$?
146			fi
147
148			if ((ret == 0)) ; then
149				log_note "Fail: $user should not have $perm " \
150					"on $dtst"
151				return 1
152			fi
153		done
154	done
155
156	return 0
157}
158
159function common_perm
160{
161	typeset user=$1
162	typeset perm=$2
163	typeset dtst=$3
164
165	case $perm in
166		send)
167			verify_send $user $perm $dtst
168			;;
169		allow)
170			verify_allow $user $perm $dtst
171			;;
172		userprop)
173			verify_userprop $user $perm $dtst
174			;;
175		compression|checksum|readonly)
176			verify_ccr $user $perm $dtst
177			;;
178		copies)
179			verify_copies $user $perm $dtst
180			;;
181		reservation)
182			verify_reservation $user $perm $dtst
183			;;
184		*)
185			return 1
186			;;
187	esac
188}
189
190function check_fs_perm
191{
192	typeset user=$1
193	typeset perm=$2
194	typeset fs=$3
195
196	case $perm in
197		create)
198			verify_fs_create $user $perm $fs
199			;;
200		destroy)
201			verify_fs_destroy $user $perm $fs
202			;;
203		snapshot)
204			verify_fs_snapshot $user $perm $fs
205			;;
206		rollback)
207			verify_fs_rollback $user $perm $fs
208			;;
209		clone)
210			verify_fs_clone $user $perm $fs
211			;;
212		rename)
213			verify_fs_rename $user $perm $fs
214			;;
215		mount)
216			verify_fs_mount $user $perm $fs
217			;;
218		share)
219			verify_fs_share $user $perm $fs
220			;;
221		mountpoint)
222			verify_fs_mountpoint $user $perm $fs
223			;;
224		promote)
225			verify_fs_promote $user $perm $fs
226			;;
227		canmount)
228			verify_fs_canmount $user $perm $fs
229			;;
230		dnodesize)
231			verify_fs_dnodesize $user $perm $fs
232			;;
233		recordsize)
234			verify_fs_recordsize $user $perm $fs
235			;;
236		quota)
237			verify_fs_quota $user $perm $fs
238			;;
239		aclmode)
240			verify_fs_aclmode $user $perm $fs
241			;;
242		aclinherit)
243			verify_fs_aclinherit $user $perm $fs
244			;;
245		snapdir)
246			verify_fs_snapdir $user $perm $fs
247			;;
248		atime|exec|devices|setuid|xattr)
249			verify_fs_aedsx $user $perm $fs
250			;;
251		zoned)
252			verify_fs_zoned $user $perm $fs
253			;;
254		sharenfs)
255			verify_fs_sharenfs $user $perm $fs
256			;;
257		receive)
258			verify_fs_receive $user $perm $fs
259			;;
260		receive:append)
261			verify_fs_receive_append $user $perm $fs
262			;;
263		*)
264			common_perm $user $perm $fs
265			;;
266	esac
267}
268
269function check_vol_perm
270{
271	typeset user=$1
272	typeset perm=$2
273	typeset vol=$3
274
275	case $perm in
276		destroy)
277			verify_vol_destroy $user $perm $vol
278			;;
279		snapshot)
280			verify_vol_snapshot $user $perm $vol
281			;;
282		rollback)
283			verify_vol_rollback $user $perm $vol
284			;;
285		clone)
286			verify_vol_clone $user $perm $vol
287			;;
288		rename)
289			verify_vol_rename $user $perm $vol
290			;;
291		promote)
292			verify_vol_promote $user $perm $vol
293			;;
294		volsize)
295			verify_vol_volsize $user $perm $vol
296			;;
297		*)
298			common_perm $user $perm $vol
299			;;
300	esac
301}
302
303function setup_unallow_testenv
304{
305	log_must restore_root_datasets
306
307	log_must zfs create $SUBFS
308
309	for dtst in $DATASETS ; do
310		log_must zfs allow -l $STAFF1 $LOCAL_SET $dtst
311		log_must zfs allow -d $STAFF2 $DESC_SET  $dtst
312		log_must zfs allow $OTHER1 $LOCAL_DESC_SET $dtst
313		log_must zfs allow $OTHER2 $LOCAL_DESC_SET $dtst
314
315		log_must verify_perm $dtst $LOCAL_SET $STAFF1
316		log_must verify_perm $dtst $LOCAL_DESC_SET $OTHER1
317		log_must verify_perm $dtst $LOCAL_DESC_SET $OTHER2
318		if [[ $dtst == $ROOT_TESTFS ]]; then
319			log_must verify_perm $SUBFS $DESC_SET $STAFF2
320			log_must verify_perm $SUBFS $LOCAL_DESC_SET $OTHER1
321			log_must verify_perm $SUBFS $LOCAL_DESC_SET $OTHER2
322		fi
323	done
324}
325
326#
327# Verify permission send for specified user on the dataset
328# $1 user
329# $2 permission
330# $3 dataset
331#
332function verify_send
333{
334	typeset user=$1
335	typeset perm=$2
336	typeset dtst=$3
337
338	typeset oldval
339	typeset stamp=${perm}.${user}.$RANDOM
340	typeset snap=$dtst@snap.$stamp
341
342	typeset -i ret=1
343
344	log_must zfs snapshot $snap
345	typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp
346	typeset bak_root=$TEST_BASE_DIR/bak.root.$stamp
347
348	user_run $user eval "zfs send $snap > $bak_user"
349	log_must eval "zfs send $snap > $bak_root"
350
351	if [ "$(cksum < $bak_user)" = "$(cksum < $bak_root)" ]; then
352		ret=0
353	fi
354
355	rm -rf $bak_user $bak_root
356
357	return $ret
358}
359
360function verify_fs_receive
361{
362	typeset user=$1
363	typeset perm=$2
364	typeset fs=$3
365
366	typeset dtst
367	typeset stamp=${perm}.${user}.$RANDOM
368	typeset newfs=$fs/newfs.$stamp
369	typeset newvol=$fs/newvol.$stamp
370	typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp
371	typeset bak_root=$TEST_BASE_DIR/bak.root.$stamp
372
373	log_must zfs create $newfs
374	typeset datasets="$newfs"
375	if is_global_zone ; then
376		log_must zfs create -V $VOLSIZE $newvol
377		block_device_wait
378		datasets="$newfs $newvol"
379	fi
380
381	for dtst in $datasets ; do
382
383		typeset dtstsnap=$dtst@snap.$stamp
384		log_must zfs snapshot $dtstsnap
385
386		log_must eval "zfs send $dtstsnap > $bak_root"
387		log_must_busy zfs destroy -rf $dtst
388
389		user_run $user eval "zfs receive $dtst < $bak_root"
390		if datasetexists $dtstsnap ; then
391			return 1
392		fi
393
394		log_must zfs allow $user create $fs
395		user_run $user eval "zfs receive $dtst < $bak_root"
396		log_must zfs unallow $user create $fs
397		if datasetexists $dtstsnap ; then
398			return 1
399		fi
400
401		log_must zfs allow $user mount $fs
402		user_run $user eval "zfs receive $dtst < $bak_root"
403		log_must zfs unallow $user mount $fs
404		if datasetexists $dtstsnap ; then
405			return 1
406		fi
407
408		log_must zfs allow $user mount,create $fs
409		user_run $user eval "zfs receive $dtst < $bak_root"
410		log_must zfs unallow $user mount,create $fs
411		if ! datasetexists $dtstsnap ; then
412			return 1
413		fi
414
415		# check the data integrity
416		log_must eval "zfs send $dtstsnap > $bak_user"
417		log_must_busy zfs destroy -rf $dtst
418		log_must eval "zfs receive $dtst < $bak_root"
419		log_must eval "zfs send $dtstsnap > $bak_root"
420		log_must_busy zfs destroy -rf $dtst
421		if [ "$(cksum < $bak_user)" != "$(cksum < $bak_root)" ]; then
422			return 1
423		fi
424
425		rm -rf $bak_user $bak_root
426
427	done
428
429	return 0
430}
431
432function verify_fs_receive_append
433{
434	typeset user=$1
435	typeset perm=$2
436	typeset fs=$3
437
438	typeset dtst
439	typeset stamp=${perm}.${user}.$RANDOM
440	typeset newfs=$fs/newfs.$stamp
441	typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp
442
443	log_must zfs create $newfs
444	typeset dtst="$newfs"
445
446	typeset dtstsnap=$dtst@snap.$stamp
447	log_must zfs snapshot $dtstsnap
448
449	log_must eval "zfs send $dtstsnap > $bak_user"
450	log_must_busy zfs destroy -rf $dtst
451
452	log_must zfs allow $user create,mount,canmount $fs
453	user_run $user eval "zfs receive -o canmount=off -F $dtst < $bak_user"
454	log_must zfs unallow $user create,mount,canmount $fs
455	if datasetexists $dtstsnap ; then
456		return 1
457	fi
458
459	log_must zfs allow $user create,mount,canmount $fs
460	user_run $user eval "zfs receive -o canmount=off $dtst < $bak_user"
461	log_must zfs unallow $user create,mount,canmount $fs
462	if ! datasetexists $dtstsnap ; then
463		return 1
464	fi
465
466	rm -rf $bak_user
467
468	return 0
469}
470
471function verify_userprop
472{
473	typeset user=$1
474	typeset perm=$2
475	typeset dtst=$3
476
477	typeset stamp=${perm}.${user}.$RANDOM
478
479	user_run $user zfs set "$user:ts=$stamp" $dtst
480	sync_pool ${dtst%%/*}
481	if [[ $stamp != $(get_prop "$user:ts" $dtst) ]]; then
482		return 1
483	fi
484
485	return 0
486}
487
488function verify_ccr
489{
490	typeset user=$1
491	typeset perm=$2
492	typeset dtst=$3
493
494	typeset oldval
495
496	set -A modes "on" "off"
497	oldval=$(get_prop $perm $dtst)
498	if [[ $oldval == "on" ]]; then
499		n=1
500	elif [[ $oldval == "off" ]]; then
501		n=0
502	fi
503	log_note "$user zfs set $perm=${modes[$n]} $dtst"
504	user_run $user zfs set $perm=${modes[$n]} $dtst
505	if [[ ${modes[$n]} != $(get_prop $perm $dtst) ]]; then
506		return 1
507	fi
508
509	return 0
510}
511
512function verify_copies
513{
514	typeset user=$1
515	typeset perm=$2
516	typeset dtst=$3
517
518	typeset oldval
519
520	set -A modes 1 2 3
521	oldval=$(get_prop $perm $dtst)
522	if [[ $oldval -eq 1 ]]; then
523		n=1
524	elif [[ $oldval -eq 2 ]]; then
525		n=2
526	elif [[ $oldval -eq 3 ]]; then
527		n=0
528	fi
529	log_note "$user zfs set $perm=${modes[$n]} $dtst"
530	user_run $user zfs set $perm=${modes[$n]} $dtst
531	if [[ ${modes[$n]} != $(get_prop $perm $dtst) ]]; then
532		return 1
533	fi
534
535	return 0
536}
537
538function verify_reservation
539{
540	typeset user=$1
541	typeset perm=$2
542	typeset dtst=$3
543
544	typeset value32m=$(( 1024 * 1024 * 32 ))
545	typeset oldval=$(get_prop reservation $dtst)
546	user_run $user zfs set reservation=$value32m $dtst
547	if [[ $value32m != $(get_prop reservation $dtst) ]]; then
548		log_must zfs set reservation=$oldval $dtst
549		return 1
550	fi
551
552	log_must zfs set reservation=$oldval $dtst
553	return 0
554}
555
556function verify_fs_create
557{
558	typeset user=$1
559	typeset perm=$2
560	typeset fs=$3
561
562	typeset stamp=${perm}.${user}.$RANDOM
563	typeset newfs=$fs/nfs.$stamp
564	typeset newvol=$fs/nvol.$stamp
565
566	user_run $user zfs create $newfs
567	if datasetexists $newfs ; then
568		return 1
569	fi
570
571	log_must zfs allow $user mount $fs
572	user_run $user zfs create $newfs
573	log_must zfs unallow $user mount $fs
574	if ! datasetexists $newfs ; then
575		return 1
576	fi
577
578	log_must zfs destroy $newfs
579
580	if is_global_zone ; then
581		# mount permission is required for sparse volume
582		user_run $user zfs create -V 150m -s $newvol
583		block_device_wait
584		if datasetexists $newvol ; then
585			return 1
586		fi
587
588		log_must zfs allow $user mount $fs
589		user_run $user zfs create -V 150m -s $newvol
590		log_must zfs unallow $user mount $fs
591		if ! datasetexists $newvol ; then
592			return 1
593		fi
594
595		block_device_wait
596		log_must zfs destroy $newvol
597		block_device_wait
598
599		# mount and reserveration permission are
600		# required for normal volume
601		user_run $user zfs create -V 150m $newvol
602		block_device_wait
603		if datasetexists $newvol ; then
604			return 1
605		fi
606
607		log_must zfs allow $user mount $fs
608		user_run $user zfs create -V 150m $newvol
609		block_device_wait
610		log_must zfs unallow $user mount $fs
611		if datasetexists $newvol ; then
612			return 1
613		fi
614
615		log_must zfs allow $user reservation $fs
616		user_run $user zfs create -V 150m $newvol
617		block_device_wait
618		log_must zfs unallow $user reservation $fs
619		if datasetexists $newvol ; then
620			return 1
621		fi
622
623		log_must zfs allow $user refreservation $fs
624		user_run $user zfs create -V 150m $newvol
625		block_device_wait
626		log_must zfs unallow $user refreservation $fs
627		if datasetexists $newvol ; then
628			return 1
629		fi
630
631		log_must zfs allow $user mount $fs
632		log_must zfs allow $user reservation $fs
633		log_must zfs allow $user refreservation $fs
634		user_run $user zfs create -V 150m $newvol
635		log_must zfs unallow $user mount $fs
636		log_must zfs unallow $user reservation $fs
637		log_must zfs unallow $user refreservation $fs
638		if ! datasetexists $newvol ; then
639			return 1
640		fi
641
642		block_device_wait
643		log_must zfs destroy $newvol
644		block_device_wait
645	fi
646
647	return 0
648}
649
650function verify_fs_destroy
651{
652	typeset user=$1
653	typeset perm=$2
654	typeset fs=$3
655
656	if ! ismounted $fs ; then
657		user_run $user zfs destroy $fs
658		if datasetexists $fs ; then
659			return 1
660		fi
661	fi
662
663	if ismounted $fs ; then
664		user_run $user zfs destroy $fs
665		if ! datasetexists $fs ; then
666			return 1
667		fi
668
669		# mount permission is required
670		log_must zfs allow $user mount $fs
671		user_run $user zfs destroy $fs
672		if datasetexists $fs ; then
673			return 1
674		fi
675	fi
676
677	return 0
678}
679
680# Verify that given the correct delegation, a regular user can:
681#	Take a snapshot of an unmounted dataset
682# 	Take a snapshot of a mounted dataset
683#	Create a snapshot by making a directory in the .zfs/snapshot directory
684function verify_fs_snapshot
685{
686	typeset user=$1
687	typeset perm=$2
688	typeset fs=$3
689
690	typeset stamp=${perm}.${user}.$RANDOM
691	typeset snap=$fs@snap.$stamp
692	typeset mntpt=$(get_prop mountpoint $fs)
693
694	if [[ "yes" == $(get_prop mounted $fs) ]]; then
695		log_must zfs umount $fs
696	fi
697
698	user_run $user zfs snapshot $snap
699	if ! datasetexists $snap ; then
700		return 1
701	fi
702	log_must zfs destroy $snap
703
704	if [[ "no" == $(get_prop mounted $fs) ]]; then
705		log_must zfs mount $fs
706	fi
707
708	user_run $user zfs snapshot $snap
709	if ! datasetexists $snap ; then
710		return 1
711	fi
712	log_must zfs destroy $snap
713
714	# Creating snaps via mkdir is not supported on FreeBSD
715	if ! is_freebsd; then
716		typeset snapdir=${mntpt}/.zfs/snapshot/snap.$stamp
717		user_run $user mkdir $snapdir
718		if ! datasetexists $snap ; then
719			return 1
720		fi
721		log_must zfs destroy $snap
722	fi
723
724	return 0
725}
726
727function verify_fs_rollback
728{
729	typeset user=$1
730	typeset perm=$2
731	typeset fs=$3
732
733	typeset oldval
734	typeset stamp=${perm}.${user}.$RANDOM
735	typeset snap=$fs@snap.$stamp
736	typeset mntpt=$(get_prop mountpoint $fs)
737
738	oldval=$(datasetcksum $fs)
739	log_must zfs snapshot $snap
740
741	if ! ismounted $fs; then
742		log_must zfs mount $fs
743	fi
744	log_must touch $mntpt/testfile.$stamp
745
746	user_run $user zfs rollback -R $snap
747	if is_global_zone ; then
748		if [[ $oldval != $(datasetcksum $fs) ]]; then
749			return 1
750		fi
751	else
752		# datasetcksum can not be used in local zone
753		if [[ -e $mntpt/testfile.$stamp ]]; then
754			return 1
755		fi
756	fi
757
758	return 0
759}
760
761function verify_fs_clone
762{
763	typeset user=$1
764	typeset perm=$2
765	typeset fs=$3
766
767	typeset stamp=${perm}.${user}.$RANDOM
768	typeset basefs=${fs%/*}
769	typeset snap=$fs@snap.$stamp
770	typeset clone=$basefs/cfs.$stamp
771
772	log_must zfs snapshot $snap
773	user_run $user zfs clone $snap $clone
774	if datasetexists $clone ; then
775		return 1
776	fi
777
778	log_must zfs allow $user create $basefs
779	user_run $user zfs clone $snap $clone
780	log_must zfs unallow $user create $basefs
781	if datasetexists $clone ; then
782		return 1
783	fi
784
785	log_must zfs allow $user mount $basefs
786	user_run $user zfs clone $snap $clone
787	log_must zfs unallow $user mount $basefs
788	if datasetexists $clone ; then
789		return 1
790	fi
791
792	log_must zfs allow $user mount $basefs
793	log_must zfs allow $user create $basefs
794	user_run $user zfs clone $snap $clone
795	log_must zfs unallow $user create $basefs
796	log_must zfs unallow $user mount $basefs
797	if ! datasetexists $clone ; then
798		return 1
799	fi
800
801	log_must zfs destroy -R $snap
802
803	return 0
804}
805
806function verify_fs_rename
807{
808	typeset user=$1
809	typeset perm=$2
810	typeset fs=$3
811
812	typeset stamp=${perm}.${user}.$RANDOM
813	typeset basefs=${fs%/*}
814	typeset snap=$fs@snap.$stamp
815	typeset renamefs=$basefs/nfs.$stamp
816
817	if ! ismounted $fs; then
818		log_must zfs mount $fs
819	fi
820
821	# case 1
822	user_run $user zfs rename $fs $renamefs
823	if datasetexists $renamefs ; then
824		return 1
825	fi
826
827	# case 2
828	log_must zfs allow $user create $basefs
829	user_run $user zfs rename $fs $renamefs
830	log_must zfs unallow $user create $basefs
831	if datasetexists $renamefs ; then
832		return 1
833	fi
834
835	# case 3
836	log_must zfs allow $user mount $basefs
837	user_run $user zfs rename $fs $renamefs
838	log_must zfs unallow $user mount $basefs
839	if datasetexists $renamefs ; then
840		return 1
841	fi
842
843	# case 4
844	log_must zfs allow $user mount $fs
845	user_run $user zfs rename $fs $renamefs
846	if datasetexists $renamefs ; then
847		log_must zfs unallow $user mount $renamefs
848		return 1
849	fi
850	log_must zfs unallow $user mount $fs
851
852	# case 5
853	log_must zfs allow $user create $basefs
854	log_must zfs allow $user mount $fs
855	user_run $user zfs rename $fs $renamefs
856	log_must zfs unallow $user create $basefs
857	if datasetexists $renamefs ; then
858		log_must zfs unallow $user mount $renamefs
859		return 1
860	fi
861	log_must zfs unallow $user mount $fs
862
863	# case 6
864	log_must zfs allow $user mount $basefs
865	log_must zfs allow $user mount $fs
866	user_run $user zfs rename $fs $renamefs
867	log_must zfs unallow $user mount $basefs
868	if datasetexists $renamefs ; then
869		log_must zfs unallow $user mount $renamefs
870		return 1
871	fi
872	log_must zfs unallow $user mount $fs
873
874	# case 7
875	log_must zfs allow $user create $basefs
876	log_must zfs allow $user mount $basefs
877	user_run $user zfs rename $fs $renamefs
878	log_must zfs unallow $user mount $basefs
879	log_must zfs unallow $user create $basefs
880	if ! datasetexists $renamefs ; then
881		return 1
882	fi
883
884	log_must zfs rename $renamefs $fs
885
886	return 0
887}
888
889function verify_fs_mount
890{
891	typeset user=$1
892	typeset perm=$2
893	typeset fs=$3
894
895	typeset stamp=${perm}.${user}.$RANDOM
896	typeset mntpt=$(get_prop mountpoint $fs)
897	typeset newmntpt=$TEST_BASE_DIR/mnt.$stamp
898
899	if ismounted $fs ; then
900		user_run $user zfs unmount $fs
901		if ismounted $fs ; then
902			return 1
903		fi
904	fi
905
906	if ! ismounted $fs ; then
907		log_must zfs set -u mountpoint=$newmntpt $fs
908		log_must rm -rf $newmntpt
909		log_must mkdir $newmntpt
910
911		user_run $user zfs mount $fs
912		if ismounted $fs ; then
913			return 1
914		fi
915
916		# mountpoint's owner must be the user
917		log_must chown $user $newmntpt
918		user_run $user zfs mount $fs
919		if ! ismounted $fs ; then
920			return 1
921		fi
922		log_must zfs umount $fs
923		log_must rm -rf $newmntpt
924		log_must zfs set -u mountpoint=$mntpt $fs
925	fi
926
927	return 0
928}
929
930function verify_fs_share
931{
932	typeset user=$1
933	typeset perm=$2
934	typeset fs=$3
935	typeset -i ret=0
936
937	svcadm enable -rs nfs/server
938	typeset stat=$(svcs -H -o STA nfs/server:default)
939	if [[ $stat != "ON" ]]; then
940		log_fail "Could not enable nfs/server"
941	fi
942
943	log_must zfs set sharenfs=on $fs
944	zfs unshare $fs
945
946	user_run $user zfs share $fs
947	if ! is_shared $fs; then
948		ret=1
949	fi
950
951	zfs unshare $fs
952	log_must zfs set sharenfs=off $fs
953
954	return $ret
955}
956
957function verify_fs_mountpoint
958{
959	typeset user=$1
960	typeset perm=$2
961	typeset fs=$3
962
963	typeset stamp=${perm}.${user}.$RANDOM
964	typeset mntpt=$(get_prop mountpoint $fs)
965	typeset newmntpt=$TEST_BASE_DIR/mnt.$stamp
966
967	if ! ismounted $fs ; then
968		user_run $user zfs set mountpoint=$newmntpt $fs
969		if [[ $newmntpt != \
970			$(get_prop mountpoint $fs) ]] ; then
971			return 1
972		fi
973		log_must zfs set mountpoint=$mntpt $fs
974	fi
975
976	if ismounted $fs ; then
977		user_run $user zfs set mountpoint=$newmntpt $fs
978		if [[ $mntpt != $(get_prop mountpoint $fs) ]]; then
979			return 1
980		fi
981
982		# require mount permission when fs is mounted
983		log_must zfs allow $user mount $fs
984		user_run $user zfs set mountpoint=$newmntpt $fs
985		log_must zfs unallow $user mount $fs
986		if [[ $newmntpt != \
987			$(get_prop mountpoint $fs) ]] ; then
988			return 1
989		fi
990		log_must zfs set mountpoint=$mntpt $fs
991	fi
992
993	return 0
994}
995
996function verify_fs_promote
997{
998	typeset user=$1
999	typeset perm=$2
1000	typeset fs=$3
1001
1002	typeset stamp=${perm}.${user}.$RANDOM
1003	typeset basefs=${fs%/*}
1004	typeset snap=$fs@snap.$stamp
1005	typeset clone=$basefs/cfs.$stamp
1006
1007	log_must zfs snapshot $snap
1008	log_must zfs clone $snap $clone
1009	log_must zfs promote $clone
1010
1011	typeset fs_orig=$(get_prop origin $fs)
1012	typeset clone_orig=$(get_prop origin $clone)
1013
1014	user_run $user zfs promote $fs
1015	# promote should fail if original fs does not have
1016	# promote permission
1017	if [[ $fs_orig != $(get_prop origin $fs) || \
1018		$clone_orig != $(get_prop origin $clone) ]]; then
1019		return 1
1020	fi
1021
1022	log_must zfs allow $user promote $clone
1023	user_run $user zfs promote $fs
1024	log_must zfs unallow $user promote $clone
1025	if [[ $fs_orig != $(get_prop origin $fs) || \
1026		$clone_orig != $(get_prop origin $clone) ]]; then
1027		return 1
1028	fi
1029
1030	log_must zfs allow $user mount $fs
1031	user_run $user zfs promote $fs
1032	log_must zfs unallow $user mount $fs
1033	if [[ $fs_orig != $(get_prop origin $fs) || \
1034		$clone_orig != $(get_prop origin $clone) ]]; then
1035		return 1
1036	fi
1037
1038	log_must zfs allow $user mount $fs
1039	log_must zfs allow $user promote $clone
1040	user_run $user zfs promote $fs
1041	log_must zfs unallow $user promote $clone
1042	log_must zfs unallow $user mount $fs
1043	if [[ $snap != $(get_prop origin $clone) || \
1044		$clone_orig != $(get_prop origin $fs) ]]; then
1045		return 1
1046	fi
1047
1048	return 0
1049}
1050
1051function verify_fs_canmount
1052{
1053	typeset user=$1
1054	typeset perm=$2
1055	typeset fs=$3
1056
1057	typeset oldval
1058	typeset stamp=${perm}.${user}.$RANDOM
1059
1060	if ! ismounted $fs ; then
1061		set -A modes "on" "off"
1062		oldval=$(get_prop $perm $fs)
1063		if [[ $oldval == "on" ]]; then
1064			n=1
1065		elif [[ $oldval == "off" ]]; then
1066			n=0
1067		fi
1068		log_note "$user zfs set $perm=${modes[$n]} $fs"
1069		user_run $user zfs set $perm=${modes[$n]} $fs
1070		if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then
1071			return 1
1072		fi
1073	fi
1074
1075
1076	# fs is mounted
1077	if ismounted $fs ; then
1078		# property value does not change if
1079		# no mount permission
1080		set -A modes "on" "off"
1081		oldval=$(get_prop $perm $fs)
1082		if [[ $oldval == "on" ]]; then
1083			n=1
1084		elif [[ $oldval == "off" ]]; then
1085			n=0
1086		fi
1087		log_note "$user zfs set $perm=${modes[$n]} $fs"
1088		log_must zfs allow $user mount $fs
1089		user_run $user zfs set $perm=${modes[$n]} $fs
1090		log_must zfs unallow $user mount $fs
1091		if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then
1092			return 1
1093		fi
1094	fi
1095
1096	return 0
1097}
1098
1099function verify_fs_recordsize
1100{
1101	typeset user=$1
1102	typeset perm=$2
1103	typeset fs=$3
1104
1105	typeset value8k=$(( 1024 * 8 ))
1106	user_run $user zfs set recordsize=$value8k $fs
1107	if [[ $value8k != $(get_prop recordsize $fs) ]]; then
1108		return 1
1109	fi
1110
1111	return 0
1112}
1113
1114function verify_fs_dnodesize
1115{
1116	typeset user=$1
1117	typeset perm=$2
1118	typeset fs=$3
1119	value="2k"
1120
1121	user_run $user zfs set dnodesize=$value $fs
1122	if [[ $value != $(get_prop dnodesize $fs) ]]; then
1123		return 1
1124	fi
1125
1126	return 0
1127}
1128
1129function verify_fs_quota
1130{
1131	typeset user=$1
1132	typeset perm=$2
1133	typeset fs=$3
1134
1135	typeset value32m=$(( 1024 * 1024 * 32 ))
1136	user_run $user zfs set quota=$value32m $fs
1137	if [[ $value32m != $(get_prop quota $fs) ]]; then
1138		return 1
1139	fi
1140
1141	return 0
1142}
1143
1144function verify_fs_aclmode
1145{
1146	typeset user=$1
1147	typeset perm=$2
1148	typeset fs=$3
1149
1150	typeset oldval
1151	set -A modes "discard" "groupmask" "passthrough"
1152	oldval=$(get_prop $perm $fs)
1153	if [[ $oldval == "discard" ]]; then
1154		n=1
1155	elif [[ $oldval == "groupmask" ]]; then
1156		n=2
1157	elif [[ $oldval == "passthrough" ]]; then
1158		n=0
1159	fi
1160	log_note "$user zfs set aclmode=${modes[$n]} $fs"
1161	user_run $user zfs set aclmode=${modes[$n]} $fs
1162	if [[ ${modes[$n]} != $(get_prop aclmode $fs) ]]; then
1163		return 1
1164	fi
1165
1166	return 0
1167}
1168
1169function verify_fs_aclinherit
1170{
1171	typeset user=$1
1172	typeset perm=$2
1173	typeset fs=$3
1174
1175	#
1176	# PSARC/2008/231 change the default value of aclinherit to "restricted"
1177	# but still keep the old interface of "secure"
1178	#
1179
1180	typeset oldval
1181	set -A modes "discard" "noallow" "secure" "passthrough"
1182	oldval=$(get_prop $perm $fs)
1183	if [[ $oldval == "discard" ]]; then
1184		n=1
1185	elif [[ $oldval == "noallow" ]]; then
1186		n=2
1187	elif [[ $oldval == "secure" || $oldval == "restricted" ]]; then
1188		n=3
1189	elif [[ $oldval == "passthrough" ]]; then
1190		n=0
1191	fi
1192	log_note "$user zfs set aclinherit=${modes[$n]} $fs"
1193	user_run $user zfs set aclinherit=${modes[$n]} $fs
1194
1195	typeset newval=$(get_prop aclinherit $fs)
1196	if [[ ${modes[$n]} == "secure" && $newval == "restricted" ]]; then
1197		return 0
1198	elif [[ ${modes[$n]} != $(get_prop aclinherit $fs) ]]; then
1199		return 1
1200	fi
1201
1202	return 0
1203}
1204
1205function verify_fs_snapdir
1206{
1207	typeset user=$1
1208	typeset perm=$2
1209	typeset fs=$3
1210
1211	typeset oldval
1212	set -A modes "visible" "hidden"
1213	oldval=$(get_prop $perm $fs)
1214	if [[ $oldval == "visible" ]]; then
1215		n=1
1216	elif [[ $oldval == "hidden" ]]; then
1217		n=0
1218	fi
1219	log_note "$user zfs set snapdir=${modes[$n]} $fs"
1220	user_run $user zfs set snapdir=${modes[$n]} $fs
1221	if [[ ${modes[$n]} != $(get_prop snapdir $fs) ]]; then
1222		return 1
1223	fi
1224
1225	return 0
1226}
1227
1228function verify_fs_aedsx
1229{
1230	typeset user=$1
1231	typeset perm=$2
1232	typeset fs=$3
1233
1234	typeset oldval
1235	set -A modes "on" "off"
1236	oldval=$(get_prop $perm $fs)
1237	if [[ $oldval == "off" ]]; then
1238		n=0
1239	else
1240		n=1
1241	fi
1242	log_note "$user zfs set $perm=${modes[$n]} $fs"
1243	user_run $user zfs set $perm=${modes[$n]} $fs
1244	if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then
1245		return 1
1246	fi
1247
1248	return 0
1249}
1250
1251function verify_fs_zoned
1252{
1253	typeset user=$1
1254	typeset perm=$2
1255	typeset fs=$3
1256
1257	typeset oldval
1258	set -A modes "on" "off"
1259	oldval=$(get_prop $perm $fs)
1260	if [[ $oldval == "on" ]]; then
1261		n=1
1262	elif [[ $oldval == "off" ]]; then
1263		n=0
1264	fi
1265	log_note "$user zfs set $perm=${modes[$n]} $fs"
1266	if is_global_zone ; then
1267		if ! ismounted $fs ; then
1268			user_run $user zfs set \
1269				$perm=${modes[$n]} $fs
1270			if [[ ${modes[$n]} != \
1271				$(get_prop $perm $fs) ]]; then
1272				return 1
1273			fi
1274			if [[ $n -eq 0 ]]; then
1275				log_mustnot zfs mount $fs
1276			else
1277				log_must zfs mount $fs
1278			fi
1279		fi
1280
1281		if ismounted $fs; then
1282			# n always is 1 in this case
1283			user_run $user zfs set \
1284				$perm=${modes[$n]} $fs
1285			if [[ $oldval != \
1286				$(get_prop $perm $fs) ]]; then
1287				return 1
1288			fi
1289
1290			# mount permission is needed
1291			# to make zoned=on
1292			log_must zfs allow $user mount $fs
1293			user_run $user zfs set \
1294				$perm=${modes[$n]} $fs
1295			log_must zfs unallow $user mount $fs
1296			if [[ ${modes[$n]} != \
1297				$(get_prop $perm $fs) ]]; then
1298				return 1
1299			fi
1300		fi
1301	fi
1302
1303	if ! is_global_zone; then
1304		user_run $user zfs set $perm=${modes[$n]} $fs
1305		if [[ $oldval != $(get_prop $perm $fs) ]]; then
1306			return 1
1307		fi
1308	fi
1309
1310	return 0
1311}
1312
1313function verify_fs_sharenfs
1314{
1315	typeset user=$1
1316	typeset perm=$2
1317	typeset fs=$3
1318	typeset nmode omode
1319
1320	omode=$(get_prop $perm $fs)
1321	if [[ $omode == "off" ]]; then
1322		nmode="on"
1323	else
1324		nmode="off"
1325	fi
1326
1327	log_note "$user zfs set $perm=$nmode $fs"
1328	user_run $user zfs set $perm=$nmode $fs
1329	if [[ $(get_prop $perm $fs) != $nmode ]]; then
1330		return 1
1331	fi
1332
1333	log_note "$user zfs set $perm=$omode $fs"
1334	user_run $user zfs set $perm=$omode $fs
1335	if [[ $(get_prop $perm $fs) != $omode ]]; then
1336		return 1
1337	fi
1338
1339	return 0
1340}
1341
1342function verify_vol_destroy
1343{
1344	typeset user=$1
1345	typeset perm=$2
1346	typeset vol=$3
1347
1348	user_run $user zfs destroy $vol
1349	if ! datasetexists $vol ; then
1350		return 1
1351	fi
1352
1353	# mount permission is required
1354	log_must zfs allow $user mount $vol
1355	user_run $user zfs destroy $vol
1356	if datasetexists $vol ; then
1357		return 1
1358	fi
1359
1360	return 0
1361}
1362
1363function verify_vol_snapshot
1364{
1365	typeset user=$1
1366	typeset perm=$2
1367	typeset vol=$3
1368
1369	typeset stamp=${perm}.${user}.$RANDOM
1370	typeset basevol=${vol%/*}
1371	typeset snap=$vol@snap.$stamp
1372
1373	user_run $user zfs snapshot $snap
1374	if datasetexists $snap ; then
1375		return 1
1376	fi
1377
1378	log_must zfs allow $user mount $vol
1379	user_run $user zfs snapshot $snap
1380	log_must zfs unallow $user mount $vol
1381	if ! datasetexists $snap ; then
1382		return 1
1383	fi
1384
1385	return 0
1386}
1387
1388function verify_vol_rollback
1389{
1390	typeset user=$1
1391	typeset perm=$2
1392	typeset vol=$3
1393
1394	typeset stamp=${perm}.${user}.$RANDOM
1395	typeset basevol=${vol%/*}
1396	typeset snap=$vol@snap.$stamp
1397
1398	typeset oldval
1399	log_must zfs snapshot $snap
1400	oldval=$(datasetcksum $vol)
1401
1402	log_must dd if=/dev/urandom of=$ZVOL_RDEVDIR/$vol \
1403		bs=512 count=1
1404
1405	user_run $user zfs rollback -R $snap
1406	sleep 10
1407	if [[ $oldval == $(datasetcksum $vol) ]]; then
1408		return 1
1409	fi
1410
1411	# rollback on volume has to be with mount permission
1412	log_must zfs allow $user mount $vol
1413	user_run $user zfs rollback -R $snap
1414	sleep 10
1415	log_must zfs unallow $user mount $vol
1416	if [[ $oldval != $(datasetcksum $vol) ]]; then
1417		return 1
1418	fi
1419
1420	return 0
1421}
1422
1423function verify_vol_clone
1424{
1425	typeset user=$1
1426	typeset perm=$2
1427	typeset vol=$3
1428
1429	typeset stamp=${perm}.${user}.$RANDOM
1430	typeset basevol=${vol%/*}
1431	typeset snap=$vol@snap.$stamp
1432	typeset clone=$basevol/cvol.$stamp
1433
1434	log_must zfs snapshot $snap
1435
1436	user_run $user zfs clone $snap $clone
1437	if datasetexists $clone ; then
1438		return 1
1439	fi
1440
1441	log_must zfs allow $user create $basevol
1442	user_run $user zfs clone $snap $clone
1443	log_must zfs unallow $user create $basevol
1444	if datasetexists $clone ; then
1445		return 1
1446	fi
1447
1448	log_must zfs allow $user mount $basevol
1449	user_run $user zfs clone $snap $clone
1450	log_must zfs unallow $user mount $basevol
1451	if datasetexists $clone ; then
1452		return 1
1453	fi
1454
1455	# require create permission on parent and
1456	# mount permission on itself as well
1457	log_must zfs allow $user mount $basevol
1458	log_must zfs allow $user create $basevol
1459	user_run $user zfs clone $snap $clone
1460	log_must zfs unallow $user create $basevol
1461	log_must zfs unallow $user mount $basevol
1462	if ! datasetexists $clone ; then
1463		return 1
1464	fi
1465
1466	return 0
1467}
1468
1469function verify_vol_rename
1470{
1471	typeset user=$1
1472	typeset perm=$2
1473	typeset vol=$3
1474
1475	typeset stamp=${perm}.${user}.$RANDOM
1476	typeset basevol=${vol%/*}
1477	typeset snap=$vol@snap.$stamp
1478	typeset clone=$basevol/cvol.$stamp
1479	typeset renamevol=$basevol/nvol.$stamp
1480
1481	user_run $user zfs rename $vol $renamevol
1482	if datasetexists $renamevol ; then
1483		return 1
1484	fi
1485
1486	log_must zfs allow $user create $basevol
1487	user_run $user zfs rename $vol $renamevol
1488	log_must zfs unallow $user create $basevol
1489	if datasetexists $renamevol ; then
1490		return 1
1491	fi
1492
1493	log_must zfs allow $user mount $basevol
1494	user_run $user zfs rename $vol $renamevol
1495	log_must zfs unallow $user mount $basevol
1496	if datasetexists $renamevol ; then
1497		return 1
1498	fi
1499
1500	# require both create permission on parent and
1501	# mount permission on parent as well
1502	log_must zfs allow $user mount $basevol
1503	log_must zfs allow $user create $basevol
1504	user_run $user zfs rename $vol $renamevol
1505	log_must zfs unallow $user mount $basevol
1506	log_must zfs unallow $user create $basevol
1507	if ! datasetexists $renamevol ; then
1508		return 1
1509	fi
1510
1511	log_must zfs rename $renamevol $vol
1512
1513	return 0
1514}
1515
1516function verify_vol_promote
1517{
1518	typeset user=$1
1519	typeset perm=$2
1520	typeset vol=$3
1521
1522	typeset stamp=${perm}.${user}.$RANDOM
1523	typeset basevol=${vol%/*}
1524	typeset snap=$vol@snap.$stamp
1525	typeset clone=$basevol/cvol.$stamp
1526
1527	log_must zfs snapshot $snap
1528	log_must zfs clone $snap $clone
1529	log_must zfs promote $clone
1530
1531	typeset vol_orig=$(get_prop origin $vol)
1532	typeset clone_orig=$(get_prop origin $clone)
1533
1534	# promote should fail if $vol and $clone
1535	# miss either mount or promote permission
1536	# case 1
1537	user_run $user zfs promote $vol
1538	if [[ $vol_orig != $(get_prop origin $vol) || \
1539		$clone_orig != $(get_prop origin $clone) ]];
1540	then
1541		return 1
1542	fi
1543
1544	# promote should fail if $vol and $clone
1545	# miss either mount or promote permission
1546	# case 2
1547	log_must zfs allow $user promote $clone
1548	user_run $user zfs promote $vol
1549	log_must zfs unallow $user promote $clone
1550	if [[ $vol_orig != $(get_prop origin $vol) || \
1551		$clone_orig != $(get_prop origin $clone) ]];
1552	then
1553		return 1
1554	fi
1555
1556	# promote should fail if $vol and $clone
1557	# miss either mount or promote permission
1558	# case 3
1559	log_must zfs allow $user mount $vol
1560	user_run $user zfs promote $vol
1561	log_must zfs unallow $user mount $vol
1562	if [[ $vol_orig != $(get_prop origin $vol) || \
1563		$clone_orig != $(get_prop origin $clone) ]];
1564	then
1565		return 1
1566	fi
1567
1568	# promote should fail if $vol and $clone
1569	# miss either mount or promote permission
1570	# case 4
1571	log_must zfs allow $user mount $clone
1572	user_run $user zfs promote $vol
1573	log_must zfs unallow $user mount $clone
1574	if [[ $vol_orig != $(get_prop origin $vol) || \
1575		$clone_orig != $(get_prop origin $clone) ]];
1576	then
1577		return 1
1578	fi
1579
1580	# promote should fail if $vol and $clone
1581	# miss either mount or promote permission
1582	# case 5
1583	log_must zfs allow $user promote $clone
1584	log_must zfs allow $user mount $vol
1585	user_run $user zfs promote $vol
1586	log_must zfs unallow $user promote $clone
1587	log_must zfs unallow $user mount $vol
1588	if [[ $vol_orig != $(get_prop origin $vol) || \
1589		$clone_orig != $(get_prop origin $clone) ]];
1590	then
1591		return 1
1592	fi
1593
1594	# promote should fail if $vol and $clone
1595	# miss either mount or promote permission
1596	# case 6
1597	log_must zfs allow $user promote $clone
1598	log_must zfs allow $user mount $clone
1599	user_run $user zfs promote $vol
1600	log_must zfs unallow $user promote $clone
1601	log_must zfs unallow $user mount $vol
1602	if [[ $vol_orig != $(get_prop origin $vol) || \
1603		$clone_orig != $(get_prop origin $clone) ]];
1604	then
1605		return 1
1606	fi
1607
1608	# promote should fail if $vol and $clone
1609	# miss either mount or promote permission
1610	# case 7
1611	log_must zfs allow $user mount $vol
1612	log_must zfs allow $user mount $clone
1613	user_run $user zfs promote $vol
1614	log_must zfs unallow $user mount $vol
1615	log_must zfs unallow $user mount $clone
1616	if [[ $vol_orig != $(get_prop origin $vol) || \
1617		$clone_orig != $(get_prop origin $clone) ]];
1618	then
1619		return 1
1620	fi
1621
1622	# promote only succeeds when $vol and $clone
1623	# have both mount and promote permission
1624	# case 8
1625	log_must zfs allow $user promote $clone
1626	log_must zfs allow $user mount $vol
1627	log_must zfs allow $user mount $clone
1628	user_run $user zfs promote $vol
1629	log_must zfs unallow $user promote $clone
1630	log_must zfs unallow $user mount $vol
1631	log_must zfs unallow $user mount $clone
1632	if [[ $snap != $(get_prop origin $clone) || \
1633		$clone_orig != $(get_prop origin $vol) ]]; then
1634		return 1
1635	fi
1636
1637	return 0
1638}
1639
1640function verify_vol_volsize
1641{
1642	typeset user=$1
1643	typeset perm=$2
1644	typeset vol=$3
1645
1646	typeset oldval
1647	oldval=$(get_prop volsize $vol)
1648	(( newval = oldval * 2 ))
1649
1650	reserv_size=$(get_prop refreservation $vol)
1651
1652	if [[ "0" == $reserv_size ]]; then
1653		# sparse volume
1654		user_run $user zfs set volsize=$newval $vol
1655		if [[ $oldval == $(get_prop volsize $vol) ]];
1656		then
1657			return 1
1658		fi
1659
1660	else
1661		# normal volume, reservation permission
1662		# is required
1663		user_run $user zfs set volsize=$newval $vol
1664		if [[ $newval == $(get_prop volsize $vol) ]];
1665		then
1666			return 1
1667		fi
1668
1669		log_must zfs allow $user reservation $vol
1670		log_must zfs allow $user refreservation $vol
1671		user_run $user zfs set volsize=$newval $vol
1672		log_must zfs unallow $user reservation $vol
1673		log_must zfs unallow $user refreservation $vol
1674		if [[ $oldval == $(get_prop volsize $vol) ]];
1675		then
1676			return 1
1677		fi
1678	fi
1679
1680	return 0
1681}
1682
1683function verify_allow
1684{
1685	typeset user=$1
1686	typeset perm=$2
1687	typeset dtst=$3
1688
1689	typeset -i ret
1690
1691	user_run $user zfs allow $user allow $dtst && return 1
1692
1693	log_must zfs allow $user copies $dtst
1694	user_run $user zfs allow $user copies $dtst
1695	ret=$?
1696	log_must zfs unallow $user copies $dtst
1697	[ $ret -ne 1 ]
1698
1699}
1700