1#!/bin/ksh -p 2# 3# This file and its contents are supplied under the terms of the 4# Common Development and Distribution License ("CDDL"), version 1.0. 5# You may only use this file in accordance with the terms of version 6# 1.0 of the CDDL. 7# 8# A full copy of the text of the CDDL should have accompanied this 9# source. A copy of the CDDL is also available via the Internet at 10# http://www.illumos.org/license/CDDL. 11# 12 13# 14# Copyright 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 15# 16 17. $STF_SUITE/include/libtest.shlib 18. $STF_SUITE/tests/functional/delegate/delegate_common.kshlib 19 20# 21# DESCRIPTION: 22# ZFS 'filesystem_limit' is enforced when executing various actions 23# NOTE: the limit should *not* be enforced if the user is allowed to change it. 24# 25# STRATEGY: 26# 1. Verify 'zfs create' and 'zfs clone' cannot exceed the filesystem_limit 27# 2. Verify 'zfs rename' cannot move filesystems exceeding the limit 28# 3. Verify 'zfs receive' cannot exceed the limit 29# 30 31verify_runnable "both" 32 33# 34# The has_capability() function was first exported in the 4.10 Linux kernel 35# then backported to some LTS kernels. Prior to this change there was no 36# mechanism to perform the needed permission check. Therefore, this test 37# is expected to fail on older kernels and is skipped. 38# 39if is_linux; then 40 if [[ $(linux_version) -lt $(linux_version "4.10") ]]; then 41 log_unsupported "Requires has_capability() kernel function" 42 fi 43fi 44 45function setup 46{ 47 # We can't delegate 'mount' privs under Linux: to avoid issues with 48 # commands that may need to (re)mount datasets we set mountpoint=none 49 if is_linux; then 50 log_must zfs create -o mountpoint=none "$DATASET_TEST" 51 log_must zfs create -o mountpoint=none "$DATASET_UTIL" 52 else 53 log_must zfs create "$DATASET_TEST" 54 log_must zfs create "$DATASET_UTIL" 55 fi 56 if is_freebsd; then 57 # Ensure our non-root user has the permission to create the 58 # mountpoints and mount the filesystems. 59 sysctl vfs.usermount=1 60 log_must chmod 777 $(get_prop mountpoint "$DATASET_TEST") 61 log_must chmod 777 $(get_prop mountpoint "$DATASET_UTIL") 62 fi 63 log_must zfs allow -d -l $STAFF1 'create,mount,rename,clone,receive' \ 64 "$DATASET_TEST" 65 log_must zfs allow -d -l $STAFF1 'create,mount,rename,clone,receive' \ 66 "$DATASET_UTIL" 67} 68 69function cleanup 70{ 71 if is_freebsd; then 72 sysctl vfs.usermount=0 73 fi 74 destroy_dataset "$DATASET_TEST" "-Rf" 75 destroy_dataset "$DATASET_UTIL" "-Rf" 76 rm -f $ZSTREAM 77} 78 79log_assert "Verify 'filesystem_limit' is enforced executing various actions" 80log_onexit cleanup 81 82DATASET_TEST="$TESTPOOL/$TESTFS/filesystem_limit_test" 83DATASET_UTIL="$TESTPOOL/$TESTFS/filesystem_limit_util" 84ZSTREAM="$TEST_BASE_DIR/filesystem_limit.$$" 85 86# 1. Verify 'zfs create' and 'zfs clone' cannot exceed the filesystem_limit 87setup 88# NOTE: we allow 'canmount' to the non-root user so we can use 'log_must' with 89# 'user_run zfs create -o canmount=off' successfully 90log_must zfs allow -d -l $STAFF1 'canmount' "$DATASET_TEST" 91log_must zfs set filesystem_limit=1 "$DATASET_TEST" 92log_must user_run $STAFF1 zfs create -o canmount=off "$DATASET_TEST/create" 93log_mustnot user_run $STAFF1 zfs create -o canmount=off "$DATASET_TEST/create_exceed" 94log_mustnot datasetexists "$DATASET_TEST/create_exceed" 95log_must zfs set filesystem_limit=2 "$DATASET_TEST" 96log_must zfs snapshot "$DATASET_TEST/create@snap" 97log_must user_run $STAFF1 zfs clone -o canmount=off "$DATASET_TEST/create@snap" "$DATASET_TEST/clone" 98log_mustnot user_run $STAFF1 zfs clone -o canmount=off "$DATASET_TEST/create@snap" "$DATASET_TEST/clone_exceed" 99log_mustnot datasetexists "$DATASET_TEST/clone_exceed" 100log_must test "$(get_prop 'filesystem_count' "$DATASET_TEST")" == "2" 101# Verify filesystem_limit is *not* enforced for users allowed to change it 102log_must zfs create "$DATASET_TEST/create_notenforced_root" 103log_must zfs allow -l $STAFF1 'filesystem_limit' "$DATASET_TEST" 104log_must user_run $STAFF1 zfs create -o canmount=off "$DATASET_TEST/create_notenforced_user" 105log_must test "$(get_prop 'filesystem_count' "$DATASET_TEST")" == "4" 106cleanup 107 108# 2. Verify 'zfs rename' cannot move filesystems exceeding the limit 109setup 110log_must zfs set filesystem_limit=0 "$DATASET_UTIL" 111log_must zfs create "$DATASET_TEST/rename" 112log_mustnot user_run $STAFF1 zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed" 113log_mustnot datasetexists "$DATASET_UTIL/renamed" 114log_must test "$(get_prop 'filesystem_count' "$DATASET_UTIL")" == "0" 115# Verify filesystem_limit is *not* enforced for users allowed to change it 116log_must zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed_notenforced_root" 117log_must zfs rename "$DATASET_UTIL/renamed_notenforced_root" "$DATASET_TEST/rename" 118log_must zfs allow -l $STAFF1 'filesystem_limit' "$DATASET_UTIL" 119log_must user_run $STAFF1 zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed_notenforced_user" 120log_must datasetexists "$DATASET_UTIL/renamed_notenforced_user" 121cleanup 122 123# 3. Verify 'zfs receive' cannot exceed the limit 124setup 125log_must zfs set filesystem_limit=0 "$DATASET_TEST" 126log_must zfs create "$DATASET_UTIL/send" 127log_must zfs snapshot "$DATASET_UTIL/send@snap1" 128log_must eval "zfs send $DATASET_UTIL/send@snap1 > $ZSTREAM" 129log_mustnot user_run $STAFF1 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 130log_mustnot datasetexists "$DATASET_TEST/received" 131log_must test "$(get_prop 'filesystem_count' "$DATASET_TEST")" == "0" 132# Verify filesystem_limit is *not* enforced for users allowed to change it 133log_must eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 134log_must zfs destroy -r "$DATASET_TEST/received" 135log_must zfs allow -l $STAFF1 'filesystem_limit' "$DATASET_TEST" 136log_must user_run $STAFF1 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 137log_must datasetexists "$DATASET_TEST/received" 138 139log_pass "'filesystem_limit' property is enforced" 140