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 'snapshot_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 snapshot' cannot exceed the snapshot_limit 27# 2. Verify 'zfs rename' cannot move snapshots exceeding the limit 28# 3. Verify 'zfs promote' cannot exceed the limit 29# 4. 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 \ 65 'create,snapshot,rename,mount,promote,receive' "$DATASET_TEST" 66 log_must zfs allow -d -l $STAFF1 \ 67 'create,snapshot,rename,mount,promote,receive' "$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 'snapshot_limit' is enforced when executing various actions" 81log_onexit cleanup 82 83DATASET_TEST="$TESTPOOL/$TESTFS/snapshot_limit_test" 84DATASET_UTIL="$TESTPOOL/$TESTFS/snapshot_limit_util" 85ZSTREAM="$TEST_BASE_DIR/snapshot_limit.$$" 86 87# 1. Verify 'zfs snapshot' cannot exceed the snapshot_limit 88setup 89log_must zfs set snapshot_limit=1 "$DATASET_TEST" 90log_must user_run $STAFF1 zfs snapshot "$DATASET_TEST@snap" 91log_mustnot user_run $STAFF1 zfs snapshot "$DATASET_TEST@snap_exceed" 92log_mustnot datasetexists "$DATASET_TEST@snap_exceed" 93log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "1" 94# Verify snapshot_limit is *not* enforced for users allowed to change it 95log_must zfs snapshot "$DATASET_TEST@snap_notenforced_root" 96log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_TEST" 97log_must user_run $STAFF1 zfs snapshot "$DATASET_TEST@snap_notenforced_user" 98log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "3" 99cleanup 100 101# 2. Verify 'zfs rename' cannot move snapshots exceeding the limit 102setup 103log_must zfs set snapshot_limit=0 "$DATASET_UTIL" 104log_must zfs create "$DATASET_TEST/rename" 105log_must zfs snapshot "$DATASET_TEST/rename@snap" 106log_mustnot user_run $STAFF1 \ 107 zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed" 108log_mustnot datasetexists "$DATASET_UTIL/renamed" 109log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "0" 110# Verify snapshot_limit is *not* enforced for users allowed to change it 111log_must zfs rename "$DATASET_TEST/rename" \ 112 "$DATASET_UTIL/renamed_notenforced_root" 113log_must zfs create "$DATASET_TEST/rename" 114log_must zfs snapshot "$DATASET_TEST/rename@snap" 115log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_UTIL" 116log_must user_run $STAFF1 \ 117 zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed_notenforced_user" 118log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "2" 119cleanup 120 121# 3. Verify 'zfs promote' cannot exceed the limit 122setup 123log_must zfs set snapshot_limit=0 "$DATASET_UTIL" 124log_must zfs create "$DATASET_TEST/promote" 125log_must zfs snapshot "$DATASET_TEST/promote@snap" 126log_must zfs clone "$DATASET_TEST/promote@snap" "$DATASET_UTIL/promoted" 127log_mustnot user_run $STAFF1 zfs promote "$DATASET_UTIL/promoted" 128log_mustnot datasetexists "$DATASET_UTIL/promoted@snap" 129log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "0" 130# Verify snapshot_limit is *not* enforced for users allowed to change it 131log_must zfs promote "$DATASET_UTIL/promoted" 132log_must zfs promote "$DATASET_TEST/promote" 133log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_UTIL" 134log_must user_run $STAFF1 zfs promote "$DATASET_UTIL/promoted" 135log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "1" 136cleanup 137 138# 4. Verify 'zfs receive' cannot exceed the limit 139setup 140log_must zfs set snapshot_limit=0 "$DATASET_TEST" 141log_must zfs create "$DATASET_UTIL/send" 142log_must zfs snapshot "$DATASET_UTIL/send@snap1" 143log_must eval "zfs send $DATASET_UTIL/send@snap1 > $ZSTREAM" 144log_mustnot user_run $STAFF1 \ 145 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 146log_mustnot datasetexists "$DATASET_TEST/received" 147log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "0" 148log_must zfs set snapshot_limit=1 "$DATASET_TEST" 149log_must user_run $STAFF1 \ 150 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 151log_must zfs snapshot "$DATASET_UTIL/send@snap2" 152log_must eval "zfs send -i @snap1 $DATASET_UTIL/send@snap2 > $ZSTREAM" 153log_mustnot user_run $STAFF1 \ 154 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 155log_mustnot datasetexists "$DATASET_TEST/received@snap2" 156log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "1" 157# Verify snapshot_limit is *not* enforced for users allowed to change it 158log_must eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 159log_must zfs snapshot "$DATASET_UTIL/send@snap3" 160log_must eval "zfs send -i @snap2 $DATASET_UTIL/send@snap3 > $ZSTREAM" 161log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_TEST" 162log_must user_run $STAFF1 \ 163 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 164log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "3" 165 166log_pass "'snapshot_limit' property is enforced" 167