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