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