1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright (c) 2016 by Delphix. All rights reserved.
25#
26
27. $STF_SUITE/include/libtest.shlib
28
29#
30# DESCRIPTION:
31#	zfs rename should work on existing datasets that exceed
32#	zfs_max_dataset_nesting (our nesting limit) except in the
33#	scenario that we try to rename it to something deeper
34#	than it already is.
35#
36# STRATEGY:
37#	1. Create a set of ZFS datasets within our nesting limit.
38#	2. Try renaming one of them on top of the other so its
39#	   children pass the limit - it should fail.
40#	3. Increase the nesting limit.
41#	4. Check that renaming a dataset on top of the other
42#	   cannot exceed the new nesting limit but can exceed
43#	   the old one.
44#	5. Bring back the old nesting limit so you can simulate
45#	   the scenario of existing datasets that exceed our
46#	   nesting limit.
47#	6. Make sure that 'zfs rename' can work only if we are
48#	   trying to keep existing datasets that exceed the limit
49#	   at the same nesting level or less. Making it even
50#	   deeper should not work.
51#
52
53verify_runnable "both"
54
55dsA01="a"
56dsA02="a/a"
57dsA49=$(printf 'a/%.0s' {1..48})"a"
58
59dsB01="b"
60dsB49=$(printf 'b/%.0s' {1..48})"b"
61
62dsC01="c"
63dsC16=$(printf 'c/%.0s' {1..15})"c"
64
65dsB16A=$(printf 'b/%.0s' {1..16})"a"
66dsB15A=$(printf 'b/%.0s' {1..15})"a"
67
68dsB15A47A=$(printf 'b/%.0s' {1..15})$(printf 'a/%.0s' {1..47})"a"
69dsB15A47C=$(printf 'b/%.0s' {1..15})$(printf 'a/%.0s' {1..47})"c"
70
71dsB15A40B=$(printf 'b/%.0s' {1..15})$(printf 'a/%.0s' {1..40})"b"
72dsB15A47B=$(printf 'b/%.0s' {1..15})$(printf 'a/%.0s' {1..47})"b"
73
74function nesting_cleanup
75{
76	log_must zfs destroy -fR $TESTPOOL/$dsA01
77	log_must zfs destroy -fR $TESTPOOL/$dsB01
78	log_must zfs destroy -fR $TESTPOOL/$dsC01
79
80	# If the test fails after increasing the limit and
81	# before resetting it, it will be left at the modified
82	# value for the remaining tests. That's the reason
83	# we reset it again here just in case.
84	mdb_set_uint32 zfs_max_dataset_nesting 50
85}
86
87log_onexit nesting_cleanup
88
89log_must zfs create -p $TESTPOOL/$dsA49
90log_must zfs create -p $TESTPOOL/$dsB49
91log_must zfs create -p $TESTPOOL/$dsC16
92
93log_mustnot zfs rename $TESTPOOL/$dsA02 $TESTPOOL/$dsB15A
94
95# extend limit
96mdb_set_uint32 zfs_max_dataset_nesting 64
97
98log_mustnot zfs rename $TESTPOOL/$dsA02 $TESTPOOL/$dsB16A
99log_must zfs rename $TESTPOOL/$dsA02 $TESTPOOL/$dsB15A
100
101# bring back old limit
102mdb_set_uint32 zfs_max_dataset_nesting 50
103
104log_mustnot zfs rename $TESTPOOL/$dsC01 $TESTPOOL/$dsB15A47C
105log_must zfs rename $TESTPOOL/$dsB15A47A $TESTPOOL/$dsB15A47B
106log_must zfs rename $TESTPOOL/$dsB15A47B $TESTPOOL/$dsB15A40B
107
108log_pass "Verify 'zfs rename' limits datasets so they don't pass " \
109	"the nesting limit. For existing ones that do, it should " \
110	"not allow them to grow anymore."
111