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