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 'snapshot_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 snapshot' cannot exceed the snapshot_limit 28# 2. Verify 'zfs rename' cannot move snapshots exceeding the limit 29# 3. Verify 'zfs promote' cannot exceed the limit 30# 4. Verify 'zfs receive' cannot exceed the limit 31# 32 33verify_runnable "both" 34 35# 36# The has_capability() function was first exported in the 4.10 Linux kernel 37# then backported to some LTS kernels. Prior to this change there was no 38# mechanism to perform the needed permission check. Therefore, this test 39# is expected to fail on older kernels and is skipped. 40# 41if is_linux; then 42 if [[ $(linux_version) -lt $(linux_version "4.10") ]]; then 43 log_unsupported "Requires has_capability() kernel function" 44 fi 45fi 46 47function setup 48{ 49 # We can't delegate 'mount' privs under Linux: to avoid issues with 50 # commands that may need to (re)mount datasets we set mountpoint=none 51 if is_linux; then 52 log_must zfs create -o mountpoint=none "$DATASET_TEST" 53 log_must zfs create -o mountpoint=none "$DATASET_UTIL" 54 else 55 log_must zfs create "$DATASET_TEST" 56 log_must zfs create "$DATASET_UTIL" 57 fi 58 if is_freebsd; then 59 # Ensure our non-root user has the permission to create the 60 # mountpoints and mount the filesystems. 61 sysctl vfs.usermount=1 62 log_must chmod 777 $(get_prop mountpoint "$DATASET_TEST") 63 log_must chmod 777 $(get_prop mountpoint "$DATASET_UTIL") 64 fi 65 log_must zfs allow -d -l $STAFF1 \ 66 'create,snapshot,rename,mount,promote,receive' "$DATASET_TEST" 67 log_must zfs allow -d -l $STAFF1 \ 68 'create,snapshot,rename,mount,promote,receive' "$DATASET_UTIL" 69} 70 71function cleanup 72{ 73 if is_freebsd; then 74 sysctl vfs.usermount=0 75 fi 76 destroy_dataset "$DATASET_TEST" "-Rf" 77 destroy_dataset "$DATASET_UTIL" "-Rf" 78 rm -f $ZSTREAM 79} 80 81log_assert "Verify 'snapshot_limit' is enforced when executing various actions" 82log_onexit cleanup 83 84DATASET_TEST="$TESTPOOL/$TESTFS/snapshot_limit_test" 85DATASET_UTIL="$TESTPOOL/$TESTFS/snapshot_limit_util" 86ZSTREAM="$TEST_BASE_DIR/snapshot_limit.$$" 87 88# 1. Verify 'zfs snapshot' cannot exceed the snapshot_limit 89setup 90log_must zfs set snapshot_limit=1 "$DATASET_TEST" 91log_must user_run $STAFF1 zfs snapshot "$DATASET_TEST@snap" 92log_mustnot user_run $STAFF1 zfs snapshot "$DATASET_TEST@snap_exceed" 93log_mustnot datasetexists "$DATASET_TEST@snap_exceed" 94log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "1" 95# Verify snapshot_limit is *not* enforced for users allowed to change it 96log_must zfs snapshot "$DATASET_TEST@snap_notenforced_root" 97log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_TEST" 98log_must user_run $STAFF1 zfs snapshot "$DATASET_TEST@snap_notenforced_user" 99log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "3" 100cleanup 101 102# 2. Verify 'zfs rename' cannot move snapshots exceeding the limit 103setup 104log_must zfs set snapshot_limit=0 "$DATASET_UTIL" 105log_must zfs create "$DATASET_TEST/rename" 106log_must zfs snapshot "$DATASET_TEST/rename@snap" 107log_mustnot user_run $STAFF1 \ 108 zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed" 109log_mustnot datasetexists "$DATASET_UTIL/renamed" 110log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "0" 111# Verify snapshot_limit is *not* enforced for users allowed to change it 112log_must zfs rename "$DATASET_TEST/rename" \ 113 "$DATASET_UTIL/renamed_notenforced_root" 114log_must zfs create "$DATASET_TEST/rename" 115log_must zfs snapshot "$DATASET_TEST/rename@snap" 116log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_UTIL" 117log_must user_run $STAFF1 \ 118 zfs rename "$DATASET_TEST/rename" "$DATASET_UTIL/renamed_notenforced_user" 119log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "2" 120cleanup 121 122# 3. Verify 'zfs promote' cannot exceed the limit 123setup 124log_must zfs set snapshot_limit=0 "$DATASET_UTIL" 125log_must zfs create "$DATASET_TEST/promote" 126log_must zfs snapshot "$DATASET_TEST/promote@snap" 127log_must zfs clone "$DATASET_TEST/promote@snap" "$DATASET_UTIL/promoted" 128log_mustnot user_run $STAFF1 zfs promote "$DATASET_UTIL/promoted" 129log_mustnot datasetexists "$DATASET_UTIL/promoted@snap" 130log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "0" 131# Verify snapshot_limit is *not* enforced for users allowed to change it 132log_must zfs promote "$DATASET_UTIL/promoted" 133log_must zfs promote "$DATASET_TEST/promote" 134log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_UTIL" 135log_must user_run $STAFF1 zfs promote "$DATASET_UTIL/promoted" 136log_must test "$(get_prop 'snapshot_count' "$DATASET_UTIL")" == "1" 137cleanup 138 139# 4. Verify 'zfs receive' cannot exceed the limit 140setup 141log_must zfs set snapshot_limit=0 "$DATASET_TEST" 142log_must zfs create "$DATASET_UTIL/send" 143log_must zfs snapshot "$DATASET_UTIL/send@snap1" 144log_must eval "zfs send $DATASET_UTIL/send@snap1 > $ZSTREAM" 145log_mustnot user_run $STAFF1 \ 146 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 147log_mustnot datasetexists "$DATASET_TEST/received" 148log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "0" 149log_must zfs set snapshot_limit=1 "$DATASET_TEST" 150log_must user_run $STAFF1 \ 151 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 152log_must zfs snapshot "$DATASET_UTIL/send@snap2" 153log_must eval "zfs send -i @snap1 $DATASET_UTIL/send@snap2 > $ZSTREAM" 154log_mustnot user_run $STAFF1 \ 155 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 156log_mustnot datasetexists "$DATASET_TEST/received@snap2" 157log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "1" 158# Verify snapshot_limit is *not* enforced for users allowed to change it 159log_must eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 160log_must zfs snapshot "$DATASET_UTIL/send@snap3" 161log_must eval "zfs send -i @snap2 $DATASET_UTIL/send@snap3 > $ZSTREAM" 162log_must zfs allow -l $STAFF1 'snapshot_limit' "$DATASET_TEST" 163log_must user_run $STAFF1 \ 164 eval "zfs receive $DATASET_TEST/received < $ZSTREAM" 165log_must test "$(get_prop 'snapshot_count' "$DATASET_TEST")" == "3" 166 167log_pass "'snapshot_limit' property is enforced" 168